평가지표

 

성능평가

분류 모델 평가

  • 분류 모델은 0인지 1인지를 예측하는 것
  • 실제 값도 0과 1이고 예측 값도 0과 1임
  • 하지만 0을 1로 예측하거나 1을 0으로 예측할 수 있음
  • 예측 값이 실제 값과 많이 같을 수록 좋은 모델이라 할 수 있음  → 정확히 예측한 비율로 모델 성능을 평가

 

오분류표(Confusion Matrix)

  • TN(True Negative, 진음성): 음성으로 잘 예측한 것(음성을 음성이라고 예측한 것)
  • FP(False Positive, 위양성): 양성으로 잘 못 예측한 것(음성을 양성이라고 예측한 것)
  • FN(False Negative, 위음성): 음성으로 잘 못 예측한 것(양성을 음성이라고 예측한 것)
  • TP(True Positive, 진양성): 양성으로 잘 예측한 것(양성을 양성이라고 예측한 것)



정확도(Accuracy) - 1과 0을 정확히 예측한 비율

  • 정분류율 이라고 부르기도 함
  • 전체 중에서 Positive와 Negative 로 정확히 예측한(TN + TP) 비율 
  • Negative를 Negative로 예측한 경우도 옳은 예측임을 고려하는 평가지표
  • 가장 직관적으로 모델 성능을 확인할 수 있는 평가지표
  • from sklearn.metrics import accuracy_score
  • accuracy_score(y_test, y_pred)

 

정밀도(Precision) - 1이라 예측한 것 중에서 정말 1인 비율

  • Positive로 예측한 것(FP + TP) 중에서 실제 Positive(TP)인 비율
  • 예) 비가 내릴 것으로 예측한 날 중에서 실제 비가 내린 날의 비율
  • 예) 암이라 예측한 환자 중에서 실제 암인 환자의 비율
  • 정밀도가 낮을 경우 발생하는 상황
    • 비가 오지 않는데 비가 온다고 했으니 불필요한 우산을 챙기는 수고 발생
    • 암이 아닌데 암이라 했으니 불필요한 치료 발생
  • from sklearn.metrics import precision_score
  • precision_score(y_test, y_pred, average = None) - average는 생략가능 하지만 추천하지는 않음
    • average = [ 'binary' - 기본값 / 'macro' - 정밀도 평균 / 'weighted' - 정밀도 가중치 평균 ]

 

재현율(Recall) - 실제 1인 것을 1이라고 예측한 비율

  • 실제 Positive(FN + TP) 중에서 Positive로 예측한(TP) 비율
  • 민감도(Sensitivity)라고 부르는 경우가 많음 
  • 예) 실제 비가 내린 날 중에서 비가 내릴 것으로 예측한 날의 비율
  • 예) 실제 암인 환자 중에서 암이라고 예측한 환자의 비율
  • 재현율이 낮을 경우 발생하는 문제
    • 비가 내리는 날 내리지 않을 것이라 했으니 우산을 챙기지 않아 비를 맞음
    • 암인 사람에게 암이 아니라 했으니 심각한 결과 초래
  • from sklearn.metrics import recall_score
  • recall_score(y_test, y_pred, average = None)

특이도(Specificity) - 실제 Negative(TN + FP) 중에서 Negative로 예측한(TN) 비율

  • 예) 실제 비가 내리지 않은 날 중에서 비가 내리지 않을 것으로 예측한 날의 비율
  • 예) 실제 암이 아닌 환자 중에서 암이 아니라고 예측한 환자의 비율
  • 특이도가 낮을 경우 발생하는 문제
    • 비가 오지 않는데 비가 온다고 했으니 불필요한 우산을 챙기는 수고 발생
    • 암이 아닌데 암이라 했으니 불필요한 치료 발생

정밀도가 높으면 재현율이 낮을 수 있다.

 

F1-Score - 정밀도와 재현율의 조화 평균

  • 분자가 같지만 분모가 다를 경우, 즉 관점이 다른 경우 조화 평균이 큰 의미를 가짐
  • 정밀도와 재현율이 적절하게 요구 될 때 사용
  • from sklearn.metrics import f1_score
  • f1_score(y_test, y_pred, average = None)

 

