回归和分类从某种意义上讲,本质上是一回事。SVM分类,就是找到一个平面,让两个分类集合的支持向量或者所有的数据(LSSVM)离分类平面最远;SVR回归,就是找到一个回归平面,让一个集合的所有数据到该平面的距离最近。
  我们来推导一下SVR。根据支持向量机二分类博客所述,数据集合归一化后,某个元素到回归平面的距离为r=d(x)g(x)<script type="math/tex" id="MathJax-Element-1">r=d(x)-g(x)</script>。另外,由于数据不可能都在回归平面上,距离之和还是挺大,因此所有数据到回归平面的距离可以给定一个容忍值ε防止过拟合。该参数是经验参数,需要人工给定。如果数据元素到回归平面的距离小于ε,则代价为0。SVR的代价函数可以表示为:

cost(x)=max(0,|d(x)g(x)|ε)
<script type="math/tex; mode=display" id="MathJax-Element-521">cost(x)=max(0,|d(x)-g(x)|-ε)</script>
其中d是标准答案。考虑松弛变量ξi,ξi<script type="math/tex" id="MathJax-Element-522">\xi_i,\xi_i^*</script>,分别代表上下边界的松弛因子。有约束条件:
{d(xi)g(xi)<ε+ξi,ξi0g(xi)d(xi)<ε+ξi,ξi0
<script type="math/tex; mode=display" id="MathJax-Element-523">\begin{cases}d(x_i)-g(x_i)<\varepsilon+\xi_i,\xi_i \ge0 \\ g(x_i)-d(x_i)<\varepsilon+\xi_i^*,\xi_i^* \ge0\end{cases}</script>
我们实际上是要最小化ξi,ξi<script type="math/tex" id="MathJax-Element-524">\xi_i,\xi_i^*</script>。我们为了获得w的稀疏解,且假设w的计算结果满足正态分布,根据贝叶斯线性回归模型,对w有L2范数约束。
  SVR可以转变为最优化问题:
Φ(x)=i(ξi+ξi)+12CwTwΦ(x)=Ci(ξi+ξi)+12wTw
<script type="math/tex; mode=display" id="MathJax-Element-525">\Phi(x)=\sum_i(\xi_i+\xi_i^*)+\frac{1}{2}C'w^Tw \\ \rightarrow \Phi(x)=C\sum_i(\xi_i+\xi_i^*)+\frac{1}{2}w^Tw</script>
其中C是惩罚因子,是人为给定的经验参数。考虑约束条件,引入拉格朗日算子α,α,β,β<script type="math/tex" id="MathJax-Element-526">\alpha,\alpha^*,\beta,\beta^*</script>,将最优化问题转化为对偶问题:
J=12wTw+Ci(ξi+ξi)+iαi[d(xi)g(xi)εξi]+iαi[g(xi)d(xi)εξi]iβiξiiβiξi
<script type="math/tex; mode=display" id="MathJax-Element-527">J=\frac{1}{2}w^Tw+C\sum_i(\xi_i+\xi_i^*)+\sum_i\alpha_i[d(x_i)-g(xi)-\varepsilon-\xi_i]+\sum_i\alpha_i^*[g(x_i)-d(x_i)-\varepsilon-\xi_i^*]-\sum_i\beta_i\xi_i-\sum_i\beta_i^*\xi_i^*</script>
然后分别求导得到:
Jw=w(iαixiiαixi)=0Jb=i(αiαi)=0Jξi=Cαiβi=0Jξi=Cαiβi=0C=αi+βi=αi+βi
<script type="math/tex; mode=display" id="MathJax-Element-528">\frac{\partial J}{\partial w}=w-(\sum_i\alpha_ix_i-\sum_i\alpha_i^*x_i)=0 \\ \frac{\partial J}{\partial b}=\sum_i(\alpha_i-\alpha^*_i)=0\\ \frac{\partial J}{\partial \xi_i}=C-\alpha_i-\beta_i=0 \\ \frac{\partial J}{\partial \xi_i^*}=C-\alpha_i^*-\beta_i^*=0 \\ C=\alpha_i+\beta_i=\alpha_i^*+\beta_i^*</script>

  将上述式子代入J函数有:

J=12wTwi(αiαi)wxibi(αiαi)i(αi+αi)ε+i(αiαi)d(xi)+Ci(ξi+ξi)iαiξiiαiξii(Cαi)ξii(Cαi)ξi=12(iαixiiαixi)(jαjxjjαjxj)(iαixiiαixi)(jαjxjjαjxj)i(αi+αi)ε+i(αiαi)d(xi)=12ij(αiαi)(αjαj)xixji(αi+αi)ε+i(αiαi)d(xi)subject to 0αi,αiC
<script type="math/tex; mode=display" id="MathJax-Element-529">J=\\ \frac{1}{2}w^Tw-\sum_i(\alpha_i-\alpha_i^*)wx_i-b\sum_i(\alpha_i-\alpha_i^*)-\sum_i(\alpha_i+\alpha_i^*)\varepsilon+\sum_i(\alpha_i-\alpha_i^*)d(x_i)\\+C\sum_i(\xi_i+\xi_i^*)-\sum_i\alpha_i\xi_i-\sum_i\alpha_i^*\xi_i^*-\sum_i(C-\alpha_i)\xi_i-\sum_i(C-\alpha_i^*)\xi_i^* \\=\frac{1}{2}(\sum_i\alpha_ix_i-\sum_i\alpha_i^*x_i)(\sum_j\alpha_jx_j-\sum_j\alpha_j^*x_j) - (\sum_i\alpha_ix_i-\sum_i\alpha_i^*x_i)(\sum_j\alpha_jx_j-\sum_j\alpha_j^*x_j)\\ -\sum_i(\alpha_i+\alpha_i^*)\varepsilon+\sum_i(\alpha_i-\alpha_i^*)d(x_i)\\ =-\frac{1}{2}\sum_i\sum_j(\alpha_i-\alpha_i^*)(\alpha_j-\alpha_j^*)x_ix_j -\sum_i(\alpha_i+\alpha_i^*)\varepsilon+\sum_i(\alpha_i-\alpha_i^*)d(x_i) \\subject to 0≤\alpha_i,\alpha_i^*≤C</script>
其中ξ,ξ,β,β<script type="math/tex" id="MathJax-Element-530">\xi,\xi^*,\beta,\beta^*</script>都在计算过程中抵消了,非常神奇。ε,C<script type="math/tex" id="MathJax-Element-531">\varepsilon,C</script>则是人为给定的参数,是常量。如果要使用核函数,可以将上式写成:
J=12ij(αiαi)(αjαj)k(xixj)i(αi+αi)ε+i(αiαi)d(xi)
<script type="math/tex; mode=display" id="MathJax-Element-532">J=-\frac{1}{2}\sum_i\sum_j(\alpha_i-\alpha_i^*)(\alpha_j-\alpha_j^*)k(x_ix_j) -\sum_i(\alpha_i+\alpha_i^*)\varepsilon+\sum_i(\alpha_i-\alpha_i^*)d(x_i)</script>
  SVR的代价函数和SVM的很相似,但是最优化的对象却不同,对偶式有很大不同,解法同样都是基于拉格朗日的最优化问题解法。求解这类问题的早期解法非常复杂,后来出来很多新的较为简单的解法,对数学和编程水平要求高,对大部分工程学人士来说还是颇为复杂和难以实现,因此大牛们推出了一些SVM库。比较出名的有libSVM,该库同时实现了SVM和SVR。
  我们来看一个简单的例子,数据为[-5.0,9.0]的随机数组,函数为y=12x2+3x+5+noise<script type="math/tex" id="MathJax-Element-533">y=\frac{1}{2}x^2+3x+5+noise</script>,我分别使用三种核SVR:两种惩罚系数rbf和一种poly。结果如下:
  
from sklearn import svm
import numpy as np
from matplotlib import pyplot as plt 

X = np.arange(-5.,9.,0.1)
X=np.random.permutation(X)
X_=[[i] for i in X]
#print X
b=5.
y=0.5 * X ** 2.0 +3. * X + b + np.random.random(X.shape)* 10.
y_=[i for i in y]

rbf1=svm.SVR(kernel='rbf',C=1, )#degree=2,,gamma=, coef0=
rbf2=svm.SVR(kernel='rbf',C=20, )#degree=2,,gamma=, coef0=
poly=svm.SVR(kernel='poly',C=1,degree=2)
rbf1.fit(X_,y_)
rbf2.fit(X_,y_)
poly.fit(X_,y_)
result1 = rbf1.predict(X_)
result2 = rbf2.predict(X_)
result3 = poly.predict(X_)
plt.hold(True)
plt.plot(X,y,'bo',fillstyle='none')
plt.plot(X,result1,'r.')
plt.plot(X,result2,'g.')
plt.plot(X,result3,'c.')
plt.show()

这里写图片描述
蓝色是poly,红色是c=1的rbf,绿色是c=20的rbf。其中效果最好的是c=20的rbf。如果我们知道函数的表达式,线性规划的效果更好,但是大部分情况下我们不知道数据的函数表达式,因此只能慢慢试验,SVM的作用就在这里了。就我来看,SVR的回归效果不如神经网络。
  csdn的blog不知为何抽风了,只好重新写了一下。

Logo

一站式虚拟内容创作平台,激发创意,赋能创作,进入R空间,遇见同道,让优质作品闪耀发光。​

更多推荐