๋ณธ ํฌ์คํ ์ <ํ์ด์ฌ ๋จธ์ ๋ฌ๋ ์๋ฒฝ ๊ฐ์ด๋>์ 3์ฅ ๋ด์ฉ์ ์ฐธ๊ณ ํ์์ต๋๋ค.
์ ์ฒด์ ์ธ ๋ฐ์ดํฐ๋ฅผ ์ดํผ๊ณ , ๋ก์ง์คํฑ ํ๊ท ๋ชจํ ๊ฒฐ๊ณผ๋ฅผ ๊ต์ ํ๋ ๋ด์ฉ์ ๋ด๊ณ ์์ต๋๋ค.
1. ๋ฐ์ดํฐ ๋ถ๋ฌ์ค๊ณ , ๊ฒฐ๊ด๊ฐ ๋ถํฌ ์ฒดํฌ
from sklearn.linear_model import LogisticRegression
import pandas as pd
diabetes_data = pd.read_csv('diabetes.csv')
print(diabetes_data['Outcome'].value_counts())
diabetes_data.head(3)
diabetes_data.info()
2. ๊ฒฐ๊ณผ ํ๊ฐ ํจ์ ์ ์
- ์ ํ๋, ์ ๋ฐ๋, ์ฌํ์จ, f1 ๊ฐ, roc_auc ๊ฐ, ํผ๋ํ๋ ฌ ์ถ๋ ฅ
- ์ ๋ ฅ ํ๋ผ๋ฏธํฐ๋ y_test, ์์ธก ๊ฒฐ๊ณผ(pred), 1๋ก ์์ธกํ ํ๋ฅ (pred_proba)
from sklearn.metrics import accuracy_score, precision_score, recall_score, f1_score, confusion_matrix, roc_auc_score
def get_clf_eval(y_test, pred=None, pred_proba=None):
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_score(y_test,pred)
# ROC-AUC ์ถ๊ฐ
roc_auc = roc_auc_score(y_test, pred_proba)
print('์ค์ฐจ ํ๋ ฌ')
print(confusion)
# ROC-AUC print ์ถ๊ฐ
print('์ ํ๋: {0:.4f}, ์ ๋ฐ๋: {1:.4f}, ์ฌํ์จ: {2:.4f},\
F1: {3:.4f}, AUC:{4:.4f}'.format(accuracy, precision, recall, f1, roc_auc))
3. 1์ฐจ ๋ชจ๋ธ๋ง(๋ก์ง์คํฑ ํ๊ท)
- ํผ์ฒ, ๋ ์ด๋ธ ๋ฐ์ดํฐ ์ธํธ ๋ถ๋ฆฌ
- train_test_split ์ผ๋ก ํ์ต/ํ๊ฐ ๋ฐ์ดํฐ ๋ถ๋ฆฌ
- ๋ก์ง์คํฑ ํ๊ท๋ก ํ์ต, ์์ธก, ํ๊ฐ โก ์์ธก๊ฐ๊ณผ, ํด๋์ค 1์ ๋ํ ์์ธก ํ๋ฅ ๊ฐ ๋์ถ
- 2์์ ์ ์ํ ํ๊ฐ ํจ์๋ก ๊ฒฐ๊ณผ ํ์ธ
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LogisticRegression
# ํผ์ฒ ๋ฐ์ดํฐ ์ธํธ(x), ๋ ์ด๋ธ ๋ฐ์ดํฐ ์ธํธ(y)๋ฅผ ์ถ์ถ
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)
# ๋ก์ง์คํฑ ํ๊ท๋ก ํ์ต, ์์ธก, ํ๊ฐ
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)
4. ์๊ณ๊ฐ ๋ณํ์ ๋ฐ๋ฅธ ์ฌํ์จ๊ณผ ์ ๋ฐ๋ ์๊ฐํ(ํจ์)
- precision_recall_curve ์ฌ์ฉ
- ์๊ฐํ ํจ์ ์ ์ : ๋งค๊ฐ๋ณ์๋ y_test, ํด๋์ค 1๊ฐ์ผ๋ก์ ์์ธก ํ๋ฅ
import matplotlib.pyplot as plt
import matplotlib.ticker as ticker
from sklearn.metrics import precision_recall_curve
import numpy as np
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)
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')
start, end = plt.xlim()
plt.xticks(np.round(np.arange(start, end, 0.1), 2))
plt.xlabel('threshold value')
plt.ylabel('Precision and Recall Value')
plt.legend()
plt.grid()
plt.show()
- ํจ์ ์ ์ฉ
pred_proba_c1 = lr_clf.predict_proba(X_test)[:, 1]
precision_recall_curve_plot(y_test, pred_proba_c1)
๋ ๊ทธ๋ํ๊ฐ ๋ง๋๋ ์ง์ ์ ์ ๋ฐ๋์ ์ฌํ์จ์ด ๋ชจ๋ 0.8 ์ดํ๋ก ๋ฎ์ ํธ์ด๋ฏ๋ก, ๋ค์ ํ๋ฒ ์ ์ฒด ๋ฐ์ดํฐ ๊ฒํ
5. ๋ฐ์ดํฐ ๋ถํฌ ์ฌํ์ธ
diabetes_data.describe()
๐ ์ผ๋ถ ์ปฌ๋ผ์ ์ต์๊ฐ์ด 0์ธ ๊ฒ์ ํ์ธ : 0์ธ ๊ฒ์ด ๋ถ๊ฐ๋ฅํ ์ปฌ๋ผ์ ์ด์์น๋ก ํ๋จ
๐ ํ์คํ ๊ทธ๋จ์ ๊ทธ๋ ค์ ์ข ๋ ์์ธํ ํ์ ํด๋ณด์.(Glucose ์ปฌ๋ผ)
plt.hist(diabetes_data['Glucose'], bins = 100)
plt.show()
๐ ํ์คํ 0๊ฐ์ด ๋ณด์
๐ 0 ๊ฐ์ ์ฒ๋ฆฌํ ํ์๊ฐ ์์ ->> ํ๊ท ์ผ๋ก ๋์ฒด
6. 0๊ฐ์ด ์๋ ์ปฌ๋ผ์ 0๊ฐ ๋น์จ ์กฐ์ฌ(์ ์ฒด ๋ฐ์ดํฐ ๋๋น)
- 0๊ฐ์ด ์์ ์ ์๋ ํผ์ฒ๋ช ์ ๋ฆฌ์คํธ๋ก ์ ๋ฆฌ
- ์ ์ฒด ๋ฐ์ดํฐ ๊ฑด์ ์ธก์
- 0๊ฐ ๊ฒ์ฌํ ํผ์ฒ๋ค ๊ฐ๊ฐ์ ์ด 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))
7. 0๊ฐ์ด ์๋ ์ปฌ๋ผ์ ํ๊ท ์ผ๋ก ๋์ฒด
- ์ ์ฒด ์ปฌ๋ผ ์ค 0๊ฐ ๋์ฒด๊ฐ ํ์ํ ์ปฌ๋ผ(zero_features)์ ํ๊ท ์ ๋์ถ
- replace() ํจ์๋ก zero_features์ 0๊ฐ์ ํ๊ท ๊ฐ์ผ๋ก ๋์ฒด
# 0๊ฐ์ ํ๊ท ๊ฐ์ผ๋ก ๋์ฒด!
mean_zero_features = diabetes_data[zero_features].mean()
diabetes_data[zero_features] = diabetes_data[zero_features].replace(0, mean_zero_features)
8. StandardScaler ํ, ๋ก์ง์คํฑ ํ๊ท ์ฌ์๋
- โ ๋ก์ง์คํฑํ๊ท๋ ์ผ๋ฐ์ ์ผ๋ก ์ซ์ ๋ฐ์ดํฐ์ ์ค์ผ์ผ๋ง์ ์ ์ฉํ๋ ๊ฒ์ด ์ข์
- ๋ค์ ํ ๋ฒ, X, y๊ฐ์ ๋๋๊ณ X ๊ฐ์ ๋ํด StandardScaler wjrdyd
- train, test ๋ฐ์ดํฐ์ ๋ถ๋ฆฌ
- ๋ก์ง์คํฑ ํ๊ท๋ก ํ์ต, ์์ธก, ํ๊ฐ(ํ๊ฐ๋ ์์์ ๋ง๋ ํจ์: get_clf_eval ์ฌ์ฉ)
from sklearn.preprocessing import StandardScaler
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)
9. ์ฌํ์จ์ด ๋ฎ์ ๋ฌธ์ ํด๊ฒฐ --- ์๊ณ๊ฐ์ ๋ณํ์ํค๋ฉฐ ๊ฒฐ๊ณผ ํ์ธ
- Binarizer ๋ฉ์๋๋ก threshold(์๊ณ๊ฐ)์ ๋ณํ์ํค๋ฉฐ predict ๊ฒฐ๊ด๊ฐ์ ๋ค๋ฅด๊ฒ ํ์ฌ
- ํ๊ฐ ๊ฒฐ๊ณผ๋ฅผ ํ์ธํ๋ ํจ์ ์์ฑ
from sklearn.preprocessing import Binarizer
def get_eval_by_thresholds(y_test, pred_proba_c1, thresholds):
for custom_threshold in thresholds:
binarizer = Binarizer(threshold = custom_threshold).fit(pred_proba_c1)
custom_predict = binarizer.transform(pred_proba_c1)
print('์๊ณ๊ฐ: ', custom_threshold)
get_clf_eval(y_test, custom_predict, pred_proba_c1)
print('\n')
- ํจ์ ์ ์ฉ
thresholds = [0.3, 0.33, 0.36, 0.39, 0.42, 0.45, 0.48, 0.50]
pred_proba = lr_clf.predict_proba(X_test)
get_eval_by_thresholds(y_test, pred_proba[:, 1].reshape(-1, 1), thresholds)
10. ์ ๋ฐ๋์ ์ฌํ์จ์ด ์ ์ ํ ๋์ ์ง์ ํ์ธ(์๊ณ๊ฐ 0.48)
-->> ์๊ณ๊ฐ 0.48๋ก ์ต์ข ๋ก์ง์คํฑ ํ๊ท ์งํ ๐
# ์๊ณ๊ฐ์ 0.48๋ก ์ค์ ํ Binarizer ์์ฑ
binarizer = Binarizer(threshold=0.48)
pred_th_048 = binarizer.fit_transform(pred_proba[:, 1].reshape(-1, 1))
get_clf_eval(y_test, pred_th_048, pred_proba[:, 1])
728x90