使用NLTK、scikit learn和OneVsRestClassifier打开多标签分类



免责声明:我是AI、Python、NLTK和scikit学习的新手。

我正在尝试训练一个分类器,将一组文档分类为一组标签。

我正在使用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,否则为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

文档试图说的是,使用2-D矩阵作为目标。所以基本上,你的训练集可以是,

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学习适配器,并导入了一个NLTK模块来帮助我将数据结构转换为可提供给scikit学习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)

快乐豆

相关内容

  • 没有找到相关文章

最新更新