복붙노트

[PYTHON] scikit-learn을 사용하여 여러 카테고리로 분류

PYTHON

scikit-learn을 사용하여 여러 카테고리로 분류

나는 scikit-learn의 감독 학습 방법 중 하나를 사용하여 텍스트 조각을 하나 이상의 범주로 분류하려고합니다. 시도한 모든 알고리즘의 예측 함수는 하나의 일치를 반환합니다.

예를 들어 텍스트가 있습니다.

"Theaters in New York compared to those in London"

그리고 나는 그것을 먹이는 모든 텍스트 스 니펫을위한 장소를 고르는 알고리즘을 훈련 시켰습니다.

위의 예에서는 뉴욕과 런던을 반환하기를 원하지만 뉴욕 만 반환합니다.

scikit-learn을 사용하여 여러 결과를 반환 할 수 있습니까? 아니면 다음으로 높은 확률로 레이블을 반환합니까?

당신의 도움을 주셔서 감사합니다.

---최신 정보

OneVsRestClassifier를 사용하여 시도했지만 텍스트 한 장당 하나의 옵션 만 반환합니다. 아래는 내가 사용하고있는 샘플 코드입니다.

y_train = ('New York','London')


train_set = ("new york nyc big apple", "london uk great britain")
vocab = {'new york' :0,'nyc':1,'big apple':2,'london' : 3, 'uk': 4, 'great britain' : 5}
count = CountVectorizer(analyzer=WordNGramAnalyzer(min_n=1, max_n=2),vocabulary=vocab)
test_set = ('nice day in nyc','london town','hello welcome to the big apple. enjoy it here and london too')

X_vectorized = count.transform(train_set).todense()
smatrix2  = count.transform(test_set).todense()


base_clf = MultinomialNB(alpha=1)

clf = OneVsRestClassifier(base_clf).fit(X_vectorized, y_train)
Y_pred = clf.predict(smatrix2)
print Y_pred

결과 : [ 'New York' 'London' 'London']

