警告 scikit-learn中的所有分類器都可以開箱即用進(jìn)行多分類。除非您想嘗試不同的多類策略,否則無需使用
sklearn.multiclass
模塊。
sklearn.multiclass
模塊通過將 multiclass
和
multilabel
分類問題分解為二分類問題,實(shí)現(xiàn)了meta-estimators(元估計(jì))。 multioutput
regression(多輸出回歸)也被支持。
多分類:具有兩個以上類的分類任務(wù)。每個樣本只能標(biāo)記為一個類。
例如,使用從一組水果圖像中提取的特征進(jìn)行分類,其中每一幅圖像都可能是一個橙子、一個蘋果或一個梨。每個圖像就是一個樣本,并被標(biāo)記為三個可能的類之一。多類分類的假設(shè)是,每個樣本分配給一個標(biāo)簽并且只有一個標(biāo)簽--例如,一個樣本不能同時(shí)是一個梨和一個蘋果。
有效的 multiclass 的
type_of_target
(y
)
表述是:
包含兩個以上離散值的一維數(shù)組或列向量。三個樣本的向量y
的例子:
>>> import numpy as np
>>> y = np.array(['apple', 'pear', 'apple'])
>>> print(y)
['apple' 'pear' 'apple']
稀疏的binary矩陣, 形狀是
(n_samples, n_classes)
, 每行有一個元素, 每一列代表一個類。這里有一個例子, 一個稀疏的binary矩陣,
對應(yīng)于三個樣本的y
,
它的列的順序是橙子、蘋果和梨子:
>>> from scipy import sparse
>>> row_ind = np.array([0, 1, 2])
>>> col_ind = np.array([1, 2, 1])
>>> y_sparse = sparse.csr_matrix((np.ones(3), (row_ind, col_ind)))
>>> print(y_sparse)
(0, 1) 1.0
(1, 2) 1.0
(2, 1) 1.0
多標(biāo)簽分類:分類任務(wù)用n_class中
的
x
標(biāo)簽標(biāo)記每個樣本,其中x
可以包含0到
n_class
。這可以看作是預(yù)測不相互排斥的樣本的屬性。形式上,為每個樣本分配二值化輸出的每個類。正類用1表示,負(fù)類用0或-1表示。因此,它可以與運(yùn)行n_class
二分類任務(wù)相媲美,例如使用
sklearn.multioutput.MultiOutputClassifier
。這種方法獨(dú)立地處理每個標(biāo)簽,而多標(biāo)簽分類器可以同時(shí)處理多個類,同時(shí)考慮它們之間的相關(guān)行為。
例如,與文本文檔或視頻相關(guān)的主題預(yù)測。這些文件或視頻的主題可以是關(guān)于“宗教”、“政治”、“金融”或“教育”其中之一, 也可以是其中的幾個,甚至全部都行 。
多標(biāo)簽 multilabel
y
的有效表示形式要么是稠密要么是稀疏的二值化矩陣, 形狀是(n_samples, n_classes)
。每一列表示一個類。每一行中的
1
表示樣本被標(biāo)記的正類。一個關(guān)于3個樣本的稠密矩陣y
的例子:
>>> y = np.array([[1, 0, 0, 1], [0, 0, 1, 1], [0, 0, 0, 0]])
>>> print(y)
[[1 0 0 1]
[0 0 1 1]
[0 0 0 0]]
稀疏矩陣形式中相同y
的一個例子:
>>> y_sparse = sparse.csr_matrix(y)
>>> print(y_sparse)
(0, 0) 1
(0, 3) 1
(1, 2) 1
(1, 3) 1
多輸出回歸:預(yù)測每個樣本的多個數(shù)值屬性。每個屬性都是一個數(shù)值變量,每個樣本預(yù)測的屬性數(shù)大于或等于2。一些支持多輸出回歸的估計(jì)器比只運(yùn)行n_output
估計(jì)器的速度更快。
例如,利用在某一地點(diǎn)獲得的數(shù)據(jù),以度為單位預(yù)測風(fēng)速和風(fēng)向。每個樣本都是在一個地點(diǎn)獲得的數(shù)據(jù),每個樣本的風(fēng)速和風(fēng)向都將被輸出。
multioutput 多輸出
y
的一個有效表示是浮點(diǎn)數(shù)組成的形狀是 (n_samples, n_classes)
的稠密矩陣。連續(xù)變量的一種列的合并。3個樣本的
y
示例:
>>> y = np.array([[31.4, 94], [40.5, 109], [25.0, 30]])
>>> print(y)
[[ 31.4 94. ]
[ 40.5 109. ]
[ 25. 30. ]]
多輸出-多類分類(也稱為多任務(wù)分類):用一組非二值化屬性標(biāo)記每個樣本的分類任務(wù)。屬性的數(shù)量和類的數(shù)量都大于2。因此,單個估計(jì)器處理多個聯(lián)合分類任務(wù)。這既是對只考慮二值屬性的多標(biāo)簽分類任務(wù)的推廣,也是對多類分類任務(wù)的推廣,其中只考慮一個屬性。
例如,對一組水果圖像的屬性“水果種類”和“顏色”進(jìn)行分類。屬性“水果種類”有可能的類別有:“蘋果”,“梨”和“橙子”。屬性“顏色”有可能的類別有:“綠色”、“紅色”、“黃色”和“橙色”。每個樣本都是一個水果的圖像,兩個屬性的標(biāo)簽都是輸出的,每個標(biāo)簽都是相應(yīng)屬性的可能類別之一。
多輸出 multioutput
y
的一個有效表示類標(biāo)簽形狀是(n_samples, n_classes)
的稠密矩陣。一維的多類變量的一種列的合并。3個樣本的
y
示例:
>>> y = np.array([['apple', 'green'], ['orange', 'orange'], ['pear', 'green']])
>>> print(y)
[['apple' 'green']
['orange' 'orange']
['pear' 'green']]
注意,所有處理多輸出-多類(也稱為多任務(wù)分類)任務(wù)的分類器,都支持將多標(biāo)簽分類任務(wù)作為特例。多任務(wù)分類類似于具有不同模型構(gòu)想的多輸出分類任務(wù)。有關(guān)更多信息,請參見相關(guān)的估值器文檔。
所有scikit-learn分類器都能夠進(jìn)行多類分類,但是
sklearn.multiclass
提供的 meta-estimators 允許改變它們處理兩個以上類的方式,因?yàn)檫@可能會影響分類器的性能(無論是泛化誤差還是所需的計(jì)算資源)。
摘要
以下是 scikit-learn按策略分組支持的分類器總結(jié);如果要使用這些方法之一,則不需要該類中的元估計(jì)器,除非您希望使用自定義的多類行為:
固有的多類分類器:
sklearn.naive_bayes.BernoulliNB
sklearn.tree.DecisionTreeClassifier
sklearn.tree.ExtraTreeClassifier
sklearn.ensemble.ExtraTreesClassifier
sklearn.naive_bayes.GaussianNB
sklearn.neighbors.KNeighborsClassifier
sklearn.semi_supervised.LabelPropagation
sklearn.semi_supervised.LabelSpreading
sklearn.discriminant_analysis.LinearDiscriminantAnalysis
sklearn.svm.LinearSVC
(setting
multi_class=”crammer_singer”)sklearn.linear_model.LogisticRegression
(setting
multi_class=”multinomial”)sklearn.linear_model.LogisticRegressionCV
(setting
multi_class=”multinomial”)sklearn.neural_network.MLPClassifier
sklearn.neighbors.NearestCentroid
sklearn.discriminant_analysis.QuadraticDiscriminantAnalysis
sklearn.neighbors.RadiusNeighborsClassifier
sklearn.ensemble.RandomForestClassifier
sklearn.linear_model.RidgeClassifier
sklearn.linear_model.RidgeClassifierCV
One-Vs-One 的多分類:
sklearn.svm.NuSVC
sklearn.svm.SVC
.sklearn.gaussian_process.GaussianProcessClassifier
(setting
multi_class = “one_vs_one”)One-Vs-The-Rest 的多分類:
sklearn.ensemble.GradientBoostingClassifier
sklearn.gaussian_process.GaussianProcessClassifier
(setting
multi_class = “one_vs_rest”)sklearn.svm.LinearSVC
(setting
multi_class=”ovr”)sklearn.linear_model.LogisticRegression
(setting
multi_class=”ovr”)sklearn.linear_model.LogisticRegressionCV
(setting
multi_class=”ovr”)sklearn.linear_model.SGDClassifier
sklearn.linear_model.Perceptron
sklearn.linear_model.PassiveAggressiveClassifier
支持多標(biāo)簽:
sklearn.tree.DecisionTreeClassifier
sklearn.tree.ExtraTreeClassifier
sklearn.ensemble.ExtraTreesClassifier
sklearn.neighbors.KNeighborsClassifier
sklearn.neural_network.MLPClassifier
sklearn.neighbors.RadiusNeighborsClassifier
sklearn.ensemble.RandomForestClassifier
sklearn.linear_model.RidgeClassifierCV
支持多類多輸出:
警告:目前,
sklearn.metrics
中沒有評估方法能夠支持多輸出多類分類任務(wù)。
在多標(biāo)簽學(xué)習(xí)中,二分類任務(wù)的聯(lián)合集合伴隨標(biāo)簽的二值化數(shù)組表示:每個樣本是一個形狀為(n_sames,n_class)的數(shù)組的一行, 該行只有兩個值:舉一個例子, 即非零元素,對應(yīng)于標(biāo)簽的子集。形如np.array([[1, 0, 0], [0, 1, 1], [0, 0, 0]])
的數(shù)組在第一個樣本中表示屬于標(biāo)簽0,第二個樣本中表示屬于標(biāo)簽1和2,在第三個樣本中沒有屬于任何標(biāo)簽。
通過一組標(biāo)簽集合來產(chǎn)生多標(biāo)簽數(shù)據(jù)可能更為直觀。 MultiLabelBinarizer
轉(zhuǎn)換器可用于標(biāo)簽集合和指示格式集合之間的轉(zhuǎn)換。
>>> from sklearn.preprocessing import MultiLabelBinarizer
>>> y = [[2, 3, 4], [2], [0, 1, 3], [0, 1, 2, 3, 4], [0, 1, 2]]
>>> MultiLabelBinarizer().fit_transform(y)
array([[0, 0, 1, 1, 1],
[0, 0, 1, 0, 0],
[1, 1, 0, 1, 0],
[1, 1, 1, 1, 1],
[1, 1, 1, 0, 0]])
這種策略,也稱為one-vs-all,是在
OneVsRestClassifier
中實(shí)現(xiàn)的。該策略包括為每個類擬合一個分類器。對于每個分類器,將一個類與其他所有類進(jìn)行分類擬合的。除了它的計(jì)算效率(只需要n_classes
個分類器)之外,這種方法的一個優(yōu)點(diǎn)是它的可解釋性。由于每個類都由一個分類器表示,并且只有一個分類器,因此可以通過檢查其對應(yīng)的分類器來獲得有關(guān)該類的知識。這是最常用的策略,也是一個公平的默認(rèn)選擇。
下面是使用 OVR 進(jìn)行多類學(xué)習(xí)的一個例子:
>>> from sklearn import datasets
>>> from sklearn.multiclass import OneVsRestClassifier
>>> from sklearn.svm import LinearSVC
>>> X, y = datasets.load_iris(return_X_y=True)
>>> OneVsRestClassifier(LinearSVC(random_state=0)).fit(X, y).predict(X)
array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 1, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2])
OneVsRestClassifier
還支持多標(biāo)簽分類。要使用此特性,向分類器提供一個指示矩陣,其中單元格[i,j]表示樣本
i 中的第 j 個標(biāo)簽。
示例 |
---|
多標(biāo)簽分類 |
OneVsOneClassifier
是對每一對類構(gòu)造一個分類器。在預(yù)測時(shí),選擇得票最多的類別。在票數(shù)相等的兩個類別中,它選擇具有最高總分類置信度的類別,方法是對由底層二分類器計(jì)算的對分類置信度進(jìn)行求和。
由于它需要擬合n_classes * (n_classes - 1) / 2
個分類器,這種方法通常比one-vs-the-rest要慢,原因就在于其復(fù)雜度O(n_classes^2)
。然而,這個方法也有優(yōu)點(diǎn),比如說是在沒有很好的縮放 n_samples
數(shù)據(jù)的核方法中。這是因?yàn)槊總€單獨(dú)的學(xué)習(xí)問題只涉及一小部分?jǐn)?shù)據(jù),而對于一個one-vs-the-rest,完整的數(shù)據(jù)集將會被使用
n_classes
次。決策函數(shù)是one-versus-one分類器單調(diào)變換的結(jié)果。
下面是使用OvO進(jìn)行多類學(xué)習(xí)的一個例子:
>>> from sklearn import datasets
>>> from sklearn.multiclass import OneVsOneClassifier
>>> from sklearn.svm import LinearSVC
>>> X, y = datasets.load_iris(return_X_y=True)
>>> OneVsOneClassifier(LinearSVC(random_state=0)).fit(X, y).predict(X)
array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 2, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2])
參考
“Pattern Recognition and Machine Learning. Springer”, Christopher M. Bishop, page 183, (First Edition)
基于Output-code的策略與 one-vs-the-rest 和 one-vs-one 的策略有很大的不同。使用這些策略,每個類都表示在歐氏空間中,其中每個維度只能是0或1。換句話說,每個類都由二進(jìn)制代碼(0和1的數(shù)組)表示。跟蹤每個類的位置/代碼的矩陣稱為代碼簿( code book)。代碼大小是上述空間的維數(shù)。直觀地說,每個類都應(yīng)該盡可能地用唯一的代碼來表示,并且應(yīng)該設(shè)計(jì)一本好的code book來優(yōu)化分類的準(zhǔn)確性。在這個實(shí)現(xiàn)中,我們只使用[3]中提倡的隨機(jī)生成的code book,盡管將來可能會添加更詳細(xì)的方法。
在訓(xùn)練的時(shí)候,在 code book 中每位上訓(xùn)練一個二分類器。在預(yù)測時(shí),使用分類器在類空間中投影新的點(diǎn),并選擇最靠近該點(diǎn)的類。
在 OutputCodeClassifier
中,
code_size
屬性允許用戶控制將要使用的分類器的數(shù)量。它是類別總數(shù)的百分比。
在0到1之間的數(shù)字需要的分類器比 one-vs-the-rest 少。理論上,log2(n_classes) / n_classes
足以明確地表示每個類。然而,在實(shí)踐中,由于
log2(n_classes)
比n_class小得多,所以它可能不會帶來很好的準(zhǔn)確性。
比 1 大的數(shù)字比 one-vs-the-rest 需要更多的分類器。在這種情況下,一些分類器在理論上會糾正其他分類器的錯誤,因此命名為 “error-correcting” 。然而在實(shí)際上這通常不會發(fā)生,因?yàn)樵S多分類器的錯誤通常意義上來說是相關(guān)的。error-correcting output codes 和 bagging 有一個相似的作用效果。
下面是使用Output-Codes進(jìn)行多類學(xué)習(xí)的一個例子:
>>> from sklearn import datasets
>>> from sklearn.multiclass import OutputCodeClassifier
>>> from sklearn.svm import LinearSVC
>>> X, y = datasets.load_iris(return_X_y=True)
>>> clf = OutputCodeClassifier(LinearSVC(random_state=0),
... code_size=2, random_state=0)
>>> clf.fit(X, y).predict(X)
array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1,
1, 2, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 2, 2, 2, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 1, 1, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2])
參考
“Solving multiclass learning problems via error-correcting output codes”, Dietterich T., Bakiri G., Journal of Artificial Intelligence Research 2, 1995. [3] “The error coding method and PICTs”, James G., Hastie T., Journal of Computational and Graphical statistics 7, 1998.
“The Elements of Statistical Learning”, Hastie T., Tibshirani R., Friedman J., page 606 (second-edition) 2008.
多輸出回歸支持 MultiOutputRegressor
可以被添加到任何回歸器中。這個策略包括對每個目標(biāo)擬合一個回歸器。因?yàn)槊恳粋€目標(biāo)可以被一個回歸器精確地表示,通過檢查對應(yīng)的回歸器,可以獲取關(guān)于目標(biāo)的信息。
因?yàn)?MultiOutputRegressor
對于每一個目標(biāo)可以訓(xùn)練出一個回歸器,所以它無法利用目標(biāo)之間的相關(guān)度信息。
下面是多輸出回歸的一個例子:
>>> from sklearn.datasets import make_regression
>>> from sklearn.multioutput import MultiOutputRegressor
>>> from sklearn.ensemble import GradientBoostingRegressor
>>> X, y = make_regression(n_samples=10, n_targets=3, random_state=1)
>>> MultiOutputRegressor(GradientBoostingRegressor(random_state=0)).fit(X, y).predict(X)
array([[-154.75474165, -147.03498585, -50.03812219],
[ 7.12165031, 5.12914884, -81.46081961],
[-187.8948621 , -100.44373091, 13.88978285],
[-141.62745778, 95.02891072, -191.48204257],
[ 97.03260883, 165.34867495, 139.52003279],
[ 123.92529176, 21.25719016, -7.84253 ],
[-122.25193977, -85.16443186, -107.12274212],
[ -30.170388 , -94.80956739, 12.16979946],
[ 140.72667194, 176.50941682, -17.50447799],
[ 149.37967282, -81.15699552, -5.72850319]])
多輸出分類支持能夠添加到任何帶有 MultiOutputClassifier
標(biāo)志的分類器中。這種方法為每一個目標(biāo)訓(xùn)練一個分類器。
這就允許產(chǎn)生多目標(biāo)變量分類器。這種類的目的是擴(kuò)展評估器用于評估一系列目標(biāo)函數(shù) (f1,f2,f3…,fn) ,在單個X預(yù)測矩陣上訓(xùn)練以預(yù)測一系列響應(yīng) (y1,y2,y3…,yn)。
下面是多輸出分類的一個例子:
>>> from sklearn.datasets import make_classification
>>> from sklearn.multioutput import MultiOutputClassifier
>>> from sklearn.ensemble import RandomForestClassifier
>>> from sklearn.utils import shuffle
>>> import numpy as np
>>> X, y1 = make_classification(n_samples=10, n_features=100, n_informative=30, n_classes=3, random_state=1)
>>> y2 = shuffle(y1, random_state=1)
>>> y3 = shuffle(y1, random_state=2)
>>> Y = np.vstack((y1, y2, y3)).T
>>> n_samples, n_features = X.shape # 10,100
>>> n_outputs = Y.shape[1] # 3
>>> n_classes = 3
>>> forest = RandomForestClassifier(random_state=1)
>>> multi_target_forest = MultiOutputClassifier(forest, n_jobs=-1)
>>> multi_target_forest.fit(X, Y).predict(X)
array([[2, 2, 0],
[1, 2, 1],
[2, 1, 0],
[0, 0, 2],
[0, 2, 1],
[0, 0, 2],
[1, 1, 0],
[1, 1, 1],
[0, 0, 2],
[2, 0, 0]])
Classifier chains(參見ClassifierChain
)是一種將多個二分類器組合成一個能夠利用目標(biāo)之間相關(guān)性的單一多標(biāo)簽?zāi)P偷姆椒ā?/p>
對于有N個類的多標(biāo)簽分類問題,N 個二分類器被分配一個介于0到N-1之間的整數(shù)。這些整數(shù)定義了鏈中模型的順序。然后,每個分類器在可用的訓(xùn)練數(shù)據(jù)和真實(shí)的類標(biāo)簽上訓(xùn)練, 模型被分配了較小的數(shù)值。
當(dāng)預(yù)測時(shí),真正的標(biāo)簽將不可用。相反,每個模型的預(yù)測被傳遞到鏈中的后續(xù)模型,作為特征使用。
顯然,鏈的順序很重要。鏈中的第一個模型沒有關(guān)于其他標(biāo)簽的信息,而鏈中的最后一個模型具有指示所有其他標(biāo)簽存在的特性。一般情況下,人們不知道模型在鏈中的最優(yōu)排序,所以通常許多隨機(jī)有序鏈?zhǔn)呛线m的,它們的預(yù)測是平均了的。
參考
Jesse Read, Bernhard Pfahringer, Geoff Holmes, Eibe Frank,
“Classifier Chains for Multi-label Classification”, 2009.
回歸鏈(參見RegressorChain
)類似于分類鏈,它是將多個回歸合并成一個能夠利用目標(biāo)間相關(guān)性的單一多目標(biāo)模型的一種方法。
更多建議: