Sklearn(v3)——SVM(乳腺癌数据)

from sklearn.datasets import load_breast_cancer
from sklearn.svm import SVC
from sklearn.model_selection import train_test_split
import matplotlib.pyplot as plt
import numpy as np
from time import time
import datetime

data = load_breast_cancer()
X = data.data
y = data.target

plt.scatter(X[:,0],X[:,1],c=y)
plt.show()

from sklearn.decomposition import PCA
x_dr = PCA(2).fit_transform(X) #提取2个主成分
Xtrain, Xtest, Ytrain, Ytest = train_test_split(X,y,test_size=0.3,random_state=420) 
Kernel = ["linear","rbf","sigmoid"]
for kernel in Kernel:
    time0 = time()
    clf= SVC(kernel = kernel,
             gamma="auto",
             #degree = 1  线性是1,其他是非线性,默认是3
             cache_size=5000).fit(Xtrain,Ytrain)   #cache_size可以使用多大的内存进行计算
    print("The accuracy under kernel %s is %f" % (kernel,clf.score(Xtest,Ytest))) 
    print(datetime.datetime.fromtimestamp(time()-time0).strftime("%M:%S:%f"))

结果: 

The accuracy under kernel linear is 0.929825
00:00:277996
The accuracy under kernel rbf is 0.596491
00:00:017869
The accuracy under kernel sigmoid is 0.596491
00:00:007693

poly这个核degree设为3的时候跑不出来,只能把degree返回成1

from sklearn.decomposition import PCA
x_dr = PCA(2).fit_transform(X) #提取2个主成分
Xtrain, Xtest, Ytrain, Ytest = train_test_split(X,y,test_size=0.3,random_state=420) 
Kernel = ["linear","poly","rbf","sigmoid"]
for kernel in Kernel:
    time0 = time()
    clf= SVC(kernel = kernel,
             gamma="auto",
             degree = 1,  #线性是1,其他是非线性,默认是3
             cache_size=5000).fit(Xtrain,Ytrain)   #cache_size可以使用多大的内存进行计算
    print("The accuracy under kernel %s is %f" % (kernel,clf.score(Xtest,Ytest))) 
    print(datetime.datetime.fromtimestamp(time()-time0).strftime("%M:%S:%f"))

结果: 

The accuracy under kernel linear is 0.929825
00:00:281354
The accuracy under kernel poly is 0.923977
00:00:033168
The accuracy under kernel rbf is 0.596491
00:00:017965
The accuracy under kernel sigmoid is 0.596491
00:00:008114

为什么高斯核表现这么差?数据存在什么问题

import pandas as pd
data = pd.DataFrame(X)
data.describe([0.01,0.05,0.1,0.25,0.5,0.75,0.9,0.99]).T
#量纲不统一
#偏态问题

from sklearn.preprocessing import StandardScaler
X = StandardScaler().fit_transform(X)
from sklearn.decomposition import PCA
x_dr = PCA(2).fit_transform(X) #提取2个主成分
Xtrain, Xtest, Ytrain, Ytest = train_test_split(X,y,test_size=0.3,random_state=420) 
Kernel = ["linear","poly","rbf","sigmoid"]
for kernel in Kernel:
    time0 = time()
    clf= SVC(kernel = kernel,
             gamma="auto",
             degree = 1,  #线性是1,其他是非线性,默认是3
             cache_size=5000).fit(Xtrain,Ytrain)   #cache_size可以使用多大的内存进行计算
    print("The accuracy under kernel %s is %f" % (kernel,clf.score(Xtest,Ytest))) 
    print(datetime.datetime.fromtimestamp(time()-time0).strftime("%M:%S:%f"))

 结果:

The accuracy under kernel linear is 0.976608
00:00:008025
The accuracy under kernel poly is 0.964912
00:00:005367
The accuracy under kernel rbf is 0.970760
00:00:010287
The accuracy under kernel sigmoid is 0.953216
00:00:006139

量纲统一之后可以观察到所有核函数的运算时间都大大地减少了尤其是对于线性核来说而多项式核函数居然变成了计算最快的。其次,  rbf表现出了非常优秀的结果经过我们的探索我们可以得到的结论是

1. 线性核尤其是多项式核函数在高次项时计算非常缓慢

2. rbf和多项式核函数都不擅长处理量纲不统一的数据集

幸运的是,这两个缺点都可以由数据无量纲化来解决因此  SVM执行之前非常推荐先进行数据的无量纲化 了这一步我们是否已经完成建模了呢?虽然线性核函数的效果是最好的但它是没有核函数相关参数可以调整的,rbf和多项式却还有着可以调整的相关参数接下来我们就来看看这些参数

但从核函数的公式来看,我们其实很难去界定具体每个参数如何影响了SVM的表现gamma的符号变化或者  degree的大小变化时,核函数本身甚至都不是永远单调的所以如果我们想要彻底地理解这三个参数我们要先推导出它们如何影响核函数地变化再找出核函数的变化如何影响了我们的预测函数(可能改变我们的核变化所在的维度),再判断出决策边界随着预测函数的改变发生了怎样的变化无论是从数学的角度来说还是从实践的角度来 这个过程太复杂也太低效所以我们往往避免去真正探究这些参数如何影响了我们的核函数而直接使用学习曲线或者网格搜索来帮助我们查找最佳的参数组合

对于高斯径向基核函数,调整gamma的方式其实比较容易,那就是画学习曲线。我们来试试看高斯径向基核函数rbf的参数gamma在乳腺癌数据集上的表现

score = []
gamma_range = np.logspace(-10, 1, 50) #返回在对数刻度上均匀间隔的数字
for i in gamma_range :
    clf = SVC(kernel="rbf",gamma = i,cache_size=5000).fit(Xtrain,Ytrain) 
    score.append(clf.score(Xtest,Ytest))
print(max(score), gamma_range[score.index(max(score))])
plt.plot(gamma_range ,score)
plt.show()

结果: 

0.9766081871345029 0.012067926406393264

 

通过学习曲线,很容就找出了rbf的最佳gamma值。但我们观察到这其实与线性核函数的准确率一模一样之前的准确率我们可以多次调整gamma_range来观察结果可以发现97.6608应该是rbf核函数的极限了

但对于多项式核函数来说一切就没有那么容易了因为三个参数共同作用在一个数学公式上影响它的效果因此们往往使用网格搜索来共同调整三个对多项式核函数有影响的参数依然使用乳腺癌数据集

from sklearn.model_selection import StratifiedShuffleSplit
from sklearn.model_selection import GridSearchCV 

time0 = time()

gamma_range = np.logspace(-10,1,20)
coef0_range = np.linspace(0,5,10)

param_grid = dict(gamma = gamma_range,coef0 = coef0_range)

cv = StratifiedShuffleSplit(n_splits=5, test_size=0.3, random_state=420)
grid = GridSearchCV(SVC(kernel="poly",degree=1,cache_size=5000),param_grid=param_grid, cv=cv)
grid.fit(X, y)
print("The best parameters are %s with a score of %0.5f" % (grid.best_params_ ,grid.best_score_))

 结果:

The best parameters are {'coef0': 0.0, 'gamma': 0.18329807108324375} with a score of 0.96959
00:05:945035

可以发现,网格搜索为我们返回了参数coef0=0  gamma=0.18329807108324375但整体的分数是0.96959,然比调参前略有提高,但依然没有超过线性核函数核rbf的结果。可见,如果最初选择核函数的时候你就发现多项式的结果不如rbf和线性核函数那就不要挣扎了试试看调整rbf者直接使用线性 

  • 1
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值