700字范文,内容丰富有趣,生活中的好帮手!
700字范文 > 机器学习实战之支持向量机

机器学习实战之支持向量机

时间:2019-10-09 13:53:13

相关推荐

机器学习实战之支持向量机

说实话,这一章算是这本书最难理解的部分了,所以挣扎了好几天这才决定想起来写写(其实这几天都看小说去了,哈哈哈哈) 书上给的案例很详细了,所以这篇文章我打算讲讲其他的部分,让大家觉得不那么枯燥。

支持向量机与Logistic回归的区别

当时看完Logistic回归这一部分后,觉得这方法还不错,很多方面都合情合理。但是看到支持向量机这部分后就发觉这两种方法没什么差别吧(不知道刚了解这两种方法的朋友们有没有这样的感觉),都是用一条直线来分割整个平面,只不过一个叫回归直线,另一个叫超平面。但仔细比较后才发现有些不同:

相同点

1、LR和SVM都是分类算法(曾经我认为这个点简直就是废话,了解机器学习的人都知道。然而,虽然是废话,也要说出来,毕竟确实是一个相同点。)

2、如果不考虑使用核函数,LR和SVM都是线性分类模型,也就是说它们的分类决策面是线性的。

其实LR也能使用核函数,但我们通常不会在LR中使用核函数,只会在SVM中使用。原因下面会提及。

3、LR和SVM都是监督学习方法。

监督学习方法、半监督学习方法和无监督学习方法的概念这里不再赘述。

4、LR和SVM都是判别模型。

判别模型和生成模型的概念这里也不再赘述。典型的判别模型包括K近邻法感知机决策树Logistic回归最大熵SVMboosting条件随机等。典型的生成模型包括朴素贝叶斯法隐马尔可夫模型高斯混合模型

5、LR和SVM在学术界和工业界都广为人知并且应用广泛。(感觉这个点也比较像废话)

不同点

1、loss function不一样

LR的loss function是

SVM的loss function是

LR基于概率理论,通过极大似然估计方法估计出参数的值,然后计算分类概率,取概率较大的作为分类结果。SVM基于几何间隔最大化,把最大几何间隔面作为最优分类面。

2、SVM只考虑分类面附近的局部的点,即支持向量,LR则考虑所有的点,与分类面距离较远的点对结果也起作用,虽然作用较小。

SVM中的分类面是由支持向量控制的,非支持向量对结果不会产生任何影响。LR中的分类面则是由全部样本共同决定。线性SVM不直接依赖于数据分布,分类平面不受一类点影响;LR则受所有数据点的影响,如果数据不同类别strongly unbalance,一般需要先对数据做balancing。

3、在解决非线性分类问题时,SVM采用核函数,而LR通常不采用核函数。

分类模型的结果就是计算决策面,模型训练的过程就是决策面的计算过程。在计算决策面时,SVM算法中只有支持向量参与了核计算,即kernel machine的解的系数是稀疏的。在LR算法里,如果采用核函数,则每一个样本点都会参与核计算,这会带来很高的计算复杂度,所以,在具体应用中,LR很少采用核函数。

4、SVM不具有伸缩不变性,LR则具有伸缩不变性。

SVM模型在各个维度进行不均匀伸缩后,最优解与原来不等价,对于这样的模型,除非本来各维数据的分布范围就比较接近,否则必须进行标准化,以免模型参数被分布范围较大或较小的数据影响。LR模型在各个维度进行不均匀伸缩后,最优解与原来等价,对于这样的模型,是否标准化理论上不会改变最优解。但是,由于实际求解往往使用迭代算法,如果目标函数的形状太“扁”,迭代算法可能收敛得很慢甚至不收敛。所以对于具有伸缩不变性的模型,最好也进行数据标准化。

5、SVM损失函数自带正则项,因此,SVM是结构风险最小化算法。而LR需要额外在损失函数上加正则项。

我总结起来就是一句话:支持向量机方法最为强大,因为SVM可以采用核函数,使得其可以解决非线性分类问题

SMO算法

关于SVM算法公式的相关推导我这儿就不写了,网上的文章比比皆是了。我就只想提提关于书中提到的SMO算法的相关推导,因为书中没有具体给出,所以我会详细指出。

fXi = float(multiply(alphas, labelMat).T * (dataMatrix * dataMatrix[i, :].T)) + b

