4 분 소요

본 게시물은 평가함수와 머신러닝 기초 예제에 대해 소개한다.

1. 평가 함수

1.1 회귀 분석

📍 MAE

  • 절대값 차이
  • 에러의 크기를 그대로 반영 ☞ 이상치에 영향을 받음
from sklearn.metrics import mean_absolute_error
mae = mean_absolute_error(y_test, y_pred)

📍 MSE

  • 제곱합 평균 ☞ 실측과 예측 차이의 면적과 동일
  • 특이값이 존재하면 수치 증가

from sklearn.metrics import mean_squared_error
mse = mean_squared_error(y_test, y_pred)

📍 RMSE

  • MSE에 루트 적용
  • 제곱합으로 인해 커지는 손실을 scale down 함
from sklearn.metrics import mean_squared_error
import numpy as np
mse = mean_squared_error(y_test, y_pred)
rmse = np.sqrt(mse) 

📍 MSLE

  • MSE에 로그 적용
  • 차이가 작을수록 큰 값을 가지기에 예측값이 작을때 유용
from sklearn.metrics import mean_squared_log_error
msle = mean_squared_log_error(y_test, y_pred) 

📍 MAPE

  • MAE를 퍼센트로 변환
  • 오차가 예측값에서 차지하는 퍼센트
import numpy as np
def MAPE(y_test, y_pred):
 mape = np.mean(np.abs((y_test - y_pred)/y_test)) * 100
 return mape
mape = MAPE(y_test, y_pred)

1.2 분류 분석

📍 Accuracy

from sklearn.metrics import accuracy_score
acc = accuracy_score(y_test, y_pred)

📍 Confusion Matrix

from sklearn.metrics import confusion_matrix
cm = confusion_matrix(y_test, y_pred)

📍 Precision

from sklearn.metrics import precision_score
precision = precision_score(y_test, y_pred)

📍 Recall

from sklearn.metrics import recall_score
recall = recall_score(y_test, y_pred)

📍 F1-score

from sklearn.metrics import f1_score
f1 = f1_score(y_test, y_pred)

📍 ROC curve

  • 분류 기준이 되는 threshold를 기준으로 FFR과 TPR을 구하고 그래프를 그림
from sklearn.metrics import roc_curve
fpr, tpr, thres = roc_curve(y_test, y_pred, pos_label = 1)
import matplotlib.pyplot as plt
plt.plot(fpr, tpr)

📍AUC score

  • ROC curve의 아래 면적으로 랜덤 수준의 AUC score는 0.5
from sklearn.metrics import roc_curve, auc
fpr, tpr, thres = roc_curve(y_test, y_pred, pos_label = 1)
auc = auc(fpr, tpr)

2. 회귀분석

😗 데이터 가져오기

from sklearn import datasets
import pandas as pd
df, price = datasets.fetch_openml('boston', return_X_y=True)
df['PRICE'] = price

2.1 데이터 확인하기

# 대략적 형태 확인
df.head()

# 행, 열 확인
df.shape
(506, 14)
# 타입 확인
df.info()
 #   Column   Non-Null Count  Dtype   
---  ------   --------------  -----   
 0   CRIM     506 non-null    float64 
 1   ZN       506 non-null    float64 
 2   INDUS    506 non-null    float64 
 3   CHAS     506 non-null    category
 4   NOX      506 non-null    float64 
 5   RM       506 non-null    float64 
 6   AGE      506 non-null    float64 
 7   DIS      506 non-null    float64 
 8   RAD      506 non-null    category
 9   TAX      506 non-null    float64 
 10  PTRATIO  506 non-null    float64 
 11  B        506 non-null    float64 
 12  LSTAT    506 non-null    float64 
 13  PRICE    506 non-null    float64 
dtypes: category(2), float64(12)
  • CHAS를 제외하고는 모두 float형이어야 하지만, RAD가 1.0, 2.0 .. 과 같은 형태라 category로 인식됨 ☞ 형변환 필요
df['RAD'] = df['RAD'].astype('float')
df.info()
 #   Column   Non-Null Count  Dtype   
---  ------   --------------  -----   
 0   CRIM     506 non-null    float64 
 1   ZN       506 non-null    float64 
 2   INDUS    506 non-null    float64 
 3   CHAS     506 non-null    category
 4   NOX      506 non-null    float64 
 5   RM       506 non-null    float64 
 6   AGE      506 non-null    float64 
 7   DIS      506 non-null    float64 
 8   RAD      506 non-null    float64 
 9   TAX      506 non-null    float64 
 10  PTRATIO  506 non-null    float64 
 11  B        506 non-null    float64 
 12  LSTAT    506 non-null    float64 
 13  PRICE    506 non-null    float64 
dtypes: category(1), float64(13)
# null 확인
df.isna().sum()
CRIM       0
ZN         0
INDUS      0
CHAS       0
NOX        0
RM         0
AGE        0
DIS        0
RAD        0
TAX        0
PTRATIO    0
B          0
LSTAT      0
PRICE      0
dtype: int64

2.2 데이터 시각화

import matplotlib.pyplot as plt
import seaborn as sns
# 3개의 행과 4개의 열을 가진 subplot 그리기
fig, axs = plt.subplots(figsize=(16,10), ncols=4, nrows=3, constrained_layout=True)
features = df.columns.difference(['PRICE', 'CHAS'])

for i, feature in zip(range(12), features):
    row = int(i/4) # 행번호 설정
    col = i%4 # 열번호 설정
    # seaborn의 regplot을 이용해 산점도와 선형 회귀직선을 함께 시각화함
    sns.regplot(x=feature, y=df['PRICE'], data=df, ax=axs[row][col])

