
๋จธ์ ๋ฌ๋ ๋ชจ๋ธ์ ์ฌ๋ฌ๊ฐ์ง ๋ฐฉ๋ฒ์ผ๋ก ์์ธก ์ฑ๋ฅ์ ํ๊ฐํ ์ ์์. ์ฑ๋ฅ ํ๊ฐ ์งํ๋ ์ผ๋ฐ์ ์ผ๋ก ๋ชจ๋ธ์ด ๋ถ๋ฅ๋ ํ๊ท๋์ ๋ฐ๋ผ ์ฌ๋ฌ ์ข ๋ฅ๋ก ๋๋จ.
๋ถ๋ฅ์ ์ฑ๋ฅ ํ๊ฐ ์งํ
๐น ์ ํ๋
๐น ์ค์ฐจํ๋ ฌ
๐น ์ ๋ฐ๋
๐น ์ฌํ์จ
๐น F1 ์ค์ฝ์ด
๐น ROC AUC
์ ํ๋๋ ์ค์ ๋ฐ์ดํฐ์์ ์์ธก ๋ฐ์ดํฐ๊ฐ ์ผ๋ง๋ ๊ฐ์์ง๋ฅผ ํ๋จํ๋ ์งํ

from sklearn.base import BaseEstimator
class MyDummyClassifier(BaseEstimator):
# fit() ๋ฉ์๋๋ ์๋ฌด๊ฒ๋ ํ์ตํ์ง ์์.
def fit(self, X, y=None):
pass
# predict() ๋ฉ์๋๋ ๋จ์ํ Sex ํผ์ฒ๊ฐ 1์ด๋ฉด 0, ๊ทธ๋ ์ง ์์ผ๋ฉด 1๋ก ์์ธกํจ.
def predict(self, X):
pred = np.zeros((X.shape[0], 1))
for i in range(X.shape[0]):
if X['Sex'].iloc[i] == 1:
pred[i] = 0
else:
pred[i] = 1
return pred
ํ์ดํ๋ ์์กด์ ์์ธก
## ์์ฑ๋ MyDummyClassifier๋ฅผ ์ด์ฉํด ํ์ดํ๋ ์์กด์ ์์ธก ์ํ
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score
from sklearn.preprocessing import LabelEncoder
## Null ์ฒ๋ฆฌ ํจ์
def fillna(df):
df['Age'].fillna(df['Age'].mean(), inplace=True)
df['Cabin'].fillna('N', inplace=True)
df['Embarked'].fillna('N', inplace=True)
df['Fare'].fillna(0, inplace=True)
return df
## ๋จธ์ ๋ฌ๋์ ๋ถํ์ํ ํผ์ฒ ์ ๊ฑฐ
def drop_features(df):
df.drop(['PassengerId', 'Name', 'Ticket'], axis=1, inplace=True)
return df
## Label Encoding ์ํ
def format_features(df):
df['Cabin'] = df['Cabin'].str[:1]
features = ['Cabin', 'Sex', 'Embarked']
for feature in features:
le = LabelEncoder()
le.fit(df[feature])
df[feature] = le.transform(df[feature])
return df
## ์์์ ์คํํ Data Preprocessing ํจ์ ํธ์ถ
def transform_features(df):
df = fillna(df)
df = drop_features(df)
df = format_features(df)
return df
import pandas as pd
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score
# ์๋ณธ ๋ฐ์ดํฐ๋ฅผ ์ฌ๋ก๋ฉ, ๋ฐ์ดํฐ ๊ฐ๊ณต, ํ์ต ๋ฐ์ดํฐ/ํ
์คํธ ๋ฐ์ดํฐ ๋ถํ
titanic_df = pd.read_csv('titanic_train.csv')
y_titanic_df = titanic_df['Survived']
X_titanic_df = titanic_df.drop('Survived', axis = 1)
X_titanic_df = transform_features(X_titanic_df)
#Survived ์นผ๋ผ์ผ๋ก target ์ค์
X_train, X_test, y_train, y_test = train_test_split(X_titanic_df, y_titanic_df, test_size=0.2, random_state=0)
# ์์์ ์์ฑํ Dummy Classifier๋ฅผ ์ด์ฉํด ํ์ต/์์ธก/ํ๊ฐ ์ํ
myclf = MyDummyClassifier()
myclf.fit(X_train, y_train)
mypredictions = myclf.predict(X_test)
print('Dummy Classifier์ ์ ํ๋๋: {0:.4f}'.format(accuracy_score(y_test, mypredictions)))
[Output]
Dummy Classifier์ ์ ํ๋๋: 0.7877
์ด๋ ๊ฒ ๋จ์ํ ์๊ณ ๋ฆฌ์ฆ์ ์ ํ๋๊ฐ ๋์ผ๋ฉด ์๋จ
๋ํ ๋ฐ์ดํฐ ๋ถํฌ๋๊ฐ ๊ท ์ผํ์ง ์์ ๊ฒฝ์ฐ ๋์ ์์น๊ฐ ๋ํ๋ ์ ์๋ ๊ฒ์ด ์ ํ๋ ํ๊ฐ ์งํ์ ๋งน์
์ค์ฐจ ํ๋ ฌ์์ TN, FP, FN, TP ๊ฐ์ ๋ค์ํ๊ฒ ๊ฒฐํฉํด ๋ถ๋ฅ ๋ชจ๋ธ ์์ธก ์ฑ๋ฅ์ ์ค๋ฅ๊ฐ ์ด๋ ํ ๋ชจ์ต์ผ๋ก ๋ฐ์ํ๋์ง ์ ์ ์๋ ๊ฒ

