1. 程式人生 > >解決多標籤分類問題(包括案例研究)

解決多標籤分類問題(包括案例研究)

由於某些原因,迴歸和分類問題總會引起機器學習領域的大部分關注。多標籤分類在資料科學中是一個比較令人頭疼的問題。在這篇文章中,我將給你一個直觀的解釋,說明什麼是多標籤分類,以及如何解決這個問題。

1.多標籤分類是什麼?

讓我們來看看下面的圖片。

如果我問你這幅圖中有一棟房子,你會怎樣回答? 選項為“Yes”或“No”。

或者這樣問,所有的東西(或標籤)與這幅圖有什麼關係?

在這些型別的問題中,我們有一組目標變數,被稱為多標籤分類問題。那麼,這兩種情況有什麼不同嗎? 很明顯,有很大的不同,因為在第二種情況下,任何影象都可能包含不同影象的多個不同的標籤。

但在深入講解多標籤之前,我想解釋一下它與多分類問題有何不同,讓我們試著去理解這兩組問題的不同之處。

2.多標籤vs多分類

用一個例子來理解這兩者之間的區別。

對於任何一部電影,電影的中央委員會會根據電影的內容頒發證書。例如,如果你看上面的圖片,這部電影被評為“UA”(意思是“12歲以下兒童需在父母陪同下觀看”)。還有其他型別的證書類,如“A”(僅限於成人)或“U”(不受限制的公開放映),但可以肯定的是,每部電影只能在這三種類型的證書中進行分類。簡而言之,有多個類別,但每個例項只分配一個,因此這些問題被稱為多類分類問題。

同時,你回顧一下這張圖片,這部電影被歸類為喜劇和浪漫型別。但不同的是,這一次,每部電影都有可能被分成一個或多個不同的類別。

所以每個例項都可以使用多個類別進行分配。因此,這些型別的問題被稱為多標籤分類問題。

現在你應該可以區分多標籤和多分類問題了。那麼,讓我們開始處理多標籤這種型別的問題。

3.載入和生成多標籤資料集

Scikit-learn提供了一個獨立的庫scikit-multilearn,用於多種標籤分類。為了更好的理解,讓我們開始在一個多標籤的資料集上進行練習。scikit-multilearn庫地址:http://scikit.ml/api/datasets.html

因此,為了開始使用這些資料集,請檢視下面的Python程式碼,將其載入到你的計算機上。在這裡,我已經從儲存庫中下載了酵母(yeast)資料集。

import scipy
from scipy.io import arff
data, meta = scipy.io.arff.loadarff('/Users/shubhamjain/Documents/yeast/yeast-train.arff')
df = pd.DataFrame(data)

這就是資料集的樣子。

在這裡,Att表示屬性或獨立變數,class表示目標變數。

出於實踐目的,我們有另一個選項來生成一個人工的多標籤資料集。

from sklearn.datasets import make_multilabel_classification

# this will generate a random multi-label dataset
X, y = make_multilabel_classification(sparse = True, n_labels = 20,
return_indicator = 'sparse', allow_unlabeled = False)

讓我們瞭解一下上面所使用的引數。

sparse(稀疏):如果是True,返回一個稀疏矩陣,稀疏矩陣表示一個有大量零元素的矩陣。

n_labels:每個例項的標籤的平均數量。

return_indicator:“sparse”在稀疏的二進位制指示器格式中返回Y。

allow_unlabeled:如果是True,有些例項可能不屬於任何類。

你一定會注意到,我們到處都使用了稀疏矩陣,而scikit-multilearn也建議使用稀疏格式的資料,因為在實際資料集中非常罕見。一般來說,分配給每個例項的標籤的數量要少得多。

好了,現在我們已經準備好了資料集,讓我們快速學習解決多標籤問題的技術。

4.解決多標籤分類問題的技術

基本上,有三種方法來解決一個多標籤分類問題,即:

  1. 問題轉換
  2. 改編演算法
  3. 整合方法

4.1問題轉換

在這個方法中,我們將嘗試把多標籤問題轉換為單標籤問題。這種方法可以用三種不同的方式進行:

  1. 二元關聯(Binary Relevance)
  2. 分類器鏈(Classifier Chains)
  3. 標籤Powerset(Label Powerset)

4.4.1二元關聯(Binary Relevance)

這是最簡單的技術,它基本上把每個標籤當作單獨的一個類分類問題。例如,讓我們考慮如下所示的一個案例。我們有這樣的資料集,X是獨立的特徵,Y是目標變數。

在二元關聯中,這個問題被分解成4個不同的類分類問題,如下圖所示。

我們不需要手動操作,multi-learn庫在python中提供了它的實現。那麼,讓我們看看它在隨機生成的資料上的實現。

# using binary relevance
from skmultilearn.problem_transform import BinaryRelevance
from sklearn.naive_bayes import GaussianNB

# initialize binary relevance multi-label classifier
# with a gaussian naive bayes base classifier
classifier = BinaryRelevance(GaussianNB())

# train
classifier.fit(X_train, y_train)

# predict
predictions = classifier.predict(X_test)

