외국에서도 평이 상당히 좋으니 머신러닝 공부하는사람들은 한번쯤 정독해보는것이 좋다.
먼저 Classification하면 가장 유명한 mnist데이터를 가지고 테스트를 진행하고있다.
from sklearn.datasets import fetch_mldata
mnist = fetch_mldata("MNIST original", data_home='./mnist_dataset/')
다음과같이 Mnist orginal 데이터를 다운받으면된다.
각각의 이미지는 28 * 28인데, 압축해서 784개의 features들로 구성이 되어있다. 흑백 이미지 라서 channel=1이다.(색깔이라면 3이 된다.)
나는 처음에 mnist의 이미지를 확인하기위해서 여러가지 고생을 했는데, 다음과같이 간단히 확인이 가능하다.
X, y = mnist['data'], mnist['target']
some_digit = X[36000]
some_digit_image = some_digit.reshape(28, 28)
plt.imshow(some_digit_image, cmap=matplotlib.cm.binary, interpolation="nearest")
plt.axis("off")
plt.show()
해당 소스를 실행해서 보면 알겠지만, 그림의 모양이 5처럼 생겼고, 실제로 라벨값을 확인해보면 값도 5로 나온다.
print(y[36000]) # 라벨값 확인.
총 이미지데이터는 7만개 가량 되며, 여기서 트레이닝셋트와 테스트셋트를 나누고, 이미지를 섞어보자(shuffle).
# 셔플해보자.
import numpy as np
X_train, X_test, y_train, y_test = X[:60000], X[60000:], y[:60000], y[60000:]
shuffle_index = np.random.permutation(60000)
X_train, y_train = X_train[shuffle_index], y_train[shuffle_index]
섞고,다시 재할당 과정.
그다음에 Binary Classifier과정으로 진행해보자.
Binary Classifier같은경우는 해당숫자가 5인지, 아닌지 True,False인경우만 구분하는 detector이다.
y_train_5 = (y_train == 5) # True for all 5s, False for all other digits.
y_test_5 = (y_test == 5)
위와같이 코드를 실행시키면, y_train 리스트에있던, 0~9까지의 숫자들이 5인경우 True, 5가 아닌경우 False로 바뀌게되어서
기존
[0 ,1 ,2 ,3 ,4, 5, 6, 7, 8, 9]
실행후
[False, False, False, False, False, True, False, False ...] 이런식으로 바뀌게된다. (5빼고 다 False)
그다음에 데이터를 훈련을 시켜야하는데,
훈련을 시키기위해서 여러가지 방법이있다.
Gradient descent, Stochastic등이있지만, 이책에서는 Stochastic방법을 이용해서 문제를 해결하고있다.
# 훈련시킴
from sklearn.linear_model import SGDClassifier
sgd_clf = SGDClassifier(random_state=42)
sgd_clf.fit(X_train, y_train_5)
위와같이 SGDClassifier객체를 생성하고, X와 Y데이터를 입력하고 훈련을 시킨다음에
print('sgd_clf.predict([some_digit])', sgd_clf.predict([some_digit]))
다음과같이 결과를 확인해볼수있다. some_digit은 확인할 X값이되고, X의 값이(이미지) 5가맞다면, True, 아니면 False로 나오게된다.
하나의 데이터를 확인하는것은 위와같이하고, 실제로 Performance를 측정해보자.
실제 업무에서는 Performance측정하는게 상당히 복잡하고, 귀찮다고하니깐 이번시간에 시간을 들여서 좀 자세하게 알아볼려고하한다.
먼저 Cross-Validation 으로 테스트하는 방법이있다.
간략히 설명하자면, 데이터들을 N개의 부분으로 나눠서 훈련시키고, 나머지 데이터들로 추론하는 방법을 진행하는것입니다.
위방법도 간단하게 함수 하나로 구현이 가능하다.
from sklearn.model_selection import cross_val_score
# cross_val_score 확인.
print('cross_val_score(sgd_clf,X_train, y_train_5, cv=3, scoring="accuracy"):',
cross_val_score(sgd_clf, X_train, y_train_5, cv=3, scoring="accuracy"))# cross_val_score(sgd_clf,X_train, y_train_5, cv=3, scoring="accuracy"): [ 0.96295 0.9594 0.95285]
위결과의 출력값이 정확도이므로 약 95%의 정확도를 보인다고보면된다. (cv=3이라서 3전체데이터를 3부분으로 나누고 각나눈데이터로 모델을 학습시킨 결과값이 95~96% 라는것을 알수있다)
하지만..웃긴게 다음과같이 전체값이 다 5가 아니라고 예측을 한다면..
from sklearn.base import BaseEstimator
class Never5Classifier(BaseEstimator):
def fit(self, X, y=None):
pass
def predict(self, X):
return np.zeros((len(X), 1), dtype=bool)
never_5 = Never5Classifier()
print('cross_val_score(sgd_clf,X_train, y_train_5, cv=3, scoring="accuracy"):',
cross_val_score(never_5, X_train, y_train_5, cv=3, scoring="accuracy"))# cross_val_score(sgd_clf,X_train, y_train_5, cv=3, scoring="accuracy"): [ 0.91025 0.91005 0.90865]
결과값이 그래도 90~91프로를 넘어가게된다. (np.zeros(shape,dtype=bool)로하게되면, X값의 모든것을 다 False로바꿔버린다)
이것만봤을때. 정확도를 측정하는것의 중요성을 다시 한번 일깨울수가있다. 특히 엉망인데이터들을 다룰때 중요하다.(어떤값이 특별히 자주나타난다거나 할때.)
덧글