True/False ์์ธก๊ฐ๊ณผ ์ค์ ๊ฐ์ด '๊ฐ์๊ฐ/ํ๋ฆฐ๊ฐ'๋ฅผ ์๋ฏธ
Negative/Positive ์์ธก ๊ฒฐ๊ณผ ๊ฐ์ด ๋ถ์ (0)/๊ธ์ (1)์ ์๋ฏธ
- TN (True Negative)
์์ธก ํด๋์ค ๊ฐ๊ณผ ์ค์ ํด๋์ค ๊ฐ์ด Negative๋ก ๊ฐ์- FP (False Positive)
์์ธก๊ฐ์ Positive, ์ค์ ๊ฐ์ Negative๋ก ๋ค๋ฆ- FN (False Negative)
์์ธก๊ฐ์ Negative, ์ค์ ๊ฐ์ Positive- TP (True Positive)
์์ธก ํด๋์ค ๊ฐ๊ณผ ์ค์ ํด๋์ค ๊ฐ์ด Positive๋ก ๊ฐ์
์ ํ๋๋ ์์ธก๊ฐ๊ณผ ์ค์ ๊ฐ์ด ์ผ๋ง๋ ๋์ผํ๊ฐ์ ๋ํ ๋น์จ๋ง์ผ๋ก ๊ฒฐ์

์ค์ ์ ์ผ๋ก ์ฐพ์์ผ ํ๋ ๋งค์ฐ ์ ์ ์์ ๊ฒฐ๊ด๊ฐ์ Positive๋ฅผ ์ค์ , ๊ทธ๋ ์ง ์์ ๊ฒฝ์ฐ Negative๋ฅผ ์ค์ Positive ๋ฐ์ดํฐ ๊ฑด์๊ฐ ์๊ธฐ ๋๋ฌธ์ Negative๋ก ์์ธก ์ ํ๋๊ฐ ๋์์ง๋ ๊ฒฝํฅ์ด ๋ฐ์ โ ๋น๋์นญํ ๋ฐ์ดํฐ ์ธํธ์์ Positive์ ๋ํ ์์ธก ์ ํ๋๋ฅผ ํ๋จํ์ง ๋ชปํ ์ฑ Negative์ ๋ํ ์์ธก ์ ํ๋๋ง์ผ๋ก๋ ๋ถ๋ฅ์ ์ ํ๋๊ฐ ๋งค์ฐ ๋๊ฒ ๋ํ๋จ
๋ถ๊ท ํ ๋ฐ์ดํฐ ์ธํธ์์ ์ ํธ๋จ(์ค์ฐจํ๋ ฌ์ ํ๊ณ ๊ทน๋ณต)
Positive ๋ฐ์ดํฐ ์ธํธ์ ์์ธก ์ฑ๋ฅ์ ์ข ๋ ์ด์ ์ ๋ง์ถ ํ๊ฐ ์งํ