注意:在這裡,我們使用了Naive Bayes的演算法,你也可以使用任何其他的分類演算法。

現在,在一個多標籤分類問題中,我們不能簡單地用我們的標準來計算我們的預測的準確性。所以,我們將使用accuracy score。這個函式計運算元集的精度,這意味著預測的標籤集應該與真正的標籤集完全匹配。

那麼,讓我們計算一下預測的準確性。

from sklearn.metrics import accuracy_score
accuracy_score(y_test,predictions)
0.45454545454545453

我們的準確率達到了45%,還不算太糟。它是最簡單和有效的方法,但是這種方法的惟一缺點是它不考慮標籤的相關性,因為它單獨處理每個目標變數。

4.1.2分類器鏈(Classifier Chains)

在這種情況下,第一個分類器只在輸入資料上進行訓練,然後每個分類器都在輸入空間和鏈上的所有之前的分類器上進行訓練。 讓我們試著通過一個例子來理解這個問題。在下面給出的資料集裡,我們將X作為輸入空間,而Y作為標籤。

在分類器鏈中,這個問題將被轉換成4個不同的標籤問題,就像下面所示。黃色部分是輸入空間,白色部分代表目標變數。

這與二元關聯非常相似,唯一的區別在於它是為了保持標籤相關性而形成的。那麼,讓我們嘗試使用multi-learn庫來實現它。

# using classifier chains
from skmultilearn.problem_transform import ClassifierChain
from sklearn.naive_bayes import GaussianNB

# initialize classifier chains multi-label classifier
# with a gaussian naive bayes base classifier
classifier = ClassifierChain(GaussianNB())

# train
classifier.fit(X_train, y_train)

# predict
predictions = classifier.predict(X_test)

accuracy_score(y_test,predictions)
0.21212121212121213

我們可以看到,使用這個我們得到了21%的準確率,這比二元關聯要低得多。可能是因為沒有標籤相關性,因為我們已經隨機生成了資料。

4.1.3標籤Powerset(Label Powerset)

在這方面,我們將問題轉化為一個多類問題,一個多類分類器在訓練資料中發現的所有唯一的標籤組合上被訓練。讓我們通過一個例子來理解它。

在這一點上,我們發現x1和x4有相同的標籤。同樣的,x3和x6有相同的標籤。因此,標籤powerset將這個問題轉換為一個單一的多類問題,如下所示。

因此,標籤powerset給訓練集中的每一個可能的標籤組合提供了一個獨特的類。讓我們看看它在Python中的實現。

# using Label Powerset
from skmultilearn.problem_transform import LabelPowerset
from sklearn.naive_bayes import GaussianNB

# initialize Label Powerset multi-label classifier
# with a gaussian naive bayes base classifier
classifier = LabelPowerset(GaussianNB())

# train
classifier.fit(X_train, y_train)

# predict
predictions = classifier.predict(X_test)

accuracy_score(y_test,predictions)
0.5757575757575758

這使我們在之前討論過的三個問題中得到了最高的準確性,57%。唯一的缺點是隨著訓練資料的增加,類的數量也會增加。因此,增加了模型的複雜性,並降低了精確度。

現在,讓我們看一下解決多標籤分類問題的第二種方法。

4.2改編演算法

改編演算法來直接執行多標籤分類,而不是將問題轉化為不同的問題子集。例如,kNN的多標籤版本是由MLkNN表示的。那麼,讓我們快速地在我們的隨機生成的資料集上實現這個。

from skmultilearn.adapt import MLkNN

classifier = MLkNN(k=20)

# train
classifier.fit(X_train, y_train)

# predict
predictions = classifier.predict(X_test)

accuracy_score(y_test,predictions)
0.69

很好,你的測試資料已經達到了69%的準確率。

在一些演算法中,例如隨機森林(Random Forest)和嶺迴歸(Ridge regression),Sci-kit learn提供了多標籤分類的內建支援。因此,你可以直接呼叫它們並預測輸出。

4.3整合方法

整合總是能產生更好的效果。Scikit-Multilearn庫提供不同的組合分類功能,你可以使用它來獲得更好的結果。

5.案例研究

在現實世界中,多標籤分類問題非常普遍。所以,來看看我們能在哪些領域找到它們。

5.1音訊分類

我們知道歌曲會被分類為不同的流派。他們也被分類為,如“放鬆的平靜”,或“悲傷的孤獨”等等情感或情緒的基礎。

5.2影象分類

使用影象的多標籤分類也有廣泛的應用。影象可以被標記為不同的物件、人或概念。

5.3生物資訊學

多標籤分類在生物資訊學領域有很多用途,例如,在酵母資料集中的基因分類。它還被用來使用幾個未標記的蛋白質來預測蛋白質的多重功能。

5.4文字分類

谷歌新聞所做的是,將每條新聞都標記為一個或多個類別,這樣它就會顯示在不同的類別之下。 例如,看看下面的圖片。

同樣的新聞出現在“Technology”,“Latest” 等類別中,因為它已經被分類為不同的標籤。從而使其成為一個多標籤分類問題。