6

有人可以請解釋(例如可能)什麼是區別OneVsRestClassifierMultiOutputClassifier在scikit學習?scikit學習中的OneVsRestClassifier和MultiOutputClassifier有什麼區別?

我讀過的文檔,我已經明白,我們使用:

  • OneVsRestClassifier - 當我們想要做的多類或者多標記分類和它的戰略包括裝修每類一個分類的。對於每個分類器,該類適用於所有其他類。 (這很清楚,這意味着多類/多標籤分類問題可以分解爲多個二元分類問題)。
  • MultiOutputClassifier - 當我們想要做的多目標分類(這是什麼?)和它的戰略包括擬合每個目標(什麼目標的意思嗎?)

我一個分類已經使用OneVsRestClassifier進行多標籤分類,我可以理解它是如何工作的,但是後來我發現了MultiOutputClassifier,並且無法理解它與OneVsRestClassifier的工作方式有何不同。

回答

9

爲了更好地說明的差別,讓我們假設你的目標是這樣的分類問題,分爲四個不同的互斥類,即'Python''Java''C++''Other language'的。讓我們考慮如下,你有一個數據集的短短半年SO問題形成的,這些問題的類標籤存儲在陣列y

import numpy as np 
y = np.asarray(['Java', 'C++', 'Other language', 'Python', 'C++', 'Python']) 

上述情況通常被稱爲多類分類。爲了適應分類器並通過scikit-learn庫驗證模型,您需要將文本類標籤轉換爲數字標籤。爲了實現這個目標,你可以使用LabelEncoder

from sklearn.preprocessing import LabelEncoder 
le = LabelEncoder() 
y_numeric = le.fit_transform(y) 

這是怎麼了你的數據集的標籤編碼:

In [220]: y_numeric 
Out[220]: array([1, 0, 2, 3, 0, 3], dtype=int64) 

其中這些數字表示以下數組的索引:

In [221]: le.classes_ 
Out[221]: 
array(['C++', 'Java', 'Other language', 'Python'], 
     dtype='|S14') 

現在讓我們假設您希望使用0123池進行這樣的多類分類二元分類器,是n_classes不同類的數量。這些二元分類器中的每一個都會決定某個項目是否屬於特定類別。在這種情況下,您不能將類標籤編碼爲從0n_classes - 1的整數,您需要改爲創建二維指示符矩陣。考慮樣本n屬於k。然後,指標矩陣的[n, k]條目是1,並且行n中的其餘元素是0。重要的是要注意,如果這些類不是互斥的,那麼連續可以有多個1。這種方法被命名爲多標記分類並且可以通過MultiLabelBinarizer可以輕鬆實現:

from sklearn.preprocessing import MultiLabelBinarizer 
mlb = MultiLabelBinarizer() 
y_indicator = mlb.fit_transform(y[:, None]) 

的指標看起來是這樣的:

In [225]: y_indicator 
Out[225]: 
array([[0, 1, 0, 0], 
     [1, 0, 0, 0], 
     [0, 0, 1, 0], 
     [0, 0, 0, 1], 
     [1, 0, 0, 0], 
     [0, 0, 0, 1]]) 

和列數其中1的實際上是這個數組的索引:

In [226]: mlb.classes_ 
Out[226]: array(['C++', 'Java', 'Other language', 'Python'], dtype=object) 

如果您想要根據兩個不同的標準同時對特定的SO問題進行分類,例如語言和應用程序,該怎麼辦?在這種情況下,您打算執行多輸出分類。爲了簡單起見,我將只考慮三個應用程序類別,即'Computer Vision','Speech Processing'和'Other application'。數據集的標籤數組應爲2維:

y2 = np.asarray([['Java', 'Computer Vision'], 
       ['C++', 'Speech Recognition'], 
       ['Other language', 'Computer Vision'], 
       ['Python', 'Other Application'], 
       ['C++', 'Speech Recognition'], 
       ['Python', 'Computer Vision']]) 

同樣,我們需要將文本類標籤轉換爲數字標籤。據我所知,該功能尚未在scikit-learn中實現,因此您需要編寫自己的代碼。 This thread描述了一些巧妙的方法來做到這一點,但對於這篇文章的目的,下面的一行代碼就足夠了:

y_multi = np.vstack((le.fit_transform(y2[:, i]) for i in range(y2.shape[1]))).T 

編碼的標籤是這樣的:

In [229]: y_multi 
Out[229]: 
array([[1, 0], 
     [0, 2], 
     [2, 0], 
     [3, 1], 
     [0, 2], 
     [3, 0]], dtype=int64) 

和的含義每列中的值可以從以下陣列推斷出:

In [230]: le.fit(y2[:, 0]).classes_ 
Out[230]: 
array(['C++', 'Java', 'Other language', 'Python'], 
     dtype='|S18') 

In [231]: le.fit(y2[:, 1]).classes_ 
Out[231]: 
array(['Computer Vision', 'Other Application', 'Speech Recognition'], 
     dtype='|S18')