【机器学习】多标签分类怎么做?(Python)

一、基本介绍

首先简单介绍下,多标签分类与多分类、多任务学习的关系:

  • 多分类学习(Multi-class):分类器去划分的类别是多个的,但对于每一个样本只能有一个类别,类别间是互斥的。例如:分类器判断这只动物是猫、狗、猪,每个样本只能有一种类别,就是一个三分类任务。常用的做法是OVR、softmax多分类60f61b88d49adb309ed1ba182c3992bd.png

  • 多标签学习(Multi-label ):对于每一个样本可能有多个类别(标签)的任务,不像多分类任务的类别是互斥。例如判断每一部电影的标签可以是多个的,比如有些电影标签是【科幻、动作】,有些电影是【动作、爱情、谍战】。需要注意的是,每一样本可能是1个类别,也可能是多个。而且,类别间通常是有所联系的,一部电影有科幻元素 同时也大概率有动作篇元素的。9e26707ce1721727598507ccb3f475f0.png

  • 多任务学习(Multi-task):基于共享表示(shared representation),多任务学习是通过合并几个任务中的样例(可以视为对参数施加的软约束)来提高泛化的一种方式。额外的训练样本以同样的方式将模型的参数推向泛化更好的方向,当模型的一部分在任务之间共享时,模型的这一部分更多地被约束为良好的值(假设共享是合理的),往往能更好地泛化。某种角度上,多标签分类可以看作是一种多任务学习的简单形式。9b9b2e790dad3c9bd9a2d7bfe6dc1cd7.png

二、多标签分类实现

实现多标签分类算法有DNN、KNN、ML-DT、Rank-SVM、CML,像决策树DT、最近邻KNN这一类模型,从原理上面天然可调整适应多标签任务的(多标签适应法),如按同一划分/近邻的客群中各标签的占比什么的做下排序就可以做到了多标签分类。这部电影10个近邻里面有5部是动作片,3部是科幻片,可以简单给这部电影至少打个【科幻、动作】。

这里着重介绍下,比较通用的多标签实现思路,大致有以下4种:

方法一:多分类思路

简单粗暴,直接把不同标签组合当作一个类别,作为一个多分类任务来学习。如上述 【科幻、动作】、【动作、爱情、谍战】、【科幻、爱情】就可以看作一个三分类任务。这种方法前提是标签组合是比较有限的,不然标签会非常稀疏没啥用。

方法二:OVR二分类思路

也挺简单的。将多标签问题转成多个二分类模型预测的任务。如电影总的子标签有K个,划分出K份数据,分别训练K个二分类模型,【是否科幻类、是否动作类....第K类】,对于每个样本预测K次打出最终的标签组合。

这种方法简单灵活,但是缺点是也很明显,各子标签间的学习都是独立的(可能是否科幻类对判定是否动作类的是有影响),忽略了子标签间的联系,丢失了很多信息。

对应的方法有sklearn的OneVsRestClassifier方法,

from xgboost import XGBClassifier
from sklearn.multiclass import OneVsRestClassifier
import numpy as np


clf_multilabel = OneVsRestClassifier(XGBClassifier())


train_data = np.random.rand(500, 100)  # 500 entities, each contains 100 features
train_label = np.random.randint(2, size=(500,20))  # 20 targets


val_data = np.random.rand(100, 100)


clf_multilabel.fit(train_data,train_label)
val_pred = clf_multilabel.predict(val_data)
方法三:二分类改良

在方法二的基础上进行改良,即考虑标签之间的关系。每一个分类器的预测结果将作为一个数据特征传给下一个分类器,参与进行下一个类别的预测。该方法的缺点是分类器之间的顺序会对模型性能产生巨大影响。

方法四:多个输出的神经网络

这以与多分类方法类似,但不同的是这里神经网络的多个输出,输出层由多个的sigmoid+交叉熵组成,并不是像softmax各输出是互斥的。

如下构建一个输出为3个标签的概率的多标签模型,模型是共用一套神经网络参数,各输出的是独立(bernoulli分布)的3个标签概率

5e62abd1111daacf7753ca37c9c70e70.png
## 多标签 分类
from keras.models import Model
from keras.layers import Input,Dense


inputs = Input(shape=(15,))
hidden = Dense(units=10,activation='relu')(inputs)
output = Dense(units=3,activation='sigmoid')(hidden)
model=Model(inputs=inputs, outputs=output)
model.compile(optimizer='adam', loss='binary_crossentropy', metrics=['accuracy'])
model.summary()


# 训练模型,x特征,y为多个标签
model.fit(x, y.loc[:,['LABEL','LABEL1','LABEL3']], epochs=3)
dc8507cab1753a9de6fbb439fdf12bbf.png

通过共享的模型参数来完成多标签分类任务,在考虑了标签间的联系的同时,共享网络参数可以起着模型正则化的作用,可能对提高模型的泛化能力有所帮助的(在个人验证中,测试集的auc涨了1%左右)。这一点和多任务学习是比较有联系的,等后面有空再好好研究下多任务。

 
 

40d1454db9d6bb3de707a9395d9af2fb.jpeg

 
 
 
 
 
 
 
 
往期精彩回顾




适合初学者入门人工智能的路线及资料下载(图文+视频)机器学习入门系列下载机器学习及深度学习笔记等资料打印《统计学习方法》的代码复现专辑机器学习交流qq群955171419,加入微信群请扫码
Python中进行单标签文本分类可以使用各种机器学习和深度学习技术。以下是一个基本的流程: 1. 数据预处理:首先,需要加载和清洗你的文本数据。这可能包括去除停用词、标点符号等,以及进行词干化或词形还原等处理。 2. 特征提取:接下来,你需要将文本转换为可供机器学习算法使用的特征向量。常见的方法包括词袋模型(Bag-of-Words)、TF-IDF(Term Frequency-Inverse Document Frequency)等。 3. 模型训练与评估:选择适合任务的分类算法,例如朴素贝叶斯、支持向量机(SVM)、随机森林等。使用训练集对模型进行训练,并使用验证集进行调参和模型选择。最后,使用测试集评估模型性能。 下面是一个简单的示例,使用朴素贝叶斯分类器进行单标签文本分类: ```python from sklearn.feature_extraction.text import CountVectorizer from sklearn.naive_bayes import MultinomialNB from sklearn.metrics import accuracy_score # 1. 数据预处理(假设你已经有了数据集) X_train = ['文本1', '文本2', ...] y_train = ['标签1', '标签2', ...] X_test = ['文本3', '文本4', ...] y_test = ['标签3', '标签4', ...] # 2. 特征提取 vectorizer = CountVectorizer() X_train_vec = vectorizer.fit_transform(X_train) X_test_vec = vectorizer.transform(X_test) # 3. 模型训练与评估 classifier = MultinomialNB() classifier.fit(X_train_vec, y_train) y_pred = classifier.predict(X_test_vec) accuracy = accuracy_score(y_test, y_pred) print("准确率:", accuracy) ``` 以上代码使用了scikit-learn库中的CountVectorizer来将文本转换为特征向量,然后使用MultinomialNB进行朴素贝叶斯分类器的训练与预测,并计算准确率。 当然,这只是一个简单的示例,实际应用中可能会有更复杂的数据预处理、特征提取和模型选择等步骤。你可以根据具体情况进行调整和优化。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值