文本数据的多标签外学习:部分拟合



我正在尝试构建一个多标签的外部文本分类器。如下所述,这个想法是在批处理中读取(大规模)文本数据集,并将它们部分拟合到分类器中。此外,当您使用此处所述的多标签实例时,这个想法是以单vs-all方式构建许多二进制分类器作为数据集中的类数。

组合sklearn的多层次列赛和OnevsrestClassifier类和部分拟合时,我会收到以下错误:

valueerror:一个以上元素的数组的真实价值是模棱两可的。使用a.any()或a.all()

代码如下:

from sklearn.naive_bayes import MultinomialNB
from sklearn.feature_extraction.text import HashingVectorizer
from sklearn.preprocessing import MultiLabelBinarizer
from sklearn.multiclass import OneVsRestClassifier
categories = ['a', 'b', 'c']
X = ["This is a test", "This is another attempt", "And this is a test too!"]
Y = [['a', 'b'],['b'],['a','b']]
mlb = MultiLabelBinarizer(classes=categories)
vectorizer = HashingVectorizer(decode_error='ignore', n_features=2 ** 18,         non_negative=True)
clf = OneVsRestClassifier(MultinomialNB(alpha=0.01))
X_train = vectorizer.fit_transform(X)
Y_train = mlb.fit_transform(Y)
clf.partial_fit(X_train, Y_train, classes=categories)

您可以想象最后三行应用于每个MiniBatch,为了简单起见,我已将其删除的代码。

如果您删除OneVSrestClassifier并仅使用多元素nb,则代码运行正常。

您正在传递y_train,因为它以[[1,1,1,0],[0,1,0],[1,1,1,0]的形式转换为MultiLabelBinarizer。,但是将类别作为['a','b','c']传递,然后通过该行通过该行: -

if np.setdiff1d(y, self.classes_):
raise ValueError(("Mini-batch contains {0} while classes " +
                 "must be subset of {1}").format(np.unique(y),
                                              self.classes_))

导致一系列布尔值,例如[false,true,..]。 if无法处理单个真实值之类的数组,因此无法处理错误。

第一件事是您应该以与Y_train相同的数值格式传递类。现在,即使您这样做,OneVSrestClassifier的内部label_binarizer_也会决定它是类型的"多类"而不是multilabel,然后将拒绝正确地转换类。我认为这是OnevsrestClassifer和/或LabelBinarizer中的错误。

请提交有关partial_fit的Scikit-Learn Github的问题,看看会发生什么。

更新显然,由于周围的所有并发症,从目标向量(y)决定"多标记"或"多类"是一个正在进行的问题。

  • https://github.com/scikit-learn/scikit-learn/issues/7665
  • https://github.com/scikit-learn/scikit-learn/issues/5959
  • https://github.com/scikit-learn/scikit-learn/issues/7931
  • https://github.com/scikit-learn/scikit-learn/issues/8098
  • https://github.com/scikit-learn/scikit-learn/issues/7628
  • https://github.com/scikit-learn/scikit-learn/pull/2626

所以您可能期望的答案可能要不同,但是我建议您不要使用OnevSrestClassifier来使用Scikit-MultiLearn库,该库构建在Scikit-Learn上,它提供了多标签分类器,它比简单的Onevsrest更具艺术品的状态。

您可以在教程中找到如何使用Scikit-MultiLearn的示例。可以在Tsoumakas的MLC简介中找到对多标签分类方法的综述。

但是,如果碰巧您的标签彼此同时存在,我建议使用其他分类器,例如使用标签powerset使用标签空间划分使用快速贪婪的社区检测到输出空间 - 我解释了为什么这起作用在我的有关标签太空部门的论文中。

将代码转换为使用Scikit-MultiLearn将使其看起来如下:

from sklearn.naive_bayes import MultinomialNB
from sklearn.feature_extraction.text import HashingVectorizer
from sklearn.preprocessing import MultiLabelBinarizer
from skmultilearn.ensemble import LabelSpacePartitioningClassifier
from skmultilearn.cluster import IGraphLabelCooccurenceClusterer
from skmultilearn.problem_transform import LabelPowerset
categories = ['a', 'b', 'c']
X = ["This is a test", "This is another attempt", "And this is a test too!"]
Y = [['a', 'b'],['b'],['a','b']]
mlb = MultiLabelBinarizer(classes=categories)
vectorizer = HashingVectorizer(decode_error='ignore', n_features=2 ** 18,         non_negative=True)
X_train = vectorizer.fit_transform(X)
Y_train = mlb.fit_transform(Y)
# base single-label classifier 
base_classifier = MultinomialNB(alpha=0.01)
# problem transformation from multi-label to single-label 
transformation_classifier = LabelPowerset(base_classifier)
# clusterer dividing the label space using fast greedy modularity maximizing scheme
clusterer = IGraphLabelCooccurenceClusterer('fastgreedy', weighted=True, include_self_edges=True) 
# ensemble
clf = LabelSpacePartitioningClassifier(transformation_classifier, clusterer)
clf.fit(X_train, Y_train)

相关内容

  • 没有找到相关文章

最新更新