one-vs-rest與one-vs-one以及sklearn的實現

sklearn:multiclass與multilabel,one-vs-rest與one-vs-one

針對多類問題的分類中,具體講有兩種,即multiclass classification和multilabel classification。multiclass是指分類任務中包含不止一個類別時,每條數據僅僅對應其中一個類別,不會對應多個類別。multilabel是指分類任務中不止一個分類時,每條數據可能對應不止一個類別標簽,例如一條新聞,可以被劃分到多個板塊。
無論是multiclass,還是multilabel,做分類時都有兩種策略,一個是one-vs-?the-rest(one-vs-all),一個是one-vs-one。

在one-vs-all策略中,假設有n個類別,那么就會建立n個二項分類器,每個分類器針對其中一個類別和剩余類別進行分類。進行預測時,利用這n個二項分類器進行分類,得到數據屬于當前類的概率,選擇其中概率最大的一個類別作為最終的預測結果。

在one-vs-one策略中,同樣假設有n個類別,則會針對兩兩類別建立二項分類器,得到k=n*(n-1)/2個分類器。對新數據進行分類時,依次使用這k個分類器進行分類,每次分類相當于一次投票,分類結果是哪個就相當于對哪個類投了一票。在使用全部k個分類器進行分類后,相當于進行了k次投票,選擇得票最多的那個類作為最終分類結果?。

?在scikit-learn框架中,分別有sklearn.multiclass.OneVsRestClassifier和sklearn.multiclass.OneVsOneClassifier完成兩種策略,使用過程中要指明使用的二項分類器是什么。另外在進行mutillabel分類時,訓練數據的類別標簽Y應該是一個矩陣,第[i,j]個元素指明了第j個類別標簽是否出現在第i個樣本數據中。例如,np.array([[1, 0, 0], [0, 1, 1], [0, 0, 0]]),這樣的一條數據,指明針對第一條樣本數據,類別標簽是第0個類,第二條數據,類別標簽是第1,第2個類,第三條數據,沒有類別標簽。有時訓練數據中,類別標簽Y可能不是這樣的可是,而是類似[[2, 3, 4], [2], [0, 1, 3], [0, 1, 2, 3, 4], [0, 1, 2]]這樣的格式,每條數據指明了每條樣本數據對應的類標號。這就需要將Y轉換成矩陣的形式,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 '系數:',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))

輸出

系數: [[-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函數算出的概率[ 1.41131020e-14 6.71679171e-02 9.99537323e-01]與我們使用邏輯函數算出的概率一樣的但是與算出的預測[ 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]

那么再看看系數三組值,sklearn默認是用one-vs-rest方法
看下面代碼,只要把目標值調整一下,剩下兩類

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 '系數:',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))

系數: [[ 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
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 230,825評論 6 546
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 99,814評論 3 429
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事?!?“怎么了?”我有些...
    開封第一講書人閱讀 178,980評論 0 384
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 64,064評論 1 319
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,779評論 6 414
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 56,109評論 1 330
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 44,099評論 3 450
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 43,287評論 0 291
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,799評論 1 338
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,515評論 3 361
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,750評論 1 375
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,221評論 5 365
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,933評論 3 351
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,327評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,667評論 1 296
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,492評論 3 400
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,703評論 2 380

推薦閱讀更多精彩內容