2.3 데이터 분할

from sklearn.model_selection import train_test_split
x = df[['CRIM', 'ZN', 'INDUS', 'NOX', 'RM', 'AGE', 'DIS', 
        'RAD', 'TAX', 'PTRATIO', 'B', 'LSTAT']].values
y = df['PRICE'].values
x_train, x_test, y_train, y_test = train_test_split(x, y, 
                                                    test_size=0.2, random_state=42)
print('학습데이터세트 PRICE 평균: ', y_train.mean())
print('평가데이터세트 PRICE 평균: ', y_test.mean())
학습데이터세트 PRICE 평균:  22.796534653465343
평가데이터세트 PRICE 평균:  21.488235294117644

2.4 전처리

from sklearn.preprocessing import MinMaxScaler
scaler = MinMaxScaler()
x_train_scaled = scaler.fit_transform(x_train) 

2.5 모델 학습

from sklearn.linear_model import LinearRegression
from sklearn.metrics import mean_absolute_error, mean_squared_error
from sklearn.metrics import r2_score
import numpy as np

# 모델 핛브
linear = LinearRegression()
linear.fit(x_train_scaled, y_train)

# 학습데이터로 평가
pred_train = linear.predict(x_train_scaled)
mae = mean_absolute_error(y_train, pred_train)
mse = mean_squared_error(y_train, pred_train)
rmse = np.sqrt(mse)
r2 = r2_score(y_train, pred_train)
print('MAE: {0: .5f}'.format(mae))
print('MSE: {0: .5f}'.format(mse))
print('RMSE: {0: .5f}'.format(rmse))

# 모델의 설명력
print('R2: {0: .5f}'.format(r2))
MAE:  3.32616
MSE:  22.11246
RMSE:  4.70239
R2:  0.74546
  • R2는 모델의 설명력을 의미함

2.6 평가

x_test_scaled = scaler.transform(x_test)
pred = linear.predict(x_test_scaled)

mae = mean_absolute_error(y_test, pred)
mse = mean_squared_error(y_test, pred)
rmse = np.sqrt(mse)
r2 = r2_score(y_test, pred)
print('MAE: {0: .5f}'.format(mae))
print('MSE: {0: .5f}'.format(mse))
print('RMSE: {0: .5f}'.format(rmse))
print('R2: {0: .5f}'.format(r2))
MAE:  3.23724
MSE:  24.63539
RMSE:  4.96341
R2:  0.66406

3. 분류분석

😗 데이터 가져오기

from sklearn.datasets import load_iris
import pandas as pd
iris = load_iris()
iris_dt = iris.data
iris_label = iris.target
df = pd.DataFrame(data=iris_dt, columns=iris.feature_names)
df['label'] = iris_label

3.1 데이터 확인

df.head()

df.label.unique()
array([0, 1, 2])
df.shape
(150, 5)
df.isna().sum()
sepal length (cm) 0
sepal width (cm) 0
petal length (cm) 0
petal width (cm) 0
Species 0
dtype: int64 

3.2 데이터 분할

from sklearn.model_selection import train_test_split
x_train, x_test, y_train, y_test = train_test_split(iris_dt, 
                                                    iris_label, 
                                                    test_size=0.2, 
                                                    random_state=0, 
                                                    stratify=iris_label)

3.3 모델 학습

from sklearn.tree import DecisionTreeClassifier
from sklearn.model_selection import cross_val_score
import numpy as np

dtree_clf_5 = DecisionTreeClassifier(max_depth=5, random_state=100)
dtree_clf_3 = DecisionTreeClassifier(max_depth=3, random_state=100)
dtree_clf_1 = DecisionTreeClassifier(max_depth=1, random_state=100) 

scores = cross_val_score(dtree_clf_5, x_train, y_train, scoring='accuracy', cv=10)
print("max depth 5")
print('교차검증 정확도: ', np.round(scores, 3))
print('평균 검증 정확도: ', np.round(np.mean(scores), 4))

scores = cross_val_score(dtree_clf_3, x_train, y_train, scoring='accuracy', cv=10)
print("max depth 3")
print('교차검증 정확도: ', np.round(scores, 3))
print('평균 검증 정확도: ', np.round(np.mean(scores), 4))


scores = cross_val_score(dtree_clf_1, x_train, y_train, scoring='accuracy', cv=10)
print("max depth 1")
print('교차검증 정확도: ', np.round(scores, 3))
print('평균 검증 정확도: ', np.round(np.mean(scores), 4))
max depth 5
교차검증 정확도:  [0.917 1.    0.917 1.    1.    0.833 1.    0.917 1.    0.833]
평균 검증 정확도:  0.9417
max depth 3
교차검증 정확도:  [0.917 1.    0.917 0.917 1.    0.833 1.    0.917 0.917 0.833]
평균 검증 정확도:  0.925
max depth 1
교차검증 정확도:  [0.667 0.667 0.667 0.667 0.667 0.667 0.667 0.667 0.667 0.667]
평균 검증 정확도:  0.6667

3.4 성능 평가

dtree_clf_5.fit(x_train, y_train)
pred = dtree_clf_5.predict(x_test)
from sklearn.metrics import accuracy_score
print('의사결정나무(교차검증 후) 예측 정확도: {0:.5f}'.format(accuracy_score(y_test, pred)))
의사결정나무(교차검증 후) 예측 정확도: 0.96667

댓글남기기