我用scikit编写代码 - 学习为一维玩具数据构建SVR预测模型,然后用matplotlib绘制它。
蓝线是真实的数据。具有线性内核的模型适合一个很好的线,但对于2级的内核,预测不是我所期望的。我想有一个模型可以预测蓝线的值略低于橙色线的预测值。我画了一条黑线来想象我的想法。
为什么会这样?数据似乎是2阶多项式的良好候选。黑色趋势线跟随真实数据然后在右边稍后减少应该导致比绿线提供的更好的拟合,如果我只看这个情节。根据数据,不能找到具有2阶多项式的模型吗?它也可以很好地在接近蓝线的X = 0处弯曲,而不是在那里具有更高估计y值的曲率。
如何实现我想要的模型?
下面的代码是完整且自包含的,运行它以获得上面的图(减去画黑线)
# some data
y = [0, 3642, 6414, 9844, 13210, 16072, 18868, 22275, 25551, 28949, 31680, 34412, 37290, 39858, 42557,
45094, 47354, 49547, 51874, 54534, 55987, 55987, 58377, 60767, 63109, 65060, 66865, 68540, 70328,
72035, 73905, 75791, 77873, 79791, 81775, 83726]
X = range(0, len(y))
X_longer = range(0, len(y)*2)
# train models
from sklearn.svm import SVR
import numpy as np
clf_1 = SVR(kernel='poly', C=1e3, degree=1)
clf_2 = SVR(kernel='poly', C=1e3, degree=2)
clf_1.fit(np.array(X).reshape(-1, 1), y)
clf_2.fit(np.array(X).reshape(-1, 1), y)
%matplotlib inline
import matplotlib as mpl
import matplotlib.pyplot as plt
# plot real data
plt.plot(X, y, linewidth=8.0, label='true data')
predicted_1_y = []
predicted_2_y = []
# predict data points based on models
for i in X_longer:
predicted_1_y.append(clf_1.predict(np.array([i]).reshape(-1, 1)))
predicted_2_y.append(clf_2.predict(np.array([i]).reshape(-1, 1)))
# plot model predictions
plt.plot(X_longer, predicted_1_y, linewidth=6.0, ls=":", label='model, degree 1')
plt.plot(X_longer, predicted_2_y, linewidth=6.0, ls=":", label='model, degree 2')
plt.legend(loc='upper left')
plt.show()
答案 0 :(得分:0)
这是因为线性和二次特征最终会长大或减小。你需要像平方根或日志这样的操作来获取你想要的衰减特征。
一种简单的方法是在拟合之前转换输入信号。例如,假设平方根趋势:
X = np.array(X)[:,None]**2
clf = SVR(kernel='linear').fit(X, y)
对于更常见的用例,你真的不知道你想要的趋势,或者不想假设像这样的特定转换,你可以尝试像Eureqa这样的回归工具来计算最佳转换和数学模型可能。