์์ธก์ Positive๋ก ํ ๋์ ์ค์ ์์ธก๊ณผ ์ค์ ๊ฐ์ด Positive๋ก ์ผ์นํ ๋ฐ์ดํฐ์ ๋น์จ
์ค์ Negative ์์ฑ์ธ ๋ฐ์ดํฐ ์์ธก์ Positive ์์ฑ์ผ๋ก ์๋ชป ํ๋จํ๊ฒ ๋๋ฉด ์
๋ฌด์ ํฐ ์ํฅ์ด ๋ฐ์ํ๋ ๊ฒฝ์ฐ(์์ ์ค๋ฅ ์ฐจ๋จํ๋ฉด ์๋๋ ๊ฒฝ์ฐ)
ex) ์คํธ๋ฉ์ผ ์ฌ๋ถ ํ๋จ ๋ชจ๋ธ
์ค์ ๊ฐ์ด Positive ๋์ ์ค์ ์์ธก๊ณผ ์ค์ ๊ฐ์ด Positive๋ก ์ผ์นํ ๋ฐ์ดํฐ์ ๋น์จ
์ฌํ์จ์ด ์ค์ ์งํ์ธ ๊ฒฝ์ฐ๋ ์ค์ Positive ์์ฑ ๋ฐ์ดํฐ๋ฅผ Negative๋ก ์๋ชป ํ๋จํ๊ฒ ๋๋ฉด ์
๋ฌด์ ํฐ ์ํฅ์ด ๋ฐ์ํ๋ ๊ฒฝ์ฐ (์ค๋ฅ๊ฐ ๋ฐ์ํ๋ฉด ์๋๋ ๊ฒฝ์ฐ)
ex) ์ ํ๋จ ๋ชจ๋ธ
get_clf_eval()confusion_matrix, accuracy, precision, recall ํ๊ฐ๋ฅผ ํ๊บผ๋ฒ์ ํธ์ถ
from sklearn.metrics import accuracy_score, precision_score, recall_score, confusion_matrix
def get_clf_eval(y_test, pred):
confusion = confusion_matrix(y_test, pred)
accuracy = accuracy_score(y_test, pred)
precision = precision_score(y_test, pred)
recall = recall_score(y_test, pred)
print('์ค์ฐจ ํ๋ ฌ')
print(confusion)
print('์ ํ๋: {0:.4f}, ์ ๋ฐ๋: {1:.4f}, ์ฌํ์จ: {2:.4f}'.format(accuracy, precision, recall))
์ด์ง ๋ถ๋ฅ(solver = liblinear)๋ก ์ํ
import pandas as pd
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LogisticRegression
# ์๋ณธ ๋ฐ์ดํฐ๋ฅผ ์ฌ๋ก๋ฉ, ๋ฐ์ดํฐ ๊ฐ๊ณต, ํ์ต ๋ฐ์ดํฐ/ํ
์คํธ ๋ฐ์ดํฐ ๋ถํ
titanic_df = pd.read_csv('titanic_train.csv')
y_titanic_df = titanic_df['Survived']
X_titanic_df = titanic_df.drop('Survived', axis=1)
X_titanic_df = transform_features(X_titanic_df)
X_train, X_test, y_train, y_test = train_test_split(X_titanic_df, y_titanic_df, test_size = 0.20, random_state=11)
lr_clf = LogisticRegression(solver='liblinear')
lr_clf.fit(X_train, y_train)
pred = lr_clf.predict(X_test)
get_clf_eval(y_test, pred)
[Output]
์ค์ฐจ ํ๋ ฌ
[[108 10]
[ 14 47]]
์ ํ๋" 0.8659, ์ ๋ฐ๋: 0.8246, ์ฌํ์จ: 0.7705
Threshold๋ฅผ ์กฐ์ ํด ์ ๋ฐ๋/์ฌํ์จ ์กฐ์ ๊ฐ๋ฅ
์ ๋ฐ๋์ ์ฌํ์จ์ ์ํธ๋ณด์์ ์ธ ํ๊ฐ ์งํ์ด๊ธฐ ๋๋ฌธ์ ์ด๋ ํ์ชฝ์ ๊ฐ์ ๋ก ๋์ด๋ฉด ๋ค๋ฅธ ํ๋์ ์์น๋ ๋จ์ด์ง๊ธฐ ๋๋ฌธ์ ํธ๋ ์ด๋ ์คํ๋ผ ๋ถ๋ฆ
์ผ๋ฐ์ ์ผ๋ก ์ด์ง๋ถ๋ฅ์์๋ ๊ณตํํ๊ฒ threshold๋ฅผ ๊ณตํํ๊ฒ 50%๋ก ์ค์
predict_proba()predict()๋ฉ์๋์ ์ ์ฌํ์ง๋ง ๋ฐํ ๊ฐ์ด ํด๋์ค ๊ฐ์ด ์๋ ์์ธก ํ๋ฅ ๊ฒฐ๊ณผ
pred_proba = lr_clf.predict_proba(X_test)
pred = lr_clf.predict(X_test)
print('pred_proba()๊ฒฐ๊ณผ Shape : {0}'.format(pred_proba.shape))
print('pred_proba array์์ ์ 3๊ฐ๋ง ์ํ๋ก ์ถ์ถ \n:',pred_proba[:3])
# ์์ธก ํ๋ฅ array์ ์์ธก ๊ฒฐ๊ด๊ฐ array๋ฅผ ๋ณํฉ(concatenate)ํด ์์ธก ํ๋ฅ ๊ณผ ๊ฒฐ๊ด๊ฐ์ ํ๋์ ํ์ธ
pred_proba_result = np.concatenate([pred_proba, pred.reshape(-1, 1)], axis=1)
print('๋ ๊ฐ์ class ์ค์์ ๋ ํฐ ํ๋ฅ ์ ํด๋์ค ๊ฐ์ผ๋ก ์์ธก \n', pred_proba_result[:3])
[Output]
pred_proba()๊ฒฐ๊ณผ Shape : (179, 2)
pred_proba array์์ ์ 3๊ฐ๋ง ์ํ๋ก ์ถ์ถ
: [[0.44935225 0.55064775]
[0.86335511 0.13664489]
[0.86429643 0.13570357]]
๋ ๊ฐ์ class ์ค์์ ๋ ํฐ ํ๋ฅ ์ ํด๋์ค ๊ฐ์ผ๋ก ์์ธก
[[0.44935225 0.55064775 1. ]
[0.86335511 0.13664489 0. ]
[0.86429643 0.13570357 0. ]]
2๊ฐ์ ์นผ๋ผ ์ค ๋ ํฐ ํ๋ฅ ๊ฐ์ผ๋ก predict() ๋ฉ์๋๊ฐ ์ต์ข ์์ธก
from sklearn.preprocessing import Binarizer
# Binarizer์ threshold์ ์ค์ ๊ฐ. ๋ถ๋ฅ ๊ฒฐ์ ์๊ณ๊ฐ์.
custom_threshold = 0.5
# predict_proba() ๋ฐํ๊ฐ์ ๋ ๋ฒ์งธ ์นผ๋ผ, ์ฆ positive ํด๋์ค ์นผ๋ผ ํ๋๋ง ์ถ์ถํด Binarizer๋ฅผ ์ ์ฉ
pred_proba_1 = pred_proba[:,1].reshape(-1, 1)
binarizer = Binarizer(threshold = custom_threshold).fit(pred_proba_1)
custom_predict = binarizer.transform(pred_proba_1)
get_clf_eval(y_test, custom_predict)
# Binarizer์ threshold์ ์ค์ ๊ฐ์ 0.4๋ก ์ค์ . ์ฆ ๋ถ๋ฅ ๊ฒฐ์ ์๊ณ๊ฐ์ 0.5์์ 0.4๋ก ๋ฎ์ถค
custom_threshold = 0.4
pred_proba_1 = pred_proba[:,1].reshape(-1, 1)
binarizer = Binarizer(threshold=custom_threshold).fit(pred_proba_1)
custom_predict = binarizer.transform(pred_proba_1) #pred_proba_1์ ์ ์ํ๋ ์์ธก ๊ฒฐ๊ณผ
get_clf_eval(y_test, custom_predict)
[Output]
์ค์ฐจ ํ๋ ฌ
[[97 21]
[11 50]]
์ ํ๋: 0.8212, ์ ๋ฐ๋: 0.7042, ์ฌํ์จ: 0.8197
Threshold๋ฅผ ๋ฎ์ถ๋ ์ฌํ์จ ๊ฐ์ด ์ฌ๋ผ๊ฐ๊ณ ์ ๋ฐ๋๊ฐ ๋จ์ด์ง
Threshold์ Positive ์์ธก๊ฐ์ ๊ฒฐ์ ํ๋ ํ๋ฅ ์ ๊ธฐ์ค์ด ๋จ. Threshold ๊ฐ์ ๋ฎ์ถ์๋ก True ๊ฐ์ด ๋ง์์ง

