diff --git a/docs/6.支持向量机.md b/docs/6.支持向量机.md index 2252c626..097161d0 100644 --- a/docs/6.支持向量机.md +++ b/docs/6.支持向量机.md @@ -99,7 +99,7 @@ This is the simplest kind of SVM (Called an LSVM) Support Vectors are those data > 松弛变量(slack variable) -* 我们知道几乎所有的数据都不那么干净, 通过引入松弛变量来允许数据点可以处于分隔面错误的一侧。 +* 我们知道几乎所有的数据都不那么干净, 通过引入松弛变量来`允许数据点可以处于分隔面错误的一侧`。 * 约束条件: \\(C>=a>=0,\ and\ \sum_{i=1}^{m} a_i·label_i=0\\) * 这里常量C用于控制“最大化间隔”和“保证大部分点的函数间隔小于1.0” 这两个目标的权重。 * 常量C是一个常数,我们通过调节该参数得到不同的结果。一旦求出了所有的alpha,那么分隔超平面就可以通过这些alpha来表示。 @@ -126,7 +126,7 @@ SVM的一般流程 * 创建时间:1996年 * SMO用途:用于训练SVM * SMO目标:求出一系列alpha和b,一旦求出alpha,就很容易计算出权重向量w并得到分隔超平面。 -* SMO思想:是讲大优化问题分解为多个小优化问题来求解的。 +* SMO思想:是将大优化问题分解为多个小优化问题来求解的。 * SMO原理:每次循环选择两个alpha进行优化处理,一旦找出一对合适的alpha,那么就增大一个同时减少一个。 * 这里指的合适必须要符合一定的条件 * 1.这两个alpha必须要在间隔边界之外 diff --git a/src/python/6.SVM/svm-complete_Non-Kernel.py b/src/python/6.SVM/svm-complete_Non-Kernel.py index d40a25f0..fe1eafbb 100644 --- a/src/python/6.SVM/svm-complete_Non-Kernel.py +++ b/src/python/6.SVM/svm-complete_Non-Kernel.py @@ -203,7 +203,7 @@ def innerL(i, oS): print("eta>=0") return 0 - # 计算出一个新的alphas[j]值 + # 计算出一个新的alphas[j]值 oS.alphas[j] -= oS.labelMat[j] * (Ei - Ej) / eta # 并使用辅助函数,以及L和H对其进行调整 oS.alphas[j] = clipAlpha(oS.alphas[j], H, L) diff --git a/src/python/6.SVM/svm-simple.py b/src/python/6.SVM/svm-simple.py index 815942ef..51fb4fb9 100644 --- a/src/python/6.SVM/svm-simple.py +++ b/src/python/6.SVM/svm-simple.py @@ -71,14 +71,14 @@ def smoSimple(dataMatIn, classLabels, C, toler, maxIter): C 松弛变量(常量值),允许有些数据点可以处于分隔面的错误一侧。 控制最大化间隔和保证大部分的函数间隔小于1.0这两个目标的权重。 可以通过调节该参数达到不同的结果。 - toler 容错率 + toler 容错率(是指在某个体系中能减小一些因素或选择对某个系统产生不稳定的概率。) maxIter 退出前最大的循环次数 Returns: b 模型的常量值 alphas 拉格朗日乘子 """ dataMatrix = mat(dataMatIn) - # 矩阵转制 和 .T 一样的功能 + # 矩阵转置 和 .T 一样的功能 labelMat = mat(classLabels).transpose() m, n = shape(dataMatrix) @@ -98,7 +98,7 @@ def smoSimple(dataMatIn, classLabels, C, toler, maxIter): # print 'alphas=', alphas # print 'labelMat=', labelMat # print 'multiply(alphas, labelMat)=', multiply(alphas, labelMat) - # 我们预测的类别 y = w^Tx[i]+b; 其中因为 w = Σ(1~n) a[n]lable[n]x[n] + # 我们预测的类别 y = w^Tx[i]+b; 其中因为 w = Σ(1~n) a[n]*lable[n]*x[n] fXi = float(multiply(alphas, labelMat).T*(dataMatrix*dataMatrix[i, :].T)) + b # 预测结果与真实结果比对,计算误差Ei Ei = fXi - float(labelMat[i]) @@ -106,6 +106,8 @@ def smoSimple(dataMatIn, classLabels, C, toler, maxIter): # 约束条件 (KKT条件是解决最优化问题的时用到的一种方法。我们这里提到的最优化问题通常是指对于给定的某一函数,求其在指定作用域上的全局最小值。) # 0<=alphas[i]<=C,但由于0和C是边界值,我们无法进行优化,因为需要增加一个alphas和降低一个alphas。 # 表示发生错误的概率:labelMat[i]*Ei 如果超出了 toler, 才需要优化。至于正负号,我们考虑绝对值就对了。 + # 如果你大于 负错误的概率,那么要求你小于C,这样才可以只优化一边 + # 如果你大于 正错误的概率,那么要求你大于0,这样才可以只优化一边 if ((labelMat[i]*Ei < -toler) and (alphas[i] < C)) or ((labelMat[i]*Ei > toler) and (alphas[i] > 0)): # 如果满足优化的条件,我们就随机选取非i的一个点,进行优化比较 @@ -117,12 +119,14 @@ def smoSimple(dataMatIn, classLabels, C, toler, maxIter): alphaJold = alphas[j].copy() # L和H用于将alphas[j]调整到0-C之间。如果L==H,就不做任何改变,直接执行continue语句 + # labelMat[i] != labelMat[j] 表示异侧,就相减,否则是同侧,就相加。 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