一、SVM
支持向量机(support vector machines, SVM)是一种二分类模型,它的基本模型是定义在特征空间上的间隔最大的线性分类器,间隔最大使它有别于感知机;SVM还包括核技巧,这使它成为实质上的非线性分类器。SVM的的学习策略就是间隔最大化,可形式化为一个求解凸二次规划的问题,也等价于正则化的合页损失函数的最小化问题。SVM的的学习算法就是求解凸二次规划的最优化算法。SVM的算法核心是找到几何间距,找到几何间距margin,处理线性可分问题,对应的非线性问题处理方法是:非线性VM
需要详细了解SVM,参考文章
SVM原理介绍
二、示例代码重做
1、鸢尾花数据集
- 绘制
import numpy as np
from sklearn import datasets #导入数据集
import matplotlib.pyplot as plt
from sklearn.preprocessing import StandardScaler
from matplotlib.colors import ListedColormap
# 边界绘制函数
def plot_decision_boundary(model,axis):
x0,x1=np.meshgrid(
np.linspace(axis[0],axis[1],int((axis[1]-axis[0])*100)).reshape(-1,1),
np.linspace(axis[2],axis[3],int((axis[3]-axis[2])*100)).reshape(-1,1))
# meshgrid函数是从坐标向量中返回坐标矩阵
x_new=np.c_[x0.ravel(),x1.ravel()]
y_predict=model.predict(x_new)#获取预测值
zz=y_predict.reshape(x0.shape)
custom_cmap=ListedColormap(['#EF9A9A','#FFF59D'])
plt.contourf(x0,x1,zz,cmap=custom_cmap)
iris = datasets.load_iris()
data_x = iris.data[:, :2]
data_y = iris.target
scaler=StandardScaler()# 标准化
data_x = scaler.fit_transform(data_x)#计算训练数据的均值和方差
plt.rcParams["font.sans-serif"] = ['SimHei'] # 用来正常显示中文标签,SimHei是字体名称,字体必须在系统中存在,字体的查看方式和安装第三部分
plt.rcParams['axes.unicode_minus'] = False # 用来正常显示负号
plt.scatter(data_x[data_y==0, 0],data_x[data_y==0, 1]) # 选取y所有为0的+X的第一列
plt.scatter(data_x[data_y==1, 0],data_x[data_y==1, 1]) # 选取y所有为1的+X的第一列
plt.xlabel('sepal length') # 设置横坐标标注xlabel为sepal width
plt.ylabel('sepal width') # 设置纵坐标标注ylabel为sepal length
plt.title('sepal散点图') # 设置散点图的标题为sepal散点图
plt.show()
- 线性处理
from sklearn.svm import LinearSVC
svc_line = LinearSVC(C =1e9,max_iter=1000000) #线性SVM分类器
svc_line.fit(data_x,data_y)#训练svm
plot_decision_boundary(svc_line,axis=[-3,3,-3,4])
plt.scatter(data_x[data_y==0,0],data_x[data_y==0,1])
plt.scatter(data_x[data_y==2,0],data_x[data_y==2,1])
plt.show()
- 多项式分类
from sklearn.preprocessing import PolynomialFeatures #导入多项式回归
from sklearn.pipeline import Pipeline #导入python里的管道
def PolynomialSVC(degree,c=5):#多项式svm
"""
:param d:阶数
:param C:正则化常数
:return:一个Pipeline实例
"""
return Pipeline([
# 将源数据 映射到 3阶多项式
("poly_features", PolynomialFeatures(degree=degree)),
# 标准化
("scaler", StandardScaler()),
# SVC线性分类器
("svm_clf", LinearSVC(C=c, loss="hinge", random_state=10,max_iter=100000))
])
poly_svc=PolynomialSVC(degree=5)
poly_svc.fit(data_x,data_y)
plot_decision_boundary(poly_svc,axis=[-3,4,-4,5])
plt.scatter(data_x[data_y==0,0],data_x[data_y==0,1])
plt.scatter(data_x[data_y==2,0],data_x[data_y==2,1])
plt.show()
- 高斯核
from sklearn.svm import SVC #导入svm
def RBFKernelSVC(gamma=1.0):
return Pipeline([
('std_scaler',StandardScaler()),
('svc',SVC(kernel='rbf',gamma=gamma))
])
svc=RBFKernelSVC(gamma=42)#gamma参数很重要,gamma参数越大,支持向量越小
svc.fit(data_x,data_y)
plot_decision_boundary(svc,axis=[-3,3,-3,4])
plt.scatter(data_x[data_y==0,0],data_x[data_y==0,1])
plt.scatter(data_x[data_y==2,0],data_x[data_y==2,1])
plt.show()
from sklearn.svm import SVC #导入svm
def RBFKernelSVC(gamma=1.0):
return Pipeline([
('std_scaler',StandardScaler()),
('svc',SVC(kernel='rbf',gamma=gamma))
])
svc=RBFKernelSVC(gamma=500)#gamma参数很重要,gamma参数越大,支持向量越小
svc.fit(data_x,data_y)
plot_decision_boundary(svc,axis=[-3,3,-3,4])
plt.scatter(data_x[data_y==0,0],data_x[data_y==0,1])
plt.scatter(data_x[data_y==2,0],data_x[data_y==2,1])
plt.show()
2、月亮数据集
- 线性SVM
# 导入月亮数据集和svm方法
#这是线性svm
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt #导入画图用的工具
from sklearn import datasets #导入数据集
from sklearn.svm import LinearSVC #导入线性svm
from matplotlib.colors import ListedColormap
from sklearn.preprocessing import StandardScaler
data_x,data_y=datasets.make_moons(noise=0.15,random_state=777)#生成月亮数据集
# random_state是随机种子,nosie是方
plt.scatter(data_x[data_y==0,0],data_x[data_y==0,1])
plt.scatter(data_x[data_y==1,0],data_x[data_y==1,1])
data_x=data_x[data_y<2,:2]#只取data_y小于2的类别,并且只取前两个特征
plt.show()
scaler=StandardScaler()# 标准化
scaler.fit(data_x)#计算训练数据的均值和方差
data_x=scaler.transform(data_x) #再用scaler中的均值和方差来转换X,使X标准化
liner_svc=LinearSVC(C=1e9,max_iter=100000)#线性svm分类器,iter是迭达次数,c值决定的是容错,c越大,容错越小
liner_svc.fit(data_x,data_y)
# 边界绘制函数
def plot_decision_boundary(model,axis):
x0,x1=np.meshgrid(
np.linspace(axis[0],axis[1],int((axis[1]-axis[0])*100)).reshape(-1,1),
np.linspace(axis[2],axis[3],int((axis[3]-axis[2])*100)).reshape(-1,1))
# meshgrid函数是从坐标向量中返回坐标矩阵
x_new=np.c_[x0.ravel(),x1.ravel()]
y_predict=model.predict(x_new)#获取预测值
zz=y_predict.reshape(x0.shape)
custom_cmap=ListedColormap(['#EF9A9A','#FFF59D','#90CAF9'])
plt.contourf(x0,x1,zz,cmap=custom_cmap)
#画图并显示参数和截距
plot_decision_boundary(liner_svc,axis=[-3,3,-3,3])
plt.scatter(data_x[data_y==0,0],data_x[data_y==0,1],color='red')
plt.scatter(data_x[data_y==1,0],data_x[data_y==1,1],color='blue')
plt.show()
print('参数权重')
print(liner_svc.coef_)
print('模型截距')
print(liner_svc.intercept_)
- 多核式
import numpy as np
import matplotlib.pyplot as plt
from sklearn import datasets
from sklearn.preprocessing import PolynomialFeatures,StandardScaler
from sklearn.svm import LinearSVC
from sklearn.pipeline import Pipeline
from sklearn.svm import SVC
X, y = datasets.make_moons() #使用生成的数据
#print(X.shape) # (100,2)
#print(y.shape) # (100,)
plt.scatter(X[y==0,0],X[y==0,1])
plt.scatter(X[y==1,0],X[y==1,1])
plt.show()
生成噪声点
plt.scatter(data_x[data_y==0,0],data_x[data_y==0,1])
plt.scatter(data_x[data_y==1,0],data_x[data_y==1,1])
data_x=data_x[data_y<2,:2]#只取data_y小于2的类别,并且只取前两个特征
plt.show()
定义非线性SVM函数,调用PolynomialSVC函数进行分类可视化,进行核处理
def PolynomialSVC(degree,C=1.0):
return Pipeline([
("poly",PolynomialFeatures(degree=degree)),#生成多项式
("std_scaler",StandardScaler()),#标准化
("linearSVC",LinearSVC(C=C))#最后生成svm
])
poly_svc = PolynomialSVC(degree=5)
poly_svc.fit(X,y)
plot_decision_boundary(poly_svc,axis=[-1.5,2.5,-1.0,1.5])
plt.scatter(X[y==0,0],X[y==0,1])
plt.scatter(X[y==1,0],X[y==1,1])
plt.show()
def PolynomialKernelSVC(degree,C=1.0):
return Pipeline([
("std_scaler",StandardScaler()),
("kernelSVC",SVC(kernel="poly")) # poly代表多项式特征
])
poly_kernel_svc = PolynomialKernelSVC(degree=5)
poly_kernel_svc.fit(X,y)
plot_decision_boundary(poly_kernel_svc,axis=[-1.5,2.5,-1.0,1.5])
plt.scatter(X[y==0,0],X[y==0,1])
plt.scatter(X[y==1,0],X[y==1,1])
plt.show()
- 高斯核
导入包与可视化
import numpy as np
import matplotlib.pyplot as plt
from sklearn import datasets
from sklearn.preprocessing import StandardScaler
from sklearn.svm import SVC
from sklearn.pipeline import Pipeline
X,y = datasets.make_moons(noise=0.15,random_state=777)
plt.scatter(X[y==0,0],X[y==0,1])
plt.scatter(X[y==1,0],X[y==1,1])
plt.show()
定义RBF核的SVM函数
from sklearn import datasets #导入数据集
from sklearn.svm import SVC #导入svm
from sklearn.pipeline import Pipeline #导入python里的管道
import matplotlib.pyplot as plt
from sklearn.preprocessing import StandardScaler#导入标准化
def RBFKernelSVC(gamma=1.0):
return Pipeline([
('std_scaler',StandardScaler()),
('svc',SVC(kernel='rbf',gamma=gamma))
])
svc=RBFKernelSVC(gamma=100)#gamma参数很重要,gamma参数越大,支持向量越小
svc.fit(data_x,data_y)
plot_decision_boundary(svc,axis=[-1.5,2.5,-1.0,1.5])
plt.scatter(data_x[data_y==0,0],data_x[data_y==0,1],color='red')#画点
plt.scatter(data_x[data_y==1,0],data_x[data_y==1,1],color='blue')
plt.show()
三、总结
对SVM有了更深的了解