import matplotlib.pyplot as plt
import matplotlib.ticker as tiker
%matplotlib inline
def precision_recall_curve_plot(y_test, pred_proba_c1):
# threshold ndarray์ ์ด threshold์ ๋ฐ๋ฅธ ์ ๋ฐ๋, ์ฌํ์จ ndarray ์ถ์ถ.
precisions, recalls, thresholds = precision_recall_curve(y_test, pred_proba_c1)
# X์ถ์ threshold๊ฐ์ผ๋ก, Y์ถ์ ์ ๋ฐ๋, ์ฌํ์จ ๊ฐ์ผ๋ก ๊ฐ๊ฐ Plot ์ํ. ์ ๋ฐ๋๋ ์ ์ ์ผ๋ก ํ์
plt.figure(figsize=(8, 6))
threshold_boundary = thresholds.shape[0]
plt.plot(thresholds, precisions[0:threshold_boundary], linestyle ='--', label='precision')
plt.plot(thresholds, recalls[0:threshold_boundary], label='recall')
# threshold ๊ฐ X ์ถ์ Scale์ 0.1 ๋จ์๋ก ๋ณ๊ฒฝ
start, end = plt.xlim()
plt.xticks(np.round(np.arange(start, end, 0.1), 2))
# x์ถ. y์ถ label๊ณผ legend, ๊ทธ๋ฆฌ๊ณ grid ์ค์
plt.xlabel('Threshold value')
plt.ylabel('Precision and Recall value')
plt.legend()
plt.grid()
plt.show()
precision_recall_curve_plot(y_test, lr_clf.predict_proba(X_test)[:,1])

