scikit Learn을 사용하여 다중 클래스 케이스에 대한 정밀도, 재현율, 정확도 및 f1 점수를 계산하는 방법은 무엇입니까?


109

나는 데이터가 다음과 같은 감정 분석 문제에서 일하고 있습니다.

label instances
    5    1190
    4     838
    3     239
    1     204
    2     127

그래서 내 데이터는 1190 instances5. scikit의 SVC를 사용하는 Im 분류의 경우 . 문제는 다중 클래스 케이스에 대한 정밀도, 재현율, 정확도 및 f1 점수를 정확하게 계산하기 위해 데이터의 균형을 올바르게 조정하는 방법을 모른다는 것입니다. 그래서 다음 접근 방식을 시도했습니다.

먼저:

    wclf = SVC(kernel='linear', C= 1, class_weight={1: 10})
    wclf.fit(X, y)
    weighted_prediction = wclf.predict(X_test)

print 'Accuracy:', accuracy_score(y_test, weighted_prediction)
print 'F1 score:', f1_score(y_test, weighted_prediction,average='weighted')
print 'Recall:', recall_score(y_test, weighted_prediction,
                              average='weighted')
print 'Precision:', precision_score(y_test, weighted_prediction,
                                    average='weighted')
print '\n clasification report:\n', classification_report(y_test, weighted_prediction)
print '\n confussion matrix:\n',confusion_matrix(y_test, weighted_prediction)

둘째:

auto_wclf = SVC(kernel='linear', C= 1, class_weight='auto')
auto_wclf.fit(X, y)
auto_weighted_prediction = auto_wclf.predict(X_test)

print 'Accuracy:', accuracy_score(y_test, auto_weighted_prediction)

print 'F1 score:', f1_score(y_test, auto_weighted_prediction,
                            average='weighted')

print 'Recall:', recall_score(y_test, auto_weighted_prediction,
                              average='weighted')

print 'Precision:', precision_score(y_test, auto_weighted_prediction,
                                    average='weighted')

print '\n clasification report:\n', classification_report(y_test,auto_weighted_prediction)

print '\n confussion matrix:\n',confusion_matrix(y_test, auto_weighted_prediction)

제삼:

clf = SVC(kernel='linear', C= 1)
clf.fit(X, y)
prediction = clf.predict(X_test)


from sklearn.metrics import precision_score, \
    recall_score, confusion_matrix, classification_report, \
    accuracy_score, f1_score

print 'Accuracy:', accuracy_score(y_test, prediction)
print 'F1 score:', f1_score(y_test, prediction)
print 'Recall:', recall_score(y_test, prediction)
print 'Precision:', precision_score(y_test, prediction)
print '\n clasification report:\n', classification_report(y_test,prediction)
print '\n confussion matrix:\n',confusion_matrix(y_test, prediction)


F1 score:/usr/local/lib/python2.7/site-packages/sklearn/metrics/classification.py:676: DeprecationWarning: The default `weighted` averaging is deprecated, and from version 0.18, use of precision, recall or F-score with multiclass or multilabel data or pos_label=None will result in an exception. Please set an explicit value for `average`, one of (None, 'micro', 'macro', 'weighted', 'samples'). In cross validation use, for instance, scoring="f1_weighted" instead of scoring="f1".
  sample_weight=sample_weight)
/usr/local/lib/python2.7/site-packages/sklearn/metrics/classification.py:1172: DeprecationWarning: The default `weighted` averaging is deprecated, and from version 0.18, use of precision, recall or F-score with multiclass or multilabel data or pos_label=None will result in an exception. Please set an explicit value for `average`, one of (None, 'micro', 'macro', 'weighted', 'samples'). In cross validation use, for instance, scoring="f1_weighted" instead of scoring="f1".
  sample_weight=sample_weight)
