目录
非线性SVM和核函数
如何选择最佳核函数
SVC在乳腺癌数据上的表现
以上4张图分别是月牙形,环形,杂乱性,对称形
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.colors import ListedColormap
from sklearn import svm
from sklearn.datasets import make_circles,make_moons,make_blobs,make_classification
n_samples=100
#生成4种不同类型数据 月牙形 环形 杂乱形 对称形
data=[
make_moons(n_samples=n_samples,noise=0.2,random_state=0),
make_circles(n_samples=n_samples,noise=0.2,factor=0.5,random_state=1),
make_blobs(n_samples=n_samples,centers=2,random_state=2),
make_classification(n_samples=n_samples,n_features=2,n_informative=2,#特征数 带特征的有两个
n_redundant=0,random_state=3) #不带特征的0个 即不存在需要舍去的特征
]
#核函数列表
Kernel = ["linear","poly","rbf","sigmoid"]
# #查看4个数据集分布
# for X,Y in data:
# plt.figure(figsize=(5,4))
# plt.scatter(X[:,0],X[:,1],c=Y,s=50,cmap="rainbow")
# plt.xticks([])
# plt.yticks([])
#构建子图
nrows=len(data)
ncols=len(Kernel) + 1
fig, axes = plt.subplots(nrows, ncols,figsize=(20,16))
#子图循环
#第一层循环:在不同的数据集中循环
for ds_cnt, (X,Y) in enumerate(data):
# 在图像中的第一列,放置原数据的分布
ax = axes[ds_cnt, 0]
if ds_cnt == 0:
ax.set_title("Input data")
ax.scatter(X[:, 0], X[:, 1], c=Y, zorder=10, cmap=plt.cm.Paired, edgecolors='k')#zorder指定层级
ax.set_xticks(())
ax.set_yticks(())
# 第二层循环:在不同的核函数中循环
# 从图像的第二列开始,一个个填充分类结果
for est_idx, kernel in enumerate(Kernel):
#定义子图位置 从每一行从1列到4列
ax=axes[ds_cnt, est_idx+1]
#建模
clf=svm.SVC(kernel=kernel,gamma=2).fit(X, Y)
score=clf.score(X, Y)
#绘制图像散点图
ax.scatter(X[:, 0], X[:, 1], c=Y, zorder = 10,
cmap = plt.cm.Paired, edgecolors = 'k')
#绘制支持向量
ax.scatter(clf.support_vectors_[:, 0], clf.support_vectors_[:, 1], s=50,
facecolors = 'none', zorder = 10, edgecolors = 'k') #facecolor表示透明 避免覆盖
#绘制决策边界
#加减0.5 避免点落在边界上
x_min, x_max = X[:, 0].min() - .5, X[:, 0].max() + .5
y_min, y_max = X[:, 1].min() - .5, X[:, 1].max() + .5
# np.mgrid,合并了我们之前使用的np.linspace和np.meshgrid的用法
# 一次性使用最大值和最小值来生成网格
# 表示为[起始值:结束值:步长]
# 如果步长是复数,则其整数部分就是起始值和结束值之间创建的点的数量,并且结束值被包含在内
XX, YY = np.mgrid[x_min:x_max:200j, y_min:y_max:200j]
# np.c_,类似于np.vstack的功能
Z = clf.decision_function(np.c_[XX.ravel(), YY.ravel()]).reshape(XX.shape)
# 填充等高线不同区域的颜色
ax.pcolormesh(XX, YY, Z > 0, shading='auto',cmap=plt.cm.Paired)
# 绘制等高线
ax.contour(XX, YY, Z, colors=['k', 'k', 'k'], linestyles=['--', '-', '--'],
levels = [-1, 0, 1])
# 设定坐标轴为不显示
ax.set_xticks(())
ax.set_yticks(())
# 将标题放在第一行的顶上
if ds_cnt == 0:
ax.set_title(kernel)
# 为每张图添加分类的分数
ax.text(0.95, 0.06, ('%.2f' % score).lstrip('0'), #0.95 0.06横纵坐标 lstrip表示不显示0
size = 15, bbox = dict(boxstyle='round',
alpha=0.8, facecolor='white'),
# 为分数添加一个白色的格子作为底色
transform = ax.transAxes, # 确定文字所对应的坐标轴,就是ax子图的坐标轴本身
horizontalalignment = 'right',) # 位于坐标轴的什么方向
plt.tight_layout()#自动调整子图大小
plt.show()
from sklearn.datasets import load_breast_cancer
from sklearn.svm import SVC
from sklearn.model_selection import train_test_split
import numpy as np
import matplotlib.pyplot as plt
from time import time
import datetime
data = load_breast_cancer()
X = data.data
y = data.target
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',cache_size=5000).fit(Xtrain,Ytrain) #cache_size 为内存 MB
print("The accuracy under kernel {} is {}".format(kernel, clf.score(Xtest,Ytest)))
print(datetime.datetime.fromtimestamp(time() - time0).strftime("%M:%S:%f")) #分 秒 微秒
尝试对数据进行标准化后
from sklearn.datasets import load_breast_cancer
from sklearn.svm import SVC
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
import numpy as np
import matplotlib.pyplot as plt
from time import time
import datetime
data = load_breast_cancer()
X = data.data
y = data.target
X = StandardScaler().fit_transform(X)#标准化数据
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',cache_size=5000).fit(Xtrain,Ytrain) #cache_size 为内存 MB
print("The accuracy under kernel {} is {}".format(kernel, clf.score(Xtest,Ytest)))
print(datetime.datetime.fromtimestamp(time() - time0).strftime("%M:%S:%f")) #分 秒 微秒