kt: 이탈고객이 생긴다(어떻게 해결할까?)>이탈을 막는 방법을 찾자!
데이터?
어떻게 문제 해결할 것인가?
타겟값은 뭔가?(이탈1 잔류0=>분류문제)
결과를 어떻게 해석? 인사이트 도출
테이블 형태의 데이터 세트인 경우 어떤 특성을 예측타겟으로 할지 먼저 정함
어떤 문제는 회귀/분류 문제가 쉽게 구분이 안되는 경우가 있음
- 이산형, 순서형, 범주형 타겟 특성도 회귀문제 또는 다중클래스분류 문제로도 볼 수 있음
- 회귀, 다중클래스분류 문제들도 이진분류 문제로 바꿀 수 있음
해결: 전처리과정에서 데이터 오염이 없도록 파이프라인 잘 만들기
회귀/분류 평가지표 다름
로지스틱-분류인데 결정계수를 쓰면 안됨
sklearn-metrics 공식문서
https://scikit-learn.org/stable/modules/model_evaluation.html#common-cases-predefined-values
분류 metrics
https://scikit-learn.org/stable/modules/model_evaluation.html#classification-metrics
-평가지표: 정밀도, 정확도, F1score, Roc curve, Auc
- 분류문제에서 타겟 클래스 비율이 70%이상 차이날 경우 정확도만 사용하면 판단을 정확히 할 수 없어서 정밀도, 재현률, ROC curve, AUC를 같이 사용
from sklearn.metrics import plot_confusion_matrix import matplotlib.pyplot as plt fig, ax = plt.subplots() pcm = plot_confusion_matrix(pipe, X_val, y_val, cmap=plt.cm.Blues, ax=ax) plt.title(f'Confusion matrix, n ={len(y_val)}', fontsize=15)
회귀 metrics
https://scikit-learn.org/stable/modules/model_evaluation.html#regression-metrics
-평가지표: MAE, RMSE, R2, MSE
선형회귀모델
# house price 데이터를 사용합니다.
df = pd.read_csv('https://ds-lecture-data.s3.ap-northeast-2.amazonaws.com/house-prices/house_prices_train.csv')
target = df['SalePrice']
# 타겟 분포가 right(positively) skewed 되어 있네요!
sns.displot(target);
위 그림은 타겟 분포가 right(positively) skewed로 되어있음
해결1. 이상치 제거 후 정규 분포로 만들어줄 필요가 있음
## 몇몇 가격이나 다른 수치들은 은 너무 높아 문제가 될 수 있습니다. import numpy as np ## 타겟 이상치(outlier)를 제거합니다. df['SalePrice'] = df[df['SalePrice'] < np.percentile(df['SalePrice'], 99.5)]['SalePrice'] ## 몇몇 변수를 합쳐주기 df['All_Flr_SF'] = df['1stFlrSF'] + df['2ndFlrSF'] df['All_Liv_SF'] = df['All_Flr_SF'] + df['LowQualFinSF'] + df['GrLivArea'] df = df.drop(['1stFlrSF','2ndFlrSF','LowQualFinSF','GrLivArea'], axis=1) #이상치 제거 df['All_Flr_SF'] = df[df['All_Flr_SF'] < np.percentile(df['All_Flr_SF'], 99.5)]['All_Flr_SF'] df['All_Liv_SF'] = df[df['All_Liv_SF'] < np.percentile(df['All_Liv_SF'], 99.5)]['All_Liv_SF'] df['SalePrice']
# 분포의 치우침이 어느정도 개선은 되었지만 여전히 right-skewed 상태입니다. target = df['SalePrice'] sns.displot(target);
해결2. 로그 변환(Log-Transform)
- 타겟이 right-skewed 상태라면 로그 변환을 사용해 비대칭 분포형태를 정규분포형태로 변환 시켜줌
위에 이미지 처럼 로그변환해서 정규분포 형태로 만들어준다는 의미plots=pd.DataFrame() plots['original']=target plots['transformed']=np.log1p(target) #로그 변환 plots['backToOriginal']=np.expm1(np.log1p(target)) #로그 풀어주기 fig, ax = plt.subplots(1,3,figsize=(15,5)) sns.histplot(plots['original'], ax=ax[0]); sns.histplot(plots['transformed'], ax=ax[1]); sns.histplot(plots['backToOriginal'], ax=ax[2]);
로그 변환 코드
from category_encoders import OrdinalEncoder from sklearn.impute import SimpleImputer from sklearn.ensemble import RandomForestRegressor from sklearn.compose import TransformedTargetRegressor pipe = make_pipeline( OrdinalEncoder(), SimpleImputer(), RandomForestRegressor(random_state=2) ) #로그 넣어주고(np.log1p) 풀어주는 함수 사용(np.expm1) tt = TransformedTargetRegressor(regressor=pipe,func=np.log1p, inverse_func=np.expm1) tt.fit(X_train, y_train) tt.score(X_val, y_val)