转自:

加载和生成多标签分类数据集

 安装工具包

pip install arff
pip install scikit-multilearn

加载多标签分类数据集

 

from skmultilearn.dataset import available_data_sets, load_dataset

#data_set = set([x[0] for x in available_data_sets().keys()])
data_set = pd.DataFrame(list(available_data_sets().keys()), columns=['name', 'usetype'])
data_set = data_set.groupby('name').apply(lambda x:'/'.join(x['usetype'].tolist()))
print(data_set)

X_train,  y_train, feature_names, label_names = load_dataset('emotions', 'train')
X_test, y_test, _, _ = load_dataset('emotions', 'test')

下载并解压到本地数据导入

多标签分类数据源:Mulan: A Java Library for Multi-Label Learning

import scipy
import pandas as pd
import numpy as np
from sklearn.model_selection import train_test_split

path = 'D:/PycharmProjects/deep_learning/data/yeast/'
data, meta = scipy.io.arff.loadarff(path + 'yeast-train.arff')
df = pd.DataFrame(data)
df = df.astype(float)  #np.float64
X, y = df.iloc[:,:103], df.iloc[:,103:]
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=0)

人工生成多标签数据集

from sklearn.datasets import make_multilabel_classification

# this will generate a random multi-label dataset
# n_labels:每个实例的标签的平均数量,allow_unlabeled:有些实例可能不属于任何类
X, y = make_multilabel_classification(sparse = True, n_labels = 20,
                                      return_indicator = 'sparse', 
                                      allow_unlabeled = False)

 

多标签分类问题解决方法主要有以下几种:

  1. 问题转换
  2. 改编算法
  3. 集成方法

1. 问题转化

1.1 二元关联(Binary Relevance)
这是最简单的技术,它基本上把每个标签当作单独的一个类分类问题。
简单有效,但不考虑标签之间的相关性

from skmultilearn.problem_transform import BinaryRelevance
from sklearn.naive_bayes import GaussianNB
from sklearn.metrics import accuracy_score

# initialize binary relevance multi-label classifier
# with a gaussian naive bayes base classifier
classifier = BinaryRelevance(GaussianNB())
classifier.fit(X_train, y_train)
predictions = classifier.predict(X_test)
accuracy_score(y_test, predictions)


from skmultilearn.problem_transform import BinaryRelevance
from sklearn.svm import SVC

classifier = BinaryRelevance(classifier=SVC(), require_dense=[False,True])
classifier.fit(X_train, y_train)
#classifier.classifiers_
y_pred = classifier.predict(X_test)
accuracy_score(y_test, y_pred)

1.2 分类器链(Classifier Chains)

第一个分类器只在输入数据上进行训练,然后每个分类器都在输入空间和链上的所有之前的分类器上进行训练。

与二元关联非常相似,唯一的区别在于它是为了保持标签相关性而形成的。

 

from skmultilearn.problem_transform import ClassifierChain
from sklearn.naive_bayes import GaussianNB

classifier = ClassifierChain(GaussianNB())
classifier.fit(X_train, y_train)
predictions = classifier.predict(X_test)
accuracy_score(y_test,predictions)

1.3 标签Powerset(Label Powerset)
将问题转化为一个多类问题,一个多类分类器在训练数据中发现的所有唯一的标签组合上被训练。
唯一的缺点是随着训练数据的增加,类的数量也会增加。因此,增加了模型的复杂性,并降低了精确度。

from skmultilearn.problem_transform import LabelPowerset
from sklearn.naive_bayes import GaussianNB

classifier = LabelPowerset(GaussianNB())
classifier.fit(X_train, y_train)
predictions = classifier.predict(X_test)
accuracy_score(y_test, predictions)

  

2. 改编算法

改编算法来直接执行多标签分类,而不是将问题转化为不同的问题子集。例如,kNN的多标签版本是由MLkNN表示的。

在一些算法中,例如随机森林(Random Forest)和岭回归(Ridge regression),Sci-kit learn提供了多标签分类的内置支持。因此,你可以直接调用它们并预测输出。

具体可查看scikit-multilearn库官方文档

from skmultilearn.adapt import MLkNN

classifier = MLkNN(k=20)
classifier.fit(X_train.values, y_train.values)
predictions = classifier.predict(X_test.values)
accuracy_score(y_test, predictions)

多模型比较

from skmultilearn.problem_transform import ClassifierChain, LabelPowerset
from sklearn.model_selection import GridSearchCV
from sklearn.naive_bayes import GaussianNB
from sklearn.ensemble import RandomForestClassifier
from skmultilearn.cluster import NetworkXLabelGraphClusterer
from skmultilearn.cluster import LabelCooccurrenceGraphBuilder
from skmultilearn.ensemble import LabelSpacePartitioningClassifier

from sklearn.svm import SVC

parameters = {
    'classifier': [LabelPowerset(), ClassifierChain()],
    'classifier__classifier': [RandomForestClassifier()],
    'classifier__classifier__n_estimators': [10, 20, 50],
    'clusterer' : [
        NetworkXLabelGraphClusterer(LabelCooccurrenceGraphBuilder(weighted=True, include_self_edges=False), 'louvain'),
        NetworkXLabelGraphClusterer(LabelCooccurrenceGraphBuilder(weighted=True, include_self_edges=False), 'lpa')
    ]
}

clf = GridSearchCV(LabelSpacePartitioningClassifier(), parameters, scoring = 'f1_macro')
clf.fit(X_train, y_train)

print (clf.best_params_, clf.best_score_)

 

参考资料:

Sklearn官方文档中文整理8——多类和多标签算法篇

AI 多类分类(multi-class) and 多标签分类(mulit-label) and 多输出-多分类-多标签classification

机器学习:多分类及多标签分类