💠 Alchemist 2주차 💠

2023. 10. 1. 16:54개발/💠 Alchemist

 

 

⏰ 진행 타임라인 ⏰

19:00 ~ 19:15       근황 토크 및 과제 확인
19:20 ~ 20:00      강의 세션
20:00 ~ 20:05     쉬는 시간
20:05 ~ 20:25     Q&A
20:25 ~ 21:00      실습 

 

 

1.  개념 정리

https://sosoeunii.tistory.com/94

 

💠 평가 💠

1. 평가 머신러닝의 대략적인 프로세스는 데이터 가공 / 변환 -> 모델 학습 / 예측 -> 평가 로 구성되어있다 이 때 '평가'란 말 그대로 모델이 결과 예측을 잘 하고 있는지 판단하는 것을 의미한다

sosoeunii.tistory.com

 

 

2.  Q&A

1.  정밀도 / 재현율 구체적인 적용 예시
2.  코드 문법 부분

 

실습 부분 미리 공부해가서 코드 부분 문법 질문 답변 잘 할 수 있도록 해야겠다

 

 

3.  실습

 

< 피마 인디언 당뇨병 예측 >

 

필요한 거 import 및 데이터 불러오기

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import matplotlib.ticker as ticker
%matplotlib inline

from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score, precision_score, recall_score, roc_auc_score
from sklearn.metrics import f1_score, confusion_matrix, precision_recall_curve, roc_curve
from sklearn.preprocessing import StandardScaler
from sklearn.preprocessing import Binarizer
from sklearn.linear_model import LogisticRegression


diabetes_data = pd.read_csv('/Users/jeongsoeun/Downloads/diabetes.csv')
print(diabetes_data['Outcome'].value_counts())
diabetes_data.head(3)

 

평가 - 오차 행렬, 정확도, 정밀도, 재현율, f1스코어, AUC 스코어 계산 및 출력 함수

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)					# f1 스코어
    roc_auc = roc_auc_score(y_test, pred_proba) # AUC 스코어
    
    
    # 출력
    print('오차 행렬')
    print(confusion)
    
    print('정확도: {0:.4f}, 정밀도: {1:.4f}, 재현율: {2:.4f},\
    F1:{3:.4f}, AUC:{4:.4f}'.format(accuracy, precision, recall, f1, roc_auc))

 

임곗값 기준으로 각 성능 평가 지표 값 출력하는 함수

def get_eval_by_threshold(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)

 

임곗값에 따른 정밀도, 재현율 값 변화 시각화 함수

def precision_recall_curve_plot(y_test, pred_proba_c1):
    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()

 

ROC 곡선 시각화 함수

def roc_curve_plot(y_test, pred_proba_c1):
    fprs, tprs, thresholds = roc_curve(y_test, pred_proba_c1)
    plt.plot(fprs, tprs, label = 'ROC')
    plt.plot([0, 1], [0, 1], 'k--', label = 'Random')
    
    start, end = plt.xlim()
    plt.xticks(np.round(np.arange(start, end, 0.1), 2))
    plt.xlabel('FPR(1 - Specificity)'); plt.ylabel('TPR(Recall)')
    plt.legned()

 

학습 / 테스트 데이터 분리 -> 로지스틱 회귀 알고리즘 실행( 모델 학습 / 예측 ) -> get_clf_eval 함수로 모델 평가

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)

 

X_test 데이터로 모델 예측 후 precision_recall_curve_plot() 함수로 시각화

pred_proba_c1 = lr_clf.predict_proba(X_test)[:, 1]
precision_recall_curve_plot(y_test, pred_proba_c1)

 

아래 세 개의 코드를 통해 min 값이 0인 건수가 매우 많다는 것을 알 수 있음

diabetes_data.describe()

plt.hist(diabetes_data['Glucose'], bins = 100)
plt.show()

zero_features = ['Glucose', 'BloodPressure', 'SkinThickness', 'Insulin', 'BMI']

total_count = diabetes_data['Glucose'].count()

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))

 

 

0값이 많은 칼럼들의 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)

 

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_threshold(y_test, pred_proba[:, 1].reshape(-1, 1), thresholds)

 

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])

'개발 > 💠 Alchemist' 카테고리의 다른 글

💠 Alchemist 3주차 💠  (0) 2023.10.04
💠 머신러닝 분류 모델 ( 1 ) 💠  (0) 2023.10.03
💠 평가 💠  (0) 2023.09.26
💠 AIchemist 1주차 💠  (0) 2023.09.25
💠 사이킷런 ( scikit-learn )💠  (0) 2023.09.19