scikit-learn (3) - 선형분류 (결과평가) 
1. 예측하기
꽃받침 너비가 4.7이고 꽃받침 길이가 3.1인 새로운 꽃이 있다고 가정하고, 이 꽃의 범주를 예측해보자. 예측 메소드는 인스턴스 배열을 입력받고, 예측 범주의 리스트를 반환한다. 다음과 같다
1 2  | >>> print clf.predict(scaler.transform([4.7, 3.1])) [0]  | cs | 
분류기가 정확했다면, 이 꽃의 범주는 세토사이다. 앞선 포스팅에서 선형 모델은 두 개의 분류를 나누는 것을 기억했다. 그러므로 예측절차는 세 개 이진 분류기의 결과를 합하고 좀 더 확실한 범주를 선택한다. 이 경우 인스턴스에서 멀리 떨어진 경계선을 선택한다. 분류기의 decision_function 메소드를 사용해 확인할 수 있다.
1 2 3  | >>> print clf.decision_function(scaler.transform([4.7, 3.1])) [[ 24.25497645  -9.30416563 -42.71765579]  | cs | 
2. 결과평가
1) 성능측정
분류기의 성능은 유효성의 측정이다. 가장 단순한 성능 측정은 정확도다. 분류기와 평가데이터를 고려해, 분류기가 정확하게 분류한 인스턴스의 비율을 측정한다. 먼저 훈련데이터에서 정확도를 측정해보자. 
1 2 3 4  | >>> from sklearn import metrics >>> y_train_pred = clf.predict(X_train) >>> print metrics.accuracy_score(y_train, y_train_pred) 0.8125  | cs | 
이 수치는 분류기가 데이터 인스턴스의 81.25%만 정확하게 분류했음을 말해준다.
2) 과적합화
훈련데이터의 정확도만을 측정하는 것은 좋지 않다. 훈련데이터를 사용해 모델을 만들었고 모델은 이 데이터에 잘 적응되었지만 미래에 형편없이 예측할 수 있다. 이 현상을 과적합화overfitting 이라고 한다. 
훈련데이터를 기반으로 측정한다면 과적합화를 절대 발견할 수 없다. 그래서 훈련데이터를 기반으로 절대 측정하지 않는다. 원본 데이터셋에서 일부를 보관한 이유가 여기에 있다. 이전에 보지 못한 데이터에 대한 성능을 평가하기 위해서이다. 이번에는 평가데이터로 정확도를 다시 측정해보자.
1 2 3  | >>> y_pred = clf.predict(X_test) >>> print metrics.accuracy_score(y_test, y_pred) 0.605263157895  | cs | 
테스트데이터에 대해 60%의 정확도를 얻었다. 일반적으로 테스트데이터의 정확도는 훈련데이터보다 낮은 정확도를 보인다. 목표는 훈련데이터로 훈련할 때 과적합화를 피하는 모델을 생성하는 일이다. 
3. 평가함수
1) 평가함수
scikit-learn 에는 몇 가지 평가함수가 있다. 이러한 함수 문제는 이진 분류 문제와 두 범주 (긍정과 부정)로 가정한다. 앞의 예를 들자면, 긍정 범주는 아이리스 세토사인 반면, 두 품종은 합해 하나의 부정 범주가 된다. 
정밀도 precision  | 
 정확한 긍정으로 예측된 인스턴스의 비율 계산  | 
재현율 recall  | 
 정확학게 평가된 긍정 인스턴스의 비율  | 
F1-점수  | 
 정밀도와 재현율의 조화평균 두 수를 결합해 한 자리수로 만든다  | 
참과 거짓, 긍정과 부정의 관점으로 이러한 측정을 다음과 같이 정의할 수 있다.
   | 
예측 : 긍정   | 
예측 : 부정   | 
 목적 경우 : 긍정  | 
참 긍정 True Positive (TP)  | 
거짓 부정 False Negative (FN)  | 
 목적 경우 : 부정  | 
거짓 긍정 False Positive (FP)  | 
참 부정 True Negative (TN)  | 
2) 평가함수의 수식
표본의 크기 m 과 다음 식을 만든다.
m = TP + FP + FN + TN
 정확도  | 
 (TP + TN ) / m  | 
정밀도  | 
 TP / (TP + FP)  | 
재현율  | 
 TP / (TP + FN)  | 
 F-1 점수  | 
 2 * 정밀도 * 재현율 / (정밀도 + 재현율)  | 
