添加多项式特征破坏了 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 回归的主要内容,如果未能解决你的问题,请参考以下文章

逻辑回归-4.添加多项式特征

机器学习二十:线性不可分支持向量机与核函数

2.线性回归

多项式回归学习曲线

运行没有特征组合的多项式回归

特征与多项式回归