모델 선택
- 샘플이 적고 feature가 많은 경우 -> 선형 모델
- 샘플이 많고 feature가 적은 경우 -> 앙상블 모델
1. Decision Tree
- 특징
- 이상치에 강한 모델임
- tree를 분리하는 과정에서 feature selection이 자동으로 사용됨
- 연속형과 범주형 변수를 모두 다루기 때문에 사전 데이터 준비가 많이 필요하지 않다
- 결측값을 하나의 가지로 다룰 수 있기 때문에 이를 예측에 활용할 수 있다.
- 분류율은 낮은편. 여러 변수를 동시에 고려하지 못함
- 엔트로피 : 결정 규칙을 분리할 수 있는 기준으로 데이터의 무질서 정도를 측정할 수 있는 방법
- 의사결정나무에서는 엔트로피가 높을 수록 class 구분을 잘 못해주는 feature가 되며, 낮을 수록 구분을 잘 해주는 유의한 feature가 된다.
- 가지치기 : 현재의 노드에서 더 이상 분리가 일어나지 못하게 하는 규칙
- 노드에 속하는 자료가 일정한 수 이하일 때 : min_samples_split
- 불순도의 감소량이 아주 적을 때 : min_impurity_decrease
- 뿌리 노드로부터 깊이가 일정 수 이상일 때: max_depth
- 리프의 수가 일정 수 이상일 때 : max_leaf_nodes
2. Random Forest
- 특징
- 숲의 크기(나무의 수)가 커질 수록 일반화 오류가 특정 값으로 수렴하게 되어 over-fitting을 피할 수 있다.
- 최종 결과에 대한 해석이 어렵다.(시각화 X)
- 하이퍼파라미터
- ntree (나무 몇개?): 기본값은 500
- mtry(feature 몇개?) : 전체 특징변수의 개수가 M이라고 할 때
- 분류: mtry=루트M
- 예측: mtry=M/3
3. LightGBM, XGBoost, Catboost
- lightGBM
- gbm보다 속도가 빠르다.
- 원핫인코딩을 다시 라벨인코딩으로 원복하는 느낌이라 샘플 수, feature 수가 줄어든다.
- XGBoost
- Catboost
- 범주형이 많을 경우 사용
- 하이퍼파라미터 튜닝 할 필요 없음
- categorical encoding을 알아서 잘 해주니까 범주형 인코딩도 굳이 필요 없음
- but 느리다.
def clf_report(tr_x, tr_y, te_x, te_y, model, seed=456):
if model ='xgb':
clf = XGBClassifier(random_state=seed)
elif model ='rf':
clf = RandomForestClassifier(random_state=seed)
elif model ='svm':
clf = svm.SVC(kernel='linear', C=0.1, probability=True)
else:
clf = ExtraTreeClassifier(random_state=seed)
clf.fit(tr_x, tr_y)
pred = clf.predict(te_x)
print(classification_report(te_y, pred))
cm = confusion_matrix(te_y, pred)
plt.figure(figsize=(8,6))
sns.heatmap(cm, annot=True, fmt='d', cmap='Blues', xticklabels=['0','1'], yticklabels=['0', '1'])
plt.xlabel('Predicted Labels')
ptl.ylabel('True Labels')
plt.title(f'{model} confusion Matrix')
plt.show()
pred_prob = clf.predict_proba(te_x)
return pred_prob[:,1]
def regression(tr_x, tr_y, te_x, te_y, reg, seed=456):
if reg ='xgb':
model = XGBRegressor(random_state=seed)
elif reg ='rf':
model = RandomForestRegressor(random_state=seed)
elif reg ='gb':
model = GradientBoostingRegressor(random_state=seed)
else:
model = ExtraTreeRegressor(random_state=seed)
model.fit(tr_x, tr_y)
pred = model.predict(te_x)
rmse = np.sqrt(mean_squared_error(te_y, pred))
r2 = r2_score(te_y, pred)
print(f"{reg} - rmse: {rmse:.2f}, r2: {r2:.2f}")
plt.figure(figsize=(8,6))
sns.scatterplot(x=np.arange(len(pred)), y=pred);
sns.scatterplot(x=np.arange(len(pred)), y=te_y);
plt.title(f"{reg} Regressor - Actual vs Predicted")
plt.show()
return pred