你玩过放风筝吗?放风筝可有讲究哦,如果你能熟练地控制着那根风筝线,风筝就能在蓝天上自由自在地飞。想象一下,风筝就是你心中追求的那个答案,而风筝线的长短、指向,就像是指引你找到答案的线索。
比如说,你在玩一个猜谜游戏,游戏里给你的提示就像是掌握在手里的风筝线,你得根据这些线索去猜风筝在天空中的具体位置。可是,风筝受风的影响,会不停地在空中变换位置。你的任务就是要依靠手上的这些线索,尽量猜出风筝现在可能在哪儿。
支持向量回归(SVR)就好比是个放风筝的行家里手。首先,他会在脑海中构想出一条完美的理想风筝线,这根线能够让风筝牢牢地定位在一个最佳点上。然后,他允许风筝在这个理想位置周围的一小块区域内自由飘荡,只要风筝不飘出这个区域,他都能接受。他更关注的是那些偏离了这个自由飘荡区域太远的风筝,因为它们脱离了正常的预期范围。
就像一个专注的放风筝人,他会一遍又一遍地调整风筝线的拉力和角度,努力让风筝尽量飞回他心中设想的那个点上。这种不断调整,寻找最合适位置的过程,就是支持向量回归的主旨所在。
你还记得咱们小时候玩的“猜数字”游戏吗?我就随便心里想一个1到10之间的数,然后你来猜。咱们玩的时候,如果你猜的数字不对,我会提示你是猜大了还是猜小了,你根据提示再接着猜,直到猜中为止。
但如果我们把规则改一改,就有点意思了。你还是猜我心里的数字,可这次我不再告诉你猜大了还是小了,我只会告诉你你猜的和我心里数的差了多少。比如说,假设我心里想的是数字3,你如果猜了个5,我就跟你说:“差了2”。你猜的越接近,我就认为你猜得越好。
这个改头换面的新游戏,其实和一个数学上的东西挺像,那就是支持向量回归,简称SVR。你可以把SVR想象成一个特别会玩儿“猜数字”游戏的高手。它不靠我告诉你猜大了还是小了,而是通过观察你和正确答案的差距,来不断调整自己的猜测。它的目的就是要把这个差距弄得尽可能小,这个过程就叫做“最优化”。
所以呢,即便我们没直接把正确答案告诉SVR,它也能通过自己聪明的方法,一步步逼近真正的答案,最后猜出一个相当准确的数来。这就是SVR这个数学工具的聪明之处。
支持向量回归(Support Vector Regression,SVR)是支持向量机(SVM)在回归问题上的应用。SVR用于预测一个连续的输出变量,相比于分类任务的SVM,其主要区别在于构造的不再是一个最大间隔的超平面,而是构造一个与目标函数值间隔在一定范围内(ε-insensitive)的最小超平面。
与SVM一样,SVR也可以通过引入核函数来解决非线性问题。通过核技巧,SVR能将原始特征空间映射为更高维的特征空间,以便找到在更高维空间中的线性回归模型。
直观理解,SVR的目标是找到一个函数 ,尽可能接近所有样本点,但忽略掉位于ε-tube(由训练误差 ε 定义)之内的预测误差。其数学定义涉及到解决以下优化问题:
SVR的优化问题可以表示为:
进行下列约束:
这里 和 是预测函数的参数,; 和 是正的缓冲变量,用于处理不在ε-tube内的样本; 是用于控制模型复杂度与训练误差之间平衡的正则化参数; 是我们希望预测函数逼近目标值的精度。
引入拉格朗日乘子, 这个问题可以通过求解对偶问题来解决,我们最后得到的优化问题是:
限制为:
求解完上述问题,得到每个样本对应的 和 后,我们可以通过下式计算对新样本 的预测值:
在SVR中,仅当样本点不落在 间的隔带中时,相应的 和 才能取非零值,这些样本点被称为“支持向量”。这就表示,SVR的解只与部分训练样本(支持向量)有关,这称为SVR的稀疏性。
同样,SVR也可以引入核函数 来处理非线性问题,从而获得非线性的SVR模型。最后的模型则为:
具体可参考准确性评价指标 的回归/时间序列问题。
1import matplotlib.pyplot as plt
2from sklearn.svm import SVR
3from sklearn import datasets
4from sklearn.model_selection import train_test_split, GridSearchCV
5from sklearn.preprocessing import StandardScaler
6from sklearn.metrics import mean_squared_error, r2_score
7plt.rcParams['font.sans-serif'] = ['SimHei']
8import numpy as np
9
10# 加载波士顿房价数据集
11boston = datasets.load_boston()
12
13# 切分训练集和测试集
14X_train, X_test, y_train, y_test = train_test_split(boston.data, boston.target, test_size=0.2, random_state=42)
15
16# 数据标准化
17scaler_x = StandardScaler()
18X_train_std = scaler_x.fit_transform(X_train)
19X_test_std = scaler_x.transform(X_test)
20
21scaler_y = StandardScaler()
22y_train_std = scaler_y.fit_transform(y_train.reshape(-1,1)).ravel()
23y_test_std = scaler_y.transform(y_test.reshape(-1,1)).ravel()
24
25# 设置待测试的参数
26param_grid = {"C": [1e0, 1e1, 1e2, 1e3],
27 "gamma": np.logspace(-2, 2, 5)}
28
29# 利用GridSearchCV寻找最优参数
30model = GridSearchCV(SVR(kernel='rbf', gamma=0.1), cv=5, param_grid=param_grid)
31model.fit(X_train_std, y_train_std)
32
33# 打印最优参数
34print("The best parameters are %s with a score of %0.2f" % (model.best_params_, model.best_score_))
35
36# 做预测
37y_pred = model.predict(X_test_std)
38
39# 打印R2分数和均方误差
40print('R2 score: ', r2_score(y_test_std, y_pred))
41print('Mean squared error: ', mean_squared_error(y_test_std, y_pred))
42
43# 绘图
44plt.scatter(y_test_std, y_pred, color='blue')
45plt.plot([y_test_std.min(), y_test_std.max()], [y_test_std.min(), y_test_std.max()], 'k--', lw=3)
46plt.xlabel('真实值')
47plt.ylabel('预测值')
48plt.title('SVR预测结果显示')
49plt.grid()
50plt.show()
1import matplotlib.pyplot as plt
2from sklearn.svm import SVR
3from sklearn import datasets
4from sklearn.model_selection import train_test_split, GridSearchCV
5from sklearn.preprocessing import StandardScaler
6from sklearn.metrics import mean_squared_error, r2_score
7plt.rcParams['font.sans-serif'] = ['SimHei']
8import numpy as np
9
10# 加载波士顿房价数据集
11boston = datasets.load_boston()
12
13# 切分训练集和测试集
14X_train, X_test, y_train, y_test = train_test_split(boston.data, boston.target, test_size=0.2, random_state=42)
15
16# 数据标准化
17scaler_x = StandardScaler()
18X_train_std = scaler_x.fit_transform(X_train)
19X_test_std = scaler_x.transform(X_test)
20
21scaler_y = StandardScaler()
22y_train_std = scaler_y.fit_transform(y_train.reshape(-1,1)).ravel()
23y_test_std = scaler_y.transform(y_test.reshape(-1,1)).ravel()
24
25# 设置待测试的参数
26param_grid = {"C": [1e0, 1e1, 1e2, 1e3],
27 "gamma": np.logspace(-2, 2, 5)}
28
29# 利用GridSearchCV寻找最优参数
30model = GridSearchCV(SVR(kernel='rbf', gamma=0.1), cv=5, param_grid=param_grid)
31model.fit(X_train_std, y_train_std)
32
33# 打印最优参数
34print("The best parameters are %s with a score of %0.2f" % (model.best_params_, model.best_score_))
35
36# 做预测
37y_pred = model.predict(X_test_std)
38
39# 打印R2分数和均方误差
40print('R2 score: ', r2_score(y_test_std, y_pred))
41print('Mean squared error: ', mean_squared_error(y_test_std, y_pred))
42
43# 绘图
44plt.scatter(y_test_std, y_pred, color='blue')
45plt.plot([y_test_std.min(), y_test_std.max()], [y_test_std.min(), y_test_std.max()], 'k--', lw=3)
46plt.xlabel('真实值')
47plt.ylabel('预测值')
48plt.title('SVR预测结果显示')
49plt.grid()
50plt.show()
这段代码的工作如下:
输出结果:
1The best parameters are {'C': 10.0, 'gamma': 0.1} with a score of 0.88
2R2 score: 0.8316248029392441
3Mean squared error: 0.14213314600372265
1The best parameters are {'C': 10.0, 'gamma': 0.1} with a score of 0.88
2R2 score: 0.8316248029392441
3Mean squared error: 0.14213314600372265
优点:
缺点: