![](/img/trans.png)
[英]Tuning hyper-parameters in SVM OVO and OVA for multiclass classification
[英]SVM-OVO vs SVM-OVA in a very basic example
為了了解 SVM-OVR (One-Vs-Rest) 的工作原理,我測試了以下代碼:
import matplotlib.pyplot as plt
import numpy as np
from sklearn.svm import SVC
x = np.array([[1,1.1],[1,2],[2,1]])
y = np.array([0,100,250])
classifier = SVC(kernel='linear', decision_function_shape='ovr')
classifier.fit(x,y)
print(classifier.predict([[1,2]]))
print(classifier.decision_function([[1,2]]))
輸出是:
[100]
[[ 1.05322128 2.1947332 -0.20488118]]
這意味着樣本[1,2]
在第100
類中被正確預測(這是很明顯的,因為[1,2]
也用於訓練)。
但是,讓我們來看看決策函數。 SVM-OVA 應該生成三個分類器,即三行。 第一個將class1
與class2 U class3
,第二個將class2
與class1 U class3
,第三個將class3
與class1 U class2
分開。 我最初的目標正是了解決策函數值的含義。 我知道正值意味着樣本在平面的右側,反之亦然; 並且該值越大,則超平面(在本例中為一條線)之間的樣本距離越大,則樣本屬於該類的置信度越大。
但是,由於兩個決策函數值都是正值,因此顯然有些錯誤,而假設只有正確的類應該報告正決策函數(因為預測值也是訓練樣本)。 出於這個原因,我試圖繪制分隔線。
fig, ax = plt.subplots()
ax.scatter(x[:, 0], x[:, 1], c=y, cmap=plt.cm.winter, s=25)
# create a mesh to plot in
x_min, x_max = x[:, 0].min() - 1, x[:, 0].max() + 1
y_min, y_max = x[:, 1].min() - 1, x[:, 1].max() + 1
xx2, yy2 = np.meshgrid(np.arange(x_min, x_max, .2),np.arange(y_min, y_max, .2))
Z = classifier.predict(np.c_[xx2.ravel(), yy2.ravel()])
Z = Z.reshape(xx2.shape)
ax.contourf(xx2, yy2, Z, cmap=plt.cm.winter, alpha=0.3)
w = classifier.coef_[0]
a = -w[0] / w[1]
xx = np.linspace(-5, 5)
yy = a * xx - (classifier.intercept_[0]) / w[1]
ax.plot(xx,yy)
w = classifier.coef_[1]
a = -w[0] / w[1]
xx = np.linspace(-5, 5)
yy = a * xx - (classifier.intercept_[1]) / w[1]
ax.plot(xx,yy)
w = classifier.coef_[2]
a = -w[0] / w[1]
xx = np.linspace(-5, 5)
yy = a * xx - (classifier.intercept_[2]) / w[1]
ax.plot(xx,yy)
ax.axis([x_min, x_max,y_min, y_max])
plt.show()
這是我得到的:
驚喜:確實,當計算 OVO(一對一)策略時,那些分隔線代表超平面:實際上,您可以注意到這些線將class1
與class2
、 class2
與class3
以及class1
與class3
。
我還嘗試添加一個類:
import matplotlib.pyplot as plt
import numpy as np
from sklearn.svm import SVC
x = np.array([[1,1.1],[1,2],[2,1],[3,3]])
y = np.array([0,100,250, 500])
classifier = SVC(kernel='linear', decision_function_shape='ovr')
classifier.fit(x,y)
發生的情況是,表示決策函數的向量的長度等於 4(根據 OVA 策略),但又生成了 6 行(好像我已經實施了 OVO 策略)。
classifier.decision_function([[1,2]])
[[ 2.14182753 3.23543808 0.83375105 -0.22753309]]
classifier.coef_
array([[ 0. , -0.9 ],
[-1. , 0.1 ],
[-0.52562421, -0.49934299],
[-1. , 1. ],
[-0.8 , -0.4 ],
[-0.4 , -0.8 ]])
我的最后一個問題:決策函數值代表什么? 為什么即使在應用 OVA 策略時,也會生成n(n-1)/2
超平面,而不是n
個?
關鍵是,默認情況下,SVM 確實實現了 OvO 策略(請參閱此處以供參考)。
SVC 和 NuSVC 實現了多類分類的“一對一”方法。
同時,默認情況下(即使在您的情況下您已經明確說明) decision_function_shape
設置為'ovr'
。
“為了提供與其他分類器一致的接口,decision_function_shape 選項允許將“一對一”分類器的結果單調轉換為形狀的“一對一”決策函數(n_samples,n_classes)。
實施 OvO 策略的原因是 SVM 算法隨着訓練集的大小而擴展性很差(並且使用 OvO 策略,每個分類器僅在與它必須區分的類別相對應的訓練集部分上進行訓練)。 原則上,你可以強制SVM分類通過實例來實現的OVA戰略OneVsRestClassifier
,如:
ovr_svc = OneVsRestClassifier(SVC(kernel='linear'))
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.