# SVM总结及SMO简单实现

http://blog.chinaunix.net/uid-28311809-id-4267135.html

1. -*- coding: utf--*
2. from numpy import *
3. import pylab as pl
4. class my_svm(object):
5.     def __init__(self,filename,c=6,tol=0.001,miter=30):
6.         self.filename = filename;
7.         self.= c;
8.         self.tol = tol;
9.         self.miter = miter;
10.         self.support_vector = [];
12.         dataMat = []; labelMat = [];
13.         fr = open(self.filename);
15.             lineArr = line.strip().split('\t');
16.             dataMat.append([float(lineArr[0]), float(lineArr[1])]);
17.             labelMat.append(float(lineArr[2]));
18.         return mat(dataMat),mat(labelMat).transpose();
19.     def rand_select_j(self,i):
20.         j=i;
21.         while j==i:
22.             j = int(random.uniform (self.m));
23.         return j;
24.     def sample_svm(self):
25.         '''alphs*Y*<X,Xi>+b'''
27.         self.m,self.= shape(self.X);
28.         self.alpha = mat(zeros((self.m,1)));
29.         self.b=iter=0;
30.         while iter<self.miter:
31.             alpha_change=0;
32.             for i in range(self.m):
33.                 '''求解Xi的预测值和误差'''
34.                 '''multiply和矩阵乘法是不一样的'''
35.                 Xi = float(multiply(self.alpha,self.Y).T*(self.X*self.X[i,:].T))+self.b;
36.                 err_i = Xi - float(self.Y[i]);
37.                 if (err_i*self.Y[i]<-self.tol and self.alpha[i]<self.C) or (err_i*self.Y[i]>self.tol and self.alpha[i]>0):
38.                     j = self.rand_select_j(i);
39.                     '''随机选择另一个确定其误差，SMO的关键就是选择两个变量同时变化'''
40.                     Xj = float(multiply(self.alpha,self.Y).T*(self.X*self.X[j,:].T))+self.b;
41.                     err_j = Xj - float(self.Y[j]);
42.                     alpha_i_old,alpha_j_old = self.alpha[i].copy(), self.alpha[j].copy();
43.                     '''求解H和L'''
44.                     if self.Y[i] == self.Y[j]:
45.                         L = float(max(0,self.alpha[i]+self.alpha[j]-self.C));
46.                         H = float(min(self.C,self.alpha[i]+self.alpha[j]));
47.                     else:
48.                         L = float(max(0,self.alpha[j]-self.alpha[i]));
49.                         H = float(min(self.C,self.C+self.alpha[j]-self.alpha[i]));
50.                     if L == H:
51.                         continue;
52.                     '''alpha的增量为：Y2*(err_1-err_2)/(K11+K22-2K12)统计学习方法上有详细的证明，其中K是核函数'''
53.                     eta = float(self.X[i,:]*self.X[i,:].T+self.X[j,:]*self.X[j,:].T-2.0*self.X[i,:]*self.X[j,:].T);
54.                     if 0==eta:
55.                         continue;
56.                     self.alpha[j] += self.Y[j]*(err_i-err_j)/eta;
57.                     '''根据限制条件：0<=alpha_j<=C,确定最终的alpha_j'''
58.                     if self.alpha[j] > H:
59.                         self.alpha[j] = H;
60.                     if self.alpha[j] < L:
61.                         self.alpha[j] = L;
62.                     #print("alpha[j]: ",float(alpha[j]),"alpha_j_old: ",float(alpha_j_old));
63.                     if (abs(float(self.alpha[j])-float(alpha_j_old))<0.00001):
64.                         '''alpha的变化太小'''
65.                         #print("alpha的变化太小");
66.                         continue;
67.                     '''两个alpha变化大小相同，单方向相反'''
68.                     self.alpha[i] += self.Y[j]*self.Y[i]*(alpha_j_old-self.alpha[j]);
69.                     '''下面确定b，主要是通过新的alpha_i和alpha_j来确定b,主要运用两个公式，统计学习方法（130）'''
70.                     b1 = self.- err_i- self.Y[i]*(self.alpha[i]-alpha_i_old)*self.X[i,:]*self.X[i,:].- self.Y[j]*(self.alpha[j]-alpha_j_old)*self.X[i,:]*self.X[j,:].T
71.                     b2 = self.- err_j- self.Y[i]*(self.alpha[i]-alpha_i_old)*self.X[i,:]*self.X[j,:].- self.Y[j]*(self.alpha[j]-alpha_j_old)*self.X[j,:]*self.X[j,:].T
72.                     if (< self.alpha[i]) and (self.> self.alpha[i]):
73.                         b = b1
74.                     elif (< self.alpha[j]) and (self.> self.alpha[j]):
75.                         self.= b2
76.                     else:
77.                         self.= (b1 + b2)/2.0
78.                     alpha_change = alpha_change + 1;
79.             if 0 == alpha_change:
80.                 iter+=1;
81.             else:
82.                 iter = 0;
83.         self.__calculate_support_vector_and_weight_();
84.     def __calculate_support_vector_and_weight_(self):
85.         '''我们根据KKT条件给出支持向量，也就是alpha不等于0的项'''
86.         '''我们根据公式为：alpha*Y*X求解w'''
87.         self.= zeros((self.n,1));
88.         for i in range(self.m):
89.             if self.alpha[i]:
90.                 self.support_vector.append([self.X[i].getA()[0][0],self.X[i].getA()[0][1]]);
91.                 self.+= multiply(self.alpha[i]*self.Y[i],self.X[i,:].T);
92.         self.support_vector = mat(self.support_vector);
93.     def plot_svm(self):
94.         X = []; Y = [];
95.         fr = open(self.filename);
97.             lineArr = line.strip().split('\t');
98.             X.append([float(lineArr[0]), float(lineArr[1])]);
99.             Y.append(float(lineArr[2]));
100.         X=mat(X);
101.         a = -self.w[0]/self.w[1];
102.         XX = linspace(-5, 15);
103.         YY = a * XX - (self.b[0].getA1()[0])/self.w[1];
104.         pl.plot(XX, YY, 'k-');
105.         pl.scatter(X[:, 0], X[:, 1], c=Y, cmap=pl.cm.Paired);
106.         pl.axis('tight');
107.         pl.show();

• 本文已收录于以下专栏：

举报原因： 您举报文章：SVM总结及SMO简单实现 色情 政治 抄袭 广告 招聘 骂人 其他 (最多只允许输入30个字)