데이터분석 6기/본캠프

2025-05-01 비즈니스 메트릭 & 머신러닝 개인 과제 & 태블로 1-2주차

seyeon1130 2025. 5. 1. 20:19

비즈니스 메트릭

Product Goal VS Metric
  • product goal : 회사/제품이 나아가고자 하는 방향성, 결과
  • metric : 해당 방향성이 잘 달성되고 있는지 판단하기 위한 수치 기반 지표

 

좋은 메트릭 smart 프레임워크


  • specific 명확하게 정의할 수 있나
  • measurable 수치로 측정 가능하냐
  • attainable 달성 가능한가
  • relevant 제품 가치와 연결 되는가
  • time-bound 어떤 기준으로 계산하는가

 

 

+ ADI

 

  • Actionable: 지표가 실질적인 개선 행동으로 이어질 수 있어야 합니다.
  • Directional: 수치의 변화가 긍정적인지 부정적인지 명확히 해석 가능해야 합니다.
  • Interpretable: 팀원과 이해관계자가 직관적으로 이해할 수 있어야 합니다.

 

나쁜 매트릭

 

1. Vanity Metrics**: 겉보기에는 좋아 보이지만 실제 의미나 가치가 없는 지표
     예: 프로필 개설 횟수
2. Irrelevant Metrics: 제품/비즈니스 목표와 무관한 지표
     예: 앱 체류시간
3. Impractical Metrics: 우리가 조작하거나 개선할 수 없는 외부적 지표
    예: 애프터 성사율
4. Complicated Metrics: 너무 복잡해서 이해하기 어렵고 활용하기 힘든 지표
    1. 예: (고객 수 * 체류시간) / 클릭수 * 0.45 
    이 지표는 계산 방식이 너무 복잡하거나 의미 해석이 어려워서 실제 제품 개선에 활용하기 어렵습니다.*
5. Delayed Metric: 측정 결과가 너무 늦게 나와서 개선에 쓸 수 없는 지표
    1. 예: 결혼 성사율, LTV (고객의 생애가치)

 

 

AARRR 프레임워크

AARRR 과 대표 매트릭

  • Acquisition 사용자가 유입되는 단계 : 유입 채널별 클릭률
  • Activation 첫 경험에서 가치를 느낀 단계: 가입 후 3일 내 핵심 기능 사용률
  • Retention 돌아오는지 여부: 주간 재방문율
  • Referral  다른 사람에게 공유했는지 :  초대 코드 사용률
  • Revenue 매출로 연결되는지 : 구매 전환율

 

머신러닝 개인 과제

문제 1번 :pandas 응용

 

 

  • statistics csv 파일을 읽고, Category 기준 Customer ID 컬럼은 Count, Purchase Amount(USD) 컬럼은 Sum 연산을 진행해주세요. 동시에 2가지 연산을 진행해주세요. (한번의 group by)
  • 그리고 이를 df2 라는 변수에 저장해주세요.
import pandas as pd
import numpy as np 
import scipy.stats as stats
from datetime import datetime, timedelta

df = pd.read_csv('./statistics.csv')
df2 =df.groupby('Category').agg(
    {'Customer ID':'count',
    'Purchase Amount (USD)':'sum'}
    ).reset_index()

 

문제 2 : pandas 응용2

 

  • Expanding 메서드를 이용하여, Purchase Amount (USD) 의 누적 합을 계산해주세요.
  • 그리고 결과값을 df의 “Purchase Amount (USD)_누적” 컬럼으로 새롭게 지정해주세요. 그리고 Purchase Amount (USD) 과 함께 보여주세요. 결과값은 아래와 같아야 합니다.
import pandas as pd
import numpy as np 
import scipy.stats as stats
from datetime import datetime, timedelta

df['Purchase Amount (USD)_누적']=df['Purchase Amount (USD)'].expanding().sum()

 

 

문제3 : 기초통계

 

  • 성별 Review Rating 에 대한 평균과 중앙값을 동시에 구해주세요. 결과는 소수점 둘째자리까지 표현해주세요.
  • 그리고 이에 대한 해석을 간략하게 설명해주세요.
import pandas as pd
import numpy as np 
import scipy.stats as stats
from datetime import datetime, timedelta

