파이썬 머신러닝 완벽 가이드

정확도
정확도: 실제 데이터에서 예측 데이터가 얼마나 같은지를 판단하는 지표
사이킷런의 BaseEstimator 클래스를 상속받아 아무런 학습을 하지 않고, 성별에 따라 생존자를 예측하는 Classifier 생성
사이킷런은 BaseEstimator를 상속받으면 Customized 형태의 Estimator를 개발자가 생성
생성할 MyDummyClssifier 클래스는 학습을 수행하는 fit() 메서드는 수행 X
예측을 수행하는 predict() 메서드는 단순히 Sex 피처가 1이면 0, 그렇지 않으면 1로 예측하는 단순한 Classifier
from sklearn.base import BaseEstimator
class MyDummyClassifier(BaseEstimator):
#fit() 메서드는 아무것도 학습하지 않음.
def fit(self, X, y=None):
pass
#predict() 메서드는 단순히 Sex피처가 1이면 0, 그렇지 않으면 1로 예측함.
def predict(self, X):
pred = np.zeros((X.shape[0],1)) # 0으로 구성된 다차원 array 생성
for i in range(X.shape[0]):
if X['Sex'].iloc[i] == 1 : #위치기반 인덱싱
pred[i] = 0
else:
pred[i] = 1
return pred
이제 생성된 MyDummyClassifier를 이용해 앞 장의 타이타닉 생존자 예측을 수행
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)
#위에서 생성한 DummyClassifier를 이용해 학습/예측/평가 수행
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]
Dummy Classifier의 정확도는: 0.7877
이렇게 단순한 알고리즘으로 예측을 하더라도 정확도 결과는 78.77%로 꽤 높은 수치가 나올 수 있기 때문에 정확도를 평가 지표로 사용할 때는 신중
유명한 MNIST 데이터 세트를 변환해 불균형한 데이터 세트로 만든 뒤 정확도 지표 적용 시 어떤 문제가 발생할 수 있는지 살펴보자.
MNIST 데이터 세트는 0~9까지 숫자 이미지의 픽셀 정보를 가지고 있다.
사이킷런은 load_digits() API를 이용해 MNST 정보 제공
레이블 값이 7인 것만 True, 나머지 값은 모두 False로 변환해 이진 분류 문제로 바꿔보자 (10% True, 90% False)
이렇게 불균형한 데이터 세트에 모든 데이터를 False, 즉 0으로 예측하는 classfier를 이용해 정확도를 측정하면 약 90%에 가까운 예측 정확도를 나타낸다.
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()
#digits 번호가 7번이면 True, 이를 astype(int)로 1로 변환, 아니면 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)
불균형한 데이터로 생성한 y_test의 데이터 분포도를 확인하고 MyFakeClassifier를 이용해 예측과 평가 수행
#불균형한 레이블 데이터 분포도 확인
print('레이블 테스트 데이터 세트 크기:', y_test.shape[0])
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)))
[output]
레이블 테스트 데이터 세트 크기: 450
테스트 세트 레이블 0과 1의 분포도
0 405
1 45
dtype: int64
모든 예측을 0으로 하여도 정확도는:0.900
단순히 predict()의 결과를 np.zeros()로 모두 0 값으로 반환함에도 불구하고 450개의 테스트 데이터 세트에 수행한 예측 정확도는 90%
이처럼 정확도 평가지표는 불균형한 레이블 데이터 세트에서는 성능 수치로 사용돼서는 안된다.
정확도가 가지는 분류 평가 지표로서 이러한 한계점을 극복하기 위해 여러가지 분류 지표와 함께 적용하여 ML 모델 성능을 평가해야한다.