具有二次项的线性回归

时间:2015-11-14 16:48:29

标签: python machine-learning scikit-learn linear-regression

我最近一直在研究机器学习,现在用scikit和线性回归开始我的第一步。

这是我的第一个样本

from sklearn import linear_model
import numpy as np

X = [[1],[2],[3],[4],[5],[6],[7],[8],[9],[10]]
y = [2,4,6,8,10,12,14,16,18,20]

clf = linear_model.LinearRegression()
clf.fit (X, y)

print(clf.predict([11]))
==> 22

输出符合预期22(显然scikit提出2x作为假设函数)。但是当我使用y = [1,4,9,16,25,36,49,64,81,100]创建一个稍微复杂的示例时,我的代码只会创建疯狂的输出。我假设线性回归会产生二次函数(x ^ 2),但我不知道发生了什么。 11的输出现在是:99。所以我想我的代码试图找到某种线性函数来映射所有的例子。

在我做的关于线性回归的教程中,有多项式项的例子,所以我假设scikits实现会得到一个正确的解决方案。我错了吗?如果是这样,我如何教scikit考虑二次,三次等函数?

1 个答案:

答案 0 :(得分:11)

LinearRegression符合数据的线性模型。对于上面所示的一维X值,结果是一条直线(即y = a + b*x)。在二维值的情况下,结果是平面(即z = a + b*x + c*y)。因此,您不能期望线性回归模型能够完美地拟合二次曲线:它没有足够的模型复杂度来做到这一点。

也就是说,可以巧妙地转换输入数据,以便使用线性回归模型拟合二次曲线。考虑上面的2D案例:

z = a + b*x + c*y

现在让我们进行替换y = x^2。也就是说,我们在包含二次项的数据中添加第二维。现在我们有另一个线性模型:

z = a + b*x + c*x^2

结果是一个在x中是二次的模型,但在系数中仍然是线性的!也就是说,我们可以通过线性回归轻松解决它:这是输入数据的基函数扩展的一个例子。这是代码:

import numpy as np
from sklearn.linear_model import LinearRegression

x = np.arange(10)[:, None]
y = np.ravel(x) ** 2

p = np.array([1, 2])
model = LinearRegression().fit(x ** p, y)
model.predict(11 ** p)
# [121]

这有点尴尬,因为模型需要2D输入到predict(),所以你必须手动转换输入。如果您希望自动进行此转换,可以在管道中使用例如{。{}}:

from sklearn.preprocessing import PolynomialFeatures
from sklearn.pipeline import make_pipeline

model = make_pipeline(PolynomialFeatures(2), LinearRegression())
model.fit(x, y).predict(11)
# [121]

这是关于线性模型的美妙之处:使用这样的基函数扩展,它们可以非常灵活,同时保持非常快!您可以考虑使用立方,四次或其他术语添加列,并且它仍然是线性回归。或者对于周期性模型,您可能会考虑添加正弦,余弦等列。在极端情况下,所谓的"内核技巧"允许您有效地为数据添加无限数量的新列,最终得到一个非常强大的模型 - 但仍然是线性的,因此仍然相对较快!有关此类估算工具的示例,请查看scikit-learn' PolynomialFeatures