print('남자')
print(df[df['Gender']=='Male']["Review Rating"].agg(["mean", "median"]).round(2))
print('여자')
print(df[df['Gender']=='Female']["Review Rating"].agg(["mean", "median"]).round(2))

 

남자
mean 3.75
median 3.80
여자
mean 3.74
median 3.70

 

해석: 두 그룹의 리뷰 점수가 크게 차이나지 않는다.

 

문제 4 : 통계적 가설검정

 

  • 성별, Review Rating 컬럼에 대한 T-TEST 를 진행해주세요.
    • 해당 데이터셋의 컬럼들은 정규성을 만족한다고 가정하겠습니다. (T-TEST 진행시, equal_var=True 로 지정해주세요.)
    • 귀무가설과 대립가설을 작성해주세요.
    • t-score, P-value 를 구해주세요. 단, t값의 부호는 어느 집단의 평균이 더 높은지에 대한 방향성에 대한 내용이므로, 아래와 같이 해석해주세요.
      • t > 0: 첫 번째 그룹 평균이 더 큼
      • t < 0: 두 번째 그룹 평균이 더 큼
  • 그리고 이에 대한 귀무가설 채택/기각 여부와 그렇게 생각한 이유를 간략하게 설명해주세요.
import pandas as pd
import numpy as np 
import scipy.stats as stats
from datetime import datetime, timedelta

f_df = df[df['Gender'] == 'Female']['Review Rating']
m_df = df[df['Gender'] == 'Male']['Review Rating']

t, pvalue = stats.ttest_ind(f_df, m_df)

print(f"t값: {t}")
print(f"p값: {pvalue}")

 

t값: -0.5097147504896427
p값: 0.6102801734916257

 

귀무가설 : 성별에 따라 리뷰 점수가 차이나지 않는다.

대립가설: 성별에 따라 리뷰 점수가 차이난다.

 

t값의 부호가 -이므로 두 번째 그룹(남성)의  리뷰 점수가 더 높지만, p값이 0.05보다 크므로 귀무가설을 채택한다.

 

 

문제 5: 통계적 가설검정 2

 

 

  • Color, Season 컬럼에 대한 카이제곱 검정을 진행해주세요.
    • 귀무가설과 대립가설을 작성해주세요.
    • 두 범주형 자료의 빈도표를 만들어주세요. 이를 코드로 작성하여 기재해주세요.
    • 카이제곱통계량, P-value 를 구해주세요.
  • 그리고 이에 대한 귀무가설 채택/기각 여부와 그렇게 생각한 이유를 간략하게 설명해주세요.
import pandas as pd
import numpy as np 
import scipy.stats as stats
from datetime import datetime, timedelta
from scipy.stats import chi2_contingency

result = pd.crosstab(df['Color'], df['Season'])
print(result)

chi2, p, dof, expected = chi2_contingency(result)
print(f"카이제곱 통계량: {chi2:.3f}, p-value값: {p:.3f}, 자유도: {dof}")
카이제곱 통계량: 64.651, p-value값: 0.719, 자유도: 72

 

귀무가설 : color와 season은 서로 독립이다

대립가설: color와 season은 서로 독립이 아니다.

 

p값이 0.05보다 크므로 귀무가설을 채택. 서로 독립이다.

 

 

문제 6번: 머신러닝 (선형회귀)
  • 아래와 같은 데이터가 있다고 가정하겠습니다.데이터를 바탕으로 선형 회귀 모델을 훈련시키고, 회귀식을 작성해주세요.
    • 독립 변수(X): 광고예산 (단위: 만원)
    • 종속 변수(Y): 일일 매출 (단위: 만원)
    • X=[10, 20, 30, 40, 60, 100]
    • Y=[50, 60, 70, 80, 90, 120]
  • 회귀식을통해, 새로운 광고예산이 1,000만원일 경우의 매출을 예측(계산)해주세요. 그리고 이에 대한 해석을 간략하게 설명해주세요.
import pandas as pd
import numpy as np 
from sklearn.linear_model import LinearRegression
from sklearn.metrics import mean_squared_error, mean_absolute_error, r2_score
import numpy as np
from sklearn.model_selection import train_test_split


X = np.array([10, 20, 30, 40, 60, 100]).reshape(-1, 1)
y = np.array([50, 60, 70, 80, 90, 120])


X_train, X_test, y_train, y_test = train_test_split(X,y,test_size=0.2,random_state=42)

