최근 포토로그


[hands-on-machine-learning with Scikit-Learn and TensorFlow] 03 Classification_03 머신러닝


Multiclass Classification
지금까지 binary 분류를 했다면, 이제 multiclass 를 분류해보자.

SGDClassifier로 10개의 클래스중에서 가장 스코어가 높은 인덱스를 반환하여서 하나의 값을 예측할수가있고, (predict함수 사용),

decision_function([some_digit]) 함수를 사용해서 10개 클래스 모두의 스코어반환값을 확인할수가있다. 

sgd_clf = SGDClassifier(random_state=42)
sgd_clf.fit(X_train, y_train)
sgd_digit_scores = sgd_clf.decision_function([some_digit])
print('sgd_digit_scores', sgd_digit_scores)
위의 코드를 실행하면, sgd_digit_scores에는 각 클래스에대한 스코어값이 나오며, 5번째인덱스가 가장높게나와서 [some_digit]값이 5라고 예측하는것이다.

성능을 cross validation 으로 측정해보자.

print('cross_val_score(sgd_clf,X_train, y_train_5, cv=3, scoring="accuracy"):',
cross_val_score(sgd_clf, X_train, y_train, cv=3, scoring="accuracy"))
측정치 값 : [ 0.86212757  0.85189259  0.82892434]

80%대 값이 나온다. 전에 binary classifier할때보다는 많이 낮아졌다. 10%정도 더 올릴수가 있는데, 

Input값을 간단히 scaling 해보고, 다시 validation을 해보자.

from sklearn.preprocessing import StandardScaler

scalar = StandardScaler()
X_train_scaled = scalar.fit_transform(X_train.astype(np.float64))
print('after: ', cross_val_score(sgd_clf, X_train_scaled, y_train, cv=3, scoring='accuracy'))
측정치 값 : [ 0.91016797  0.91019551  0.91223684]

이렇게 90%가 넘게 나오게된다.


에러분석(Error Analysis)

모델의 에러를 분석하는것은 중요하다. 에러를분석해서 모델의 성능을 더욱 향상시키고, 어떤부분에서 에러가났는지를 정확히 파악할수가 있기때문이다.

전에 배웠던 confusion matrix를 multiclass에서도 확인해보자.
y_train_pred = cross_val_predict(sgd_clf, X_train_scaled, y_train, cv=3)
conf_mx = confusion_matrix(y_train, y_train_pred)
print('conf_mx', conf_mx)
결과값은 10행 10열의 많은 수가 나온다.

그래서 보기가 힘들다. matplot의 matshow()함수를 이용해서 시각적으로 확인해보자.

plt.matshow(conf_mx, cmap=plt.cm.gray)
plt.show()
위 코드의 결과값이다. 대각선의 그림중에서 약간더 어둡게 보이는부분이 좀더 예측을 못한다는의미가 된다.

위그림에서 5부분이 다른대각선 값보다 좀더 어두운데, 5의 데이터셋들이 얼마없거나, 5의 예측을 잘못하는 의미가 된다.

어쨋든 평균적으로 정확하게 예측하는것은 잘 하는것같고, 이제 에러율을 한번 확인해보자!

확인하기위해서는 절대값보다는 에러 율(rate)로 확인하는것이 좋아서,

각셀의 값/행들의 합 으로 normalization을 시켜준후 , 대각선의 값들은 다 0으로 맞춘다.

row_sums = conf_mx.sum(axis=1, keepdims=True)
norm_conf_mx = conf_mx / row_sums
np.fill_diagonal(norm_conf_mx, 0)
plt.matshow(norm_conf_mx, cmap=plt.cm.gray)
위의 그림을 8열과 9열이 다른것보다 더밝은것을 볼수가 있다. 이말은 많은 이미지가 8이나 9로 잘못분류된다는 의미가 된다.

반대로 1행 을보면은 다른것보다 더 어두운것을 볼수가있는데, 숫자0을 다른것보다 더 잘 구분해낸다는 의미가된다.

따라서 에러율이 더클수록 밝고, 낮을수록 더 어둡다고 볼수있다.

이렇게, confusion matrix를 이용해서 에러rate를 확인하고 모델을 좀더 분석할수가있다. 예를들어서 8과 9의 에러율이 높으면 해당하는 데이터셋트를 더 준비하거나, 모델을 알맞게 수정하거나, 전처리작업을해서 모델의 성능을 높일방법을 모색할수있다.


해당하는 에러들을 확인해보면 인간은 정확하게 구벼해낼수있는정도의 이미지인데 컴퓨터는 정확하게 구분해 내지 못하고있다.

왜일까 ? 

바로 SGDClassifier에 문제가있다. SGDClassifier는 선형모델이고, 각 픽셀에 웨이트값들을 할당한다.

새로운 값이 들어오면 각 픽셀의 웨으트값을 더해서 score결과값을 반환한다. 그래서 8과 9 아니면 3과 5는 몇픽셀밖에 차이가 안나서 SGDClassifier알고리즘으로 구분하기가 쉽지 않았던것이다.

Multilabel Classification

지금까지, 하나의 이미지에 하나의 라벨만 할당했다면, 하나의 이미지에 여러개의 라벨을 할당해보자

예르르들어 사진을 찍어서 영희 기철 이가 나오고 철수가 안나온 상황일때, 라벨은 [1, 0, 1] 로 표시되게 해보자.

from sklearn.neighbors import KNeighborsClassifier

y_train_large = (y_train > 7)
y_train_odd = (y_train % 2 == 1)
y_multilabel = np.c_[y_train_large, y_train_odd]

knn_clf = KNeighborsClassifier()
knn_clf.fit(X_train, y_multilabel)
print(knn_clf.predict([some_digit]))
출력값 : [[False  True]] (some_digit의 값은 5이다)

코드상으로 간단하게 np.c_[] 를 이용해서 multilabel을 만들어낼수가있고, KNeighborsClassifier 알고리즘을 써서 구분자를 생성하고(멀티라벨을 이용할수있는 모델이 많지않다) 훈련시킨다.

Multioutput Classification

Multioutput-multiclass classification또는 간단히 Multioutput classification이라고한다. 

말그대로 각 라벨에 가능한 값이 여러개인 경우이다. (multi class)

예를들어 노이즈가 심한 이미지를 받아서 그 노이즈를 제거해서 output으로 노이즈가 제거된 이미지가 나오는 시스템을 만든다고 가정하자.

그럼, 분류기의 output값은 하나의 픽셀당 하나의 라벨이 되니깐, multilabel이 된다.
그리고 하나의 라벨은 여러개의 input값(value값)도 가진다(픽셀 데이터).










덧글

댓글 입력 영역


통계 위젯 (화이트)

01
2
8133

구글애널리틱스