์๊ณ๊ฐ์ด ๋ฎ์ ์๋ก ๋ง์ ์์ ์์ฑ ์์ธก์ผ๋ก ์ธํด ์ฌํ์จ์ด ๊ทน๋๋ก ๋
๋ ๊ฐ ์์น๋ฅผ ์ํธ๋ณด์ ํ ์ ์๋ ์์ค์์ ์ ์ฉ๋ผ์ผ ํจ. ๋จ์ํ ํ๋์ ์ฑ๋ฅ ์งํ ์์น๋ฅผ ๋์ด๊ธฐ ์ํ ์๋จ์ผ๋ก ์ฌ์ฉ๋ผ์๋ ์ ๋จ.
F1 ์ค์ฝ์ด๋ ์ ๋ฐ๋์ ์ฌํ์จ์ ๊ฒฐํฉํ ์งํ
์ ๋ฐ๋ ๋๋ ์ ํ๋ ์ชฝ์ผ๋ก ์น์ฐ์น์ง ์๋ ์์น๋ฅผ ๋ํ๋ผ ๋ ์๋์ ์ผ๋ก ๋์ ๊ฐ์ ๊ฐ์ง

from sklearn.metrics import f1_score
f1 = f1_score(y_test, pred)
print('F1 ์ค์ฝ์ด: {0:.4f}'.format(f1))
#์ด์ f1 ์ค์ฝ์ด๋ ์ถ๋ ฅ๊ฐ์ ์ถ๊ฐ
def get_clf_eval(y_test, pred):
confusion = confusion_matrix(y_test, pred)
accuracy = accuracy_score(y_test, pred)
precision = precision_score(y_test, pred)
recall = recall_score(y_test, pred)
#F1 ์ค์ฝ์ด ์ถ๊ฐ
f1 = f1_score(y_test, pred)
print('์ค์ฐจ ํ๋ ฌ')
print(confusion)
#f1 score print ์ถ๊ฐ
print('์ ํ๋: {0:.4f}, ์ ๋ฐ๋: {1:.4f}, ์ฌํ์จ: {2:.4f}, F1:{3:.4f}'.format(accuracy, precision, recall, f1))
thresholds = [0.4, 0.45, 0.50, 0.55, 0.60]
pred_proba = lr_clf.predict_proba(X_test)
get_eval_by_threshold(y_test, pred_proba[:,1].reshape(-1, 1), thresholds)
[Output]
์๊ณ๊ฐ: 0.4
์ค์ฐจ ํ๋ ฌ
[[97 21]
[11 50]]
์ ํ๋: 0.8212, ์ ๋ฐ๋: 0.7042, ์ฌํ์จ: 0.8197, F1:0.7576
์๊ณ๊ฐ: 0.45
์ค์ฐจ ํ๋ ฌ
[[105 13]
[ 13 48]]
์ ํ๋: 0.8547, ์ ๋ฐ๋: 0.7869, ์ฌํ์จ: 0.7869, F1:0.7869
์๊ณ๊ฐ: 0.5
์ค์ฐจ ํ๋ ฌ
[[108 10]
[ 14 47]]
์ ํ๋: 0.8659, ์ ๋ฐ๋: 0.8246, ์ฌํ์จ: 0.7705, F1:0.7966
์๊ณ๊ฐ: 0.55
์ค์ฐจ ํ๋ ฌ
[[111 7]
[ 16 45]]
์ ํ๋: 0.8715, ์ ๋ฐ๋: 0.8654, ์ฌํ์จ: 0.7377, F1:0.7965
์๊ณ๊ฐ: 0.6
์ค์ฐจ ํ๋ ฌ
[[113 5]
[ 17 44]]
์ ํ๋: 0.8771, ์ ๋ฐ๋: 0.8980, ์ฌํ์จ: 0.7213, F1:0.8000
ROC ๊ณก์ ๊ณผ ์ด์ ๊ธฐ๋ฐํ AUC ์ค์ฝ์ด๋ ์ด์ง ๋ถ๋ฅ์ ์์ธก ์ฑ๋ฅ ์ธก์ ์์ ์ค์ํ๊ฒ ์ฌ์ฉ๋๋ ์งํ
ROC ๊ณก์ ์ FPR(False Positive Rate)์ด ๋ณํ ๋ TPR(True Positive Rate)์ด ์ด๋ป๊ฒ ๋ณํ๋ ์ง ๋ํ๋ด๋ ๊ณก์
๋ฏผ๊ฐ๋(TPR) ์ค์ ๊ฐ Positive(์์ฑ)๊ฐ ์ ํํ ์์ธก๋ผ์ผ ํ๋ ์์ค์ ๋ํ๋
ํน์ด์ฑ(TNR) ์ค์ ๊ฐ Negative(์์ฑ)๊ฐ ์ ํํ ์์ธก๋ผ์ผ ํ๋ ์์ค์ ๋ํ๋

