機器學習系列(三十四)——支撐向量迴歸(SVR)

本篇主要內容:SVR

SVM解決迴歸問題

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

於是可以定義損失函數:
loss=\frac{1}{2}||w||^2+C\sum_{i=1}^{m}l_{\epsilon}(f(x_i)-y_i)

其中C是正則化常數,l_{\epsilon}\epsilon-不敏感損失函數。最終SVR問題又被轉化爲數學上的一個最優化問題(該最優化問題的求解自行翻閱機器學習教材),通過指定超參數C和\epsilon求解該模型,即可得到迴歸方程。SVR不只可以進行線性迴歸,通過核函數的作用,SVR同樣能解決非線性迴歸。
下面在模擬數據集上使用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()

這個數據集符合的真實迴歸曲線是y=0.5x^2+x+2,加入了一定的標準Gauss噪音。
首先使用線性SVR進行迴歸,爲線性SVR過程創建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在這個數據集上的效果一般,雖然有一定的線性關係,但是線性關係不強烈。因爲模擬數據實際符合的是二次曲線。下面換用帶核函數的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))
    ])

訓練一個帶多項式核函數的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()

此時迴歸曲線已經和真實的趨勢非常接近,而且R方值相比於線性SVR要優秀許多。實際中還是要進行多次參數調節,可以通過網格搜索方式來尋找最優模型。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章