【问题标题】:SVC sigmoid kernel is not working properlySVC sigmoid 内核无法正常工作
【发布时间】:2021-03-14 06:31:38
【问题描述】:

我正在使用 sklearn 和 SVC 在虹膜数据上测试带有 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))


【问题讨论】:

    标签: python machine-learning scikit-learn svm


    【解决方案1】:

    我明白发生了什么。在 0.22 之前的 sklearn 版本中,传递给 SVC 的默认 gamma 参数是“auto”,在后续版本中,它被更改为“scale”。这篇文章的作者似乎一直在使用以前的版本,因此隐式传递了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
    
    

    【讨论】:

    • 非常感谢您的详尽回答!
    猜你喜欢
    • 2020-04-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-07-14
    • 1970-01-01
    • 2016-12-01
    • 2019-10-21
    • 2010-11-24
    相关资源
    最近更新 更多