ROC ๊ณก์ ์ X์ถ ๊ธฐ์ค FPR , Y์ถ์ TPR

FPR = 0 โ ์๊ณ๊ฐ์ 1๋ก ์ง์ ํ๋ฉด ๋จ
FPR = 1 โ ์๊ณ๊ฐ์ 0์ผ๋ก ์ง์ ํ๋ฉด ๋จ
def roc_curve_plot(y_test, pred_proba_c1):
# ์๊ณ๊ฐ์ ๋ฐ๋ฅธ FPR, TPR ๊ฐ์ ๋ฐํ๋ฐ์.
fprs, tprs, thresholds = roc_curve(y_test, pred_proba_c1)
# ROC ๊ณก์ ์ ๊ทธ๋ํ ๊ณก์ ์ผ๋ก ๊ทธ๋ฆผ
plt.plot(fprs, tprs, label='ROC')
# ๊ฐ์ด๋ฐ ๋๊ฐ์ ์ง์ ์ ๊ทธ๋ฆผ.
plt.plot([0,1], [0,1], 'k--', label='Random')
# FPR X์ถ์ Scale์ 0.1 ๋จ์๋ก ๋ณ๊ฒฝ, X, Y์ถ ๋ช
์ค์ ๋ฑ
start, end = plt.xlim()
plt.xticks(np.round(np.arange(start, end, 0.1),2))
plt.xlim(0,1)
plt.ylim(0,1)
plt.xlabel('FPR(1 - Specificity)')
plt.ylabel('TPR(Recall)')
plt.legend()
roc_curve_plot(y_test, pred_proba[:,1])