이중 분류 성능 평가★

  • from sklearn.metrics import classification_report, confusion_matrix
  • confusion_matrix (y_test, y_pred) - 구조 확인 가능
  • classification_report(y_test, y_pred) - 모든 지표를 확인 가능

 

분류모델 머신러닝 예제

선언 및 데이터 읽어오기

# 라이브러리 불러오기
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
import warnings

warnings.filterwarnings(action='ignore')
%config InlineBackend.figure_format = 'retina'

# 데이터 읽어오기
path = 'https://raw.githubusercontent.com/Jangrae/csv/master/admission_simple.csv'
data = pd.read_csv(path)

 

데이터 확인

  • data.head()
  • data.tail()
  • data.info()
  • data.describe()
  • data.corr(numeric_only=True).style.background_gradient()

x와 y 분리

# target 확인
target = 'ADMIT'

# 데이터 분리
x = data.drop(target, axis=1)
y = data.loc[:, target]

# 모듈 불러오기
from sklearn.model_selection import train_test_split

# 7:3으로 분리
x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.3, random_state=1 )

 

모델링

# 1단계: 불러오기
from sklearn.neighbors import KNeighborsClassifier

# 2단계: 선언하기
model = KNeighborsClassifier()

# 3단계: 학습하기
model.fit(x_train, y_train)

# 4단계: 예측하기
y_pred = model.predict(x_test)

 

분류 성능 평가

# 모듈 불러오기
from sklearn.metrics import confusion_matrix

# 성능 평가
print(confusion_matrix(y_test, y_pred))

plt.figure(figsize = (5, 2))
sns.heatmap(confusion_matrix(y_test, y_pred),
           annot = True, cbar = False, cmap = 'Purples',
           annot_kws = {'size' : 16})

plt.show()

# 모듈 불러오기
from sklearn.metrics import classification_report

