拉格朗日乘子法
求在约束条件 gj(x1,x2,...,xn)=0 的条件下,求 f(x1,x2,...,xn)的极值
引进拉格朗日乘子 a ;建立方程
L(x1,x2,...,xn,a1,a2,...,am)=f(x1,x2,...,xn)+∑mj=1aj∗gj(x1,x2,...,xn)
建立 n+m 个函数的无约束条件的极值,即分别对 x1,x2,...,xn,a1,a2,...,an 求导
KTT条件
gj(x1,x2,...,xn)=0 或者 gj(x1,x2,...,xn)<=0
或者 gj(x1,x2,...,xn)>=0 可以转化为小于号约束,等号约束
L(x,α)=f(x)+∑αigi(x)+∑βihi(x)
其中 g 是不等式约束, h 是等式约束,那么KKT条件就是函数的最优值必定满足下面条件:
构造分析器的原理
如果数据点离决策边界越远,’那么其最后的预测结果也就越可信。
支持向量(support vector):离分隔超平面最近的那些点。(距离:指垂直于直线的点与当前点的距离)
目标函数
min1/2WTW
s.t.yi(Wxi+b)>=1
后续公式推导
svm的一般流程
SMO高效优化算法
from numpy import *
import pylab as pl
def loadDataSet():
dataMat = []
labelMat = []
fr = open('d:\\testSet.txt','r')
for line in fr:
lineArr = line.split('\t',3)
dataMat.append([float(lineArr[0]),float(lineArr[1])])
labelMat.append(float(lineArr[2]))
return dataMat,labelMat
'''
下一个函数3616£^0^1«1()有两个参数值,其中1是第一个&姊 &的下标,1(\是所有3中1^的数
目。只要函数值不等于输人值1 ,函数就会进行随机选择。
'''
def selectJrand(i,m):
j = i;
while j==i :
j = random.randint(0,m-1)
return j
#是用于调整大于H或小于L的alpha值
def clipAlpha(aj,L,H):
if aj>H :
aj = H
if ajreturn aj
#数据集、类别标签、常数 、容错率和取消前最大的循环次数
def smoSimple(dataMatIn ,classLabls ,C, toler, maxIter):
dataMatrix = mat(dataMatIn) #比如之前有m个样例,每个样例有m个数据
labelMat = mat(classLabls).transpose()#生成一个1*m的矩阵
b = 0
m,n = shape(dataMatrix)
alphas = mat(zeros((m,1))) #初始化为m行1列的矩阵,初始值为0
iter = 0 #当前的循环次数
while iter < maxIter:
alphaPairsChanged = 0 #标记是否有修改
for i in range(m):
fxi = float(multiply(alphas,labelMat).T * (dataMatrix*dataMatrix[i,:].T))+b
'''
multiply是numpy的ufunc函数,执行方法是对应元素相乘,而不是线性代数中的矩阵运算方式,类似于matlab中的点乘,当矩阵的维度不相同时,会根据一定的广播规则将维数扩充到一致的形式
* 就表示矩阵乘法
[i,:]是Numpy花式索引
.T就是进行轴对换而transpose则可以接收参数进行更丰富的变换
f(x)=W^T*x+b=sum(alphas(i)*yi*K(x,xi)) +b
w的值可以通过拉格朗日乘子法求偏导为0得到
'''
Ei = fxi - float(labelMat[i]) #误差
#是否可以继续优化
if ((labelMat[i]*Ei < -toler) and (alphas[i] or((labelMat[i]*Ei > toler) and (alphas[i] > 0)):
'''
原理解释:
labelMat[i]*Ei = (fxi - labelMat[i])*labelMat[i] = yi*(W^T*x+b) - 1
拉格朗日的约束条件是yi*(W^T*x+b) >= 1 且 alphas[i](1-yi*(W^T*x+b)) = 0
目标函数是最小化1/2*||w||^2+sum(1-alphas[i]*(yi(w^T*x+b)))
toler表示允许误差
如果labelMat[i]*Ei < -toler,那么表示离分界线太近,不符合,此时alphas[i]应该为C,使答案过大,从而调整
如果labelMat[i]*Ei > toler,那么表示离分界线太远,此时alphas[i]应该为0,符合约束条件alphas[i](1-yi*(W^T*x+b)) = 0
'''
j = selectJrand(i,m) #随机选择第j个样本
fxj = float(multiply(alphas,labelMat).T*(dataMatrix*dataMatrix[j,:].T)) + b
Ej = 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])
'''
a1new y1 + a2new y2 =a1old y1 + a2old = xi
当y1 = y2 = 1,根据a1new的范围->a2new的范围,再与自身的范围进行比较
其余同理
'''
if L==H:
print("L==H")
continue
eta = 2.0 * dataMatrix[i,:]*dataMatrix[j,:].T - dataMatrix[i,:]*dataMatrix[i,:].T - dataMatrix[j,:]*dataMatrix[j,:].T
'''
eta = K11 + K22 - 2K12
推导见http://blog.csdn.net/willbkimps/article/details/54697698
'''
if eta >= 0: print("eta>=0"); continue
alphas[j] -= labelMat[j]*(Ei - Ej)/eta
alphas[j] = clipAlpha(alphas[j],H,L) # 门限函数阻止alpha_j的修改量过大
#如果修改量很微小
if (abs(alphas[j] - alphaJold) < 0.00001): print("j not moving enough"); continue
# alpha_i的修改方向相反
alphas[i] += labelMat[j]*labelMat[i]*(alphaJold - alphas[j])
# 为两个alpha设置常数项b
b1 = b - Ei- labelMat[i]*(alphas[i]-alphaIold)*dataMatrix[i,:]*dataMatrix[i,:].T - labelMat[j]*(alphas[j]-alphaJold)*dataMatrix[i,:]*dataMatrix[j,:].T
b2 = b - Ej- labelMat[i]*(alphas[i]-alphaIold)*dataMatrix[i,:]*dataMatrix[j,:].T - labelMat[j]*(alphas[j]-alphaJold)*dataMatrix[j,:]*dataMatrix[j,:].T
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
dataArr,labelArr = loadDataSet();
b,alphas = smoSimple(dataArr,labelArr,0.6,0.001,40)
核函数
核函数:从某个特征空间到另外一个特征空间的映射。
经过空间转换之后,我们可以在高维空间中解决线性问题,等价于在低维空间中解决非线性问题。
设X是输入空间(欧氏空间或离散集合),Η为特征空间(希尔伯特空间),如果存在一个从X到Η的映射
φ(x): X→Η
使得对所有的x,y∈X,函数Κ(x,y)=φ(x)∙φ(y), 则称Κ(x,y)为核函数,φ(x)为映射函数,φ(x)∙φ(y)为x,y映射到特征空间上的内积。