SVM简单代码实现错题本

一.题目

SVM简易代码实现

二.正确答案

def smoSimple(dataMatIn, classLabels, C, toler, maxIter):
    dataMatrix = mat(dataMatIn); labelMat = mat(classLabels).transpose()
    #初始化b为0
    b=0
    #获取数据维度
    m,n = shape(dataMatrix)
    #初始化所有alpha为0
    alphas = mat(zeros((m,1)))
    iter = 0
    #迭代求解
    while (iter < maxIter):
        alphaPairsChanged = 0
        for i in range(m):
            #计算g(xi)
            gXi = float(multiply(alphas,labelMat).T*(dataMatrix*dataMatrix[i,:].T))+b
            #计算Ei
            Ei = gXi-float(labelMat[i])
            if ((labelMat[i]*Ei < -toler) and (alphas[i] < C)) or ((labelMat[i]*Ei > toler) and (alphas[i] > 0)):
                #随机选择一个待优化的alpha(先随机出alpha下标)
                j = selectJrand(i,m)
                #计算g(xj)
                gXj = float(multiply(alphas,labelMat).T*(dataMatrix*dataMatrix[j,:].T))+b
                #计算Ej
                Ej = gXj-float(labelMat[j])
                #把原来的alpha值复制,作为old值
                alphaIold = alphas[i].copy(); alphaJold = alphas[j].copy();
                #计算上下界
                if (labelMat[i] != labelMat[j]):
                    L = max(0,alphas[j]-alphas[i])
                    H = min(C,C+alphas[j]-alphas[i])
                else:
                    L = max(0,alphas[j]+alphas[i]-C)
                    H = min(C,alphas[j]+alphas[i])
                if L==H: print("L==H"); continue
                #计算eta
                eta = 2*dataMatrix[i,:]*dataMatrix[j,:].T-dataMatrix[i,:]*dataMatrix[i,:].T-dataMatrix[j,:]*dataMatrix[j,:].T
                if eta >= 0: print("eta>=0"); continue
                #计算alpha[j],为了和公式对应把j看出2
                alphas[j]-=labelMat[j]*(Ei-Ej)/eta
                #剪辑alpha[j],为了和公式对应把j看出2
                alphas[j] = clipAlpha(alphas[j],H,L)
                if (abs(alphas[j] - alphaJold) < 0.00001): print("j not moving enough"); continue
                #计算alpha[i] ,为了和公式对应把j看出1
                alphas[i] += labelMat[i]*labelMat[j]*(alphaJold-alphas[j])
                #计算b1
                b1 = -Ei-labelMat[i]*(dataMatrix[i,:]*dataMatrix[i,:].T)*(alphas[i]-alphaIold)-labelMat[j]*(dataMatrix[j,:]*dataMatrix[i,:].T)*(alphas[j]-alphaJold)+b
                #计算b2
                b2 = b - Ej- labelMat[i]*(alphas[i]-alphaIold)*dataMatrix[i,:]*dataMatrix[j,:].T - labelMat[j]*(alphas[j]-alphaJold)*dataMatrix[j,:]*dataMatrix[j,:].T
                #求解b
                if (0 < alphas[i]) and (C > alphas[i]): b = b1
                elif (0 < alphas[j]) and (C > alphas[j]): b = b2
                else: b = (b1 + b2)/2.0
                alphaPairsChanged += 1
                print("iter: %d i:%d, pairs changed %d" % (iter,i,alphaPairsChanged))
        if (alphaPairsChanged == 0): iter += 1
        else: iter = 0
        print("iteration number: %d" % iter)
    return b,alphas

三.我当时是怎么错的

1.用几个词或者短句描述自己的思维过程

想通过分块分别求出未知数或者算式,再将它们合并到一起

2.我有没有基础知识点、公式上的错误

3.对照正确答案,我卡在哪一步了

1.计算eta以及计算alpha[j]

eta=multiply(dataMatrix[i,:],dataMatrix[i,:])+multiply(dataMatrix[j,:],dataMatrix[j,:])-2*multiply(dataMatrix[i,:],dataMatrix[j,:])
alphas[j] += labelMat[j]*(Ei-Ej)/eta

2.计算b1

b1 = -Ei-labelMat[i]*multiply(dataMatrix[i,:],dataMatrix[i,:]).T*(alphas[i]-alphaIold)-labelMat[j]*multiply(dataMatrix[j,:],dataMatrix[i,:]).T*(alphas[j]-alphaJold)+b

4.卡住的这一步是哪里出了问题

4.1陌生的解题技巧没见过

4.2已有的解题技巧没想到(模式识别)

1.为什么我没有做出来?

1.因为我只是认为老师不过是想换一下计算顺序而且,而换计算顺序对结果不会起太大影响
2.没有分清multiply和*的功能,乱用

2.我的方法为什么不行,哪一步走不下去了?

1.公式完全错了,图画不了
2.用点对点的相乘应用到行对列的相乘,使它们的结果变成了两个不同的数组

3.换个角度的话能不能利用现有条件做下去?

1.给eta的计算式上添加符号
2.将multiply后的一列数相加求和,得到dot后的结果

3.1如果不行的话是什么限制了它?
4.原答案是如何想到下面的思路的?我哪一步想差了?

1.因为接下来与eta相除的Ej和Ei以及labelMat[j]都是1行1列的数,所以eta的最终值必须为1行1列的数值去匹配,因此multiply的结果为1行2列以及在第一个数上加转置再使用dot乘法也是1行2列都不符合,最后在第二个数上加转置再使用dot乘法最终得到1行1列的结果。
我天真地以为multiply就是将两个数胡乱相乘的方法,结果导致的是要么是计算错误要么是得出不同维度的数组在下一个计算中出错
2.同上,以为Ei和b都是1行1列的数组,因此dataMatrix[j,:]以及dataMatrix[j,:]的结果必然为1行1列的数值

4.1由哪个或者哪些条件导致了这个解题步骤的出现?

1.Ei————》gXi——————》b
2.b

5.这种条件可以用到哪些地方? 有没有题和它类似,可以形成一种题型?

5.需不需要用到其他思维方法

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值