这一步就是这个意思

eta = 2.0 * dataMatrix[i, :] * dataMatrix[j, :].T - dataMatrix[i, :] * dataMatrix[i, :].T - \dataMatrix[j, :] * dataMatrix[j, :].T

这一步就是这个意思

alphas[j] = clipAlpha(alphas[j], H, L)alphas[i] += labelMat[j] * labelMat[i] * (alphaJold - alphas[j])

这一步的意思

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

这一步的意思是

上面的核心步骤写完了下面就直接把源码贴出来

import randomimport smoComfrom os import listdirfrom numpy import mat, shape, zeros, multiply, nonzero, sign# 加载本地数据def loadDataSet(fileName):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 loadImages(dirName):hwLabels = []trainingFileList = listdir(dirName)m = len(trainingFileList)trainingMat = zeros((m, 1024))for i in range(m):fileNameStr = trainingFileList[i]fileStr = fileNameStr.split('.')[0]classNumStr = int(fileStr.split('_')[0])if classNumStr == 9:hwLabels.append(-1)else:hwLabels.append(1)trainingMat[i, :] = img2vector('%s/%s' % (dirName, fileNameStr))return trainingMat, hwLabels# 随机选择不同数def selectJrand(i, m):j = iwhile j == i:j = int(random.uniform(0, m))return j# 用于调整大于H或小于L的alpha值def clipAlpha(aj, H, L):if aj > H:aj = Hif L > aj:aj = Lreturn aj# 将图像转换为向量def img2vector(filename):returnVect = zeros((1, 1024))fr = open(filename)for i in range(32):lineStr = fr.readline()for j in range(32):returnVect[0, 32 * i + j] = int(lineStr[j])return returnVect# 简化版SMO算法def smoSimple(dataMatIn, classLabels, C, toler, maxIter):dataMatrix = mat(dataMatIn)labelMat = mat(classLabels).transpose()b = 0m, n = shape(dataMatrix)alphas = mat(zeros((m, 1)))iter = 0while iter < maxIter:alphsPairsChanged = 0for i in range(m):fXi = float(multiply(alphas, labelMat).T * (dataMatrix * dataMatrix[i, :].T)) + bEi = fXi - float(labelMat[i])if ((labelMat[i] * Ei < -toler) and (alphas[i] < C)) or ((labelMat[i] * Ei > toler) and (alphas[i] > 0)):j = selectJrand(i, m)fXj = float(multiply(alphas, labelMat).T * (dataMatrix * dataMatrix[j, :].T)) + bEj = fXj - float(labelMat[j])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')continueeta = 2.0 * dataMatrix[i, :] * dataMatrix[j, :].T - dataMatrix[i, :] * dataMatrix[i, :].T - \dataMatrix[j, :] * dataMatrix[j, :].Tif eta >= 0:print("eta == 0")continuealphas[j] -= labelMat[j] * (Ei - Ej) / etaalphas[j] = clipAlpha(alphas[j], H, L)if abs(alphas[j] - alphaJold) < 0.00001:print("j not moving enough")continuealphas[i] += labelMat[j] * labelMat[i] * (alphaJold - alphas[j])b1 = b - Ei - labelMat[i] * (alphas[i] - alphaIold) * dataMatrix[i, :] * dataMatrix[i, :].T - labelMat[j] * \(alphas[j] - alphaJold) * dataMatrix[j, :] * dataMatrix[j, :].Tb2 = b - Ej - labelMat[i] * (alphas[i] - alphaIold) * dataMatrix[i, :] * dataMatrix[i, :].T - labelMat[j] * \(alphas[j] - alphaJold) * dataMatrix[j, :] * dataMatrix[j, :].Tif (0 < alphas[i]) and (C > alphas[i]):b = b1elif (0 < alphas[j]) and (C > alphas[j]):b = b2else:b = (b1 + b2)/2.0alphsPairsChanged += 1print("iter: %d i: %d, paris changed %d" % (iter, i, alphsPairsChanged))if alphsPairsChanged == 0:iter += 1else:iter = 0print("iteration number: %d" % iter)return b, alphas

关于这一章节我暂时就只想写到这儿了,说实话我到现在还不能完全理解,所以我只敢写到这儿了,等过段时间我再回头来看看看能不能有些新收获

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。