sklearn:multiclass與multilabel遣蚀,one-vs-rest與one-vs-one
針對多類問題的分類中断楷,具體講有兩種,即multiclass classification和multilabel classification奶赠。multiclass是指分類任務中包含不止一個類別時近刘,每條數(shù)據(jù)僅僅對應其中一個類別,不會對應多個類別橘沥。multilabel是指分類任務中不止一個分類時窗轩,每條數(shù)據(jù)可能對應不止一個類別標簽,例如一條新聞座咆,可以被劃分到多個板塊痢艺。
無論是multiclass,還是multilabel介陶,做分類時都有兩種策略堤舒,一個是one-vs-?the-rest(one-vs-all),一個是one-vs-one哺呜。
在one-vs-all策略中舌缤,假設有n個類別,那么就會建立n個二項分類器某残,每個分類器針對其中一個類別和剩余類別進行分類国撵。進行預測時,利用這n個二項分類器進行分類玻墅,得到數(shù)據(jù)屬于當前類的概率介牙,選擇其中概率最大的一個類別作為最終的預測結果。
在one-vs-one策略中椭豫,同樣假設有n個類別耻瑟,則會針對兩兩類別建立二項分類器,得到k=n*(n-1)/2個分類器赏酥。對新數(shù)據(jù)進行分類時喳整,依次使用這k個分類器進行分類,每次分類相當于一次投票裸扶,分類結果是哪個就相當于對哪個類投了一票框都。在使用全部k個分類器進行分類后,相當于進行了k次投票呵晨,選擇得票最多的那個類作為最終分類結果?魏保。
?在scikit-learn框架中,分別有sklearn.multiclass.OneVsRestClassifier和sklearn.multiclass.OneVsOneClassifier完成兩種策略摸屠,使用過程中要指明使用的二項分類器是什么谓罗。另外在進行mutillabel分類時,訓練數(shù)據(jù)的類別標簽Y應該是一個矩陣季二,第[i,j]個元素指明了第j個類別標簽是否出現(xiàn)在第i個樣本數(shù)據(jù)中檩咱。例如揭措,np.array([[1, 0, 0], [0, 1, 1], [0, 0, 0]]),這樣的一條數(shù)據(jù)刻蚯,指明針對第一條樣本數(shù)據(jù)绊含,類別標簽是第0個類,第二條數(shù)據(jù)炊汹,類別標簽是第1躬充,第2個類,第三條數(shù)據(jù)讨便,沒有類別標簽充甚。有時訓練數(shù)據(jù)中,類別標簽Y可能不是這樣的可是霸褒,而是類似[[2, 3, 4], [2], [0, 1, 3], [0, 1, 2, 3, 4], [0, 1, 2]]這樣的格式津坑,每條數(shù)據(jù)指明了每條樣本數(shù)據(jù)對應的類標號。這就需要將Y轉(zhuǎn)換成矩陣的形式傲霸,sklearn.preprocessing.MultiLabelBinarizer提供了這個功能。
以Logistic為例子
from sklearn.linear_model import LogisticRegression
from sklearn.preprocessing import StandardScaler
from sklearn.cross_validation import train_test_split
import numpy as np
import matplotlib
from sklearn import datasets
import matplotlib.pyplot as plt
from sklearn.metrics import accuracy_score
from matplotlib.colors import ListedColormap
iris = datasets.load_iris()
# print iris
X = iris.data[:, [2, 3]]
y = iris.target
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=0)
sc = StandardScaler()
sc.fit(X_train)
X_train_std = sc.transform(X_train)
X_test_std = sc.transform(X_test)
'''sc.scale_標準差, sc.mean_平均值, sc.var_方差'''
lr = LogisticRegression(C=10000.0, random_state=0)
lr.fit(X_train_std, y_train)
print '系數(shù):',lr.coef_,lr.intercept_
# 預測
#print lr.intercept_
print 'phiz', 1.0/(1+np.e**(-(np.dot(lr.coef_, X_test_std[0])+lr.intercept_)))
print 'decision', lr.decision_function(X_test_std[0])
print 'phiz',1.0/(1+np.e**(-lr.decision_function(X_test_std[0])))
y_pred = lr.predict(X_test_std)
print '測試集',X_test_std[0]
print '預測值', y_pred[0]
print '預測概率',lr.predict_proba(X_test_std[0])
print('Misclassified samples: %d' % (y_test != y_pred).sum())
print('Accuracy: %.2f' % accuracy_score(y_test, y_pred))
輸出
系數(shù): [[-9.38725178 -8.62196104]
[ 2.54760621 -2.34616582]
[ 9.8260878 6.51345035]] [-12.237882 -0.89485178 -9.10527128]
phiz [ 1.41131020e-14 6.71679171e-02 9.99537323e-01]
decision [[-31.89167281 -2.6310295 7.67801924]]
phiz [[ 1.41131020e-14 6.71679171e-02 9.99537323e-01]]
測試集 [ 0.70793846 1.50872803]
預測值 2
預測概率 [[ 1.32305547e-14 6.29676452e-02 9.37032355e-01]]
Misclassified samples: 1
Accuracy: 0.98
使用decision_function函數(shù)算出的概率[ 1.41131020e-14 6.71679171e-02 9.99537323e-01]與我們使用邏輯函數(shù)算出的概率一樣的但是與算出的預測[ 1.32305547e-14 6.29676452e-02 9.37032355e-01]]是不符的眉反,sklearn是怎么算出來的呢昙啄,看下面
a = [ 1.41131020e-14, 6.71679171e-02, 9.99537323e-01]
a = np.array(a)
print a/a.sum()
輸出
[ 1.32305547e-14 6.29676452e-02 9.37032355e-01]
那么再看看系數(shù)三組值,sklearn默認是用one-vs-rest方法
看下面代碼,只要把目標值調(diào)整一下寸五,剩下兩類
from sklearn.linear_model import LogisticRegression
from sklearn.preprocessing import StandardScaler
from sklearn.cross_validation import train_test_split
import numpy as np
import matplotlib
from sklearn import datasets
import matplotlib.pyplot as plt
from sklearn.metrics import accuracy_score
from matplotlib.colors import ListedColormap
iris = datasets.load_iris()
# print iris
X = iris.data[:, [2, 3]]
y = iris.target
for i in range(len(y)):
if y[i] == 1:
y[i] = 0
if y[i] == 2:
y[i] = 1
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=0)
sc = StandardScaler()
sc.fit(X_train)
X_train_std = sc.transform(X_train)
X_test_std = sc.transform(X_test)
'''sc.scale_標準差, sc.mean_平均值, sc.var_方差'''
lr = LogisticRegression(C=10000.0, random_state=0)
lr.fit(X_train_std, y_train)
print '系數(shù):',lr.coef_,lr.intercept_
# 預測
#print lr.intercept_
print 'phiz', 1.0/(1+np.e**(-(np.dot(lr.coef_, X_test_std[0])+lr.intercept_)))
print 'decision', lr.decision_function(X_test_std[0])
print 'phiz',1.0/(1+np.e**(-lr.decision_function(X_test_std[0])))
y_pred = lr.predict(X_test_std)
print '測試集',X_test_std[0]
print '預測值', y_pred[0]
print '預測概率',lr.predict_proba(X_test_std[0])
print('Misclassified samples: %d' % (y_test != y_pred).sum())
print('Accuracy: %.2f' % accuracy_score(y_test, y_pred))
系數(shù): [[ 9.8260878 6.51345035]] [-9.10527128]
phiz [ 0.99953732]
decision [ 7.67801924]
phiz [ 0.99953732]
測試集 [ 0.70793846 1.50872803]
預測值 1
預測概率 [[ 4.62676696e-04 9.99537323e-01]]
Misclassified samples: 1
Accuracy: 0.98