/usr/local/lib/python2.7/site-packages/sklearn/metrics/classification.py:1082: DeprecationWarning: The default `weighted` averaging is deprecated, and from version 0.18, use of precision, recall or F-score with multiclass or multilabel data or pos_label=None will result in an exception. Please set an explicit value for `average`, one of (None, 'micro', 'macro', 'weighted', 'samples'). In cross validation use, for instance, scoring="f1_weighted" instead of scoring="f1".
  sample_weight=sample_weight)
 0.930416613529

그러나 다음과 같은 경고가 표시됩니다.

/usr/local/lib/python2.7/site-packages/sklearn/metrics/classification.py:1172:
DeprecationWarning: The default `weighted` averaging is deprecated,
and from version 0.18, use of precision, recall or F-score with 
multiclass or multilabel data or pos_label=None will result in an 
exception. Please set an explicit value for `average`, one of (None, 
'micro', 'macro', 'weighted', 'samples'). In cross validation use, for 
instance, scoring="f1_weighted" instead of scoring="f1"

분류기의 메트릭을 올바른 방식으로 계산하기 위해 불균형 데이터를 어떻게 올바르게 처리 할 수 ​​있습니까?


그렇다면 average세 번째 경우에 매개 변수를 추가하지 않는 이유 는 무엇입니까?
yangjie

1
@yangjie 몰라요. 문서를 확인했지만 불균형 데이터에 대한 메트릭을 올바르게 사용하는 방법을 이해하지 못합니다. 좀 더 넓은 설명과 예를 제공해 주시겠습니까?. 감사!
new_with_python

답변:


164

어떤 가중치가 무엇에 사용되는지에 대해 많은 혼란이 있다고 생각합니다. 나는 당신을 괴롭히는 것이 무엇인지 정확히 알지 못하므로 다른 주제를 다루고, 저를 참아 드리겠습니다.).

클래스 가중치

class_weight매개 변수 의 가중치 는 분류기훈련하는 데 사용됩니다 . 그들은 당신이 사용하는 메트릭의 계산에 사용되지 않는 : 다른 클래스 무게, 숫자는 분류가 다르기 때문에 단순히 다른 것입니다.

기본적으로 모든 scikit-learn 분류기에서 클래스 가중치는 모델에 클래스가 얼마나 중요한지 알려주는 데 사용됩니다. 즉, 훈련 중에 분류자는 가중치가 높은 클래스를 적절하게 분류하기 위해 추가 노력을 기울일 것입니다.
그 방법은 알고리즘에 따라 다릅니다. SVC에서 작동하는 방법에 대한 세부 정보를 원하고 문서가 이해가되지 않는 경우 언제든지 언급하십시오.

메트릭

분류 기가 있으면 그것이 얼마나 잘 수행되고 있는지 알고 싶습니다. 다음은 당신이 언급 한 측정 항목을 사용할 수 있습니다 accuracy, recall_score, f1_score...

일반적으로 클래스 분포가 불균형 인 경우 가장 빈번한 클래스를 예측하는 모델에 높은 점수를 부여하므로 정확도는 잘못된 선택으로 간주됩니다.

이 모든 측정 항목에 대해 자세히 설명하지는 않겠지 만,를 제외 accuracy하고는 자연스럽게 클래스 수준에서 적용됩니다 print. 분류 보고서 에서 볼 수 있듯이 각 클래스에 대해 정의됩니다. 그들은 어떤 클래스가 긍정적 인 클래스인지 정의해야하는 true positives또는 같은 개념에 의존합니다 .false negative

             precision    recall  f1-score   support

          0       0.65      1.00      0.79        17
          1       0.57      0.75      0.65        16
          2       0.33      0.06      0.10        17
avg / total       0.52      0.60      0.51        50

경고

F1 score:/usr/local/lib/python2.7/site-packages/sklearn/metrics/classification.py:676: DeprecationWarning: The 
default `weighted` averaging is deprecated, and from version 0.18, 
use of precision, recall or F-score with multiclass or multilabel data  
or pos_label=None will result in an exception. Please set an explicit 
value for `average`, one of (None, 'micro', 'macro', 'weighted', 
'samples'). In cross validation use, for instance, 
scoring="f1_weighted" instead of scoring="f1".

