本篇主要內(nèi)容:SVR
SVM解決回歸問題
前面我們說過SVM不只可以解決分類問題,也可以解決回歸問題,現(xiàn)在就簡要敘述下SVM如何解決回歸問題。
所謂回歸問題其實就是找到一條擬合曲線,使得預測輸出能與真值盡可能地接近,同時面對未知數(shù)據(jù)又要有很好的泛化能力。在線性回歸中我們是讓MSE的值達到最小,與線性回歸不同,支撐向量機回歸(Support Vector Regression,下簡稱SVR)能容忍模型輸出與真實值最多有的誤差,只有模型輸出與真實值的誤差超過
時才去計算損失值。如圖所示,這相當于以回歸直線為中心,構(gòu)建了一個寬度為
的間隔帶,只要訓練樣本落入此間則認為預測是準確的,否則才去計算損失值。

于是可以定義損失函數(shù):
其中C是正則化常數(shù),是
-不敏感損失函數(shù)。最終SVR問題又被轉(zhuǎn)化為數(shù)學上的一個最優(yōu)化問題(該最優(yōu)化問題的求解自行翻閱機器學習教材),通過指定超參數(shù)C和
求解該模型,即可得到回歸方程。SVR不只可以進行線性回歸,通過核函數(shù)的作用,SVR同樣能解決非線性回歸。
下面在模擬數(shù)據(jù)集上使用SVR進行回歸,宏觀感受一下SVR的效果:
import numpy as np
import matplotlib.pyplot as plt
x = np.random.uniform(-3,3,size=100)
X = x.reshape(-1,1)
y = 0.5 * x**2 +x +2 +np.random.normal(0,1,size=100)
plt.scatter(x,y)
plt.show()

這個數(shù)據(jù)集符合的真實回歸曲線是,加入了一定的標準Gauss噪音。
首先使用線性SVR進行回歸,為線性SVR過程創(chuàng)建Pipeline:
def StandardLinearSVR(epsilon=0.1):
return Pipeline([
('std_scaler',StandardScaler())
,('linearSVC',LinearSVR(epsilon=epsilon))
])
訓練一個線性SVR并繪制出回歸曲線:
svr = LinearSVR()
svr.fit(X,y)
y_predict = svr.predict(X)
plt.scatter(x,y)
plt.plot(np.sort(x),y_predict[np.argsort(x)],color='r')#有序排序后繪制曲線
plt.show()
回歸曲線和R方值:


由回歸曲線和R方值可見線性SVR在這個數(shù)據(jù)集上的效果一般,雖然有一定的線性關(guān)系,但是線性關(guān)系不強烈。因為模擬數(shù)據(jù)實際符合的是二次曲線。下面換用帶核函數(shù)的SVR進行該回歸任務。首先修改Pipeline:
def StandardSVR(epsilon=0.1,degree=3,C=1.0):
return Pipeline([
('std_scaler',StandardScaler())
,('SVC',SVR(kernel='poly',degree=degree,C=C))
])
訓練一個帶多項式核函數(shù)的SVR并繪制回歸曲線:
'''使用非線性SVR'''
svr2 = SVR(degree=2)
svr2.fit(X,y)
y_predict2 = svr2.predict(X)
plt.scatter(x,y)
plt.plot(np.sort(x),y_predict2[np.argsort(x)],color='r')#有序排序后繪制曲線
plt.show()


此時回歸曲線已經(jīng)和真實的趨勢非常接近,而且R方值相比于線性SVR要優(yōu)秀許多。實際中還是要進行多次參數(shù)調(diào)節(jié),可以通過網(wǎng)格搜索方式來尋找最優(yōu)模型。