机器学习系列(三十四)——支撑向量回归(SVR)
2019-07-29 本文已影响20人
Ice_spring
本篇主要内容:SVR
SVM解决回归问题
前面我们说过SVM不只可以解决分类问题,也可以解决回归问题,现在就简要叙述下SVM如何解决回归问题。
所谓回归问题其实就是找到一条拟合曲线,使得预测输出能与真值尽可能地接近,同时面对未知数据又要有很好的泛化能力。在线性回归中我们是让MSE的值达到最小,与线性回归不同,支撑向量机回归(Support Vector Regression,下简称SVR)能容忍模型输出与真实值最多有的误差,只有模型输出与真实值的误差超过时才去计算损失值。如图所示,这相当于以回归直线为中心,构建了一个宽度为的间隔带,只要训练样本落入此间则认为预测是准确的,否则才去计算损失值。
于是可以定义损失函数:
其中C是正则化常数,是-不敏感损失函数。最终SVR问题又被转化为数学上的一个最优化问题(该最优化问题的求解自行翻阅机器学习教材),通过指定超参数C和求解该模型,即可得到回归方程。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()
数据集
这个数据集符合的真实回归曲线是,加入了一定的标准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方值:
线性SVR 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()
poly_d2
R方
此时回归曲线已经和真实的趋势非常接近,而且R方值相比于线性SVR要优秀许多。实际中还是要进行多次参数调节,可以通过网格搜索方式来寻找最优模型。