1 2 3 4 5 6 7 8  | >>> print metrics.classification_report(y_test, y_pred, target_names=iris.target_names)             precision    recall  f1-score   support      setosa       1.00      1.00      1.00         8  versicolor       0.38      0.27      0.32        11   virginica       0.64      0.74      0.68        19 avg / total       0.64      0.66      0.64        38  | cs | 
분류기는 세토사 범주에 대해 1.0인 정밀도와 재현율을 얻었다. 
정밀도는 세토사로 분류한 인스턴스의 100%가 실제 세토사 인스턴스였고, 재현율은 세토사 인스턴스의 100%가 세토사로서 분류되었음을 뜻한다.
한편 버시칼라 범주에서는 결과가 좋지 않았다. 43%의 정밀도는 단지 버시칼라로 분류된 인스턴스의 43%가 실제 버시칼라 인스턴스로 분류되었다. 또한 0.27%의 재현율은 버시칼라의 27% 인스턴스가 정확하게 분류했다.
3) 혼돈 매트릭스 confusion matrix
다른 유용한 메트릭은 혼돈 매트릭스다. ( i, j ) 칸은 범주 j 로 예측한 반면, 실제 범주가 i 인 인스턴스의 개수를 나타낸다. 좋은 분류기는 정확하게 분류된 혼돈 매트릭스의 대각선에 인스턴스 개수가 많다.
1 2 3 4  | >>> print metrics.confusion_matrix(y_test, y_pred) [[ 8  0  0]  [ 0  0 11]  [ 0  0 19]]  | cs | 
분류기는 범주가 0인 꽃을 분류할 때 평가에서 절대 틀리지 않았다. 그러나 범주가 1과 2인 꽃을 직면해서 이 꽃들을 혼동했다. 혼돈 매트릭스는 분류기가 행한 실수의 종류에 대해 유용한 정보를 준다. 
4) 교차 검증 cross-validation
데이터의 분할은 훈련하는 인스턴스의 개수와 특정 속성의 분할에 의존적이므로 최종 결과에 영향을 미친다. 교차 검증은 이러한 특정 경우를 피할 수 있게 하며, 결과의 변화를 줄이고 모델에 대해 현실적인 점수를 만든다. k-중첩 교차검증의 일반적인 단계는 다음과 같다. 
- k 개의 부분집합으로 나눈다.
 - k-1 개 부분집합으로 훈련하고 나머지 부분 집합으로 테스트한 k 개의 모델을 만든다
 - k 모델에 대해 성능을 측정하고 평균을 구한다.
 
먼저 선형 모델과 표준화를 파이프라인으로 합성한 에스터메이터를 만든다. 파이프라인을 사용해 각 반복에서 데이터를 표준화하고, 변환된 데이터로 훈련 및 테스트를 한다. Pipeline 클래스는 변환을 연속적으로 적용해 좀 더 복잡한 모델을 단순하게 생성하는데 사용된다. 
k = 5 중첩으로, 매번 데이터의 80%로 훈련하고 남은 20%를 사용하게 한다. 기본적으로 교차검증은 성능 측정으로서 정확도를 사용하지만, 매개변수에 대해 다른 점수 함수를 지정해 측정을 선택할 수 있다. 
1 2 3 4 5 6 7 8 9 10 11  | >>> from sklearn.cross_validation import cross_val_score, KFold >>> from sklearn.preprocessing import StandardScaler >>> from sklearn.pipeline import Pipeline >>> clf = Pipeline({ >>>         ('scaler', StandardScaler()), >>>         ('linear_model', SGDClassifier())         >>>     } >>> ) >>> cv = KFold(X.shape[0], 5, shuffle=True, random_state=33) >>> scores = cross_val_score(clf, X, y, cv=cv) >>> print scores  | cs | 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27  | --------------------------------------------------------------------------- TypeError                                 Traceback (most recent call last) <ipython-input-14-4c521b642cbf> in <module>()       8 )       9 cv = KFold(X.shape[0], 5, shuffle=True, random_state=33) ---> 10 scores = cross_val_score(clf, X, y, cv=cv)      11 print scores /root/anaconda/envs/tensorflow/lib/python2.7/site-packages/sklearn/cross_validation.pyc in cross_val_score(estimator, X, y, scoring, cv, n_jobs, verbose, fit_params, pre_dispatch)    1509     1510     cv = check_cv(cv, X, y, classifier=is_classifier(estimator)) -> 1511     scorer = check_scoring(estimator, scoring=scoring)    1512     # We clone the estimator to make sure that all the folds are    1513     # independent, and that it is pickle-able. /root/anaconda/envs/tensorflow/lib/python2.7/site-packages/sklearn/metrics/scorer.pyc in check_scoring(estimator, scoring, allow_none)     271         raise TypeError(     272             "If no scoring is specified, the estimator passed should " --> 273             "have a 'score' method. The estimator %r does not." % estimator)     274      275  TypeError: If no scoring is specified, the estimator passed should have a 'score' method. The estimator Pipeline(steps=[('linear_model', SGDClassifier(alpha=0.0001, average=False, class_weight=None, epsilon=0.1,        eta0=0.0, fit_intercept=True, l1_ratio=0.15,        learning_rate='optimal', loss='hinge', n_iter=5, n_jobs=1,        penalty='l2', power_t=0.5, random_state=None, shuffle=True,        verbose=0, warm_start=False)), ('scaler', StandardScaler(copy=True, with_mean=True, with_std=True))]) does not.  | cs | 
k 개 점수로 배열을 구했다. 최종 수치를 얻기 위해 표준 편차와 평균을 계산한다.
1 2 3 4  | >>> from scipy.stats import sem >>> def mean_score(scores): >>>     return ("Mean score: {0:.3f} (+/-{1:.3f})").format(np.mean(scores), sem(scores)) >>> print mean_score(scores)  | cs | 
'Season 1 아카이브 > 프로그래밍' 카테고리의 다른 글
| 서포터 벡터 머신과 이미지 인식 (2) - 이미지 픽셀을 사용한 학습 (0) | 2016.11.06 | 
|---|---|
| 서포터 벡터 머신과 이미지 인식 (1) - 정의 및 장점 (0) | 2016.11.06 | 
| scikit-learn (2) - 선형분류 (훈련데이터 만들기) (0) | 2016.11.06 | 
| matplotlib - <matplotlib.text.Text at 0x7fc3298533d0> (0) | 2016.11.03 | 
| Jupyter Notebook 셀 크기 조절하기 How to increase/decrease the cell width of the jupyter notebook in browser (0) | 2016.11.03 |