article thumbnail image
Published 2021. 11. 12. 15:25

머신러닝 모델 성능 평가 지표

  1. Accuracy(정확도)
    1. 직관적으로 모델 예측 성능을 나타낼 수 있지만, 이진분류의 경우 숫자 놀음이 될 수 있다.
    2. (예측 결과랑 동일한 데이터 수) / (전체 예측 데이터 수)
  2. Confusion Matrix(오차 행렬)
  3. Precision(정밀도)
  4. Recall(재현율)
  5. F1 score : 정밀도와 재현율이 얼마나 균형 잡혀 있는 지 확인한다.
  6. ROC AUC : 이진분류에서 굉장히 많이 사용된다.

 

 

 

import numpy as np
from sklearn.base import BaseEstimator

class MyDummyClassifier(BaseEstimator): # BaseEstimator를 상속받는다.
    # fit( ) 메소드는 아무것도 학습하지 않음. 원래라면 학습하지만 더미이기 때문에.
    def fit(self, X , y=None): # 이 함수는 더미이기 때문에 아무것도 안하고 그냥 패스한다.
        pass
    
    # predict( ) 메소드는 단순히 성별 feature가 1 이면 0 , 그렇지 않으면 1 로 예측함. 
    def predict(self, X): # X = test용 피쳐 데이터프레임이 들어온다. 
        # 남자이면 0 그렇지 않으면 1로 예측
        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

 

 

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

정확도 약 78%가 나온다.

성별이 남자인가, 여자인가 만 넣어도 사망, 생존의 결과가 78%가 나온다.

accuracy가 이러한 이슈가 있다.

 

mnist dataset도 마찬가지이다.

from sklearn.datasets import load_digits
from sklearn.model_selection import train_test_split
from sklearn.base import BaseEstimator
from sklearn.metrics import accuracy_score
import numpy as np
import pandas as pd

class MyFakeClassifier(BaseEstimator):
    def fit(self,X,y):
        pass
    
    # 입력값으로 들어오는 X 데이터 셋의 크기만큼 모두 0값으로 만들어서 반환
    def predict(self,X):
        return np.zeros( (len(X), 1) , dtype=bool)

# 사이킷런의 내장 데이터 셋인 load_digits( )를 이용하여 MNIST 데이터 로딩
digits = load_digits()

print(digits.data)
print("### digits.data.shape:", digits.data.shape)
print(digits.target)
print("### digits.target.shape:", digits.target.shape)

1797개의 데이터

target : 0이면 숫자 0이미지이다, 1이면 숫자 1이미지이다 를 나타냄

 

# digits번호가 7번이면 True이고 이를 astype(int)로 1로 변환, 7번이 아니면 False이고 0으로 변환. 
y = (digits.target == 7).astype(int)
X_train, X_test, y_train, y_test = train_test_split( digits.data, y, random_state=11)

정답을 무조건 7인지만 확인하고 

 

# 불균형한 레이블 데이터 분포도 확인. 
print('레이블 테스트 세트 크기 :', y_test.shape)
print('테스트 세트 레이블 0 과 1의 분포도')
print(pd.Series(y_test).value_counts())

# Dummy Classifier로 학습/예측/정확도 평가
fakeclf = MyFakeClassifier()
fakeclf.fit(X_train , y_train)
fakepred = fakeclf.predict(X_test)
print('모든 예측을 0으로 하여도 정확도는:{:.3f}'.format(accuracy_score(y_test , fakepred)))

90%의 정확도가 나온다.

정확도는 이렇게 이진분류일 경우에 잘 사용되지 않는다.

복사했습니다!