支持向量机代码实践

本文档详细介绍了支持向量机(SVM)的原理,并提供了SVM的Python代码实现。通过加载平衡秤重量和距离数据库进行训练,采用SMO优化算法进行模型训练。在训练集和测试集上分别计算错误率,展示了SVM在二分类问题上的应用。代码中还包含了RBF核函数的使用。
摘要由CSDN通过智能技术生成

支持向量机代码实践

理论部分:(72条消息) 支持向量机详细解释_better_than的博客-CSDN博客

代码:https://github.com/vistor985/-.git

数据集

标题:平衡秤重量和距离数据库

相关信息:

这个数据集是用来建立心理学模型的实验结果。每个例子都被归类为具有天平向右倾斜,向左倾斜,还是向左倾斜平衡。这些属性是左权重距离,合适的重量,合适的距离。的正确的查找类的方法是较大的(left-distance * left-weight)和(right-distance *)的重量)。如果它们相等,那就是平衡的。

1.实例数:625(49平衡,288左,288右)

2.属性数量:4(数字)+类名= 5

属性信息:

  1. 类名称:3 (L, B, R)
  2. 左权重:5 (1,2,3,4,5)
  3. 左距离:5 (1,2,3,4,5)
  4. 右权重:5(1、2、3、4、5)
  5. 右距离:5 (1,2,3,4,5)

类分布:

  1. 46.08%是L
  2. 07.84%的人是B
  3. 3.46.08%是R

修改:

为了方便用于二分类,我们选择将R和B改为1,L为0

加载数据集

def loadCSVfile2():
    from sklearn.model_selection import train_test_split
    tmp = np.loadtxt("balance-scale.csv", dtype=str, delimiter=",")
    for line in tmp:
        if line[0] == 'L':
            line[0] = 0
        else:
            line[0] = 1
    data = tmp[1:, 1:].astype(float)  # 加载数据部分
    label = tmp[1:, 0].astype(float)  # 加载类别标签部分
    for i in range(len(label)):
        if label[i] == 0:
            label[i] = -1
    # print(tmp)
    x_train, x_test, y_train, y_test = train_test_split(data, label, test_size=0.2)
    return x_train, x_test, y_train, y_test  # 返回array类型的数据

算法类

仅用于记录重要的变量,方便代码编写即理解。

class optStruct:
    def __init__(self, dataMatIn, classLabels, C, toler, kTup):
        # 数据矩阵
        self.X = dataMatIn
        # 数据标签
        self.labelMat = classLabels
        # 松弛变量
        self.C = C
        # 容错率
        self.tol = toler
        # 矩阵的行数
        self.m = np.shape(dataMatIn)[0]
        # 根据矩阵行数初始化alphas矩阵,一个m行1列的全零列向量
        self.alphas = np.mat(np.zeros((self.m, 1)))
        # 初始化b参数为0
        self.b = 0
        # 根据矩阵行数初始化误差缓存矩阵,第一列为是否有效标志位,第二列为实际的误差E的值
        self.eCache = np.mat(np.zeros((self.m, 2)))
        # 初始化核K
        self.K = np.mat(np.zeros((self.m, self.m)))
        # 计算所有数据的核K
        for i in range(self.m):
            self.K[:, i] = kernelTrans(self.X, self.X[i, :], kTup)

SMO算法

以下是算法的核心代码

def smoP(dataMatIn, classLabels, C, toler, maxIter, kTup=('lin', 0)):
    # 初始化数据结构
    oS = optStruct(np.mat(dataMatIn), np.mat(classLabels).transpose(), C, toler, kTup)
    # 初始化当前迭代次数
    iter = 0
    entrieSet = True
    alphaPairsChanged = 0
    # 遍历整个数据集alpha都没有更新或者超过最大迭代次数,则退出循环
    while (iter < maxIter) and ((alphaPairsChanged > 0) or (entrieSet)):
        alphaPairsChanged = 0
        # 遍历整个数据集
        if entrieSet:
            for i in range(oS.m):
                # 使用优化的SMO算法
                alphaPairsChanged += innerL(i, oS)
                print("全样本遍历:第%d次迭代 样本:%d, alpha优化次数:%d" % (iter, i, alphaPairsChanged))
            iter += 1
        # 遍历非边界值
        else:
            # 遍历不在边界0和C的alpha
            nonBoundIs = np.nonzero((oS.alphas.A > 0) * (oS.alphas.A < C))[0]
            for i in nonBoundIs:
                alphaPairsChanged += innerL(i, oS)
                print("非边界遍历:第%d次迭代 样本:%d, alpha优化次数:%d" % (iter, i, alphaPairsChanged))
            iter += 1
        # 遍历一次后改为非边界遍历
        if entrieSet:
            entrieSet = False
        # 如果alpha没有更新,计算全样本遍历
        elif (alphaPairsChanged == 0):
            entrieSet = True
        print("迭代次数:%d" % iter)
    # 返回SMO算法计算的b和alphas
    return oS.b, oS.alphas

训练及测试

def testRbf(k1=1.3):
    # 加载训练集
    dataArr, testDataArr, labelArr, testLabelArr = loadCSVfile2()
    # 根据训练集计算b, alphas
    b, alphas = smoP(dataArr, labelArr, 200, 0.0001, 100, ('rbf', k1))
    datMat = np.mat(dataArr)
    labelMat = np.mat(labelArr).transpose()
    # 获得支持向量
    svInd = np.nonzero(alphas.A > 0)[0]
    sVs = datMat[svInd]
    labelSV = labelMat[svInd]
    print("支持向量个数:%d" % np.shape(sVs)[0])
    m, n = np.shape(datMat)
    errorCount = 0
    for i in range(m):
        # 计算各个点的核
        kernelEval = kernelTrans(sVs, datMat[i, :], ('rbf', k1))
        # 根据支持向量的点计算超平面,返回预测结果
        predict = kernelEval.T * np.multiply(labelSV, alphas[svInd]) + b
        # 返回数组中各元素的正负号,用1和-1表示,并统计错误个数
        if np.sign(predict) != np.sign(labelArr[i]):
            errorCount += 1
    # 打印错误率
    print('训练集错误率:%.2f%%' % ((float(errorCount) / m) * 100))
    # showDataSet(dataArr, labelMat)
    # 加载测试集
    dataArr = testDataArr
    labelArr = testLabelArr
    errorCount = 0
    datMat = np.mat(dataArr)
    labelMat = np.mat(labelArr).transpose()
    m, n = np.shape(datMat)
    for i in range(m):
        # 计算各个点的核
        kernelEval = kernelTrans(sVs, datMat[i, :], ('rbf', k1))
        # 根据支持向量的点计算超平面,返回预测结果
        predict = kernelEval.T * np.multiply(labelSV, alphas[svInd]) + b
        # 返回数组中各元素的正负号,用1和-1表示,并统计错误个数
        if np.sign(predict) != np.sign(labelArr[i]):
            errorCount += 1
    # 打印错误率
    print('测试集错误率:%.2f%%' % ((float(errorCount) / m) * 100))
    return (float(errorCount) / m) * 100


if __name__ == '__main__':
    sumerrorrate = 0.0
    for i in range(10):
        sumerrorrate += testRbf()
        print("第%d次测试完成" % i)
    print("平均错误率:%.2f%%" % (sumerrorrate / 10))

运行结果如下:

在这里插入图片描述

具体代码可以参见:

https://github.com/vistor985/-.git

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值