SVM类
| 48 | return dataArr, labelArr |
| 49 | |
| 50 | class SVM: |
| 51 | ''' |
| 52 | SVM类 |
| 53 | ''' |
| 54 | def __init__(self, trainDataList, trainLabelList, sigma = 10, C = 200, toler = 0.001): |
| 55 | ''' |
| 56 | SVM相关参数初始化 |
| 57 | :param trainDataList:训练数据集 |
| 58 | :param trainLabelList: 训练测试集 |
| 59 | :param sigma: 高斯核中分母的σ |
| 60 | :param C:软间隔中的惩罚参数 |
| 61 | :param toler:松弛变量 |
| 62 | 注: |
| 63 | 关于这些参数的初始值:参数的初始值大部分没有强要求,请参照书中给的参考,例如C是调和间隔与误分类点的系数, |
| 64 | 在选值时通过经验法依据结果来动态调整。(本程序中的初始值参考于《机器学习实战》中SVM章节,因为书中也 |
| 65 | 使用了该数据集,只不过抽取了很少的数据测试。参数在一定程度上有参考性。) |
| 66 | 如果使用的是其他数据集且结果不太好,强烈建议重新通读所有参数所在的公式进行修改。例如在核函数中σ的值 |
| 67 | 高度依赖样本特征值范围,特征值范围较大时若不相应增大σ会导致所有计算得到的核函数均为0 |
| 68 | ''' |
| 69 | self.trainDataMat = np.mat(trainDataList) #训练数据集 |
| 70 | self.trainLabelMat = np.mat(trainLabelList).T #训练标签集,为了方便后续运算提前做了转置,变为列向量 |
| 71 | |
| 72 | self.m, self.n = np.shape(self.trainDataMat) #m:训练集数量 n:样本特征数目 |
| 73 | self.sigma = sigma #高斯核分母中的σ |
| 74 | self.C = C #惩罚参数 |
| 75 | self.toler = toler #松弛变量 |
| 76 | |
| 77 | self.k = self.calcKernel() #核函数(初始化时提前计算) |
| 78 | self.b = 0 #SVM中的偏置b |
| 79 | self.alpha = [0] * self.trainDataMat.shape[0] # α 长度为训练集数目 |
| 80 | self.E = [0 * self.trainLabelMat[i, 0] for i in range(self.trainLabelMat.shape[0])] #SMO运算过程中的Ei |
| 81 | self.supportVecIndex = [] |
| 82 | |
| 83 | |
| 84 | def calcKernel(self): |
| 85 | ''' |
| 86 | 计算核函数 |
| 87 | 使用的是高斯核 详见“7.3.3 常用核函数” 式7.90 |
| 88 | :return: 高斯核矩阵 |
| 89 | ''' |
| 90 | #初始化高斯核结果矩阵 大小 = 训练集长度m * 训练集长度m |
| 91 | #k[i][j] = Xi * Xj |
| 92 | k = [[0 for i in range(self.m)] for j in range(self.m)] |
| 93 | |
| 94 | #大循环遍历Xi,Xi为式7.90中的x |
| 95 | for i in range(self.m): |
| 96 | #每100个打印一次 |
| 97 | #不能每次都打印,会极大拖慢程序运行速度 |
| 98 | #因为print是比较慢的 |
| 99 | if i % 100 == 0: |
| 100 | print('construct the kernel:', i, self.m) |
| 101 | #得到式7.90中的X |
| 102 | X = self.trainDataMat[i, :] |
| 103 | #小循环遍历Xj,Xj为式7.90中的Z |
| 104 | # 由于 Xi * Xj 等于 Xj * Xi,一次计算得到的结果可以 |
| 105 | # 同时放在k[i][j]和k[j][i]中,这样一个矩阵只需要计算一半即可 |
| 106 | #所以小循环直接从i开始 |
| 107 | for j in range(i, self.m): |