# 성능 평가
print(classification_report(y_test, y_pred))
  • Accuracy
    • from sklearn.metrics import accuracy_score
    • print('정확도(Accuracy) =', accuracy_score(y_test, y_pred))
  • Precision  
    • from sklearn.metrics import precision_score
    • print('정밀도(Precision) =', precision_score(y_test, y_pred, average = None)) # 권고  
  • Recall
    • from sklearn.metrics import recall_score
    • print('재현율(Recall) =', recall_score(y_test, y_pred, average = None)
  • F1-Score
    • from sklearn.metrics import f1_score
    • print('F1_score) =', f1_score(y_test, y_pred, average = None))

 

회귀 모델 평가

  • 회귀 모델이 정확한 값을 예측하기는 사실상 어려움
  • 예측 값과 실제 값에 차이(=오차)가 존재할 것이라 예상
  • 예측 값이 실제 값에 가까울 수록 좋은 모델이라 할 수 있음 → 예측한 값과 실제 값의 차이(=오차)로 모델 성능을 평가

 

𝑦 : 실젯값

  • 우리가 실제로 예측하고 싶은 값, Target, 목푯값
  • 실제값과 비교해 모델의 성능을 평가
  • 우리가 관심을 갖는 오차는 이 값과 예측값의 차이

ȳ : 평균값

  • 이미 알고 있는, 이미 존재하고 있는 평균으로 예측한 값
  • 최소한 이 평균값 보다는 실젯값에 가까운 예측값을 원함
  • 우리 모델의 예측값이 평균값보다 오차를 얼마나 더 줄였는지 확인

y^ : 예측값

  • 우리 모델로 새롭게 예측한 값
  • 이 예측값이 얼마나 정확한지 알고 싶은 상황
  • 최소한, 평균값 보다는 좋아야 의미가 있음
  • 우리 모델이 평균값보다 얼마나 잘 예측했을지 검증

 

오차 합 구하기

오차 제곱의 합

  • SSE(Sum Squared Error) - 제곱해서 더함
  • MSE(Mean squared Error) - 제곱해서 더한것을 n(행수)으로 나눔 / 손실함수
  • RMSE(Root MSE) - MSE에 루트를 씌움 

 

오차 절대값의 합

  • MAE(Mean Absolute Error) - 오차의 절대값으로 더하고 n으로 나눔
  • MAPE(Mean Absolute Percentage Error) - 절대값의 합을 y로 나누어 퍼센테이지로 구함

 

 

 

  • SST(Sum Squared Total) - 전체 오차(최소한 평균 보다는 성능이 좋아야 하니, 우리에게 허용된(?) 오차)
    • 실제값과 평균값의 오차를 제곱
  • SSR(Sum Squared Regression) - 전체 오차 중에서 회귀식이 잡아낸 오차 (우리가 해결한 것 / 클수록 좋음)
    • 예측값과 평균값의 오차를 제곱
  • SSE(Sum Squared Error) - 전체 오차 중에서 회귀식이 여전히 잡아내지 못한 오차
    • 예측값과 실제값의 오차를 제곱
  • SST = SSR + SSE

결정계수 R^2 (R-Squared)

  • 모델 성능을 잘 해석하기 위해서 만든 MSE의 표준화된 버전이 결정 계수
  • 전체 오차 중에서 회귀식이 잡아낸 오차 비율(일반적으로 0 ~ 1 사이)
  • 오차의 비 또는 설명력이라고도 부름
  • 𝑅 2 = 1이면 𝑀𝑆𝐸 = 0이고 모델이 데이터를 완벽하게 학습한 것

 

회귀모델 머신러닝 예제

선언 및 데이터 읽어오기

# 라이브러리 불러오기
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
import warnings

warnings.filterwarnings(action='ignore')
%config InlineBackend.figure_format = 'retina'

# 데이터 읽어오기
path = 'https://raw.githubusercontent.com/Jangrae/csv/master/airquality_simple.csv'
data = pd.read_csv(path)

 

데이터 확인

  • data.head()
  • data.tail()
  • data.info()
  • data.describe()
  • data.corr(numeric_only=True).style.background_gradient()

전처리 - 결측치 처리, 변수 제

# 결측치 확인
data.isnull().sum()
Ozone      0
Solar.R    7
Wind       0
Temp       0
Month      0
Day        0
dtype: int64
# 전날 값으로 결측치 채우기
#data.fillna(method='ffill', inplace=True)
data.ffill(inplace = True)
# 확인
data.isnull().sum()
Ozone      0
Solar.R    0
Wind       0
Temp       0
Month      0
Day        0
dtype: int64

 

# 변수 제거
drop_cols = ['Month', 'Day']
# data.drop(drop_cols, axis=1, inplace=True)
data.drop(columns = drop_cols, inplace=True)
# 확인
data.head(1)

x와 y 분리

# target 확인
target = 'Ozone'

# 데이터 분리
x = data.drop(target, axis=1)
y = data.loc[:, target]

# 모듈 불러오기
from sklearn.model_selection import train_test_split

# 7:3으로 분리
x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.3, random_state=1)
# stratify=y를 활용하면 일정한 기준으로 나뉘어진 y값으로 분리됨
  • stratify=y를 활용하면 일정한 기준으로 나뉘어진 y값으로 분리됨

모델링

# 1단계: 불러오기
from sklearn.linear_model import LinearRegression

# 2단계: 선언하기
model = LinearRegression()

# 3단계: 학습하기
model.fit(x_train, y_train)

# 4단계: 예측하기
y_pred = model.predict(x_test)

 

회귀 성능 평가

# 모듈 불러오기
from sklearn.metrics import mean_absolute_error

# 성능 평가
print('MAE =', mean_absolute_error(y_test, y_pred))
MAE = 13.976843190385708

 

  • MAE(Mean Absolute Error)
    • from sklearn.metrics import mean_absolute_error
    • print('MAE =', mean_absolute_error(y_test, y_pred))
  • MSE(Mean Squared Error)
    • from sklearn.metrics import mean_squared_error
    • print('MSE =', mean_squared_error(y_test, y_pred))
  • RMSE(Root Mean Squared Error)  
    • from sklearn.metrics import root_mean_squared_error
    • print('RMSE =', root_mean_squared_error(y_test, y_pred))
  • MAPE(Mean Absolute Percentage Error)
    • from sklearn.metrics import mean_absolute_percentage_error
    • print('MAPE =', mean_absolute_percentage_error(y_test, y_pred))
  • R2-Score
    • from sklearn.metrics import r2_score
    • print('R2 =', r2_score(y_test, y_pred))

+ Recent posts