계산 방법을 정의하지 않고 f1 점수, 재현율 및 정밀도를 사용하기 때문에이 경고가 표시됩니다! 질문은 다시 표현할 수 있습니다. 위의 분류 보고서 에서 f1 점수에 대해 하나의 글로벌 숫자를 어떻게 출력 합니까? 다음과 같이 할 수 있습니다.

  1. 각 클래스에 대한 f1 점수의 평균을 취하십시오. 이것이 avg / total위 의 결과입니다. 매크로 평균 이라고도 합니다.
  2. 참 양성 / 거짓 음성 등의 글로벌 카운트를 사용하여 f1 점수를 계산합니다 (각 클래스에 대한 참 양성 / 거짓 음성의 수를 합산합니다). 일명 마이크로 평균.
  3. f1 점수의 가중 평균을 계산합니다. 'weighted'scikit-learn에서 사용 하면 클래스의 지원에 따라 f1- 점수가 가중됩니다. 클래스에 요소가 많을수록 계산에서이 클래스의 f1- 점수가 더 중요합니다.

다음은 scikit-learn의 3 가지 옵션입니다. 경고는 하나를 선택해야한다는 경고입니다 . 따라서 averagescore 메서드에 대한 인수 를 지정해야합니다 .

선택하는 것은 분류기의 성능을 측정하는 방법에 달려 있습니다. 예를 들어 매크로 평균화는 클래스 불균형을 고려하지 않으며 클래스 1의 f1- 점수는 클래스의 f1- 점수만큼 중요합니다 5. 가중 평균을 사용하면 클래스 5의 중요성이 더 높아집니다.

이러한 메트릭의 전체 인수 사양은 현재 scikit-learn에서 매우 명확하지 않으며 문서에 따르면 버전 0.18에서 더 나아질 것입니다. 그들은 일부 명확하지 않은 표준 동작을 제거하고 개발자가이를 알 수 있도록 경고를 발행합니다.

점수 계산

마지막으로 언급하고 싶은 것은 (알고 있다면 건너 뛰어도됩니다) 점수는 분류자가 본 적이없는 데이터에 대해 계산 된 경우에만 의미가 있다는 것 입니다. 분류자를 맞추는 데 사용 된 데이터에서 얻은 점수는 완전히 관련이 없기 때문에 이것은 매우 중요합니다.

다음 StratifiedShuffleSplit은 라벨 분포를 유지하는 데이터의 무작위 분할 (셔플 링 후)을 제공하는를 사용하여 수행하는 방법 입니다.

from sklearn.datasets import make_classification
from sklearn.cross_validation import StratifiedShuffleSplit
from sklearn.metrics import accuracy_score, f1_score, precision_score, recall_score, classification_report, confusion_matrix

# We use a utility to generate artificial classification data.
X, y = make_classification(n_samples=100, n_informative=10, n_classes=3)
sss = StratifiedShuffleSplit(y, n_iter=1, test_size=0.5, random_state=0)
for train_idx, test_idx in sss:
    X_train, X_test, y_train, y_test = X[train_idx], X[test_idx], y[train_idx], y[test_idx]
    svc.fit(X_train, y_train)
    y_pred = svc.predict(X_test)
    print(f1_score(y_test, y_pred, average="macro"))
    print(precision_score(y_test, y_pred, average="macro"))
    print(recall_score(y_test, y_pred, average="macro"))    

도움이 되었기를 바랍니다.


다중 클래스의 경우 클래스 가중치를 어떻게 지정합니까? 예를 들어, class_weight={1:10}3 개의 클래스가있는 데이터 의 의미는 무엇 입니까?
Aziz Javed

어쨌든 레이블 현명한 정확도 점수를 얻을 수 있습니까?
Ankur Sinha

마이크로가 어떻게 작동하는지 더 명확하게 설명해 주시겠습니까? 또한 바이너리에 대해 언급하지 않습니다
겸손한