# 모델 학습
lin_reg = LinearRegression()
lin_reg.fit(X_train, y_train)

#  예측
y_pred_lin = lin_reg.predict(X_test)

# 성능 측정
mse_lin = mean_squared_error(y_test, y_pred_lin)
rmse_lin = np.sqrt(mse_lin)  # √MSE
mae_lin = mean_absolute_error(y_test, y_pred_lin)
r2_lin = r2_score(y_test, y_pred_lin)

# 결과 출력
print("[LinearRegression 결과]")
print("가중치(coefficient):", lin_reg.coef_)
print("절편(intercept):", lin_reg.intercept_)
print("MAE:", mae_lin)
print("MSE:", mse_lin)
print("RMSE:", rmse_lin)
print("R2 점수:", r2_lin)

#1000만원일 때 예측값
x_new = np.array([[10000000]]) 
y_pred = lin_reg.predict(x_new)
print(y_pred)

 

[LinearRegression 결과]
가중치(coefficient): [0.69565217]
절편(intercept): 49.999999999999986
MAE: 5.434782608695642
MSE: 31.85255198487701
RMSE: 5.643806515542237
R2 점수: -0.27410207939508036
예측값 [6956571.73913044]

 

회귀식 : y = 50 + 0.7x

1000만원일 때: 6956571.74

 

문제 7. 머신러닝 ( 랜덤포레스트 분류)

 

 

Review Rating, Age, Previous Purchases 컬럼을 활용하여, 고객이 할인(Discount Applied)을 받을지 예측하는 RandomForest모델을 학습시켜 주세요. 그리고 모델 정확도를 계산해주세요.

 

import pandas as pd
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import LabelEncoder
from sklearn.ensemble import RandomForestClassifier
from sklearn.metrics import accuracy_score
from sklearn.metrics import classification_report

X= df[['Review Rating', 'Age', 'Previous Purchases']]
y = df['Discount Applied']

#데이터셋 나누기
X_train, X_test , y_train,y_test = train_test_split(X,y,test_size=0.3,random_state=42, stratify=y)

#라벨인코딩
le = LabelEncoder()
y_train = le.fit_transform(y_train)
y_test = le.transform(y_test)
print(le.classes_)

#모델
rf_model = RandomForestClassifier(random_state=42)
rf_model.fit(X_train, y_train)
y_prd = rf_model.predict(X_test)
accuracy = rf_model.score(X_test, y_test)

print(accuracy)
print(classification_report(y_test, y_prd))

 

 

랜덤포레스트 모델은 숫자의 크기와 상관없어서 표준화 작업을 안해도 된다.

accuracy 안에는 predict가 아니라 test가 들어간다. (내부적으로 predict 호출)

 

정확도는 0.51

구독 no : 정밀도보다 재현율이 더 높음, 즉 실제 비할인자들을 잘 예측했다.

구독 yes : 정밀도가 재현율보다 높음. 즉 할인자 예측의 정확도가 높다.

 

문제8 : 머신러닝 ( 로지스틱 회귀 분류)

 

 

import pandas as pd
import numpy as np

from sklearn.model_selection import train_test_split
from sklearn.preprocessing import LabelEncoder, StandardScaler
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import accuracy_score, classification_report


X= df[['Age','Purchase Amount (USD)', 'Review Rating']]
y = df['Subscription Status']


#데이터 나누기
X_train, X_test , y_train,y_test = train_test_split(X,y,test_size=0.3,random_state=42, stratify=y)


#라벨인코딩
le = LabelEncoder()
y_train = le.fit_transform(y_train)
y_test = le.transform(y_test)

#표준화
standard_scaler = StandardScaler()
X_train = standard_scaler.fit_transform(X_train)
X_test = standard_scaler.transform(X_test)


#로지스틱 회귀
log_reg = LogisticRegression(random_state=42, max_iter=10000)
log_reg.fit(X_train, y_train)

y_pred_logistic = log_reg.predict(X_test)

# 계수와 절편 출력
coeff_df = pd.DataFrame({
    "Feature": X.columns,
    "Coefficient": log_reg.coef_[0]
})

print("=== [로지스틱 회귀 계수] ===")
print(coeff_df.sort_values(by="Coefficient", key=abs, ascending=False))  # 절댓값 기준 정렬