๊ฐ์ด๋ฐ ์ง์ ์์ ๋ฉ์ด์ง๊ณ ์ผ์ชฝ ์๋จ ๋ชจ์๋ฆฌ ์ชฝ์ผ๋ก ๊ฐํ๋ฅด๊ฒ ์ด๋ํ ์๋ก ์ง์ฌ๊ฐํ์ ๊ฐ๊น์ด ๊ณก์ ์ด ๋์ด ๋ฉด์ ์ด 1์ ๊ฐ๊น์์ง๋ ์ข์ ROC AUC ์ฑ๋ฅ ์์น๋ฅผ ์ป๊ฒ ๋จ
#ํผ์ฒ ๋ฐ์ดํฐ ์ธํธ X, ๋ ์ด๋ธ ๋ฐ์ดํฐ ์ธํธ y๋ฅผ ์ถ์ถ
# ๋งจ ๋์ด Outcome ์นผ๋ผ์ผ๋ก ๋ ์ด๋ธ ๊ฐ์, ์นผ๋ผ ์์น -1๋ฅผ ์ด์ฉํด ์ถ์ถ
X= diabetes_data.iloc[:,:-1]
y = diabetes_data.iloc[:, -1]
X_train, X_test, y_train, y_test = train_test_split(X,y,test_size=0.2, random_state = 156, stratify=y)
#what is stratify?
# ๋ก์ง์คํฑ ํ๊ท๋ก ํ์ต, ์์ธก ๋ฐ ํ๊ฐ ์ํ
lr_clf = LogisticRegression(solver='liblinear')
lr_clf.fit(X_train, y_train)
pred = lr_clf.predict(X_test)
pred_proba = lr_clf.predict_proba(X_test)[:,1]
get_clf_eval(y_test, pred, pred_proba)
[Output]
์ค์ฐจ ํ๋ ฌ
[[87 13]
[22 32]]
์ ํ๋: 0.7727, ์ ๋ฐ๋: 0.7111, ์ฌํ์จ: 0.5926, F1:0.6465, AUC:0.8083
์ ์ฒด ๋ฐ์ดํฐ์ 65%๊ฐ Negative์ด๋ฏ๋ก ์ฌํ์จ ์ฑ๋ฅ์ ์ฌ๋ ค์ผ๋จ(์ฌํ์จ ๊ณต์์ Negative ์์ผ๋ฏ๋ก ์ฌํ์จ์ด Negative์ ์ด์ ๋ง์ถ ์งํ)

