《scikit-learn》SVM(一)

至于SVM的数学理解,强烈推荐如下三篇知乎博文,我是自学视频学习的,但是如下三篇博文讲的是真的好啊,完全跟我在视频里学习到的是一样的,我很激动啊。
https://zhuanlan.zhihu.com/p/28660098
https://zhuanlan.zhihu.com/p/28954032
https://zhuanlan.zhihu.com/p/77750026

这三篇写的真的是用心极力推荐啊。我就不自己重复工作了,为了搞懂这点,或者说初步搞懂这点,我花了两天的时间,因为自己的数学能力有点薄弱。

我们这一篇主要讲解各个核函数和一些参数的调试过程。
我们拿乳腺癌数据进行学习
第一步,先加载数据。且简单查看一下。

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

# 第一步骤:加载数据
breast_cancer = load_breast_cancer()
x = breast_cancer.data
y = breast_cancer.target
print(x.shape)
print(y.shape)
print(breast_cancer.feature_names)
print(breast_cancer.target_names)

# 随便挑选两个特征来可视化一下数据
plt.scatter(x[:, 0], x[:, 1], c=y, cmap='rainbow')
plt.show()
plt.scatter(x[:, 2], x[:, 3], c=y, cmap='rainbow')
plt.show()

第二步:我们尝试使用不同的核函数来拟合

# 第二步骤:查看不同的核函数下的表现哈
Xtrain, Xtest, Ytrain, Ytest = train_test_split(x, y, test_size=0.7, random_state=2)
kernels = ['linear', 'poly', 'rbf', 'sigmoid']
for kernel in kernels:
    time0 = time()
    clf = SVC(kernel=kernel,
              degree=1,  # 多项式的d参数
              gamma='auto',
              cache_size=5000).fit(Xtrain, Ytrain)  # 可以使用的内存缓存,单位是M
    print('The accuracy under %s kernel is %f' % (kernel, clf.score(Xtest, Ytest)))
    print(datetime.datetime.fromtimestamp(time() - time0).strftime('%M:%S:%f'))

输出如下:
The accuracy under linear kernel is 0.939850
00:00:116686
The accuracy under poly kernel is 0.942356
00:00:008981
The accuracy under rbf kernel is 0.614035
00:00:013000
The accuracy under sigmoid kernel is 0.614035
00:00:002995

说明在poly核函数下,拟合乳腺癌数据是又快又好啊,rbf和sigmoid核函数的虽然也挺快,但是效果却及其差。
在我们印象中啊,rbf可以很强大吧,几乎可以做到很多数据集的吧,但是这里的效果确实很不好。
我们来分析下数据。

# 查看数据的分布
import pandas as pd
data = pd.DataFrame(x)
print(data.describe([0.01, 0.05, 0.1, 0.25, 0.5, 0.75, 0.90, 0.99]).T)

从结果来看呢,数据存在量纲不统一的问题,很多数据偏差有点大。

我们先来重新进行数据的标准化

from sklearn.preprocessing import StandardScaler
x = StandardScaler().fit_transform(x)
data = pd.DataFrame(x)
print(data.describe([0.01, 0.05, 0.1, 0.25, 0.5, 0.75, 0.90, 0.99]).T)

此时,每一特征的均值接近于0,方差接近于1,都是标准正太分布了。

我们这时候再来一次。

# 第二步骤:查看不同的核函数下的表现哈
Xtrain, Xtest, Ytrain, Ytest = train_test_split(x, y, test_size=0.7, random_state=2)
kernels = ['linear', 'poly', 'rbf', 'sigmoid']
for kernel in kernels:
    time0 = time()
    clf = SVC(kernel=kernel,
              degree=1,  # 多项式的d参数
              gamma='auto',
              cache_size=5000).fit(Xtrain, Ytrain)  # 可以使用的内存缓存,单位是M
    print('The accuracy under %s kernel is %f' % (kernel, clf.score(Xtest, Ytest)))
    print(datetime.datetime.fromtimestamp(time() - time0).strftime('%M:%S:%f'))

输出如下:
The accuracy under linear kernel is 0.952381
00:00:002958
The accuracy under poly kernel is 0.969925
00:00:000998
The accuracy under rbf kernel is 0.969925
00:00:002992
The accuracy under sigmoid kernel is 0.957393
00:00:002035

诶?这下就好多了吧。几个核函数都提高了,Rbf的表现是最好的啊,而且速度也都是提升了。可以得出,数据的标准化是多么重要啊。
所以我们得出一个经验,在执行svm之前啊,先进行数据的无量纲化和标准化。
在执行svm之前啊,先进行数据的无量纲化和标准化。
在执行svm之前啊,先进行数据的无量纲化和标准化。

至于还有一些参数,比如说是gamma,我们来试着使用学习曲线来看看。
在上面代码运行的基础上,数据经过了那个标准化:

scores = []
gammas = np.linspace(0.001, 1, 100)
for i in gammas:
    clf = SVC(kernel='rbf',
              # degree=1,  # 多项式的d参数
              gamma=i,
              cache_size=5000).fit(Xtrain, Ytrain)  # 可以使用的内存缓存,单位是M
    scores.append(clf.score(Xtest, Ytest))

print(max(scores), gammas[scores.index(max(scores))])
plt.plot(gammas, scores)
plt.show()

如果我们使用多项式核函数,那么就会涉及3个参数,gamma,degree和coef,我们一般取degree是1,我们试着找出其他两个参数来看看。
我们使用网格搜索,数据同样需要提前标准化啊:

from sklearn.model_selection import StratifiedShuffleSplit, GridSearchCV

time0 = time()

gamma_range = np.linspace(0.001, 0.1, 10)
coef0_range = np.linspace(0, 5, 10)

param_grid = {'gamma': gamma_range, 'coef0': coef0_range}
cv = StratifiedShuffleSplit(n_splits=10, test_size=0.3, random_state=34)
svc = SVC(kernel='poly', degree=1, cache_size=2000)
grid = GridSearchCV(estimator=svc, param_grid=param_grid, cv=cv)
grid.fit(x, y)

print('best parameters are %s and the score is %0.5f' % (grid.best_params_, grid.best_score_))
print(datetime.datetime.fromtimestamp(time() - time0).strftime('%M:%S:%f'))

在软间隔的问题上有一个参数C(自行学习),软间隔其实就是在噪声的影响下,允许一小点的训练误差,来达到更好的泛化效果,这个参数如何作用呢?

scores = []
kernels = ['linear', 'rbf']
C_range = np.linspace(0.001, 1, 100)
for k in kernels:
    score = []
    for c in C_range:
        clf = SVC(kernel=k,
                  # degree=1,  # 多项式的d参数
                  gamma='auto',
                  C=c,
                  cache_size=5000).fit(Xtrain, Ytrain)  # 可以使用的内存缓存,单位是M
        score.append(clf.score(Xtest, Ytest))
    scores.append(score)

for i in range(len(kernels)):
    plt.plot(C_range, scores[i], label=kernels[i])

plt.legend()  # 显示图例
plt.show()
  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值