# 성능 평가

print("=== Logistic Regression ===")
print("Accuracy:", accuracy_score(y_test, y_pred_logistic))
print(classification_report(y_test, y_pred_logistic))

 

로지스틱 회귀 계수는 클래스 1의 확률을 예측

여기서는 0: no, 1: yes 이므로 yes 일 확률

 

로지스틱 회귀 계수 해석: 

나이가 많을수록 구독할 가능성이 다소 증가하고, 구매 금액과 리뷰 점수는 구독 가능성에 부정적인 영향을 미치는 경향이 있다. 다만 모든 계수 값이 작기 때문에 개별 변수의 영향력은 크지 않다고 해석할 수 있다.

 

여기서는 데이터 불균형 때문에 구독할 사람들도 모두 구독 안한다고 예측해버림.

0일 때는 재현율이 1이므로  실제 비구독자를 모두 예측함.

 

불균형을 해소하기 위해 샘플링 작업을 해야함

 

 

불균형 처리 : smote사용

import pandas as pd
import numpy as np

from sklearn.model_selection import train_test_split
from sklearn.preprocessing import LabelEncoder, StandardScaler
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import accuracy_score, classification_report

from imblearn.over_sampling import SMOTE


X= df[['Age','Purchase Amount (USD)', 'Review Rating']]
y = df['Subscription Status']


#데이터 나누기
X_train, X_test , y_train,y_test = train_test_split(X,y,test_size=0.3,random_state=42, stratify=y)


#라벨인코딩
le = LabelEncoder()
y_train = le.fit_transform(y_train)
y_test = le.transform(y_test)
print(le.classes_)

#표준화
standard_scaler = StandardScaler()
X_train = standard_scaler.fit_transform(X_train)
X_test = standard_scaler.transform(X_test)


#############데이터 불균형 처리
smote = SMOTE(random_state=42)
X_train, y_train= smote.fit_resample(X_train, y_train)

#로지스틱 회귀
log_reg = LogisticRegression(random_state=42, max_iter=10000)
log_reg.fit(X_train, y_train)

y_pred_logistic = log_reg.predict(X_test)

# 계수와 절편 출력
coeff_df = pd.DataFrame({
    "Feature": X.columns,
    "Coefficient": log_reg.coef_[0]
})

print("=== [로지스틱 회귀 계수] ===")
print(coeff_df.sort_values(by="Coefficient", key=abs, ascending=False))  # 절댓값 기준 정렬

# 성능 평가

print("=== Logistic Regression ===")
print("Accuracy:", accuracy_score(y_test, y_pred_logistic))
print(classification_report(y_test, y_pred_logistic))

#새로운 데이터 예측
new_customer = np.array([[30,50,4.0]])
log_reg.predict_proba(new_customer)

 

test 데이터에는 불균형 처리를 하면 안된다.

 

 

0의 경우 정밀도가 높으므로 비구독자 예측 정확도가 높다.

1의 경우 재현율이 높으므로 실제 비구독자를 잘 예측했다.

 

predict_proba를 사용하여 새로운 데이터 예측 가능. 확률(%)로 나옴
[0.77382988, 0.22617012] 이탈할 확률이 0.77
 
 
 

개인과제 튜터님 피드백

# 필수 문제 1: Pandas 응용 필수 문제 1을 완벽하게 해결했습니다. Category 기준으로 그룹화하여 Customer ID는 count, Purchase Amount는 sum 연산을 동시에 수행하는 방법을 정확히 구현했습니다. reset_index()를 추가해서 결과를 더 보기 좋게 만든 점도 훌륭합니다. agg 함수를 사용할 때 딕셔너리 형태로 각 컬럼에 대해 서로 다른 연산을 적용하는 방법을 잘 이해하고 있습니다.

 

# 필수 문제 2: Pandas 응용 expanding 메서드를 정확하게 사용하여 누적합을 계산했습니다. 새로운 컬럼에 누적합을 저장하는 과정이 정확하고 코드도 간결하게 작성했습니다. 이 방식을 사용하면 각 행에서 해당 행까지의 모든 값을 누적하여 계산합니다.

 

