3

질문에 올바른 태그를 예측하려고하는 다중 레이블 분류를 수행하고 있습니다.oneVsRestClassifier를 사용할 때 sklearn.svm.SVC의 decision_function_shape는 무엇입니까?

(X = 질문, y = X의 각 질문에 대한 태그 목록).

내가 의 sklearn.svm.SVCOneVsRestClassifier과 함께 사용해야합니까?

decision_function_shape : 우리가 그 decision_function_shape 두 값 'ovo''ovr' 수 있습니다 읽을 수있는 문서에서

'비켜', 'OVR'또는 없음, 기본값 = 없음

을 반환 여부 shape (n_samples, n_classes)의 one-vs-rest ('ovr') 결정 함수를 다른 모든 분류 자로 사용하거나 one-vs-one ('ovo') 결정 함수 libsvm의 모양을 (n_samples, n_classes * (n_classes - 1)/2). 없음의 기본값은 은 현재 이전 버전과의 호환성을 위해 'ovo'로 동작하고 지원 중단 경고를 발생 시키지만 0.19에서는 'ovr'을 변경합니다.

하지만 여전히 사이의 차이가 무엇인지 이해하지 않습니다 decision_function_shapemulti-label classification 문제 사용해야

# First decision_function_shape set to 'ovo' 
estim = OneVsRestClassifier(SVC(kernel='linear', decision_function_shape ='ovo')) 

# Second decision_function_shape set to 'ovr' 
estim = OneVsRestClassifier(SVC(kernel='linear', decision_function_shape ='ovr')) 

?

편집 :Question 답변이없는 비슷한 것을 묻습니다.

+0

당신은 모두를 시도하고 확인할 수있는 하나는 특정 데이터에 대해 더 나은 결과를 제공합니다. –

답변

2

어떤 것이 사용되어야하는지에 대한 의문은 상황에 따라 달라질 수 있습니다. 그리드 서치의 일부가 될 수 있습니다. 그러나 직관적으로 나는 차이점까지 똑같은 일을 할 것이라고 생각합니다. 여기 내 추론은 다음과 같습니다.

OneVsRestClassifier은 각 클래스를 다른 모든 클래스와 독립적으로 모델링하고 각 상황에 따라 분류자를 생성하도록 설계되었습니다. 이 과정을 이해하는 방법은 OneVsRestClassifier이 클래스를 잡고, 해당 클래스가 클래스인지 아닌지에 대한 2 진 레이블을 작성하는 것입니다. 그런 다음이 라벨링은 귀하가 사용하기로 선택한 측정기에 공급됩니다. SVC도이 동일한 선택을 할 수 있다는 혼란이 있다고 믿습니다. 그러나이 구현에서는 실제로 두 클래스를 SVC에 넣기 때문에 선택의 여지가 없습니다.

from sklearn.datasets import load_iris 
from sklearn.multiclass import OneVsRestClassifier 
from sklearn.svm import SVC 

data = load_iris() 

X, y = data.data, data.target 
estim1 = OneVsRestClassifier(SVC(kernel='linear', decision_function_shape='ovo')) 
estim1.fit(X,y) 

estim2 = OneVsRestClassifier(SVC(kernel='linear', decision_function_shape='ovr')) 
estim2.fit(X,y) 

print(estim1.coef_ == estim2.coef_) 
array([[ True, True, True, True], 
     [ True, True, True, True], 
     [ True, True, True, True]], dtype=bool) 

그래서 당신은 계수가 모두 두 모델에 의해 지어 세 추정량에 대한 동일 볼 수 있습니다 여기

그리고

은 예입니다. 이 데이터 세트에는 150 개의 샘플과 3 개의 클래스 만 있으므로 복잡한 데이터 세트의 경우 이러한 결과가 다를 수 있지만 간단한 개념 증명입니다. ovo2 쌍의 클래스 조합 ovr 열차 반면 다른 모든 클래스에 대해 부착 각 클래스에 대해 하나의 분류를위한 분류 기차 때문에 결정 기능

2

형상은 상이하다.

내가 찾을 수있는 가장 좋은 예는 found here on http://scikit-learn.org 될 수 있습니다

SVCNuSVC은 "한 - 대한 - 하나"접근 방식을 구현하는 멀티 클래스 (Knerr 등, 1990). 분류. n_class이 클래스 수인 경우 n_class * (n_class - 1)/2 분류자를 생성하고 및 각 클래스는 두 클래스의 데이터를 전달합니다. 다른 분류와 일치 인터페이스를 제공하기 위해, decision_function_shape 옵션 모양의 결정 함수에 "한 - 대한 - 하나"분류 의 결과를 집계 할 수 있습니다 (N_SAMPLES, n_classes)

