
使用这些基本 REST API 最佳实践构建出色的 API
首先简单介绍下,多标签分类与多分类、多任务学习的关系:
实现多标签分类算法有DNN、KNN、ML-DT、Rank-SVM、CML,像决策树DT、最近邻KNN这一类模型,从原理上面天然可调整适应多标签任务的(多标签适应法),如按同一划分/近邻的客群中各标签的占比什么的做下排序就可以做到了多标签分类。这部电影10个近邻里面有5部是动作片,3部是科幻片,可以简单给这部电影至少打个【科幻、动作】。
这里着重介绍下,比较通用的多标签实现思路,大致有以下4种:
简单粗暴,直接把不同标签组合当作一个类别,作为一个多分类任务来学习。如上述 【科幻、动作】、【动作、爱情、谍战】、【科幻、爱情】就可以看作一个三分类任务。这种方法前提是标签组合是比较有限的,不然标签会非常稀疏没啥用。
也挺简单的。将多标签问题转成多个二分类模型预测的任务。如电影总的子标签有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个标签概率
## 多标签 分类
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)
通过共享的模型参数来完成多标签分类任务,在考虑了标签间的联系的同时,共享网络参数可以起着模型正则化的作用,可能对提高模型的泛化能力有所帮助的(在个人验证中,测试集的auc涨了1%左右)。这一点和多任务学习是比较有联系的,等后面有空再好好研究下多任务。
文章转自微信公众号@算法进阶