web-dev-qa-db-ja.com

OLS回帰:Scikit対Statsmodels?

Short version:一部のデータでscikit LinearRegressionを使用していましたが、p値に慣れているため、データをstatsmodels OLSに入れます。 R ^ 2はほぼ同じですが、可変係数はすべて大きく異なります。最も可能性の高い問題はどこかでエラーを発生させたため、どちらの出力にも自信が持てないことです(1つのモデルを誤って作成した可能性がありますが、どちらのモデルかわからないため)。

長いバージョン:問題がどこにあるのかわからないので、どの詳細を含めるべきか正確にわかりません、そしてすべてを含めるのはおそらく多すぎます。コードやデータを含めるかどうかもわかりません。

ScikitのLRとstatsmodelsのOLSはどちらもOLSを実行しているはずであり、OLSがOLSであることを知っている限り、結果は同じになるはずです。

ScikitのLRの場合、normalize = Trueまたは= Falseを設定してもしなくても、結果は(統計的に)同じですが、これは少し変です。

Statsmodels 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アプローチ(R ^ 2は毎回テストデータとトレーニングデータの両方で一貫しています)に5倍のcvを使用しており、statsmodelsではすべてのデータを投げます。

R ^ 2は、sklearnモデルとstatsモデルの両方で約0.41です(これは社会科学に適しています)。これは良い兆候かもしれないし、単なる偶然かもしれません。

データは、WoWでのアバターの観測です( http://mmnet.iis.sinica.edu.tw/dl/wowah/ から)いくつかの異なる機能を使用して毎週作成するように変更しました。もともとこれはデータサイエンスクラスのクラスプロジェクトでした。

独立変数には、1週間の観察数(int)、文字レベル(int)、ギルド内の場合(ブール)、見た場合(平日、平日前夜、平日遅くのブール、週末は同じ3)、文字クラスのダミー(データ収集時には、WoWには8つのクラスしかなかったため、7つのダミー変数があり、元の文字列カテゴリ変数は削除されます)など。

従属変数は、その週の間に各キャラクターが獲得したレベル数(int)です。

興味深いことに、同様の変数内の相対的な順序の一部は、statsmodelsおよびsklearn全体で維持されます。したがって、「見られるとき」の順位は、ローディングが非常に異なっていても同じであり、キャラクタークラスのダミーの順位は、ローディングが非常に異なっていても同じです。

私はこの質問はこれに似ていると思います: Python statsmodels OLS and R's lmの違い

私はPythonとstatsでそれを実行するのに十分ですが、このようなものを理解するのに十分ではありません。sklearnのドキュメントとstatsmodelsのドキュメントを読んでみましたが、そこに私が顔を見つめていたので、理解できませんでした。

私は知りたいです:

  1. どの出力が正確かもしれませんか? (私がクワーグを逃した場合、それらは両方かもしれないことを認めた。)
  2. 私が間違えた場合、それは何であり、どのように修正しますか?
  3. ここで尋ねずにこれを理解できましたか?

この質問には多少あいまいな部分(コードなし、データなし、出力なし)があることは知っていますが、2つのパッケージの一般的なプロセスについての詳細だと思います。確かに、1つは統計量が多く、もう1つは機械学習が多いようですが、どちらもOLSであるため、出力が同じではない理由がわかりません。

(私は三角測量のために他のいくつかのOLS呼び出しを試みました、1つははるかに低いR ^ 2を与え、1つは5分間ループし、私はそれを殺し、1つはクラッシュしました。)

ありがとう!

24
Nat Poor

両方のプロシージャに同じリグレッサXを与えていないようです(ただし、以下を参照)。これは、sklearnとstatsmodelsが同じ結果を生成するために使用する必要があるオプションを示す例です。

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は完全な列ランクを持たない可能性があり、SM/SKはOLS計算を実行するために内部で(異なる)アクションを実行している可能性があります(つまり別の列を削除します)。

これを処理するには、pandasおよびpatsyを使用することをお勧めします。

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

35
Vincent

ここで追加したいのは、sklearnの観点では、内部での線形回帰にOLSメソッドを使用しないことです。 sklearnはデータマイニング/機械学習の領域からのものであるため、最急降下勾配アルゴリズムを使用することを好みます。これは初期条件などに敏感な数値的方法ですが、OLSは分析的な閉じた形のアプローチであるため、違いを期待する必要があります。したがって、statsmodelsは古典的な統計フィールドから取得されるため、OLS手法を使用します。したがって、2つの異なるライブラリからの2つの線形回帰には違いがあります

1
Palu

Statsmodelsを使用する場合は、代わりにstatsmodels式インターフェースを使用することを強くお勧めします。 sklearn.linear_model.LinearRegression、R、またはSAS、Excelと同じように、statsmodels数式インターフェイスを使用して、OLSから同じ古い結果を取得します。

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

迷ったときはどうぞ

  1. ソースコードを読んでみてください
  2. ベンチマークに別の言語を試す、または
  3. 基本的な線形代数であるゼロからOLSを試してください。
1
Sarah