나를 위해 계층화 된 셔플이 문제를 일으키고 있었기 때문에 표시 되는대로 기차 테스트 분할로 다시 전환했습니다 ValueError: The least populated class in y has only 1 member, which is too few. The minimum number of labels for any class cannot be less than 2.. 기차 테스트 분할로 잘 작동하지만 SSS 에서이 오류가 발생하는 이유를 누구든지 도와 줄 수 있습니까? 감사.
Akash Kandpal

안녕하세요, 코드를 테스트했지만이 오류 메시지가 있습니다. C : \ Users \\ Anaconda3 \ lib \ site-packages \ sklearn \ metrics \ classification.py : 976 : DeprecationWarning : 버전 0.18부터는 사용할 때 바이너리 입력이 특별히 처리되지 않습니다 평균 정밀도 / 재현율 / F- 점수. 긍정적 인 수업 성적 만보고하려면 average = 'binary'를 사용하십시오. '긍정적 인 수준의 성능을 제공합니다.', DeprecationWarning)
체디 Bechikh

73

여기에 매우 자세한 답변이 많이 있지만 올바른 질문에 답하고 있다고 생각하지 않습니다. 질문을 이해했듯이 두 가지 우려 사항이 있습니다.

  1. 다중 클래스 문제를 어떻게 채점합니까?
  2. 불균형 데이터를 어떻게 처리합니까?

1.

단일 클래스 문제와 마찬가지로 다중 클래스 문제와 함께 scikit-learn에서 대부분의 채점 함수를 사용할 수 있습니다. 전의.:

from sklearn.metrics import precision_recall_fscore_support as score

predicted = [1,2,3,4,5,1,2,1,1,4,5] 
y_test = [1,2,3,4,5,1,2,1,1,4,1]

precision, recall, fscore, support = score(y_test, predicted)

print('precision: {}'.format(precision))
print('recall: {}'.format(recall))
print('fscore: {}'.format(fscore))
print('support: {}'.format(support))

이렇게하면 각 클래스에 대해 유형적이고 해석 가능한 숫자로 끝납니다.

| Label | Precision | Recall | FScore | Support |
|-------|-----------|--------|--------|---------|
| 1     | 94%       | 83%    | 0.88   | 204     |
| 2     | 71%       | 50%    | 0.54   | 127     |
| ...   | ...       | ...    | ...    | ...     |
| 4     | 80%       | 98%    | 0.89   | 838     |
| 5     | 93%       | 81%    | 0.91   | 1190    |

그때...

2.

... 불균형 데이터가 문제인지 알 수 있습니다. 덜 표현 된 클래스 (클래스 1 및 2)에 대한 점수가 더 많은 훈련 샘플이있는 클래스 (클래스 4 및 5)보다 낮다면 불균형 데이터가 실제로 문제라는 것을 알고 있으므로 다음과 같이 조치를 취할 수 있습니다. 이 스레드의 다른 답변 중 일부에 설명되어 있습니다. 그러나 예측하려는 데이터에 동일한 클래스 분포가 있으면 불균형 훈련 데이터가 데이터를 잘 대표하므로 불균형이 좋은 것입니다.


1
좋은 게시물과 잘 말했습니다. 감사합니다
Alvis 2017 년

1
다음 질문이 있습니다. 어떻게 라벨을 인쇄 했 precision_recall_fscore_support습니까? 라벨은 순서대로 인쇄됩니까?
BigD

@BigD 예, 맨 아래에있는 scikit-learn.org/stable/modules/generated/… 를 참조하십시오 . average=None레이블을 설정 하고 정의하면 지정된 각 레이블에 대해 찾고있는 메트릭을 얻을 수 있습니다.
wonderkid2

어쨌든 레이블 현명한 정확도 점수를 얻을 수 있습니까?
Ankur Sinha

@trollster 무슨 말인지 잘 모르겠어요? 라벨 별 정확도 점수에 대한 답변이 아닙니까?
wonderkid2

