OLS Regression: Scikit vs. Statsmodels?



短版本:我对一些数据使用了scikit LinearRegression,但我习惯于p值,所以将数据放入统计模型OLS中,尽管R^2大致相同,但变量系数都有很大的不同。这让我很担心,因为最有可能的问题是我在某个地方犯了错误,现在我对任何一个输出都没有信心(因为我可能错误地制作了一个模型,但不知道是哪一个)。

更长的版本:因为我不知道问题在哪里,我不知道该包括哪些细节,包括所有内容可能太多了。我也不确定是否包含代码或数据。

我的印象是,scikit的LR和statsmodels OLS都应该进行OLS,据我所知,OLS就是OLS,所以结果应该是一样的。

对于scikit的LR,无论我是否设置normalize=True或=False,结果(统计上)都是相同的,我觉得这有点奇怪。

对于统计模型OLS,我使用sklearn中的StandardScaler对数据进行归一化。我添加了一列1,这样它就包含了一个截距(因为scikit的输出包含了一次截距)。点击此处了解更多信息:http://statsmodels.sourceforge.net/devel/examples/generated/example_ols.html(添加此列并没有显著改变可变系数,截距非常接近零。)StandardScaler不喜欢我的int不是浮点值,所以我尝试了这样做:https://github.com/scikit-learn/scikit-learn/issues/1709这使得警告消失了,但结果完全相同。

当然,我在sklearn方法中使用了5倍的cv(每次测试和训练数据的R^2都是一致的),而对于统计模型,我只是把所有的数据都扔了出去。

对于sklearn和statsmodels来说,R^2大约是0.41(这对社会科学有好处)。这可能是个好兆头,也可能只是个巧合。

数据是魔兽世界中化身的观察结果(来自http://mmnet.iis.sinica.edu.tw/dl/wowah/)这本书我想每周都会有一些不同的特色。最初,这是一个数据科学课程的课堂项目。

自变量包括一周内的观察次数(int)、字符级别(int),如果在公会中(布尔值),当看到时(布尔值在工作日、工作日前夕、工作日晚,周末也是三个),字符类的伪值(在数据收集时,魔兽世界中只有8个类,因此有7个伪变量,原始字符串类别变量被删除),以及其他。

因变量是每个角色在该周内获得的级别(int)。

有趣的是,类变量中的一些相对顺序是在statsmodels和sklearn之间保持的。因此,"当看到"的等级顺序是相同的,尽管负载非常不同,而角色类假人的等级顺序也是相同的,虽然负载也非常不同。

我认为这个问题与这个问题类似:Python统计模型OLS和R';s lm

我在Python和统计方面做得足够好,可以成功,但还不够好,无法想出这样的办法。我试着阅读sklearn文档和statsmodels文档,但如果答案就在那里,我就不明白了。

我很想知道:

  1. 哪种输出可能是准确的?(当然,如果我错过了一场比赛,他们可能都是。)
  2. 如果我犯了一个错误,它是什么?如何修复
  3. 我能不用问这里就知道这一点吗?如果是的话,我是怎么想的

我知道这个问题有一些相当模糊的部分(没有代码,没有数据,没有输出),但我认为它更多的是关于两个包的一般过程。当然,一个似乎是更多的统计数据,一个看起来是更多的机器学习,但它们都是OLS,所以我不明白为什么输出不一样。

(我甚至尝试了其他一些OLS调用来进行三角测量,其中一个给出了低得多的R^2,一个循环了五分钟,我杀死了它,还有一个崩溃了。)

谢谢!

听起来您没有向两个过程提供相同的回归矩阵X(但请参见下文)。这里有一个示例,向您展示了sklearn和statsmodel需要使用哪些选项才能产生相同的结果。

import numpy as np
import statsmodels.api as sm
from sklearn.linear_model import LinearRegression
# Generate artificial data (2 regressors + constant)
nobs = 100 
X = np.random.random((nobs, 2)) 
X = sm.add_constant(X)
beta = [1, .1, .5] 
e = np.random.random(nobs)
y = np.dot(X, beta) + e 
# Fit regression model
sm.OLS(y, X).fit().params
>> array([ 1.4507724 ,  0.08612654,  0.60129898])
LinearRegression(fit_intercept=False).fit(X, y).coef_
>> array([ 1.4507724 ,  0.08612654,  0.60129898])

正如一位评论者所建议的那样,即使你给两个程序都给定了相同的X,X也可能没有完整的列秩,他们可能会在后台采取(不同的)行动来完成OLS计算(即删除不同的列)。

我建议您使用pandaspatsy来处理以下问题:

import pandas as pd
from patsy import dmatrices
dat = pd.read_csv('wow.csv')
y, X = dmatrices('levels ~ week + character + guild', data=dat)

或者,statsmodels公式接口:

import statsmodels.formula.api as smf
dat = pd.read_csv('wow.csv')
mod = smf.ols('levels ~ week + character + guild', data=dat).fit()

编辑:此示例可能很有用:http://statsmodels.sourceforge.net/devel/example_formulas.html

如果您使用statsmodels,我强烈建议您改用statsmodel公式接口。使用statsmodels公式接口,您将从OLS中获得与从sklearn.linear_model.LinearRevision、R、SAS或Excel中相同的旧结果。

smod = smf.ols(formula ='y~ x', data=df)
result = smod.fit()
print(result.summary())

如有疑问,请

  1. 尝试读取源代码
  2. 尝试使用不同的语言进行基准测试,或者
  3. 从头开始尝试OLS,它是基本的线性代数

我只是想在这里补充一点,就sklearn而言,它不使用OLS方法进行线性回归。由于sklearn来自数据挖掘/机器学习领域,他们喜欢使用最陡下降梯度算法。这是一种对初始条件等敏感的数值方法,而OLS是一种分析闭合形式的方法,因此应该预料到差异。所以统计模型来自于经典的统计学领域,所以它们将使用OLS技术。因此,来自两个不同库的两个线性回归之间存在差异

相关内容

  • 没有找到相关文章

最新更新