添加多项式特征破坏了 SVM 回归
Posted
技术标签:
【中文标题】添加多项式特征破坏了 SVM 回归【英文标题】:SVM regression ruined by adding polynomial features 【发布时间】:2015-11-21 01:52:32 【问题描述】:我试图通过一个玩具示例来感受 SVM 回归。我生成了 1 到 100 之间的随机数作为预测变量,然后获取它们的对数并添加高斯噪声来创建目标变量。将这些数据弹出到 sklearn 的 SVR 模块中会生成一个外观合理的模型:
但是,当我通过加入原始预测变量的平方来增加训练数据时,一切都变得混乱:
我知道 RBF 内核的作用类似于获取原始特征的权力,因此加入第二个特征大部分是多余的。但是,SVM 在处理功能冗余方面真的如此糟糕吗?还是我做错了什么?
这是我用来生成这些图表的代码:
from sklearn.svm import SVR
import numpy as np
import matplotlib.pyplot as plt
# change to highest_power=2 to get the bad model
def create_design_matrix(x_array, highest_power=1):
return np.array([[x**k for k in range(1, highest_power + 1)] for x in x_array])
N = 1000
x_array = np.random.uniform(1, 100, N)
y_array = np.log(x_array) + np.random.normal(0,0.2,N)
model = SVR(C=1.0, epsilon=0.1)
print model
X = create_design_matrix(x_array)
#print X
#print y_array
model = model.fit(X, y_array)
test_x = np.linspace(1.0, 100.0, num=10000)
test_y = model.predict(create_design_matrix(test_x))
plt.plot(x_array, y_array, 'ro')
plt.plot(test_x, test_y)
plt.show()
感谢您对这个谜团的任何帮助!
【问题讨论】:
你有没有搞过 C 语言? 是的,我为 C 尝试了从 0.01 到 1000 的值(并且也使用了 epsilon),但无法获得合理的曲线。 【参考方案1】:您的模型似乎过多地吸收了异常值,这是方差错误的症状。这是有道理的,因为添加多项式特征会增加模型的方差。您应该尝试通过调整参数来通过交叉验证来调整偏差-方差权衡。要修改的参数是 C、epsilon 和 gamma。使用 RBF 内核时,gamma 参数非常重要,所以我将从那里开始。
手动摆弄这些参数(不推荐 - 见下文)给了我以下模型:
这里使用的参数是 C=5,epsilon=0.1,gamma=2**-15。
选择这些参数对于正确的模型选择框架来说确实是一项任务。我更喜欢模拟退火+交叉验证。目前最好的 scikit-learn 是随机网格搜索 + crossval。我帮助的模拟退火模块的无耻插件:https://github.com/skylergrammer/SimulatedAnnealing
注意:多项式特征实际上是大小为 d 的所有组合(有放回)的乘积,而不仅仅是特征的平方。在二级情况下,由于您只有一个特征,因此它们是等价的。 Scikit-learn 有一个类可以计算这些:sklearn.preprocessing.PolynomialFeatures
【讨论】:
以上是关于添加多项式特征破坏了 SVM 回归的主要内容,如果未能解决你的问题,请参考以下文章