多标签分类基本上,有三种方法来解决一个多标签分类问题,即:
- 问题转换
- 改编算法
- 集成方法
4.1问题转换
在这个方法中,我们将尝试把多标签问题转换为单标签问题。这种方法可以用三种不同的方式进行:
- 二元关联(Binary Relevance)
- 分类器链(Classifier Chains)
- 标签Powerset(Label Powerset)
4.4.1二元关联(Binary Relevance)
这是最简单的技术,它基本上把每个标签当作单独的一个类分类问题。例如,让我们考虑如下所示的一个案例。我们有这样的数据集,X是独立的特征,Y是目标变量。
在二元关联中,这个问题被分解成4个不同的类分类问题,如下图所示。
我们不需要手动操作,multi-learn库在python中提供了它的实现。那么,让我们看看它在随机生成的数据上的实现。
# using binary relevance from skmultilearn.problem_transform import BinaryRelevance from sklearn.naive_bayes import GaussianNB # initialize binary relevance multi-label classifier # with a gaussian naive bayes base classifier classifier = BinaryRelevance(GaussianNB()) # train classifier.fit(X_train, y_train) # predict predictions = classifier.predict(X_test)
注意:在这里,我们使用了Naive Bayes的算法,你也可以使用任何其他的分类算法。
现在,在一个多标签分类问题中,我们不能简单地用我们的标准来计算我们的预测的准确性。所以,我们将使用accuracy score。这个函数计算子集的精度,这意味着预测的标签集应该与真正的标签集完全匹配。
那么,让我们计算一下预测的准确性。
from sklearn.metrics import accuracy_score accuracy_score(y_test,predictions)
0.45454545454545453
我们的准确率达到了45%,还不算太糟。它是最简单和有效的方法,但是这种方法的惟一缺点是它不考虑标签的相关性,因为它单独处理每个目标变量。
4.1.2分类器链(Classifier Chains)
在这种情况下,第一个分类器只在输入数据上进行训练,然后每个分类器都在输入空间和链上的所有之前的分类器上进行训练。
让我们试着通过一个例子来理解这个问题。在下面给出的数据集里,我们将X作为输入空间,而Y作为标签。
在分类器链中,这个问题将被转换成4个不同的标签问题,就像下面所示。黄色部分是输入空间,白色部分代表目标变量。
这与二元关联非常相似,唯一的区别在于它是为了保持标签相关性而形成的。那么,让我们尝试使用multi-learn库来实现它。
# using classifier chains from skmultilearn.problem_transform import ClassifierChain from sklearn.naive_bayes import GaussianNB # initialize classifier chains multi-label classifier # with a gaussian naive bayes base classifier classifier = ClassifierChain(GaussianNB()) # train classifier.fit(X_train, y_train) # predict predictions = classifier.predict(X_test) accuracy_score(y_test,predictions)
0.21212121212121213
我们可以看到,使用这个我们得到了21%的准确率,这比二元关联要低得多。可能是因为没有标签相关性,因为我们已经随机生成了数据。
4.1.3标签Powerset(Label Powerset)
在这方面,我们将问题转化为一个多类问题,一个多类分类器在训练数据中发现的所有唯一的标签组合上被训练。让我们通过一个例子来理解它。
在这一点上,我们发现x1和x4有相同的标签。同样的,x3和x6有相同的标签。因此,标签powerset将这个问题转换为一个单一的多类问题,如下所示。
因此,标签powerset给训练集中的每一个可能的标签组合提供了一个独特的类。让我们看看它在Python中的实现。
# using Label Powerset from skmultilearn.problem_transform import LabelPowerset from sklearn.naive_bayes import GaussianNB # initialize Label Powerset multi-label classifier # with a gaussian naive bayes base classifier classifier = LabelPowerset(GaussianNB()) # train classifier.fit(X_train, y_train) # predict predictions = classifier.predict(X_test) accuracy_score(y_test,predictions)
0.5757575757575758
这使我们在之前讨论过的三个问题中得到了最高的准确性,57%。唯一的缺点是随着训练数据的增加,类的数量也会增加。因此,增加了模型的复杂性,并降低了精确度。
现在,让我们看一下解决多标签分类问题的第二种方法。
4.2改编算法
改编算法来直接执行多标签分类,而不是将问题转化为不同的问题子集。例如,kNN的多标签版本是由MLkNN表示的。那么,让我们快速地在我们的随机生成的数据集上实现这个。
from skmultilearn.adapt import MLkNN classifier = MLkNN(k=20) # train classifier.fit(X_train, y_train) # predict predictions = classifier.predict(X_test) accuracy_score(y_test,predictions)
0.69
很好,你的测试数据已经达到了69%的准确率。
在一些算法中,例如随机森林(Random Forest)和岭回归(Ridge regression),Sci-kit learn提供了多标签分类的内置支持。因此,你可以直接调用它们并预测输出。
如果你想了解更多关于其他类型的改编算法,你可以查看multi-learn库。地址:http://scikit.ml/api/api/skmultilearn.adapt.html#module-skmultilearn.adapt
4.3集成方法
集成总是能产生更好的效果。Scikit-Multilearn库提供不同的组合分类功能,你可以使用它来获得更好的结果。
对于直接实现,你可以查看:http://scikit.ml/api/classify.html#ensemble-approaches