一家懂得用细节留住客户的3年潮牌老店我必须支持!➕🛰:luyao1931
实验知识点:
1、支持向量机SVM相关知识
2、从文本文件中解析和导入数据
3、SMO分类算法
4、归一化数值
SVM算法概述:
支持向量机(Support Vector Machine, SVM)是一类按监督学习(supervised learning)方式对数据进行二元分类(binary classification)的广义线性分类器(generalized linear classifier),其决策边界是对学习样本求解的最大边距超平面。
优点:泛化错误率低,计算开销不大,结果易解释
缺点:对参数调节和核函数的选择敏感,原始分类器不加修改仅适用于处理二类问题。
适用数据类型:数值型和标称型数据。
SVM的一般流程:
1、 收集数据:提供文本文件
2、 准备数据:基于二值图像构造向量
3、 分析数据:对图像进行目测
4、 训练算法:采用两种不同的核函数,并对径向基核函数采用不同的设置来运行SMO算法
5、 测试算法:编写一个函数来测试不同核函数并计算错误率
6、 使用算法:几乎所有分类问题都可以使用SVM,SVM本身是一个二类分类器,对多类问题应用SVM需要对代码做一些修改
实验步骤:
1、 SOM算法中的辅助函数:
#SNMO算法中的辅助函数
def loadDataSet(fileName):
"""
loadDataSet(对文件进行逐行解析,从而得到每行的类标签和整个数据矩阵)
Args:
fileName 文件名
Returns:
dataMat 数据矩阵
labelMat 类标签
"""
dataMat = []
labelMat = []
fr = open(fileName)
for line in fr.readlines():
lineArr = line.strip().split('\t')
dataMat.append([float(lineArr[0]), float(lineArr[1])])
labelMat.append(float(lineArr[2]))
return dataMat, labelMat
def selectJrand(i, m):
"""
随机选择一个整数
Args:
i 第一个alpha的下标
m 所有alpha的数目
Returns:
j 返回一个不为i的随机数,在0~m之间的整数值
"""
j = i
while (j == i):
j = int(random.uniform(0, m))
return j
# 调整alpha值
def clipAlpha(aj, H, L):
"""clipAlpha(调整aj的值,使aj处于 L<=aj<=H)
Args:
aj 目标值
H 最大值
L 最小值
Returns:
aj 目标值
"""
if aj > H:
aj = H
if L > aj:
aj = L
return aj
2、完整的Platt SMO的支持函数:
# begin 完整版Platt SMO支持函数
class optStruct:
def __init__(self, dataMatIn, classLabels, C, toler):
self.X = dataMatIn
self.labelMat = classLabels
self.C = C
self.tol = toler
self.m = shape(dataMatIn)[0]
self.alphas = mat(zeros((self.m, 1)))
self.b = 0
self.eCache = mat(zeros((self.m, 2)))# 第一列是有效标志位,第二列是E值
#EK计算较多,所以单独拎出来
def calcEk(oS, k):
"""calcEk(求 Ek误差:预测值-真实值的差)
该过程在完整版的SMO算法中陪出现次数较多,因此将其单独作为一个方法
Args:
oS optStruct对象
k 具体的某一行
Returns:
Ek 预测结果与真实结果比对,计算误差Ek
"""
# fXk = float(multiply(oS.alphas, oS.labelMat).T * (oS.X * oS.X[k, :].T)) + oS.b
fXk = float(multiply(oS.alphas, oS.labelMat).T * oS.K[:, k] + oS.b)
Ek = fXk - float(oS.labelMat[k])
return Ek
#在选择第2个alphas参数时(也就是进行SMO的内循环时),不再是随机选择,而是选择最长步长的那个(就是选择|E_i-Ej|最大的)
def selectJ(i, oS, Ei):
"""selectJ(返回最优的j和Ej)
内循环的启发式方法。
选择第二个(内循环)alpha的alpha值
这里的目标是选择合适的第二个alpha值以保证每次优化中采用最大步长。
该函数的误差与第一个alpha值Ei和下标i有关。
Args:
i 具体的第i一行
oS optStruct对象
Ei 预测结果与真实结果比对,计算误差Ei
Returns:
j 随机选出的第j一行
Ej 预测结果与真实结果比对
,计算误差Ej
"""
maxK = -1
maxDeltaE = 0
Ej = 0
# 首先将输入值Ei在缓存中设置成为有效的。这里的有效意味着它已经计算好了。
oS.eCache[i] = [1, Ei]
# 非零E值的行的list列表,所对应的alpha值
validEcacheList = nonzero(oS.eCache[:, 0].A)[0]
if (len(validEcacheList)) > 1:
for k in validEcacheList: # 在所有的值上进行循环,并选择其中使得改变最大的那个值
if k == i: continue # don't calc for i, waste of time如果j=i直接跳过
Ek = calcEk(oS, k) # 求 Ek误差:预测值-真实值的差
deltaE = abs(Ei - Ek)
if (deltaE > maxDeltaE):
maxK = k #get max j下标
maxDeltaE = deltaE #get max j's deltaE
Ej =