해결법

  1. ==============================

    1.원하는 것은 다중 레이블 분류라고합니다. Scikits-learn은 그것을 할 수 있습니다. 여기를 참조하십시오 : http://scikit-learn.org/dev/modules/multiclass.html.

    원하는 것은 다중 레이블 분류라고합니다. Scikits-learn은 그것을 할 수 있습니다. 여기를 참조하십시오 : http://scikit-learn.org/dev/modules/multiclass.html.

    귀하의 예에서 무엇이 잘못 될지 확신하지 못합니다. 제 스켈레톤 버전에는 분명 WordNGramAnalyzer가 없습니다. 아마도 더 많은 훈련 예제를 사용하거나 다른 분류자를 시도하는 것이 문제일까요? 멀티 레이블 분류기는 대상이 레이블의 튜플 / 목록 목록이 될 것으로 기대합니다.

    나를 위해 다음 작품 :

    import numpy as np
    from sklearn.pipeline import Pipeline
    from sklearn.feature_extraction.text import CountVectorizer
    from sklearn.svm import LinearSVC
    from sklearn.feature_extraction.text import TfidfTransformer
    from sklearn.multiclass import OneVsRestClassifier
    
    X_train = np.array(["new york is a hell of a town",
                        "new york was originally dutch",
                        "the big apple is great",
                        "new york is also called the big apple",
                        "nyc is nice",
                        "people abbreviate new york city as nyc",
                        "the capital of great britain is london",
                        "london is in the uk",
                        "london is in england",
                        "london is in great britain",
                        "it rains a lot in london",
                        "london hosts the british museum",
                        "new york is great and so is london",
                        "i like london better than new york"])
    y_train = [[0],[0],[0],[0],[0],[0],[1],[1],[1],[1],[1],[1],[0,1],[0,1]]
    X_test = np.array(['nice day in nyc',
                       'welcome to london',
                       'hello welcome to new york. enjoy it here and london too'])   
    target_names = ['New York', 'London']
    
    classifier = Pipeline([
        ('vectorizer', CountVectorizer(min_n=1,max_n=2)),
        ('tfidf', TfidfTransformer()),
        ('clf', OneVsRestClassifier(LinearSVC()))])
    classifier.fit(X_train, y_train)
    predicted = classifier.predict(X_test)
    for item, labels in zip(X_test, predicted):
        print '%s => %s' % (item, ', '.join(target_names[x] for x in labels))
    

    나를 위해, 이것은 결과물을 산출합니다 :

    nice day in nyc => New York
    welcome to london => London
    hello welcome to new york. enjoy it here and london too => New York, London
    

    희망이 도움이됩니다.

  2. ==============================

    2.편집 : 제안 된대로 MultiLabelBinarizer를 사용하여 파이썬 3, scikit-0.18.1에 대해 업데이트되었습니다.

    편집 : 제안 된대로 MultiLabelBinarizer를 사용하여 파이썬 3, scikit-0.18.1에 대해 업데이트되었습니다.

    나는 이것에 대해서도 연구 해 왔으며 mwv의 훌륭한 대답을 약간 향상시켜 유용 할 수 있습니다. 바이너리 레이블이 아닌 입력으로 텍스트 레이블을 가져 와서 MultiLabelBinarizer를 사용하여 인코딩합니다.

    import numpy as np
    from sklearn.pipeline import Pipeline
    from sklearn.feature_extraction.text import CountVectorizer
    from sklearn.svm import LinearSVC
    from sklearn.feature_extraction.text import TfidfTransformer
    from sklearn.multiclass import OneVsRestClassifier
    from sklearn.preprocessing import MultiLabelBinarizer
    
    X_train = np.array(["new york is a hell of a town",
                        "new york was originally dutch",
                        "the big apple is great",
                        "new york is also called the big apple",
                        "nyc is nice",
                        "people abbreviate new york city as nyc",
                        "the capital of great britain is london",
                        "london is in the uk",
                        "london is in england",
                        "london is in great britain",
                        "it rains a lot in london",
                        "london hosts the british museum",
                        "new york is great and so is london",
                        "i like london better than new york"])
    y_train_text = [["new york"],["new york"],["new york"],["new york"],["new york"],
                    ["new york"],["london"],["london"],["london"],["london"],
                    ["london"],["london"],["new york","london"],["new york","london"]]
    
    X_test = np.array(['nice day in nyc',
                       'welcome to london',
                       'london is rainy',
                       'it is raining in britian',
                       'it is raining in britian and the big apple',
                       'it is raining in britian and nyc',
                       'hello welcome to new york. enjoy it here and london too'])
    target_names = ['New York', 'London']
    
    mlb = MultiLabelBinarizer()
    Y = mlb.fit_transform(y_train_text)
    
    classifier = Pipeline([
        ('vectorizer', CountVectorizer()),
        ('tfidf', TfidfTransformer()),
        ('clf', OneVsRestClassifier(LinearSVC()))])
    
    classifier.fit(X_train, Y)
    predicted = classifier.predict(X_test)
    all_labels = mlb.inverse_transform(predicted)
    
    for item, labels in zip(X_test, all_labels):
        print('{0} => {1}'.format(item, ', '.join(labels)))
    

    이것은 다음과 같은 결과를 준다 :

    nice day in nyc => new york
    welcome to london => london
    london is rainy => london
    it is raining in britian => london
    it is raining in britian and the big apple => new york
    it is raining in britian and nyc => london, new york
    hello welcome to new york. enjoy it here and london too => london, new york
    
  3. ==============================

    3.방금이 문제도 만났습니다. 문제는 y_train이 문자열 시퀀스가 ​​아니라 문자열 시퀀스 였기 때문입니다. 분명히 OneVsRestClassifier는 다중 레이블 대 다중 레이블을 사용할 것인지 여부에 따라 입력 레이블 형식을 기반으로 결정합니다. 그래서 변화 :

    방금이 문제도 만났습니다. 문제는 y_train이 문자열 시퀀스가 ​​아니라 문자열 시퀀스 였기 때문입니다. 분명히 OneVsRestClassifier는 다중 레이블 대 다중 레이블을 사용할 것인지 여부에 따라 입력 레이블 형식을 기반으로 결정합니다. 그래서 변화 :

    y_train = ('New York','London')
    

    y_train = (['New York'],['London'])
    

    분명히 앞으로는 사라질 것입니다. 모든 레이블이 끊어지기 때문입니다. https://github.com/scikit-learn/scikit-learn/pull/1987

  4. ==============================

    4.파이썬의 새 버전에서 작동하도록이 줄을 변경하십시오.

    파이썬의 새 버전에서 작동하도록이 줄을 변경하십시오.

    # lb = preprocessing.LabelBinarizer()
    lb = preprocessing.MultiLabelBinarizer()
    
  5. ==============================

    5.몇 가지 다중 분류 예는 다음과 같습니다 : -

    몇 가지 다중 분류 예는 다음과 같습니다 : -

    예 1 : -

    import numpy as np
    from sklearn.preprocessing import LabelBinarizer
    encoder = LabelBinarizer()
    
    arr2d = np.array([1, 2, 3,4,5,6,7,8,9,10,11,12,13,14,1])
    transfomed_label = encoder.fit_transform(arr2d)
    print(transfomed_label)
    

    출력

    [[1 0 0 0 0 0 0 0 0 0 0 0 0 0]
     [0 1 0 0 0 0 0 0 0 0 0 0 0 0]
     [0 0 1 0 0 0 0 0 0 0 0 0 0 0]
     [0 0 0 1 0 0 0 0 0 0 0 0 0 0]
     [0 0 0 0 1 0 0 0 0 0 0 0 0 0]
     [0 0 0 0 0 1 0 0 0 0 0 0 0 0]
     [0 0 0 0 0 0 1 0 0 0 0 0 0 0]
     [0 0 0 0 0 0 0 1 0 0 0 0 0 0]
     [0 0 0 0 0 0 0 0 1 0 0 0 0 0]
     [0 0 0 0 0 0 0 0 0 1 0 0 0 0]
     [0 0 0 0 0 0 0 0 0 0 1 0 0 0]
     [0 0 0 0 0 0 0 0 0 0 0 1 0 0]
     [0 0 0 0 0 0 0 0 0 0 0 0 1 0]
     [0 0 0 0 0 0 0 0 0 0 0 0 0 1]
     [1 0 0 0 0 0 0 0 0 0 0 0 0 0]]
    

    예 2 : -

    import numpy as np
    from sklearn.preprocessing import LabelBinarizer
    encoder = LabelBinarizer()
    
    arr2d = np.array(['Leopard','Lion','Tiger', 'Lion'])
    transfomed_label = encoder.fit_transform(arr2d)
    print(transfomed_label)
    

    출력

    [[1 0 0]
     [0 1 0]
     [0 0 1]
     [0 1 0]]
    
  6. from https://stackoverflow.com/questions/10526579/use-scikit-learn-to-classify-into-multiple-categories by cc-by-sa and MIT license