[๋ผ์ดํŠธ ๋จธ์‹ ๋Ÿฌ๋‹] Session 18. ROC ๊ณก์„ ๊ณผ ๋ถˆ๊ท ํ˜• ๋ฐ์ดํ„ฐ ๊ท ํ˜• ๋งž์ถ”๊ธฐ!

2020. 2. 29. 23:12ยท๐Ÿฌ ML & Data/๐ŸŽซ ๋ผ์ดํŠธ ๋จธ์‹ ๋Ÿฌ๋‹
728x90

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๊นŒ์ง€ ๋ชจ๋ธ ํ‰๊ฐ€์™€ ํ•˜์ดํผํŒŒ๋ผ๋ฏธํ„ฐ ํŠœ๋‹์˜ ์‚ฌ๋ก€์™€ ๋ฐฉ๋ฒ•๋“ค์„ ์•Œ์•„๋ณด์•˜์Šต๋‹ˆ๋‹ค. ์„ธ ์„ธ์…˜์—์„œ ๊ณต๋ถ€ํ•œ ๋ฐฉ๋ฒ•๋“ค์„ ์ ์ ˆํžˆ ์ด์šฉํ•ด ์•ž์œผ๋กœ ๋ชจ๋ธ์ด ์–ผ๋งˆ๋‚˜ ์ž˜ํ•˜๊ณ  ์žˆ๋Š”์ง€, ํ˜น์€ ๋ชจ๋ธ์„ ์„ ํƒํ•ด์•ผํ•  ๋•Œ ๋“ฑ๋“ฑ์— ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค! ๋‹ค์Œ ์„ธ์…˜๋ถ€ํ„ฐ๋Š” ์•™์ƒ๋ธ” ๊ธฐ๋ฒ•์— ๋Œ€ํ•ด์„œ ์•Œ์•„๋ณด๊ฒŒ ๋ ํ…๋ฐ์š”, ๋น„๊ต์  ํฅ๋ฏธ๋กœ์šด ๋‚ด์šฉ๋“ค์„ ๋‹ค๋ฃจ๊ฒŒ ๋ ํ…Œ๋‹ˆ ๊ธฐ๋Œ€ํ•˜์„ธ์š”! ๋‹ค์Œ๋ฒˆ์— ๋ต™๊ฒ ์Šต๋‹ˆ๋‹ค :)

728x90
์ €์ž‘์žํ‘œ์‹œ (์ƒˆ์ฐฝ์—ด๋ฆผ)

'๐Ÿฌ ML & Data > ๐ŸŽซ ๋ผ์ดํŠธ ๋จธ์‹ ๋Ÿฌ๋‹' ์นดํ…Œ๊ณ ๋ฆฌ์˜ ๋‹ค๋ฅธ ๊ธ€

[๋ผ์ดํŠธ ๋จธ์‹ ๋Ÿฌ๋‹] Session 19. ์•™์ƒ๋ธ”์˜ ์ •์˜์™€ ๋‹ค์ˆ˜๊ฒฐ ํˆฌํ‘œ!  (0) 2020.03.08
[๋ผ์ดํŠธ ๋จธ์‹ ๋Ÿฌ๋‹] Session 17. ํ•™์Šต๊ณผ ๊ฒ€์ฆ ๊ณก์„ , ๊ทธ๋ฆฌ๊ณ  ๊ทธ๋ฆฌ๋“œ ์„œ์น˜  (0) 2020.02.28
[๋ผ์ดํŠธ ๋จธ์‹ ๋Ÿฌ๋‹] Session 16. ํŒŒ์ดํ”„๋ผ์ธ์œผ๋กœ ๋ฌถ๊ณ , ๊ต์ฐจ ๊ฒ€์ฆ์œผ๋กœ ๋ชจ๋ธ์„ ํ‰๊ฐ€ํ•˜์ž!  (0) 2020.02.26
[๋ผ์ดํŠธ ๋จธ์‹ ๋Ÿฌ๋‹] Session 15. ์ปค๋„ PCA๋ฅผ ์ด์šฉํ•œ ๋น„์„ ํ˜• ๋งคํ•‘  (0) 2020.02.24
[๋ผ์ดํŠธ ๋จธ์‹ ๋Ÿฌ๋‹] Session 14. LDA๋ฅผ ํ†ตํ•œ ์ง€๋„ํ•™์Šต๋ฐฉ์‹ ๋ฐ์ดํ„ฐ ์••์ถ•  (0) 2020.02.21
'๐Ÿฌ ML & Data/๐ŸŽซ ๋ผ์ดํŠธ ๋จธ์‹ ๋Ÿฌ๋‹' ์นดํ…Œ๊ณ ๋ฆฌ์˜ ๋‹ค๋ฅธ ๊ธ€
  • [๋ผ์ดํŠธ ๋จธ์‹ ๋Ÿฌ๋‹] Session 19. ์•™์ƒ๋ธ”์˜ ์ •์˜์™€ ๋‹ค์ˆ˜๊ฒฐ ํˆฌํ‘œ!
  • [๋ผ์ดํŠธ ๋จธ์‹ ๋Ÿฌ๋‹] Session 17. ํ•™์Šต๊ณผ ๊ฒ€์ฆ ๊ณก์„ , ๊ทธ๋ฆฌ๊ณ  ๊ทธ๋ฆฌ๋“œ ์„œ์น˜
  • [๋ผ์ดํŠธ ๋จธ์‹ ๋Ÿฌ๋‹] Session 16. ํŒŒ์ดํ”„๋ผ์ธ์œผ๋กœ ๋ฌถ๊ณ , ๊ต์ฐจ ๊ฒ€์ฆ์œผ๋กœ ๋ชจ๋ธ์„ ํ‰๊ฐ€ํ•˜์ž!
  • [๋ผ์ดํŠธ ๋จธ์‹ ๋Ÿฌ๋‹] Session 15. ์ปค๋„ PCA๋ฅผ ์ด์šฉํ•œ ๋น„์„ ํ˜• ๋งคํ•‘
