위키북스의 파이썬 머신러닝 완벽 가이드 책을 토대로 공부한 내용입니다.
머신러닝은 데이터 가공/변환, 모델 학습/예측, 평가(Evaluation)의 프로세스로 구성된다. 그리고 성능 평가 지표(Evaluation Metrix)는 일반적으로 모델이 분류인지, 회귀인지에 따라 여러 종류로 구분된다. 분류의 평가방법은 일반적으로는 실제 결과 데이터와 예측 결과 데이터가 얼마나 정확하고 오류가 적게 발생하는지에 기반하지만, 단순히 이러한 정확도만 가지고 판단하는 것은 잘못된 결과에 빠질 수 있다.
- 분류의 성능 평가 지표
1. 정확도 (Accuracy)
- 오차 행렬 (Confusion Matrix)
- 정밀도 (Precision)
- 재현율 (Recall)
- F1 스코어
- ROC AUC
위에서 언급된 분류의 성능 지표는 이진/멀티 분류에 모두 적용되는 지표이지만, 특히 이진 분류에서 더욱 중요하게 강조되는 지표이다.
정확도(Accuracy) = 예측 결과가 동일한 데이터 건수 / 전체 예측 데이터 건수
정확도는 직관적으로 모델 예측 성능을 나타내는 평가 지표이다. 하지만 이진 분류의 경우 데이터의 구성에 따라 ML 모델의 성능을 왜곡할 수 있기 때문에 정확도 수치 하나만으로 성능을 평가하지 않는다. 예를 들어 타이타닉 예제의 경우, 사실 생존 확률이 남자보다 여자가 더 많았기 때문에 단순하게 여자면 생존, 남자면 사망으로 예측하여도 80%대의 정확도가 나타날 것이다.
import numpy as np from sklearn.base import BaseEstimator class MyDummyClassifier(BaseEstimator): # fit( ) 메소드는 아무것도 학습하지 않음. def fit(self, X , y=None): pass # predict( ) 메소드는 단순히 Sex feature가 1 이면 0 , 그렇지 않으면 1 로 예측함. def predict(self, X): 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.preprocessing import LabelEncoder # Null 처리 함수 def fillna(df): df['Age'].fillna(df['Age'].mean(),inplace=True) df['Cabin'].fillna('N',inplace=True) df['Embarked'].fillna('N',inplace=True) df['Fare'].fillna(0,inplace=True) return df # 머신러닝 알고리즘에 불필요한 속성 제거 def drop_features(df): df.drop(['PassengerId','Name','Ticket'],axis=1,inplace=True) return df # 레이블 인코딩 수행. def format_features(df): df['Cabin'] = df['Cabin'].str[:1] features = ['Cabin','Sex','Embarked'] for feature in features: le = LabelEncoder() le = le.fit(df[feature]) df[feature] = le.transform(df[feature]) return df # 앞에서 설정한 Data Preprocessing 함수 호출 def transform_features(df): df = fillna(df) df = drop_features(df) df = format_features(df) return df import pandas as pd from sklearn.model_selection import train_test_split from sklearn.metrics import accuracy_score # 원본 데이터를 재로딩, 데이터 가공, 학습데이터/테스트 데이터 분할. titanic_df = pd.read_csv('/content/drive/MyDrive/pymldg-rev/2장/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)))
[output] 사이킷런의 BaseEstimator 클래스를 이용하여 학습을 하지 않고 성별만으로 생존자를 예측하는 Classifier를 생성했다. 사이킷런은 BaseEstimator를 상속받으면 Customized 형태의 Estimator를 개발자가 직접 생성할 수 있다. 생성할 MyDummyClassifier 클래스는 fit() method에선 아무 학습도 진행하지 않고, predict() method에서 Sex feature가 1이면 0으로, 1이 아니면 1로 예측하도록 하였다. 이렇게 단순하게 알고리즘을 만들어도 정확도가 78.77%로 높은 수치가 나오는 것을 확인할 수 있다. 따라서 정확도를 평가 지표로 사용할 때는 매우 신중해야하며, 특히 불균형한(imbalanced) label 분포레서 ML 모델의 성능을 판단할 경우에는 적합한 평가 지표로 사용될 수 없다.
정확도 평가 지표는 불균형한 label dataset에서 사용되면 안된다. 정확도가 가지는 분류 평가 지표로서 이러한 한계점을 극복하기 위헤 여러 가지 분류 지표와 함께 적용해야 하는데, 우선 다음 포스트에서 True/False, Positive/Negative의 4분면으로 구성되는 오차 행렬(Confusion Matrix)에 대해 설명할 것이다.