0์ผ๋ก ๋ผ ์๋ ํผ์ฒ๊ฐ ๋ง์. ํฌ๋๋น ์์น๊ฐ 0์ด๋ผ๋ ์์น๋ ์๋ชป๋ ๊ฐ.
โ ๋ณด์ ํ์
#0๊ฐ์ ๊ฒ์ฌํ ํผ์ฒ๋ช
๋ฆฌ์คํธ
zero_features = ['Glucose', 'BloodPressure', 'SkinThickness', 'Insulin', 'BMI']
#์ ์ฒด ๋ฐ์ดํฐ ๊ฑด์
total_count = diabetes_data['Glucose'].count()
# ํผ์ฒ๋ณ๋ก ๋ฐ๋ณตํ๋ฉด์ ๋ฐ์ดํฐ ๊ฐ์ด 0์ธ ๋ฐ์ดํฐ ๊ฑด์๋ฅผ ์ถ์ถํ๊ณ , ํผ์ผํธ ๊ณ์ฐ
for feature in zero_features:
zero_count = diabetes_data[diabetes_data[feature]==0][feature].count()
print('{0} 0 ๊ฑด์๋ {1}, ํผ์ผํธ๋ {2: 2f} %'.format(feature, zero_count, 100*zero_count/total_count))
[Output]
Glucose 0 ๊ฑด์๋ 5, ํผ์ผํธ๋ 0.651042 %
BloodPressure 0 ๊ฑด์๋ 35, ํผ์ผํธ๋ 4.557292 %
SkinThickness 0 ๊ฑด์๋ 227, ํผ์ผํธ๋ 29.557292 %
Insulin 0 ๊ฑด์๋ 374, ํผ์ผํธ๋ 48.697917 %
BMI 0 ๊ฑด์๋ 11, ํผ์ผํธ๋ 1.432292 %
0 ๊ฐ์ ๊ฐ์ง feature๊ฐ ๋ง๊ธฐ ๋๋ฌธ์ 0์ ํ๊ท ๊ฐ์ผ๋ก ๋์ฒด
# zero_features ๋ฆฌ์คํธ ๋ด๋ถ์ ์ ์ฅ๋ ๊ฐ๋ณ ํผ์ฒ๋ค์ ๋ํ์ฌ 0๊ฐ์ ํ๊ท ๊ฐ์ผ๋ก ๋์ฒด
mean_zero_features = diabetes_data[zero_features].mean()
diabetes_data[zero_features] = diabaetes_data[zero_features].replace(0, mean_zero_features)
์ซ์ ๋ฐ์ดํฐ์ ์ค์ผ์ผ๋ง ์ ์ฉ
ํ์ต/ํ
์คํธ ๋ฐ์ดํฐ ์ธํธ๋ก ๋๋๊ธฐ
๋ก์ง์คํฑ ํ๊ท๋ฅผ ์ด์ฉํด ์ฑ๋ฅ ํ๊ฐ ์งํ๋ฅผ ํ์ธ
# zero_features ๋ฆฌ์คํธ ๋ด๋ถ์ ์ ์ฅ๋ ๊ฐ๋ณ ํผ์ฒ๋ค์ ๋ํด์ 0๊ฐ์ ํ๊ท ๊ฐ์ผ๋ก ๋์ฒด
mean_zero_features = diabetes_data[zero_features].mean()
diabetes_data[zero_features]=diabetes_data[zero_features].replace(0, mean_zero_features)
X= diabetes_data.iloc[:,:-1]
y= diabetes_data.iloc[:,-1]
#StandardScaler ํด๋์ค๋ฅผ ์ด์ฉํด ํผ์ฒ ๋ฐ์ดํฐ ์ธํธ์ ์ผ๊ด์ ์ผ๋ก ์ค์ผ์ผ๋ง ์ ์ฉ
scaler = StandardScaler()
X_scaled = scaler.fit_transform(X)
X_train, X_test, y_train, y_test = train_test_split(X_scaled, y, test_size=0.2, random_state=156, stratify=y)
#๋ก์ง์คํฑ ํ๊ท๋ก ํ์ต, ์์ธก ๋ฐ ํ๊ฐ ์ํ
lr_clf = LogisticRegression()
lr_clf.fit(X_train, y_train)
pred = lr_clf.predict(X_test)
pred_proba = lr_clf.predict_proba(X_test)[:,1]
get_clf_eval(y_test, pred, pred_proba)
1. ์๊ณ๊ฐ: 0.3
์ ํ๋: 0.7143, ์ ๋ฐ๋: 0.5658, ์ฌํ์จ: 0.7963
2. ์๊ณ๊ฐ: 0.33
์ ํ๋: 0.7403, ์ ๋ฐ๋: 0.6000, ์ฌํ์จ: 0.7778
3. ์๊ณ๊ฐ: 0.36
์ ํ๋: 0.7468, ์ ๋ฐ๋: 0.6190, ์ฌํ์จ: 0.7222
4. ์๊ณ๊ฐ: 0.39
์ ํ๋: 0.7532, ์ ๋ฐ๋: 0.6333, ์ฌํ์จ: 0.7037
5. ์๊ณ๊ฐ: 0.42
์ ํ๋: 0.7792, ์ ๋ฐ๋: 0.6923, ์ฌํ์จ: 0.6667
6. ์๊ณ๊ฐ: 0.45
์ ํ๋: 0.7857, ์ ๋ฐ๋: 0.7059, ์ฌํ์จ: 0.6667
7. ์๊ณ๊ฐ: 0.48
์ ํ๋: 0.7987, ์ ๋ฐ๋: 0.7447, ์ฌํ์จ: 0.6481
8. ์๊ณ๊ฐ: 0.5
์ ํ๋: 0.7987, ์ ๋ฐ๋: 0.7674, ์ฌํ์จ: 0.6111
์๊ณ๊ฐ 0.48์ด ์ ์ฒด์ ์ธ ์ฑ๋ฅ ํ๊ฐ ์งํ๋ฅผ ์ ์งํ๋ฉด์ ์ฌํ์จ์ ์ฝ๊ฐ ํฅ์์ํค๋ ์ข์ ์๊ณ๊ฐ
#์๊ณ๊ฐ์ 0.48๋ก ์ค์ ํ Binarizer ์์ฑ
binarizer = Binarizer(threshold=0.48)
#์์์ ๊ตฌํ lr_clf์ predict_proba() ์์ธก ํ๋ฅ array์์ 1์ ํด๋นํ๋ ์นผ๋ผ๊ฐ์ Binarizer ๋ณํ
pred_th_048 = binarizer.fit_transform(pred_proba[:,1].reshape(-1,1))
get_clf_eval(y_test, pred_th_048, pred_proba[:,1])
[Output]
์ค์ฐจ ํ๋ ฌ
[[88 12]
[19 35]]
์ ํ๋: 0.7987, ์ ๋ฐ๋: 0.7447, ์ฌํ์จ: 0.6481, F1:0.6931, AUC:0.8433