SVC sigmoid 内核无法正常工作

SVC sigmoid kernel is not working properly

我正在使用 sklearn 和 SVC 在 iris 数据上测试带有 sigmoid 内核的 SVM。它的性能极差,精度为 25%。我使用完全相同的代码并将功能规范化为 https://towardsdatascience.com/a-guide-to-svm-parameter-tuning-8bfe6b8a452c(sigmoid 部分),这应该会显着提高性能。然而,我无法重现他的结果,准确率只增加到 33%。

使用其他内核(例如线性内核)产生了良好的结果(准确度为 82 %)。 SVC(kernel = 'sigmoid') 函数中是否存在问题?

Python 重现问题的代码:


##sigmoid iris example
from sklearn import datasets 
iris = datasets.load_iris()
from sklearn.svm import SVC 

sepal_length = iris.data[:,0] 
sepal_width = iris.data[:,1]

#assessing performance of sigmoid SVM
clf = SVC(kernel='sigmoid') 
clf.fit(np.c_[sepal_length, sepal_width], iris.target) 
pr=clf.predict(np.c_[sepal_length, sepal_width])
pd.DataFrame(classification_report(iris.target, pr, output_dict=True))

from sklearn.metrics.pairwise import sigmoid_kernel 
sigmoid_kernel(np.c_[sepal_length, sepal_width]) 

#normalizing features
from sklearn.preprocessing import normalize 
sepal_length_norm = normalize(sepal_length.reshape(1, -1))[0] 
sepal_width_norm = normalize(sepal_width.reshape(1, -1))[0] 
clf.fit(np.c_[sepal_length_norm, sepal_width_norm], iris.target) 
sigmoid_kernel(np.c_[sepal_length_norm, sepal_width_norm]) 

#assessing perfomance of sigmoid SVM with normalized features
pr_norm=clf.predict(np.c_[sepal_length_norm, sepal_width_norm])
pd.DataFrame(classification_report(iris.target, pr_norm, output_dict=True))


我明白发生了什么。在 sklearn 版本 0.22 之前,传递给 SVC 的默认 gamma 参数是“auto”,在后续版本中,它被更改为“scale”。这篇文章的作者似乎一直在使用以前的版本,因此隐含地传递了 gamma="auto"(他提到“gamma 的当前默认设置是‘auto’”)。因此,如果您使用的是最新版本的 sklearn (0.23.2),您需要在实例化 SVC 时显式传递 gamma='auto'

clf = SVC(kernel='sigmoid',gamma='auto') 
#normalizing features
sepal_length_norm = normalize(sepal_length.reshape(1, -1))[0] 
sepal_width_norm = normalize(sepal_width.reshape(1, -1))[0] 

clf.fit(np.c_[sepal_length_norm, sepal_width_norm], iris.target)

所以现在当您打印分类报告时:

pr_norm=clf.predict(np.c_[sepal_length_norm, sepal_width_norm])
print(pd.DataFrame(classification_report(iris.target, pr_norm, output_dict=True)))

#                    0          1          2  accuracy   macro avg  weighted avg
# precision   0.907407   0.650000   0.750000  0.766667    0.769136      0.769136
# recall      0.980000   0.780000   0.540000  0.766667    0.766667      0.766667
# f1-score    0.942308   0.709091   0.627907  0.766667    0.759769      0.759769
# support    50.000000  50.000000  50.000000  0.766667  150.000000    150.000000

可以解释您看到的 33% 准确度的原因是默认 gamma 是“比例”,然后将所有预测放在决策平面的单个区域中,并且目标是分成三份,你得到的最大准确率为 33.3%:

clf = SVC(kernel='sigmoid') 
#normalizing features
sepal_length_norm = normalize(sepal_length.reshape(1, -1))[0] 
sepal_width_norm = normalize(sepal_width.reshape(1, -1))[0] 

clf.fit(np.c_[sepal_length_norm, sepal_width_norm], iris.target) 

X = np.c_[sepal_length_norm, sepal_width_norm]

pr_norm=clf.predict(np.c_[sepal_length_norm, sepal_width_norm])
print(pd.DataFrame(classification_report(iris.target, pr_norm, output_dict=True)))

#               0     1          2  accuracy   macro avg  weighted avg
# precision   0.0   0.0   0.333333  0.333333    0.111111      0.111111
# recall      0.0   0.0   1.000000  0.333333    0.333333      0.333333
# f1-score    0.0   0.0   0.500000  0.333333    0.166667      0.166667
# support    50.0  50.0  50.000000  0.333333  150.000000    150.000000