16

제기 된 질문

'불균형 데이터가있는 다중 클래스 분류에 사용되어야하는 메트릭'질문에 대한 응답 : Macro-F1-measure. Macro Precision 및 Macro Recall도 사용할 수 있지만 이진 분류와 같이 쉽게 해석 할 수 없으며 이미 F- 측정에 통합되어 있으며 초과 메트릭은 방법 비교, 매개 변수 조정 등을 복잡하게합니다.

마이크로 평균화는 클래스 불균형에 민감합니다. 예를 들어 방법이 가장 일반적인 레이블에 적합하고 다른 레이블을 완전히 망칠 경우 마이크로 평균 메트릭이 좋은 결과를 보여줍니다.

가중치 평균은 레이블 수를 기준으로 가중치를 부여하기 때문에 불균형 데이터에 적합하지 않습니다. 더욱이, 너무 해석하기 어렵고 인기가 없습니다. 예를 들어, 다음의 매우 상세한 설문 조사 에서 이러한 평균에 대한 언급이 없습니다 .

Sokolova, Marina 및 Guy Lapalme. "분류 작업에 대한 성능 측정의 체계적인 분석." 정보 처리 및 관리 45.4 (2009) : 427-437.

애플리케이션 별 질문

그러나 귀하의 작업으로 돌아가서 두 가지 주제를 조사하겠습니다.

  1. 특정 작업에 일반적으로 사용되는 메트릭-(a) 방법을 다른 사람과 비교하고 잘못한 경우 이해하고 (b) 직접 탐색하지 않고 다른 사람의 결과를 재사용 할 수 있습니다.
  2. 방법의 다른 오류로 인한 비용-예를 들어 애플리케이션의 사용 사례는 별 4 개 및 5 개 리뷰에만 의존 할 수 있습니다.이 경우 좋은 측정 항목은이 2 개의 라벨 만 계산해야합니다.

일반적으로 사용되는 측정 항목입니다. 문헌을 살펴본 후 추론 할 수 있듯이 두 가지 주요 평가 지표가 있습니다.

  1. 사용되는 정확도 , 예 :

Yu, April 및 Daryl Chang. "Yelp Business를 이용한 다중 클래스 감성 예측."

( 링크 )-저자는 거의 동일한 등급 분포로 작업합니다 (그림 5 참조).

Pang, Bo, Lillian Lee. "별보기 : 등급 척도와 관련하여 감정 분류를 위해 계급 관계를 악용합니다." 제 43 차 전산 언어학 협회 연례회의. 전산 언어학 협회, 2005.

( 링크 )

  1. MSE (또는 덜 자주, Mean Absolute Error- MAE )-예를 들어 다음을 참조하십시오.

이문태, R. 그레이프. "식당 리뷰를 통한 다중 클래스 감정 분석." CS N 224 (2010)의 최종 프로젝트.

( 링크 )-정확도와 MSE를 모두 탐색하며 후자가 더 나은 것으로 간주합니다.

Pappas, Nikolaos, Rue Marconi 및 Andrei Popescu-Belis. "별 설명하기 : 측면 기반 감정 분석을위한 가중 다중 인스턴스 학습." 자연어 처리의 경험적 방법에 관한 2014 년 컨퍼런스 회보. 아니오. EPFL-CONF-200899. 2014.

( 링크 )-평가 및 기준 접근 방식에 scikit-learn을 활용하고 코드를 사용할 수 있음을 명시합니다. 그러나 나는 그것을 찾을 수 없기 때문에 필요하다면 저자에게 편지를 쓰십시오. 그 작품은 꽤 새롭고 파이썬으로 작성된 것 같습니다.

다른 오류의 비용 . 예를 들어 별점 1 개에서 별 5 개로 평가하는 것과 같은 중대한 실수를 피하는 데 더 관심이 있다면 MSE를보십시오. 차이가 중요하지만 그다지 중요하지 않은 경우 제곱 차이가 아니므로 MAE를 사용해보십시오. 그렇지 않으면 정확성을 유지하십시오.

