1、支持向量机
支持向量机比较复杂,看了好多遍讲义对深入原理还不是很理解。想深入研究的可以看支持向量机通俗导论(理解SVM的三层境界)
1.1 作业介绍
在本练习的前半部分,您将使用支持向量机。各种示例2D数据集。使用这些数据集进行实验将帮助您直观地了解支持向量机如何工作,以及如何使用支持向量机的高斯内核。
1.2 导入模块和数据
导入模块
import matplotlib.pyplot as plt
import numpy as np
import scipy.io as scio
from sklearn import svm # 调用sklearn的svm模块
import plotData as pd
import visualizeBoundary as vb # 可视化边界
# import gaussianKernel as gk # 高斯核函数
from sklearn.model_selection import GridSearchCV # 使用sklearn已有网格选择模块
plt.ion()
np.set_printoptions(formatter={'float': '{: 0.6f}'.format})
导入数据
# Load from ex6data1:
data = scio.loadmat('ex6data1.mat')
X = data['X']
y = data['y'].flatten()
m = y.size
打印X y维度
print('X.shape: ', X.shape, '\ny.shape: ', y.shape)
X.shape: (51, 2)
y.shape: (51,)
1.3 plotData 绘图函数
def plot_data(X, y):
plt.figure()
pos_X = X[np.where(y==1)] # 正类
neg_X = X[np.where(y==0)] # 负类
plt.scatter(pos_X[:, 0], pos_X[:, 1], c='b', marker='+') #散点图绘制正类
plt.scatter(neg_X[:, 0], neg_X[:, 1], c='y', marker='o') #散点图绘制负类
调用函数绘图
# Plot training data
plot_data(X, y)
1.4 svm模块之线性核函数
c=100,可以很好的拟合正类和负类,但由于一个异常点造成过拟合,不能最大边界
# ===================== Part 2: Training Linear SVM =====================
c = 100
clf = svm.SVC(c, kernel='linear', tol=1e-3)
clf.fit(X, y)
plot_data(X, y)
vb.visualize_boundary(clf, X, 0, 4.5, 1.5, 5)
plt.title('decision boundary with c = {}'.format(c))
Text(0.5,1,'decision boundary with c = 100')
c=1,此时不因为一个异常点影响“大边界”,拟合效果较好
c = 1
clf = svm.SVC(c, kernel='linear', tol=1e-3)
clf.fit(X, y)
plot_data(X, y)
vb.visualize_boundary(clf, X, 0, 4.5, 1.5, 5)
plt.title('decision boundary with c = {}'.format(c))
Text(0.5,1,'decision boundary with c = 1')
1.5 svm模块之高斯核函数
x1 = np.array([1, 2, 1])
x2 = np.array([0, 4, -1])
sigma = 2
高斯核函数公式:
高斯核函数gaussian_kernel
def gaussian_kernel(x1, x2, sigma=0.1):
x1 = x1.flatten()
x2 = x2.flatten()
sim = 0
sim = np.exp(-np.sum(np.power((x1 - x2), 2)) / (2 * np.power(sigma,2)))
return sim
调用高斯核函数测试,结果正确
sim = gaussian_kernel(x1, x2, sigma)
print('Gaussian kernel between x1 = [1, 2, 1], x2 = [0, 4, -1], sigma = {} : {:0.6f}\n'
'(for sigma = 2, this value should be about 0.324652'.format(sigma, sim))
Gaussian kernel between x1 = [1, 2, 1], x2 = [0, 4, -1], sigma = 2 : 0.324652
(for sigma = 2, this value should be about 0.324652
1.6 加载一组更复杂数据,不能线性核函数拟合
加载数据
data = scio.loadmat('ex6data2.mat')
X = data['X']
y = data['y'].flatten()
m = y.size
打印X y维度
print('X.shape: ', X.shape, '\ny.shape: ', y.shape)
X.shape: (863, 2)
y.shape: (863,)
调用绘图函数绘制图形,可以看出很不规则,无法用线性核函数拟合
# Plot training data
plot_data(X, y)
1.6.1 visualizeBoundary函数,绘制等高线图
import matplotlib.pyplot as plt
import numpy as np
from sklearn import svm, datasets
def visualize_boundary(clf, X, x_min, x_max, y_min, y_max):
h = .02
xx, yy = np.meshgrid(np.arange(x_min, x_max, h), np.arange(y_min, y_max, h))
Z = clf.predict(np.c_[xx.ravel(), yy.ravel()])
Z = Z.reshape(xx.shape)
plt.contour(xx, yy, Z, colors='r')
1.6.2 使用sklearn.svm.SVCmo模块rbf核函数拟合数据,并绘图
c = 1
sigma = 0.1
clf = svm.SVC(c, kernel='rbf', gamma=np.power(sigma, -2))
clf.fit(X, y)
plot_data(X, y)
vb.visualize_boundary(clf, X, 0, 1, .4, 1.0)
可以看出用高斯核函数拟合效果较好
1.7 高斯核函数 合适参数拟合效果
导入数据
data = scio.loadmat('ex6data3.mat')
X = data['X']
y = data['y'].flatten()
Xval = data['Xval']
yval = data['yval']
m = y.size
print('X.shape: ', X.shape, '\ny.shape: ', y.shape)
X.shape: (211, 2)
y.shape: (211,)
print('X.shape: ', Xval.shape, '\ny.shape: ', yval.shape)
X.shape: (200, 2)
y.shape: (200, 1)
绘制图形
plot_data(X, y)
绘制C=1时拟合效果图
c = 1
clf = svm.SVC(c, kernel='rbf')
clf.fit(X, y)
plot_data(X, y)
vb.visualize_boundary(clf, X, -0.7, 0.4, -0.7, 0.6)
1.8 使用sklearn的GridSearchCV自动搜索最佳参数(c gamma)
不同C和gamma配合产生不同拟合效果,详情参考博客:SVM基本使用
GridSearchCV能自动选择最优的参数,达到最佳效果
def svm_c(X, y, Xval, yval):
# rbf核函数
svc = svm.SVC(kernel='rbf', class_weight='balanced',)
c_list = gamma_list = np.array([0.01, 0.03, 0.1, 0.3, 1, 3, 10, 30])
# 网格搜索交叉验证的参数范围,cv=3,3折交叉
param_grid = [{'kernel': ['rbf'], 'C': c_list, 'gamma': gamma_list}]
grid = GridSearchCV(svc, param_grid, cv=3, n_jobs=-1)
# 训练模型
clf = grid.fit(X, y)
# 计算测试集精度
score = grid.score(Xval, yval)
print('精度为: {}'.format( score))
svm_c(X, y, Xval, yval)
精度为: 0.95
前一篇 吴恩达机器学习 EX5 作业 正则化线性回归 偏差 VS 方差 学习曲线
后一篇 吴恩达机器学习 EX6 第二部分 支持向量机 垃圾邮件分类