Python和R之间线性回归系数的差异

Python和R之间线性回归系数的差异,python,r,pandas,scikit-learn,regression,Python,R,Pandas,Scikit Learn,Regression,我试图在Python中运行一个线性回归,我已经在R中完成了这项工作,以便找到系数为0的变量。我遇到的问题是,R中的线性回归返回低方差列的NAs,而scikit学习回归返回系数。在R代码中,我通过将变量与NAs一起保存为线性回归的输出来查找和保存这些变量,但我似乎无法找到一种方法来模拟python中的这种行为。我使用的代码可以在下面找到 R代码: a <- c(23, 45, 546, 42, 68, 15, 47) b <- c(1, 2, 4, 6, 34, 2, 8) c <

我试图在Python中运行一个线性回归,我已经在R中完成了这项工作,以便找到系数为0的变量。我遇到的问题是,R中的线性回归返回低方差列的NAs,而scikit学习回归返回系数。在R代码中,我通过将变量与NAs一起保存为线性回归的输出来查找和保存这些变量,但我似乎无法找到一种方法来模拟python中的这种行为。我使用的代码可以在下面找到

R代码:

a <- c(23, 45, 546, 42, 68, 15, 47)
b <- c(1, 2, 4, 6, 34, 2, 8)
c <- c(22, 33, 44, 55, 66, 77, 88)
d <- c(1, 1, 1, 1, 1, 1, 1)
e <- c(1, 1, 1, 1, 1, 1, 1.1)
f <- c(1, 1, 1, 1, 1, 1, 1.01)
g <- c(1, 1, 1, 1, 1, 1, 1.001)

df <- data.frame(a, b, c, d, e, f, g)
var_list = c('b', 'c', 'd', 'e', 'f', 'g')

target <- temp_dsin.df$a
reg_data <- cbind(target, df[, var_list])


if (nrow(reg_data) < length(var_list)){
  message(paste0('    WARNING: Data set is rank deficient. Result may be doubtful'))
}
reg_model <- lm(target ~ ., data = reg_data)

print(reg_model$coefficients)

#store the independent variables with 0 coefficients
zero_coef_IndepVars.v <- names(which(is.na(reg_model$coefficients)))

print(zero_coef_IndepVars.v)
Python的输出:

           b             c   d               e              f            g
[-0.66925301   -1.05471932   0.   -353.1483504   -35.31483504   -3.5314835]
如您所见,列“b”、“c”和“e”的值非常接近,但“d”、“f”和“g”的值非常不同。对于这个示例回归,我希望返回['d','f','g',],因为它们的输出是R中的NA。问题是sklearn线性回归对列'd'返回0,而对列'f'返回-35.31,对列'g'返回-3.531


有人知道R如何决定是否返回NA或值/如何在Python版本中实现此行为吗?了解这些差异的来源可能有助于我在python中实现R行为。我需要python脚本的结果与R输出完全匹配

这在实现上是不同的lm使用基于QR分解的底层C代码。模型矩阵分解为正交矩阵Q和三角矩阵R。这导致了其他人所谓的“共线检查”。R没有检查,QR分解的性质确保了最小共线变量在拟合算法中获得“优先级”

有关线性回归中QR分解的更多信息:

sklearn中的代码基本上是围绕
numpy.linalg.lstsq
的包装,它最小化了欧几里得二次范数。如果您的模型是
Y=AX
,它会最小化
|Y-AX | ^2
。这是一种不同的(计算稳定性较差)算法,它没有QR分解的好的副作用


个人提示:如果您希望在一个经过验证和测试的计算框架中对模型进行健壮的拟合,并坚持使用Python,请寻找基于QR或SVD的线性回归实现。软件包
scikit learn
statsmodels
(截至2017年4月22日仍处于测试阶段)应能让您达到目标

我想没有足够的数据。这是statsmodel的结果:

将statsmodels.formula.api导入为smf
lm=smf.ols(公式='a~b+c+d+e+f+g',data=df).fit()

lm.summary()
只是注意到它们是
NA
,而不是
NaN
@SinanÜnür那么你认为在r线性回归中存在协线性检验吗?我想是这样的,这就是我选择数据的原因,但我需要在python中复制这种行为。谢谢大家,这非常有用!我将仔细查看,看看python中是否存在使用QR分解实现的任何内容,如果不起作用,请坚持使用R。个人提示:如果您希望从回归中随机删除一些变量,请使用R。如果您希望SVD/pinv正则化解决方案,请使用python scikit learn或statsmodels。如果两者都不需要,请清理数据并自己选择变量。@user333700 QR分解并不是随机的,如问题所示。但无论如何,感谢您提供了一个指向基于SVD的方法的指针。记录在案:我们部门一半的研究是用Python完成的。Python是一种很棒的语言。但是对于一个简单的线性回归,我们现在已经提到了5个软件包(numpy、scipy、sklearn、scikit learn和statsmodels)。在我的统计计算课上,我将坚持使用R:不太需要解释,标准工具是一个稳定的工具。我想每个人都有自己的答案。有关更多详细信息,请参见中的答案。(即使现在可以用scipy.linalg实现,statsmodels也不太可能通过旋转QR获得变量选择。)我用了一个例子:如果我们通过添加1e-6来更改
d
,即
d
(Intercept)           b           c           d           e           f           g 
 537.555988   -0.669253   -1.054719          NA -356.715149          NA          NA 

> print(zero_coef_IndepVars.v)
[1] "d" "f" "g"
           b             c   d               e              f            g
[-0.66925301   -1.05471932   0.   -353.1483504   -35.31483504   -3.5314835]