多标签分类:用Python的Scikit-Learn进行介绍

多标签分类介绍:Python的Scikit-Learn使用

 

在机器学习任务中,分类是一种有监督学习方法,用于根据输入数据预测标签。例如,我们想要根据历史特征预测某人对销售优惠是否感兴趣。通过使用可用的训练数据训练机器学习模型,我们可以对输入数据进行分类任务。

我们经常遇到经典的分类任务,如二元分类(两个标签)和多类别分类(超过两个标签)。在这种情况下,我们会训练分类器,模型会尝试从所有可用标签中预测一个标签。用于分类的数据集类似于下面的图像。

   

上面的图像显示了目标(销售优惠)在二元分类中包含两个标签,在多类别分类中包含三个标签。模型会根据可用特征进行训练,然后只输出一个标签。

多标签分类与二元或多类别分类不同。在多标签分类中,我们不仅尝试预测一个输出标签。相反,多标签分类会尝试预测尽可能多的标签适用于输入数据。输出可以是从没有标签到最大可用标签数的任意数量的标签。

多标签分类通常用于文本数据分类任务。例如,这是一个多标签分类的示例数据集。

   

在上面的示例中,假设文本1到文本5是可以归类为四个类别的句子:事件、体育、流行文化和自然。通过上述训练数据,多标签分类任务会预测哪个标签适用于给定的句子。每个类别不相互排斥,它们不是互斥的;每个标签都可以被视为独立的。

更详细的内容,请看到文本1的标签是体育和流行文化,而文本2的标签是流行文化和自然。这表明每个标签是相互排斥的,多标签分类可以具有无标签或同时具有所有标签的预测输出。

有了这个介绍,让我们尝试使用Scikit-Learn构建多类别分类器。

 

使用Scikit-Learn进行多标签分类

 

本教程将使用Kaggle上公开可用的Biomedical PubMed多标签分类数据集。该数据集包含多种特征,但我们只使用abstractText特征和它们的MeSH分类(A:解剖学,B:有机体,C:疾病等)。示例数据显示在下面的图像中。

   

上述数据集显示每篇论文可以被分类到多个类别中,这是多标签分类的情况。有了这个数据集,我们可以使用Scikit-Learn构建多标签分类器。在训练模型之前,让我们准备数据集。

import pandas as pd
from sklearn.feature_extraction.text import TfidfVectorizer

df = pd.read_csv('PubMed Multi Label Text Classification Dataset Processed.csv')
df = df.drop(['Title', 'meshMajor', 'pmid', 'meshid', 'meshroot'], axis =1)

X = df["abstractText"]
y = np.asarray(df[df.columns[1:]])

vectorizer = TfidfVectorizer(max_features=2500, max_df=0.9)
vectorizer.fit(X)

 

在上面的代码中,我们将文本数据转换为TF-IDF表示,以便我们的Scikit-Learn模型能够接受训练数据。此外,为了简化教程,我跳过了数据预处理步骤,如停用词去除。

数据转换后,我们将数据集分割为训练集和测试集。

from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=101)
  
X_train_tfidf = vectorizer.transform(X_train)
X_test_tfidf = vectorizer.transform(X_test)

 

准备工作完成后,我们将开始训练我们的多标签分类器。在Scikit-Learn中,我们将使用MultiOutputClassifier对象来训练多标签分类器模型。该模型的策略是为每个标签训练一个分类器。基本上,每个标签都有自己的分类器。

在本示例中,我们将使用逻辑回归,并且MultiOutputClassifier会将其扩展到所有标签上。

from sklearn.multioutput import MultiOutputClassifier
from sklearn.linear_model import LogisticRegression

clf = MultiOutputClassifier(LogisticRegression()).fit(X_train_tfidf, y_train)

 

我们可以更改模型并调整传递给MultiOutputClassifier的模型参数,以满足您的要求。训练完成后,让我们使用该模型来预测测试数据。

prediction = clf.predict(X_test_tfidf)
prediction

 

 

预测结果是每个MeSH类别的标签数组。每一行表示一个句子,每一列表示一个标签。 

最后,我们需要评估我们的多标签分类器。我们可以使用准确率指标来评估模型。

from sklearn.metrics import accuracy_score
print('准确率:', accuracy_score(y_test, prediction))

 

准确率:0.145

准确率得分为0.145,这表明该模型只能在不到14.5%的时间内准确预测出完全正确的标签组合。然而,准确率得分在多标签预测评估中存在弱点。准确率得分需要每个句子在确切位置具有所有标签存在,否则将被视为错误。

例如,第一行预测与测试数据之间仅在一个标签上有差异。

     

对于准确率得分来说,这将被视为错误预测,因为标签组合不同。这就是为什么我们的模型得分较低。

为了解决这个问题,我们必须评估标签预测而不是它们的标签组合。在这种情况下,我们可以依靠Hamming Loss评估指标。Hamming Loss通过将错误预测的部分与标签总数的比例来计算。因为Hamming Loss是一个损失函数,得分越低越好(0表示没有错误预测,1表示所有预测都错误)。

from sklearn.metrics import hamming_loss
print('Hamming Loss: ', round(hamming_loss(y_test, prediction),2))

 

Hamming Loss: 0.13

我们的多标签分类器Hamming Loss模型为0.13,这意味着我们的模型在独立的情况下会有13%的错误预测。这意味着每个标签的预测可能有13%的错误。

 

结论

 

多标签分类是一种机器学习任务,输出可以是没有标签或给定输入数据的所有可能标签。它与二元或多类分类不同,其中标签输出是互斥的。

使用Scikit-Learn的MultiOutputClassifier,我们可以开发多标签分类器,其中我们为每个标签训练一个分类器。在模型评估方面,最好使用Hamming Loss指标,因为准确率得分可能无法正确反映整个情况。Cornellius Yudha Wijaya是一名数据科学助理经理和数据作家。在全职工作于Allianz Indonesia期间,他喜欢通过社交媒体和写作媒体分享Python和数据技巧。