A. ์ฌ๋ฌ๊ฐ์ง ์ฑ๋ฅ ํ๊ฐ ์งํ
1. ์ค์ฐจ ํ๋ ฌ
์ค์ฐจํ๋ ฌ(confusion matrix)์ ํ์ต ์๊ณ ๋ฆฌ์ฆ์ ์ฑ๋ฅ์ ํ๋ ฌ๋ก ํผ์ณ๋ ๊ฒ์ ๋๋ค. ์๋ ๊ทธ๋ฆผ๊ณผ ๊ฐ์ด ์ง์ง ์์ฑ(True Positive, TP), ์ง์ง ์์ฑ(True Negative, TV), ๊ฐ์ง ์์ฑ(False Positive, FP), ๊ฐ์ง ์์ฑ(False Negative, FN)์ ๊ฐ์๋ฅผ ์ ์ ์ ๋ฐฉ ํ๋ ฌ์ด์ฃ .
์ด ํ๋ ฌ์ ๋ง๋ค ๋ ๋ฌผ๋ก ์ง์ ์ธ์ด์ ๊ณ์ฐํ ์๋ ์์ง๋ง ์ฌ์ดํท๋ฐ์ ํจ์ confusion_matrix ๋ฅผ ์ฌ์ฉํ ์๋ ์์ต๋๋ค.
from sklearn.metrics import confusion_matrix
pipe_svc.fit(X_train, y_train)
y_pred = pipe_svc.predict(X_test)
confmat = confusion_matrix(y_true=y_test, y_pred=y_pred)
print(confmat)
์ด ์ฝ๋๋ฅผ ์คํํด ์ป์ ๋ฐฐ์ด์ด ๋ถ๋ฅ๊ธฐ๊ฐ ํ ์คํธ ์ธํธ์์ ์ผ์ผํจ ์ค๋ฅ์ ์ข ๋ฅ๋ฅผ ์๋ ค์ค๋๋ค. ์ด์ matshow ํจ์๋ฅผ ํตํด ์ ๊ทธ๋ฆผ๊ณผ ๊ฐ์ด ํํํด๋ณด๊ฒ ์ต๋๋ค.
fig, ax = plt.subplots(figsize=(2.5, 2.5))
ax.matshow(confmat, cmap=plt.cm.Blues, alpha=0.3)
for i in range(confmat.shape[0]):
for j in range(confmat.shape[1]):
ax.text(x=j, y=i, s=confmat[i, j], va='center', ha='center')
plt.xlabel('Predicted label')
plt.ylabel('True label')
plt.tight_layout()
plt.show()
์์ ์ธ์ ์์ ์ฐ๊ณ ์์๋ ์ ๋ฐฉ์ ๋ฐ์ดํฐ์ ์์ ํด๋์ค 1, ์ ์ฑ ์ข ์์ด ์์ฑ ํด๋์ค์ ๋๋ค. ์ด ๋ชจ๋ธ์ 71๊ฐ ์ ์ฑ ์ข ์๊ณผ 40๊ฐ์ ์ ์ฑ์ด ์๋ ์ข ์์ ์ ํํ๊ฒ ๊ตฌ๋ถํ์ง๋ง, ํด๋์ค 1์ธ ์ํ ๋ ๊ฐ๋ 2๋ก ์๋ชป ๋ถ๋ฅํ๊ณ 2์ธ ์ํ ํ๋๋ 1๋ก ์๋ชป ๋ถ๋ฅํ์์ ์ ์ ์์ต๋๋ค.
2. ๋ถ๋ฅ ๋ชจ๋ธ์ ์ ๋ฐ๋์ ์ฌํ์จ ์ต์ ํ
์์ธก ์ค์ฐจ(ERR)์ ์ ํ๋(ACC)๋ ์ผ๋ง๋ ๋ง์ ์ํ์ ์๋ชป ๋ถ๋ฅํ๋์ง์ ๋ํ ์ ๋ณด๋ฅผ ์๋ ค์ค๋๋ค. ์ค์ฐจ๋ ์๋ชป๋ ์์ธก/์ ์ฒด ์์ธก์ด๊ณ , ์ ํ๋๋ ์ณ์ ์์ธก/์ ์ฒด ์์ธก์ ๋๋ค. ์๋๊ฐ ์์ธก ์ค์ฐจ๋ฅผ ๊ณ์ฐํ๋ ๋ฐฉ๋ฒ์ ๋๋ค.
์๋ ์์์ด ์์ธก ์ ํ๋์ ๋๋ค.
์ง์ง ์์ฑ ๋น์จ๊ณผ ๊ฑฐ์ง ์์ฑ ๋น์จ์ ํด๋์ค์ ๋น์จ์ด ๋ค๋ฅธ ๊ฒฝ์ฐ์ ์ ์ฉํฉ๋๋ค. ๊ณ์ฐ์ ์๋์ ๊ฐ์ต๋๋ค.
์ ํ๋(PRE)์ ์ฌํ์จ(REC)๋ ์ง์ง ์์ฑ๊ณผ ์ง์ง ์์ฑ ์ํ์ ๋น์จ๊ณผ ๊ด๋ จ์์ต๋๋ค. ์ฌ์ค ์ฌํ์จ์ ์ง์ง ์์ฑ ๋น์จ์ ๋ค๋ฅธ ๋ง์ด์ฃ . ์ค์ ์์๋ ์ ํ๋์ ์ฌํ์จ์ ํฉ์น F1-์ ์๋ฅผ ์์ฃผ ์ฌ์ฉํฉ๋๋ค.
์ด์ ์ด๋ฐ ์ฑ๋ฅ ์งํ๋ค์ ์ฌ์ดํท๋ฐ์ผ๋ก ๊ตฌํํด๋ณผ๊น์? sklearn.metrics์์ ์ฌ์ฉํ ์ ์์ต๋๋ค.
from sklearn.metrics import precision_score, recall_score, f1_score
print('์ ๋ฐ๋: %.3f' % precision_score(y_true=y_test, y_pred=y_pred))
print('์ฌํ์จ: %.3f' % recall_score(y_true=y_test, y_pred=y_pred))
print('F1: %.3f' % f1_score(y_true=y_test, y_pred=y_pred))
ํน์ GridSearchCV์ scoring ๋งค๊ฐ๋ณ์๋ฅผ ์ฌ์ฉํด์ ์ ํ๋ ๋์ ๋ค๋ฅธ ์งํ๋ฅผ ์ฌ์ฉํ ์๋ ์์ต๋๋ค. scoring์ ๋ํ ์์ธํ ๋ด์ฉ์ ๋งํฌ๋ฅผ ์ฐธ์กฐํ์ธ์! (https://scikit-learn.org/stable/modules/model_evaluation.html)
์ฌ์ดํท๋ฐ์์ ์์ฑ ํด๋์ค๋ ํญ์ ๋ ์ด๋ธ์ด 1์ธ ํด๋์ค์ ๋๋ค. ๋ฐ๊พธ๊ณ ์ถ๋ค๋ฉด make_scorer ํจ์๋ฅผ ์ฌ์ฉํ๊ณ , scoring ๋งค๊ฐ๋ณ์์ ์ ๋ฌํ ์ ์์ต๋๋ค.
from sklearn.metrics import make_scorer
scorer = make_scorer(f1_score, pos_label=0)
c_gamma_range = [0.01, 0.1, 1.0, 10.0]
param_grid = [{'svc__C': c_gamma_range,
'svc__kernel': ['linear']},
{'svc__C': c_gamma_range,
'svc__gamma': c_gamma_range,
'svc__kernel': ['rbf']}]
gs = GridSearchCV(estimator=pipe_svc,
param_grid=param_grid,
scoring=scorer,
cv=10,
n_jobs=-1)
gs = gs.fit(X_train, y_train)
print(gs.best_score_)
print(gs.best_params_)
3. ROC ๊ณก์ ๊ทธ๋ฆฌ๊ธฐ
ROC(Receiver Operating Characteristic) ๊ทธ๋ํ๋ ๋ถ๋ฅ๊ธฐ์ ์๊ณ ๊ฐ์ ๋ฐ๊พธ๋ฉด์ ๊ณ์ฐํด๋ FPR๊ณผ TPR ์ ์๋ฅผ ๊ธฐ๋ฐ์ผ๋ก ๋ถ๋ฅ ๋ชจ๋ธ์ ์ ํํ๋ ๋๊ตฌ๋ผ๊ณ ํ ์ ์์ต๋๋ค. ROC ๊ทธ๋ํ์ ๋๊ฐ์ ์ ๋๋ค ์ถ์ธก, ๋๊ฐ์ ์๋์ ๋ถ๋ฅ ๋ชจ๋ธ์ ๋๋ค ์ถ์ธก๋ณด๋ค ๊ฒฐ๊ณผ๊ฐ ๋ฎ์ ๊ฒ์ ์๋ฏธํฉ๋๋ค. ์๋ฒฝํ ๋ถ๋ฅ๊ธฐ๋ ROC ๊ทธ๋ํ์์ TPR์ด 1์ด๊ณ FPR์ด 0์ธ ์ผ์ชฝ ์ ๊ตฌ์์ ์์นํฉ๋๋ค.
ROC ๊ณก์ ์ ์๋ซ ๋ถ๋ถ ๋ฉด์ ์ ROC AUC(ROC Area under the curve)๋ผ๊ณ ํ๋๋ฐ์, ์ด ๋ถ๋ถ์ ๊ณ์ฐํ๋ฉด ๋ถ๋ฅ ๋ชจ๋ธ์ ์ฑ๋ฅ์ ์ข ํฉํ ์๋ ์์ต๋๋ค.
ROC ๊ณก์ ๊ณผ ๋น์ทํ๊ฒ ๋ถ๋ฅ ๋ชจ๋ธ์ ํ๋ฅ ์๊ณ ๊ฐ์ ๋ฐ๊พธ๋ฉด์ ์ ๋ฐ๋-์ฌํ์จ ๊ณก์ ์ ๊ทธ๋ฆด ์ ์์ต๋๋ค. ์ด ํจ์๋ ์ฌ์ดํท๋ฐ์ ๊ตฌํ๋์ด์๋๋ฐ, ์ด ๋งํฌ์์ ํ์ธํ์ค ์ ์์ต๋๋ค.(http://scikit-learn.org/stable/modules/generated/sklearn.metrics.precision_recall_curve.html)
์ด์ ์์ ์ญ ์ฌ์ฉํด์จ ์์ค์ฝ์ ๋ฐ์ดํฐ๋ฅผ ํตํด ROC ๊ณก์ ์ ๊ทธ๋ ค๋ณด๋๋ก ํ๊ฒ ์ต๋๋ค. ๋ก์ง์คํฑ ํ๊ท ํ์ดํ๋ผ์ธ์ ์ฌ์ฉํ์ง๋ง ์กฐ๊ธ ๋ ๋์ ๊ณก์ ์ ๊ทธ๋ฆฌ๊ธฐ ์ํด์ ์กฐ๊ธ ์ด๋ ต๊ฒ ์์ ์ ๊ตฌ์ฑํ์์ต๋๋ค.
from sklearn.metrics import roc_curve, auc
from scipy import interp
pipe_lr = make_pipeline(StandardScaler(),
PCA(n_components=2),
LogisticRegression(solver='liblinear',
penalty='l2',
random_state=1,
C=100.0))
X_train2 = X_train[:, [4, 14]]
cv = list(StratifiedKFold(n_splits=3,
random_state=1).split(X_train, y_train))
fig = plt.figure(figsize=(7, 5))
mean_tpr = 0.0
mean_fpr = np.linspace(0, 1, 100)
all_tpr = []
for i, (train, test) in enumerate(cv):
probas = pipe_lr.fit(X_train2[train],
y_train[train]).predict_proba(X_train2[test])
fpr, tpr, thresholds = roc_curve(y_train[test],
probas[:, 1],
pos_label=1)
mean_tpr += interp(mean_fpr, fpr, tpr)
mean_tpr[0] = 0.0
roc_auc = auc(fpr, tpr)
plt.plot(fpr,
tpr,
label='ROC fold %d (area = %0.2f)'
% (i+1, roc_auc))
plt.plot([0, 1],
[0, 1],
linestyle='--',
color=(0.6, 0.6, 0.6),
label='random guessing')
mean_tpr /= len(cv)
mean_tpr[-1] = 1.0
mean_auc = auc(mean_fpr, mean_tpr)
plt.plot(mean_fpr, mean_tpr, 'k--',
label='mean ROC (area = %0.2f)' % mean_auc, lw=2)
plt.plot([0, 0, 1],
[0, 1, 1],
linestyle=':',
color='black',
label='perfect performance')
plt.xlim([-0.05, 1.05])
plt.ylim([-0.05, 1.05])
plt.xlabel('false positive rate')
plt.ylabel('true positive rate')
plt.legend(loc="lower right")
plt.tight_layout()
plt.show()
์ฌ์ดํท๋ฐ์ StratifiedKFold๋ฅผ ์ฌ์ฉํ์ต๋๋ค. ๋ฐ๋ณต๋ฌธ ์์์ sklearn.metrics๋ชจ๋์ roc_curve ํจ์๋ฅผ ์ด์ฉํด pipe_lr ํ์ดํ ๋ผ์ธ์ ๋ก์ง์คํฑ ๋ฆฌ๊ทธ๋ ์ด์ ๋ชจ๋ธ์ ROC๋ฅผ ๊ณ์ฐํด์ฃผ์์ต๋๋ค.๊ทธ๋ฆฌ๊ณ Scipy ์ interpํจ์๋ก ๊ฐ ํด๋์ ROC ๊ณก์ ์ ๋ณด๊ฐํด ํ๊ท ์ ๊ตฌํด์ฃผ์์ต๋๋ค. ์ฌ๊ธฐ์ ๋ณด๊ฐ์ด๋ผ๋ ๋ง์ด ์์ํ์คํ ๋ฐ์, ๋ณด๊ฐ์ ๋ ์ ์ ์ฐ๊ฒฐํ๋ ๋ฐฉ๋ฒ์ ์๋ฏธํฉ๋๋ค. ์ฌ๊ธฐ์ ๋งํ๋ ์ฐ๊ฒฐ์ ๊ถค์ ์ ์์ฑํ๋ค๋ ๋ป์ ๊ฐ์ง๊ณ ์์ต๋๋ค.
๊ทธ๋ฆฌ๊ณ auc ํจ์๋ก ๊ณก์ ์๋ ๋ฉด์ ์ ๊ณ์ฐํด์ฃผ์์ต๋๋ค. ์ฌ๊ธฐ์ ํ๊ท ROC AUC(0.76)์ ์๋ฒฝํ๊ฒ ๋ถ๋ฅ๋ ๊ฒฝ์ฐ 0.5์์ 1.0 ์ฌ์ด์ ๊ฐ์ ๊ฐ์ง๋๋ค. ROC AUC ์ ์์๋ง ๊ด์ฌ์ด ์์ผ๋ฉด sklearn.metrics ๋ชจ๋์ roc_auc_score ํจ์๋ฅผ ์ฌ์ฉํ ์๋ ์๋ค๊ณ ํฉ๋๋ค.
์ด์ฒ๋ผ ROC AUC๋ก ์ฑ๋ฅ์ ์กฐ์ฌํ๋ฉด ๋ถ๊ท ํํ ๋ฐ์ดํฐ์์ ๋ถ๋ฅ๊ธฐ์ ์ฑ๋ฅ์ด ์ด๋ค์ง ๋ ํ์คํ ์ ์ ์์ต๋๋ค.
4. ๋ค์ค ๋ถ๋ฅ์ ์ฑ๋ฅ ์งํ
์ด๋ฒ์ ์ธ๊ธํ ์ฑ๋ฅ ์งํ๋ ์ด์ง ๋ถ๋ฅ์ ์ ์ฉ๋๋ ์ด์ผ๊ธฐ์ ๋๋ค. ์ฌ์ดํท๋ฐ์ ํ๊ท ์งํ์ ๋งํฌ๋ก(macro)์ ๋ง์ดํฌ๋ก(micro) ํ๊ท ๋ฐฉ์์ ๊ตฌํํด OvA(One-versus-All) ๋ฐฉ์์ ์ฌ์ฉํ๋ ๋ค์ค ๋ถ๋ฅ๋ก ํ์ฅ์ํต๋๋ค. ๋ง์ดํฌ๋ก ํ๊ท ๊ณผ ๋งํฌ๋ก ํ๊ท ์ ๋ํด์ ๋ฏธ๋ฆฌ ๋น๊ตํด๋ณผ๊น์?
๋ง์ดํฌ๋ก ํ๊ท ์ ํด๋์ค๋ณ๋ก TP, TN, FP, FN์ ๊ณ์ฐํฉ๋๋ค. k๊ฐ ํด๋์ค๊ฐ ์๋ ๊ฒฝ์ฐ ์ ๋ฐ๋์ ๋ง์ดํฌ๋ก ํ๊ท ์ ์๋์ ๊ฐ์ด ๊ณ์ฐํฉ๋๋ค.
๋งํฌ๋ก ํ๊ท ์ ๊ฐ๋จํ๊ฒ ํด๋์ค ๋ณ ์ ๋ฐ๋์ ํ๊ท ์ ๋๋ค. ์์ ์๋์ ๊ฐ์ต๋๋ค.
๋ง์ดํฌ๋ก ํ๊ท ์ ๊ฐ ์ํ ํน์ ์์ธก์ ๊ฐ์ ๊ฐ์ค์น๋ฅผ ๋ถ์ฌํ๋ ค๊ณ ํ ๋ ์ฌ์ฉํฉ๋๋ค. ๋งํฌ๋ก ํ๊ท ์ ๋ชจ๋ ํด๋์ค์ ๋์ผํ ๊ฐ์ค์น๋ฅผ ๋ถ์ฌํด ๋ถ๋ฅ๊ธฐ์ ์ ๋ฐ์ ์ฑ๋ฅ์ ํ๊ฐํ์ฃ . ์ด ๊ฒฝ์ฐ์๋ ๊ฐ์ฅ ๋์ ๋น๋๋ฅผ ์๋ํ๋ ํด๋์ค ๋ ์ด๋ธ์์์ ์ฑ๋ฅ์ด ์ค์ํฉ๋๋ค.
์ฌ์ดํท ๋ฐ์์ ์ด์ง ์ฑ๋ฅ ์งํ๋ก ๋ค์ค ๋ถ๋ฅ ๋ชจ๋ธ์ ํ๊ฐํ๋ฉด ์ ๊ทํ๊ฐ ๊ธฐ๋ณธ์ ์ผ๋ก ์ ์ฉ๋๊ฑฐ๋ ๊ฐ์ค์น๊ฐ ์ ์ฉ๋ ๋งํฌ๋ก ํ๊ท ์ด ์ ์ฉ๋ฉ๋๋ค. ๋งํฌ๋ก ํ๊ท ์ ํ๊ท ๊ณ์ฐ ์์ ๊ฐ ํด๋์ค์ ์ํ ๊ฐ์๋ฅผ ๊ฐ์คํด ๊ณ์ฐํด์ค๋๋ค. ๋ ์ด๋ธ๋ง๋ค ์ํ ๊ฐ์๊ฐ ๋ค๋ฅผ ๋ ์ ์ฉํ์ฃ .
๋งํฌ๋ก ํ๊ท ์ด ๊ธฐ๋ณธ๊ฐ์ด์ง๋ง sklearn.metrics ๋ชจ๋ ์๋์ ์ธก์ ํจ์๋ค์ average ๋งค๊ฐ๋ณ์๋ก ํ๊ท ์ ๊ณ์ฐํ ์ ์์ต๋๋ค. precision_score ์ด๋ maker_scorer ํจ์์ ๋๋ค.
pre_scorer = make_scorer(score_func=precision_score,
pos_label=1,
greater_is_better=True,
average='micro')
B. ๋ถ๊ท ํํ ํด๋์ค ๋ค๋ฃจ๊ธฐ
์, ์์ ์ธ์ ๊ณผ ๋จ๋ฝ์์ ๊ณ์ ๋ถ๊ท ํํ ํด๋์ค๋ฅผ ์ธ๊ธํด์์ง๋ง ์ ์ ํ ์ฒ๋ฆฌ ๋ฐฉ๋ฒ์ ๋ํด์๋ ์ด์ผ๊ธฐํ์ง ์์๋ ๊ฒ ๊ฐ์์. ํด๋์ค ๋ถ๊ท ํ์ ๊ต์ฅํ ์์ฃผ ๋ํ๋๋ ๋ฌธ์ ์ ๋๋ค. ์คํธ ํํฐ๋ง, ์ง๋ณ ์ฐจ๋จ ๋ฑ์ ์์๋ก ๋ค ์ ์์ต๋๋ค.
๊ณ์ ์ฌ์ฉ์ค์ธ ์ ๋ฐฉ์ ๋ฐ์ดํฐ์ ์ด 90%๋ ๊ฑด๊ฐํ ํ์๋ผ๊ณ ๊ฐ์ ํด๋ณด๊ฒ ์ต๋๋ค. ์ด ๊ฒฝ์ฐ์๋ ๋ชจ๋ ์ํ์ ๋ํด ์์ฑ ์ข ์์ด๋ผ๊ณ ์์ธกํ๊ธฐ๋ง ํด๋ ํ ์คํธ ์ธํธ์์ ์ ํ๋๊ฐ 90%๊ฐ ๋๊ฒ ์ฃ ? ์ด ๊ฒฝ์ฐ์๋ ์ ํ๋๋ ๋๋ค๊ณ ํด๋ ์ ํ์ตํ ๊ฒฝ์ฐ๋ ๋น์ฐํ ์๋๋๋ค.
์ผ๋จ, ๋ถ๊ท ํํ ๋ฐ์ดํฐ์ ์ ๋ค๋ฃฐ ๋ ๋์์ ์ค ์ ์๋ ๊ธฐ๋ฒ์ ์์๋ณด๊ธฐ ์ ์ 212๊ฐ ์ ์ฑ ์ข ์๊ณผ 357๊ฐ ์์ฑ ์ข ์์ ๊ฐ์ง ์ ๋ฐฉ์ ๋ฐ์ดํฐ ์ ์์ ๋ถ๊ท ํ ๋ฐ์ดํฐ๋ฅผ ๋ง๋ค์ด๋ณด๊ฒ ์ต๋๋ค.
X_imb = np.vstack((X[y == 0], X[y == 1][:40]))
y_imb = np.hstack((y[y == 0], y[y == 1][:40]))
y_pred = np.zeros(y_imb.shape[0])
np.mean(y_pred == y_imb) * 100
์ด๋ฐ ๋ฐ์ดํฐ์์๋ ์ ํ๋๋ฅผ ์ฌ์ฉํ๋ ๊ฒ๋ณด๋ค ๋ค๋ฅธ ์งํ๋ฅผ ์ฌ์ฉํด ๋ชจ๋ธ์ ๋น๊ตํ๋ ๊ฒ์ด ์ข์ต๋๋ค. ์ฃผ์ ๊ด์ฌ ๋์์ด ๋ฌด์์ธ์ง์ ๋ฐ๋ผ ์ ํ๋ ๋์ ์ฌํ์จ, ROC ๊ณก์ ๋ฑ์ ์ฌ์ฉํ ์ ์์ต๋๋ค. ์๋ฅผ ๋ค์ด ์ถ๊ฐ ๊ฒ์ฌ๊ฐ ํ์ํ ์ ์ฑ ์ข ์ ํ์๋ฅผ ๊ตฌ๋ณํ๋ ๊ฒ์ด ๊ด์ฌ ๋์์ด๋ผ๋ฉด ์ฌํ์จ ์งํ๋ฅผ ์ ํํ๋ ๊ฒ ๋ง๊ฒ ์ฃ .
๋ชจ๋ธ ํ๊ฐ์๋ ๋ณ๊ฐ๋ก ํด๋์ค ๋ถ๊ท ํ์ ํ๋ จํ๋ ๋์ ์๊ณ ๋ฆฌ์ฆ ์์ฒด์ ์ํฅ์ ๋ฏธ์นฉ๋๋ค. ํ๋ จํ๋ ๋์ ์ฒ๋ฆฌํ ์ํ์์ ๋น์ฉํจ์์ ํฉ์ ์ต์ ํํ๊ธฐ ๋๋ฌธ์, ๊ฒฐ๊ณผ๊ฐ ๋ค์ ํด๋์ค ์ชฝ์ผ๋ก ํธํฅ๋๊ธฐ ์ฝ์ต๋๋ค. ๋น์ฉ์ ์ต์ํํ๊ธฐ ์ํด์ ๋ฐ์ดํฐ ์ ์์ ๊ฐ์ฅ ๋น๋๋์ ํด๋์ค์ ์์ธก์ ์ต์ ํํ๋ ๋ชจ๋ธ์ ํ์ตํ๋ ๊ฒ์ด์ฃ .
๋ถ๊ท ํํ ํด๋์ค๋ฅผ ๋ค๋ฃจ๋ ๋ฐฉ๋ฒ ํ ๊ฐ์ง๋ ์์ ํด๋์ค์์ ๋ฐ์ํ ์์ธก ์ค๋ฅ์ ํฐ ๋น์ฉ์ ๋ถ์ฌํ๋ ๊ฒ์ ๋๋ค. class_weight ๋งค๊ฐ๋ณ์๋ฅผ class_weight='balanced'๋ก ์ค์ ํด์ ์กฐ์ ํ ์ ์์ต๋๋ค.
๋๋ฆฌ ์ฐ์ด๋ ๋ค๋ฅธ ๋ฐฉ๋ฒ์ ์์ ํด๋์ค ์ํ์ ๋๋ฆฌ๊ฑฐ๋ ๋ค์ ํด๋์ค ์ํ์ ์ค์ด๊ฑฐ๋ ์ธ๊ณต์ ์ผ๋ก ํ๋ จ ์ํ์ ์์ฑํ๋ ๊ฒ์ ๋๋ค. ์ค์ ์์๋ ์ฌ๋ฌ ์ ๋ต์ ์๋ํด์ ์ ์ ํ ๊ธฐ๋ฒ์ ์ ํํ๋ ๊ฒ์ด ์ข์ต๋๋ค.
์ฌ์ดํท๋ฐ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ ๋ฐ์ดํฐ์์ ์ค๋ณต์ ํ์ฉํจ์ผ๋ก์จ ์์ ํด๋์ค ์ํ์ ๋๋ฆฌ๋ resample ํจ์๋ฅผ ์ ๊ณตํฉ๋๋ค. ๋ค์ ์ฝ๋๋ ๋ถ๊ท ํํ ์ ๋ฐฉ์ ๋ฐ์ดํฐ์์ ์์ ํด๋์ค๋ฅผ ์ ํํด ๋ค๋ฅธ ํด๋์ค์ ๋์ผํ ๋๊น์ง ์๋ก์ด ์ํ์ ๋ฐ๋ณต์ ์ผ๋ก ์ถ์ถํฉ๋๋ค.
from sklearn.utils import resample
print('์ํ๋งํ๊ธฐ ์ ์ ํด๋์ค 1์ ์ํ ๊ฐ์:', X_imb[y_imb == 1].shape[0])
X_upsampled, y_upsampled = resample(X_imb[y_imb == 1],
y_imb[y_imb == 1],
replace=True,
n_samples=X_imb[y_imb == 0].shape[0],
random_state=123)
print('์ํ๋งํ ํ์ ํด๋์ค 1์ ์ํ ๊ฐ์:', X_upsampled.shape[0])
X_bal = np.vstack((X[y == 0], X_upsampled))
y_bal = np.hstack((y[y == 0], y_upsampled))
y_pred = np.zeros(y_bal.shape[0])
np.mean(y_pred == y_bal) * 100
์ํ์ ์ถ์ถํ ํ ํด๋์ค 0์ ์๋ณธ ์ํ๊ณผ ์ ์ํ๋ง๋ ํด๋์ค 1์ ์ฐ๊ฒฐํด ๊ท ํ์กํ ๋ฐ์ดํฐ ์ ์ ์ป์ ์ ์์ต๋๋ค. ๊ทธ ํ ๋ค์ ํด๋์ค๋ฅผ ์์ธกํ๋ ๊ท์น์ด 50% ์ ํ๋๋ฅผ ๋ฌ์ฑํ ๊ฒ์ ์ ์ ์์ต๋๋ค.
๋ค์ด ์ํ๋ง์ ์ํด์๋ resample ํจ์๋ฅผ ์ฌ์ฉํด ํด๋์ค๋ ์ด๋ธ 1๊ณผ 0์ ์๋ก ๋ฐ๊ฟ์ฃผ๋ฉด ๋ฉ๋๋ค.
์ธ์ 16๋ถํฐ 18๊น์ง ๋ชจ๋ธ ํ๊ฐ์ ํ์ดํผํ๋ผ๋ฏธํฐ ํ๋์ ์ฌ๋ก์ ๋ฐฉ๋ฒ๋ค์ ์์๋ณด์์ต๋๋ค. ์ธ ์ธ์ ์์ ๊ณต๋ถํ ๋ฐฉ๋ฒ๋ค์ ์ ์ ํ ์ด์ฉํด ์์ผ๋ก ๋ชจ๋ธ์ด ์ผ๋ง๋ ์ํ๊ณ ์๋์ง, ํน์ ๋ชจ๋ธ์ ์ ํํด์ผํ ๋ ๋ฑ๋ฑ์ ์ฌ์ฉํ ์ ์์ต๋๋ค! ๋ค์ ์ธ์ ๋ถํฐ๋ ์์๋ธ ๊ธฐ๋ฒ์ ๋ํด์ ์์๋ณด๊ฒ ๋ ํ ๋ฐ์, ๋น๊ต์ ํฅ๋ฏธ๋ก์ด ๋ด์ฉ๋ค์ ๋ค๋ฃจ๊ฒ ๋ ํ ๋ ๊ธฐ๋ํ์ธ์! ๋ค์๋ฒ์ ๋ต๊ฒ ์ต๋๋ค :)