# 필수 문제 3: 기초 통계 성별에 따른 Review Rating의 평균과 중앙값을 계산하는 코드를 정확하게 작성했습니다. 결과를 소수점 둘째자리까지 반올림하여 표현한 것도 좋습니다. 다만, 코드를 조금 더 간결하게 작성할 수 있습니다. ```python df.groupby('Gender')['Review Rating'].agg(['mean', 'median']).round(2) ``` 해석에서 두 그룹의 리뷰 점수가 크게 차이나지 않는다고 언급한 것은 좋습니다. 추가로 평균과 중앙값이 비슷하다는 점에서 데이터가 정규분포에 가깝다는 해석을 추가했다면 더 좋았을 것입니다.

 

# 필수 문제 4: 통계적 가설검정 t-test를 올바르게 구현했고, 귀무가설과 대립가설을 명확하게 설정했습니다. 성별로 데이터를 나누어 분석하는 과정이 정확합니다. t값과 p값을 모두 출력했고, t값의 부호 해석과 p값 해석을 통해 가설 검정 결과를 잘 도출했습니다. 귀무가설을 채택한다는 결론이 정확합니다.

 

# 필수 문제 5: 통계적 가설검정 카이제곱 검정을 정확하게 구현했습니다. pd.crosstab을 사용하여 빈도표를 생성하고, chi2_contingency 함수로 카이제곱 검정을 수행했습니다. 귀무가설과 대립가설을 정확하게 설정했고, p값 해석을 통해 가설 검정 결과를 잘 도출했습니다. 카이제곱 통계량, p값, 자유도까지 모두 출력한 것이 좋습니다. # 필수 문제 6: 머신러닝 선형 회귀 모델을 올바르게 구현했고, 여러 성능 지표(MAE, MSE, RMSE, R2)까지 계산한 점이 인상적입니다. 회귀식을 정확하게 도출했고 새로운 광고예산에 대한 예측도 수행했습니다.

 

# 도전 문제 1: 머신러닝 RandomForest 모델을 사용하여 할인 적용 여부를 예측하는 코드를 잘 작성했습니다. LabelEncoder를 사용하여 종속변수를 인코딩하고, train_test_split으로 데이터를 분할했습니다. stratify 파라미터를 사용하여 클래스 균형을 유지한 점이 훌륭합니다. 정확도뿐만 아니라 classification_report까지 출력하여 모델의 성능을 다각도로 평가한 점이 인상적입니다. 해석에서 정밀도와 재현율의 차이를 설명한 부분도 매우 좋습니다. 정확도가 0.51로 낮은 점을 인식하고 있는 것도 좋습니다.

 

# 도전 문제 2: 머신러닝 로지스틱 회귀 모델을 구현하여 구독 상태를 예측했습니다. 추가적인 기법들(StandardScaler, SMOTE)을 적용하여 모델 성능을 개선하려고 시도한 점이 인상적입니다. 데이터 불균형 문제를 인식하고 SMOTE를 사용하여 해결하려 한 점은 뛰어난 문제 해결 능력을 보여줍니다. 계수 해석을 통해 각 변수가 종속변수에 미치는 영향을 분석한 점도 훌륭합니다. 새로운 고객 데이터에 대한 예측 확률을 구했고, 분류 보고서를 통해 모델 성능을 자세히 분석했습니다.

 

 

 

태블로 1주차 강의

BI : 비즈니스 인텔리전스

조직의 의사결정을 위한 데이터 시각화 도구

 

 

데이터 인프라: 데이터 레이크 → 데이터 웨어하우스 → 데이터 마트 → BI 툴

 

📍데이터 레이크: 모든 Raw data(정형 데이터, 로그 데이터, 테이블 등) 저장할 수 있는 스토리지

📍 데이터 웨어하우스(DW): 데이터를 장기적인 보존용으로 통합, 정제, 분석하여 정리한 저장소 예) AWS Redshift, Snowflake, Google Bigquery

📍 데이터 마트(DM): 부서별, 목적별 분석용으로 만든 데이터 웨어하우스의 데이터 일부분

 

태블로 2주차 강의

 

 

연결에 + 버튼 눌러서 테이블 불러오기

연결 됐으면 파일 눌러서 화면으로 끌어오면 다른 테이블과 관계 형성 가능

 

공통키 선택하면 join 가능

 

워드 카운트

 

 

차원: id 등 기준이 되는 것

측정값 : 매출 등 집계할 수 있는 값

 

매개변수: 변수들 필터링 할 수 있음