簡體   English   中英

使用NLTK,scikit-learn和OneVsRestClassifier啟用多標簽分類

[英]Turning on multi-label classification with NLTK, scikit-learn and OneVsRestClassifier

免責聲明:我對AI,Python,NLTK和scikit-learn還是很陌生。

我正在嘗試訓練一個分類器,以將一組文檔分類為一組標簽。

我正在使用NLTK包裝程序來與scikit-learn的OneVsRestClassifier進行對話。

training_set = [
    [{"car": True, ...}, "Label 1"],
    [{"car": False, ...}, "Label 2"],
    ...
    [{"car": False, ...}, "Label 1"],
]

ovr = SklearnClassifier(OneVsRestClassifier(MultinomialNB()))
ovr.train(training_set)

這適用於多類別分類,其中分類器嘗試將文檔僅分類為標簽。 准確性很好,但我希望分類器將0、1或多個標簽分配給文檔。 我怎樣才能做到這一點?

可悲的是,我不能僅僅初始化分類器,告訴它是一個多標簽分類器, 文檔說:

此策略也可用於多標簽學習,其中分類器可用於預測多個標簽,例如,如果樣本i具有標簽j,則擬合其中單元格[i,j]為1的2-d矩陣,否則為0。

因為我不熟悉這種語言,所以這對我來說真的不是很清楚。 我有種感覺,我必須以某種方式來塑造訓練集,以便分類器能夠理解我希望它對數據進行多標簽分類嗎? 如果是,怎么辦?

我試圖在數組中提供標簽,如下所示:

training_set = [
    [{"car": True, ...}, ["Label 1"]],
    [{"car": False, ...}, ["Label 2"]],
    ...
    [{"car": False, ...}, ["Label 1"]],
]

這沒有按預期方式工作並提出:

DataConversionWarning: A column-vector y was passed when a 1d array was expected. Please change the shape of y to (n_samples, ), for example using ravel().
  y = column_or_1d(y, warn=True)
One-vs-rest accuracy percent: 0.0

文檔試圖說的是,使用二維矩陣作為目標。 所以基本上,您的訓練集可以是

training_set = [
    [{"car": True, ...}, [is_label_1, is_label_2, is_label_3]],
    [{"car": False, ...}, [is_label_1, is_label_2, is_label_3]],
    ...
    [{"car": False, ...}, [is_label_1, is_label_2, is_label_3]],
]

對於特定樣品,使用多個標簽訓練它,例如對於第一個樣品,如果存在標簽1和標簽3,則將其作為[1、0、1]傳遞。

希望,答案很清楚。

通過擺脫將NLTK移植到scikit-learn適配器並導入NLTK模塊來幫助我將數據結構轉換為可提供給scikit-learn的OneVsRestClassifier的方法,我解決了這一問題。

from nltk import compat
from sklearn.feature_extraction import DictVectorizer
from sklearn.naive_bayes import MultinomialNB
from sklearn.multiclass import OneVsRestClassifier

_vectorizer = DictVectorizer(dtype=float, sparse=True)

def prepare_scikit_x_and_y(labeled_featuresets):
    X, y = list(compat.izip(*labeled_featuresets))
    X = _vectorizer.fit_transform(X)

    set_of_labels = []
    for label in y:
        set_of_labels.append(set(label))

    y = self.mlb.fit_transform(set_of_labels)

    return X, y

def train_classifier(labeled_featuresets):
    X, y = prepare_scikit_x_and_y(labeled_featuresets)
    classifier.fit(X, y)

training_set = [
    [{"car": True, ...}, ["Label 1"]],
    [{"car": False, ...}, ["Label 2"]],
    ...
    [{"car": False, ...}, ["Label 1"]],
]


ovr = OneVsRestClassifier(MultinomialNB())
ovr.train(training_set)

快樂的豆子

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM