一、基本介紹
首先簡(jiǎn)單介紹下,多標(biāo)簽分類與多分類、多任務(wù)學(xué)習(xí)的關(guān)系:
-
多分類學(xué)習(xí)(Multi-class):分類器去劃分的類別是多個(gè)的,但對(duì)于每一個(gè)樣本只能有一個(gè)類別,類別間是互斥的。例如:分類器判斷這只動(dòng)物是貓、狗、豬,每個(gè)樣本只能有一種類別,就是一個(gè)三分類任務(wù)。常用的做法是OVR、softmax多分類
-
多標(biāo)簽學(xué)習(xí)(Multi-label ):對(duì)于每一個(gè)樣本可能有多個(gè)類別(標(biāo)簽)的任務(wù),不像多分類任務(wù)的類別是互斥。例如判斷每一部電影的標(biāo)簽可以是多個(gè)的,比如有些電影標(biāo)簽是【科幻、動(dòng)作】,有些電影是【動(dòng)作、愛情、諜戰(zhàn)】。需要注意的是,每一樣本可能是1個(gè)類別,也可能是多個(gè)。而且,類別間通常是有所聯(lián)系的,一部電影有科幻元素 同時(shí)也大概率有動(dòng)作篇元素的。
-
多任務(wù)學(xué)習(xí)(Multi-task):
基于共享表示(shared representation),多任務(wù)學(xué)習(xí)是通過(guò)合并幾個(gè)任務(wù)中的樣例(可以視為對(duì)參數(shù)施加的軟約束)來(lái)提高泛化的一種方式。額外的訓(xùn)練樣本以同樣的方式將模型的參數(shù)推向泛化更好的方向,當(dāng)模型的一部分在任務(wù)之間共享時(shí),模型的這一部分更多地被約束為良好的值(假設(shè)共享是合理的),往往能更好地泛化。某種角度上,多標(biāo)簽分類可以看作是一種多任務(wù)學(xué)習(xí)的簡(jiǎn)單形式。
二、多標(biāo)簽分類實(shí)現(xiàn)
實(shí)現(xiàn)多標(biāo)簽分類算法有DNN、KNN、ML-DT、Rank-SVM、CML,像決策樹DT、最近鄰KNN這一類模型,從原理上面天然可調(diào)整適應(yīng)多標(biāo)簽任務(wù)的(多標(biāo)簽適應(yīng)法),按同一劃分/近鄰的客群中各標(biāo)簽的占比什么的做下排序就可以做到了。
這里著重介紹下,比較通用的多標(biāo)簽實(shí)現(xiàn)思路,大致有以下4種:
方法一:多分類思路
簡(jiǎn)單粗暴,直接把不同標(biāo)簽組合當(dāng)作一個(gè)類別,作為一個(gè)多分類任務(wù)來(lái)學(xué)習(xí)。如上述 【科幻、動(dòng)作】、【動(dòng)作、愛情、諜戰(zhàn)】、【科幻、愛情】就可以看作一個(gè)三分類任務(wù)。這種方法前提是標(biāo)簽組合是比較有限的,不然標(biāo)簽會(huì)非常稀疏沒(méi)啥用。
方法二:OVR二分類思路
也挺簡(jiǎn)單的。將多標(biāo)簽問(wèn)題轉(zhuǎn)成多個(gè)二分類模型預(yù)測(cè)的任務(wù)。如電影總的子標(biāo)簽有K個(gè),劃分出K份數(shù)據(jù),分別訓(xùn)練K個(gè)二分類模型,【是否科幻類、是否動(dòng)作類....第K類】,對(duì)于每個(gè)樣本預(yù)測(cè)K次打出最終的標(biāo)簽組合。
這種方法簡(jiǎn)單靈活,但是缺點(diǎn)是也很明顯,各子標(biāo)簽間的學(xué)習(xí)都是獨(dú)立的(可能是否科幻類對(duì)判定是否動(dòng)作類的是有影響),忽略了子標(biāo)簽間的聯(lián)系,丟失了很多信息。
對(duì)應(yīng)的方法有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)
方法三:二分類改良
在方法二的基礎(chǔ)上進(jìn)行改良,即考慮標(biāo)簽之間的關(guān)系。 每一個(gè)分類器的預(yù)測(cè)結(jié)果將作為一個(gè)數(shù)據(jù)特征傳給下一個(gè)分類器,參與進(jìn)行下一個(gè)類別的預(yù)測(cè)。該方法的缺點(diǎn)是分類器之間的順序會(huì)對(duì)模型性能產(chǎn)生巨大影響。
方法四:多個(gè)輸出的神經(jīng)網(wǎng)絡(luò)
這以與多分類方法類似,但不同的是這里神經(jīng)網(wǎng)絡(luò)的多個(gè)輸出,輸出層由多個(gè)的sigmoid+交叉熵組成,并不是像softmax各輸出是互斥的。
如下構(gòu)建一個(gè)輸出為3個(gè)標(biāo)簽的概率的多標(biāo)簽?zāi)P停P褪枪灿靡惶咨窠?jīng)網(wǎng)絡(luò)參數(shù),各輸出的是獨(dú)立(bernoulli分布)的3個(gè)標(biāo)簽概率

## 多標(biāo)簽 分類
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ùn)練模型,x特征,y為多個(gè)標(biāo)簽
model.fit(x, y.loc[:,['LABEL','LABEL1','LABEL3']], epochs=3)

通過(guò)共享的模型參數(shù)來(lái)完成多標(biāo)簽分類任務(wù),在考慮了標(biāo)簽間的聯(lián)系的同時(shí),共享網(wǎng)絡(luò)參數(shù)可以起著模型正則化的作用,可能對(duì)提高模型的泛化能力有所幫助的(在個(gè)人驗(yàn)證中,測(cè)試集的auc漲了1%左右)。這一點(diǎn)和多任務(wù)學(xué)習(xí)是比較有聯(lián)系的,等后面有空再好好研究下多任務(wù)。


