一、实验目的
1、熟悉SMO算法的求解过程;
2、掌握SMO算法的代码实现;
3、掌握SVM的分类方法;
4、熟悉numpy的使用。
二、实验设备
计算机:CPU四核i7 6700处理器;内存8G; SATA硬盘2TB硬盘; Intel芯片主板;集成声卡、千兆网卡、显卡; 20寸液晶显示器。
编译环境:python解释器、Pycharm编辑器
三、实验内容
1、新建项目和文件,并导入numpy
(1)打开Pycharm,新建项目,并在该项目下新建文件svm_smo.py。
(2)导入一些编程中需要的包。
import numpy as np
import matplotlib.pyplot as plt
import math
import random
2、构造一个函数data_producer
(1)定义函数头data_producer,该函数用于生成二维正态分布的点,共有三个参数,miu,sigma和sample_no,分别表示二维正态分布的均值,标准差和产生样本个数。
def data_producer(miu, sigma, sample_no):
data = np.random.multivariate_normal(miu, sigma, sample_no)
return data
3、编写一个类SVMSMO
(1)构造一个类SVMSMO,并添加构造函数,需要训练数据集、测试数据集、最大迭代次数和核函数的参数作为输入;
(2)构造类方法get_j用于获取第二个alpha的索引;
(3)构造类方法clip_alpha用于切割更新的alpha_j;
(4)构造类方法kernel_function用于返回核函数的值;
(5)构造类方法smo用于计算alpha和b;
(6)构造类方法svm用于计算分类结果。
class SVMSMO:
def __init__(self, data_train, data_test, maxcihsu):
self.data_train = data_train
self.data_test = data_test
self.maxcihsu = maxcihsu #迭代次数
self.alpha = None #用于保存alpha值
self.b=0 #用于保存b的值
def get_j(self, i):
while True:
j = random.choice(range(160)) #随机选择第二个变量
if j != i:
break
return j
def clip_alpha(self, a_j, l, h): #用于剪辑的解
if a_j > h:
a_j = h
elif a_j < l:
a_j = l
else:
a_j = a_j
return a_j
def kernel_function(self, x_i, x_j): #线性核函数
return np.dot(x_i, x_j)
def gaisidange(self, x_i, x_j): #高斯核函数
a = 1.1
c = np.array(x_i)-np.array(x_j)
if len(x_j.shape) == 1: #因为是向量,所以根据传入的参数要运用不同的计算方式
kern = np.exp((-1*np.dot(c,c.T))/(2*a**2))
else:
kern = np.exp((-1*np.diag(np.dot(c,c.T)))/(2*a**2)) #np.diag表示对角线,意思是取对角线上的值
return kern
def smo(self):
alphas = np.zeros(int(2*num*0.8)) #a为行向量形式(1600,)
b = 0; C = 0.8; iter = 0; renew = 1 #初始化 偏置b,松弛量c,循环次数iter, 更新次数renew
while (iter <= self.maxcihsu) and renew >