svmMLiA.py,为没有用启发式算法,随机选择alphas[i],alphas[j]的SMO算法的实现。
svmQuicken.py,为启用了启发是算法选择alphas[i],alphas[j]的SMO算法的实现。
代码写的有点乱,结果出来之前,没心思整理代码,结果出来后,就更没心思整理代码了。
(以下正确率的结果,都是由训练数据获得超平面之后,再拿训练数据去测试的。没有专门去整理测试数据)
一、线性可分-线性核
下图一是svmMLiA.py实现的,线性可分,随机选择alphas[i]和alphas[j],很慢,但效果很好。红色点大圈为支持向量点,正确率为0.92
下图二是svmQuicken.py实现的,线性可分,启发式算法选择alphas[i]和alphas[j],很快,效果还行,不如图一。红色点大圈为支持向量点,正确率为0.90
二、线性不可分-高斯核
下图都是svmMLiA.py实现的,随机选择alphas[i]和alphas[j]。图三、图四、图五分别是高斯核的参数sigma = 0.1、0.3、0.6得出的结果,红色的大圈为支持向量。显然,sigma越小,得到的支持向量点越多,结果越准确,如果支持向量太多,相当于每次都利用整个数据集进行分类,这时便成了K近邻算法了。sigma = 0.1、0.3、0.6的准确率分别是0.915254,0.830508,0.813559
svmMLiA.py
'''
Created on 2017年7月9日
@author: fujianfei
'''
from os.path import os
import numpy as np
#导入数据,数据集
def loadDataSet (fileName):
data_path = os.getcwd()+'\\data\\'
labelMat = []
svmData = np.loadtxt(data_path+fileName,delimiter=',')
dataMat=svmData[:,0:2]
#零均值化
# meanVal=np.mean(dataMat,axis=0)
# dataMat=dataMat-meanVal
label=svmData[:,2]
for i in range (np.size(label)):
if label[i] == 0 or label[i] == -1:
labelMat.append(float(-1))
if label[i] == 1:
labelMat.append(float(1))
return dataMat.tolist(),labelMat
#简化版SMO算法,不启用启发式选择alpha,先随机选
def selectJrand(i,m):
j=i
while (j==i):
j = int(np.random.uniform(0,m))#在0-m的随机选一个数
return j
#用于调整大于H或小于L的值,剪辑最优解
def clipAlpha(aj,H,L):
if aj > H:
aj = H
if L > aj:
aj = L
return aj
'''
定义核函数
kernelOption=linear 线性
kernelOption=rbf 高斯核函数
'''
def calcKernelValue(matrix_x, sample_x, kernelOption):
kernelType = kernelOption[0]
numSamples = matrix_x.shape[0]
kernelValue = np.mat(np.zeros((numSamples, 1)))
if kernelType == 'linear':
kernelValue = matrix_x.dot(sample_x.T)
elif kernelType == 'rbf':
sigma = kernelOption[1]
if sigma == 0:
sigma = 1.0
for i in range(numSamples):
diff = matrix_x[i, :] - sample_x
kernelValue[i] = np.exp(diff.dot(diff.T) / (-2.0 * sigma**2))
else:
raise NameError('Not support kernel type! You can use linear or rbf!')
return kernelValue
'''
简化版SMO算法。
dataMatIn:输入的数据集
classLabels:类别标签
C:松弛变量前的常数
toler:容错率
maxIter:最大循环数
'''
def smoSimple(dataMatIn,classLabels,C,toler,maxIter,kernelOption):
dataMatrix = np.mat(dataMatIn);labelMat = np.mat(classLabels).transpose()
b=0;m,n = np.shape(dataMatrix)
alphas = np.mat(np.zeros((m,1)))