darly213
darly213
ํ˜ธ๋ฝํ˜ธ๋ฝํ•˜์ง€ ์•Š์€ ๊ฐœ๋ฐœ์ž๊ฐ€ ๋˜์–ด๋ณด์ž
  • darly213
    ERROR DENY
    darly213
  • ์ „์ฒด
    ์˜ค๋Š˜
    ์–ด์ œ
    • ๋ถ„๋ฅ˜ ์ „์ฒด๋ณด๊ธฐ (97)
      • ๐Ÿฌ ML & Data (50)
        • ๐ŸŒŠ Computer Vision (2)
        • ๐Ÿ“ฎ Reinforcement Learning (12)
        • ๐Ÿ“˜ ๋…ผ๋ฌธ & ๋ชจ๋ธ ๋ฆฌ๋ทฐ (8)
        • ๐Ÿฆ„ ๋ผ์ดํŠธ ๋”ฅ๋Ÿฌ๋‹ (3)
        • โ” Q & etc. (5)
        • ๐ŸŽซ ๋ผ์ดํŠธ ๋จธ์‹ ๋Ÿฌ๋‹ (20)
      • ๐Ÿฅ Web (21)
        • โšก Back-end | FastAPI (2)
        • โ›… Back-end | Spring (5)
        • โ” Back-end | etc. (9)
        • ๐ŸŽจ Front-end (4)
      • ๐ŸŽผ Project (8)
        • ๐ŸงŠ Monitoring System (8)
      • ๐Ÿˆ Algorithm (0)
      • ๐Ÿ”ฎ CS (2)
      • ๐Ÿณ Docker & Kubernetes (3)
      • ๐ŸŒˆ DEEEEEBUG (2)
      • ๐ŸŒ  etc. (8)
      • ๐Ÿ˜ผ ์‚ฌ๋‹ด (1)
  • ๋ธ”๋กœ๊ทธ ๋ฉ”๋‰ด

    • ํ™ˆ
    • ๋ฐฉ๋ช…๋ก
    • GitHub
    • Notion
    • LinkedIn
  • ๋งํฌ

    • Github
    • Notion
  • ๊ณต์ง€์‚ฌํ•ญ

    • Contact ME!
  • 250x250
  • hELLOยท Designed By์ •์ƒ์šฐ.v4.10.3
darly213
[๋ผ์ดํŠธ ๋จธ์‹ ๋Ÿฌ๋‹] Session 18. ROC ๊ณก์„ ๊ณผ ๋ถˆ๊ท ํ˜• ๋ฐ์ดํ„ฐ ๊ท ํ˜• ๋งž์ถ”๊ธฐ!
์ƒ๋‹จ์œผ๋กœ

ํ‹ฐ์Šคํ† ๋ฆฌํˆด๋ฐ”