메트릭이 아닌 접근 방식

일반적으로 SVC 또는 OVA SVM과 같은 다중 클래스 분류자를 능가하므로 회귀 접근법 (예 : SVR)을 사용해보십시오 .


13

우선 데이터의 불균형 여부를 확인하기 위해 계산 분석을 사용하는 것이 조금 더 어렵습니다. 예를 들어, 긍정적 인 관찰 1000 명 중 1 명은 단지 소음, 오류 또는 과학의 돌파구입니까? 당신은 몰라요.
따라서 가능한 모든 지식을 사용하고 현명하게 상태를 선택하는 것이 항상 좋습니다.

좋아요, 정말 불균형이라면 어떨까요?
다시 한 번-데이터를 살펴보십시오. 때로는 한두 개의 관측치에 백배를 곱한 것을 찾을 수 있습니다. 때로는이 가짜 단일 클래스 관찰을 만드는 것이 유용합니다.
모든 데이터가 깨끗한 경우 다음 단계는 예측 모델에서 클래스 가중치를 사용하는 것입니다.

그렇다면 다중 클래스 메트릭은 어떻습니까?
내 경험상 일반적으로 사용되는 메트릭은 없습니다. 두 가지 주요 이유가 있습니다.
첫째 : 확실한 예측보다 확률로 작업하는 것이 항상 더 낫습니다
. 하나의 좋은 측정 항목에만 의존합니다.
내 경험상 logloss 또는 MSE (또는 제곱 오차를 의미)를 추천 할 수 있습니다.

sklearn 경고를 수정하는 방법?
(yangjie가 알아 차린대로) average매개 변수를 'micro'(전역 적으로 메트릭 계산), 'macro'(각 레이블에 대한 메트릭 계산) 또는 'weighted'(매크로와 동일하지만 자동 가중치 포함) 값 중 하나로 덮어 씁니다 .

f1_score(y_test, prediction, average='weighted')

모든 경고는 기본으로 측정 기능을 호출 한 후 온 average'binary'멀티 클래스 예측을위한 적합하지 않습니다.
행운을 빕니다. 머신 러닝을 즐기세요!

편집 :
동의 할 수없는 회귀 접근 방식 (예 : SVR)으로 전환 할 다른 응답자 권장 사항을 찾았습니다. 내가 기억하는 한 다중 클래스 회귀와 같은 것은 없습니다. 예, 훨씬 다른 다중 레이블 회귀가 있으며, 경우에 따라 회귀와 분류 (클래스가 정렬 된 경우)간에 전환 할 수 있지만 매우 드뭅니다.

내가 추천하고 싶은 것은 (scikit-learn의 범위에서) 또 다른 매우 강력한 분류 도구 인 그래디언트 부스팅 , 랜덤 포레스트 (내가 가장 좋아하는), KNeighbors 등을 시도 하는 것입니다.

그 후 예측 사이의 산술 또는 기하 평균을 계산할 수 있으며 대부분의 경우 더 나은 결과를 얻을 수 있습니다.

final_prediction = (KNNprediction * RFprediction) ** 0.5

1
> "회귀와 분류 (수업이 정렬 된 경우) 사이를 전환하지만 매우 드뭅니다."다음과 같은 경우입니다. 5> 4> 3> 2> 1.이 작업에 대한 논문을 살펴볼 것을 제안합니다. 작업에 대한 많은 회귀 및 분류 접근 방식 (때로는 동일한 작업).
Nikita Astrakhantsev

그런 다음 다중 클래스 분류가 아니라 단순한 회귀입니다.
Vlad Mironov

예, 내부적으로 또는 ML 관점에서 회귀이지만 마지막 단계에서 회귀 결과를 레이블로 변환하므로 사용자 또는 애플리케이션 관점에서 다중 클래스 분류입니다.
Nikita Astrakhantsev
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.