>>> X = [[0], [1], [2], [3]] 
>>> Y = [0, 1, 2, 3] 
>>> clf = svm.SVC(decision_function_shape='ovo') 
>>> clf.fit(X, Y) 
SVC(C=1.0, cache_size=200, class_weight=None, coef0=0.0, 
    decision_function_shape='ovo', degree=3, gamma='auto', kernel='rbf', 
    max_iter=-1, probability=False, random_state=None, shrinking=True, 
    tol=0.001, verbose=False) 
>>> dec = clf.decision_function([[1]]) 
>>> dec.shape[1] # 4 classes: 4*3/2 = 6 
6 
>>> clf.decision_function_shape = "ovr" 
>>> dec = clf.decision_function([[1]]) 
>>> dec.shape[1] # 4 classes 
4 

이 말은 단순한 의미에서 무엇을 의미합니까?

n_class * (n_class - 1)/2의 의미를 이해하려면 itertools.combinations을 사용하여 2 종 조합을 생성하십시오.

def ovo_classifiers(classes): 
    import itertools 
    n_class = len(classes) 
    n = n_class * (n_class - 1)/2 
    combos = itertools.combinations(classes, 2) 
    return (n, list(combos)) 

>>> ovo_classifiers(['a', 'b', 'c']) 
(3.0, [('a', 'b'), ('a', 'c'), ('b', 'c')]) 
>>> ovo_classifiers(['a', 'b', 'c', 'd']) 
(6.0, [('a', 'b'), ('a', 'c'), ('a', 'd'), ('b', 'c'), ('b', 'd'), ('c', 'd')]) 

다중 레이블 분류에는 어떤 견적서를 사용해야합니까?

상황에 따라 StackOverflow의 여러 태그에 질문이 있습니다. 당신이-사전 태그 (클래스)를 알고 있다면, 내가 OneVsRestClassifier(LinearSVC()) 제안 할 수 있지만 당신이 시도 할 수 DecisionTreeClassifier 또는 RandomForestClassifier (내 생각) :

import pandas as pd 
from sklearn.preprocessing import MultiLabelBinarizer 
from sklearn.svm import SVC, LinearSVC 
from sklearn.feature_extraction.text import CountVectorizer 
from sklearn.pipeline import Pipeline 
from sklearn.multiclass import OneVsRestClassifier, OneVsOneClassifier 

df = pd.DataFrame({ 
    'Tags': [['python', 'pandas'], ['c#', '.net'], ['ruby'], 
      ['python'], ['c#'], ['sklearn', 'python']], 
    'Questions': ['This is a post about python and pandas is great.', 
      'This is a c# post and i hate .net', 
      'What is ruby on rails?', 'who else loves python', 
      'where to learn c#', 'sklearn is a python package for machine learning']}, 
        columns=['Questions', 'Tags']) 

X = df['Questions'] 
mlb = MultiLabelBinarizer() 
y = mlb.fit_transform(df['Tags'].values) 

pipeline = Pipeline([ 
    ('vect', CountVectorizer(token_pattern='|'.join(mlb.classes_))), 
    ('linear_svc', OneVsRestClassifier(LinearSVC())) 
    ]) 
pipeline.fit(X, y) 

final = pd.DataFrame(pipeline.predict(X), index=X, columns=mlb.classes_) 

def predict(text): 
    return pd.DataFrame(pipeline.predict(text), index=text, columns=mlb.classes_) 

test = ['is python better than c#', 'should i learn c#', 
     'should i learn sklearn or tensorflow', 
     'ruby or c# i am a dinosaur', 
     'is .net still relevant'] 
print(predict(test)) 

출력 :

         .net c# pandas python ruby sklearn 
is python better than c#     0 1  0  1  0  0 
should i learn c#      0 1  0  0  0  0 
should i learn sklearn or tensorflow  0 0  0  0  0  1 
ruby or c# i am a dinosaur    0 1  0  0  1  0 
is .net still relevant     1 0  0  0  0  0 
+0

좋은 답변입니다. 이 특별한 문제에 대해 왜 SVC (kernel = 'linear') 대신 LinearSVC()를 사용하겠습니까? 워드 프로세서에 따른 구현상의 차이점이 있지만 기본적으로 동일하지 않습니까? (LinearSVC()의 단 하나의 이점에 대해 알고 있습니다 - 더 큰 데이터 세트의 경우 더 잘 확장됩니다) – delusionX

+0

솔직히, 그것은 이상합니다! 위의 샘플에서'파이프 라인'에서'LinearSVC()'를'SVC (kernel = 'linear')'로 바꾸면 예측 결과가 좋지 않습니다. 예를 들어'sklearn'이나'.net'을 식별하지 않습니다. 나는 그것이 정말로 흥미있는 것을 안다. 그러나 나는 이유를 모른다. 나는 그들이 기본적으로 동일하다고 생각했다. 이것은 놀람이었다. – Jarad