如何在Python的sklearn中添加交互项

32

如果我有自变量[x1, x2, x3], 如果我在sklearn中进行线性回归拟合, 它会给我这样的结果:

y = a*x1 + b*x2 + c*x3 + intercept

使用2次多项式回归会给我类似于以下内容:

y = a*x1^2 + b*x1*x2 ......

我不想使用类似 x1^2 这样的二次项。

我该如何实现?

y = a*x1 + b*x2 + c*x3 + d*x1*x2

如果x1和x2之间的相关性高于某个阈值j。

3个回答

38

为了生成多项式特征,我假设您正在使用sklearn.preprocessing.PolynomialFeatures

该方法中有一个参数可以考虑仅交互作用,因此您可以编写类似以下内容的代码:

poly = PolynomialFeatures(interaction_only=True,include_bias = False)
poly.fit_transform(X)

现在只考虑交互项,忽略更高阶项。你的新特征空间变成了[x1,x2,x3,x1*x2,x1*x3,x2*x3]

你可以在此基础上拟合回归模型

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

使您的结果方程式为 y = a*x1 + b*x2 + c*x3 + d*x1*x + e*x2*x3 + f*x3*x1

注意: 如果您具有高维特征空间,则这将导致维度诅咒,可能会导致过拟合/高方差等问题。


2
很好。我会进一步设置 include_bias=False,因为偏置列可能会导致某些估计器的退化问题,并且 LinearRegression 会自动添加拦截项。 - MB-F
1
非常有用的答案。看起来你的结果方程式中有一个小错字:右边第四项应该是dx1x2。 - LucCW

21

使用patsy构建设计矩阵,方法如下:

y, X = dmatrices('y ~ x1 + x2 + x3 + x1:x2', your_data)

假设您的数据为DataFrame格式,有响应列y以及输入列x1、x2和x3。

那么只需调用您估计器的fit方法,例如LinearRegression().fit(X,y)。


1
喜欢在R中使用lm()函数后的设计。 - notMyName

12

如果您在scikit-learn中使用线性回归进行"y = a*x1 + b*x2 + c*x3 + 截距"的计算,我认为您会执行以下操作:

# x = array with shape (n_samples, n_features)
# y = array with shape (n_samples)

from sklearn.linear_model import LinearRegression

model = LinearRegression().fit(x, y)

自变量x1x2x3是特征矩阵x的列,系数abc包含在model.coef_中。

如果需要交互项,请将其添加到特征矩阵中:

x = np.c_[x, x[:, 0] * x[:, 1]]

现在前三列包含变量,后面一列包含交互项x1 * x2。拟合模型后,您会发现model.coef_包含四个系数abcd

请注意,这将始终为您提供具有交互作用的模型(尽管理论上可能为0),而不考虑x1x2之间的相关性。当然,您可以事先测量相关性并使用它来决定要拟合哪种模型。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接