二次项线性回归
Linear Regression with quadratic terms
我最近一直在研究机器学习,现在正在迈出 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 考虑二次、三次等函数?
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()
,因此您必须手动转换输入。如果您希望这种转换自动发生,您可以在管道中使用例如PolynomialFeatures
:
from sklearn.preprocessing import PolynomialFeatures
from sklearn.pipeline import make_pipeline
model = make_pipeline(PolynomialFeatures(2), LinearRegression())
model.fit(x, y).predict(11)
# [121]
这是线性模型的美妙之处之一:使用这样的基函数展开,它们可以非常灵活,同时保持非常快!您可以考虑添加具有三次、四次或其他项的列,它仍然是线性回归。或者对于周期模型,您可能会考虑添加正弦、余弦等列。在这个极限下,所谓的 "kernel trick" 允许您有效地添加一个 infinite 数据的新列数,并最终得到一个非常强大的模型——但仍然是线性的,因此仍然相对较快!有关此类估算器的示例,请查看 scikit-learn 的 KernelRidge
.
我最近一直在研究机器学习,现在正在迈出 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 考虑二次、三次等函数?
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()
,因此您必须手动转换输入。如果您希望这种转换自动发生,您可以在管道中使用例如PolynomialFeatures
:
from sklearn.preprocessing import PolynomialFeatures
from sklearn.pipeline import make_pipeline
model = make_pipeline(PolynomialFeatures(2), LinearRegression())
model.fit(x, y).predict(11)
# [121]
这是线性模型的美妙之处之一:使用这样的基函数展开,它们可以非常灵活,同时保持非常快!您可以考虑添加具有三次、四次或其他项的列,它仍然是线性回归。或者对于周期模型,您可能会考虑添加正弦、余弦等列。在这个极限下,所谓的 "kernel trick" 允许您有效地添加一个 infinite 数据的新列数,并最终得到一个非常强大的模型——但仍然是线性的,因此仍然相对较快!有关此类估算器的示例,请查看 scikit-learn 的 KernelRidge
.