ロジスティック回帰:Scikit Learn vs Statsmodels


31

これら2つのライブラリのロジスティック回帰からの出力が異なる結果を与える理由を理解しようとしています。

私は、UCLAのidreのからのデータセットを使用していますチュートリアル予測、admitに基づいてgregparankrankはカテゴリ変数として扱われるため、最初にrank_1ドロップされてダミー変数に変換されます。インターセプト列も追加されます。

df = pd.read_csv("https://stats.idre.ucla.edu/stat/data/binary.csv")
y, X = dmatrices('admit ~ gre + gpa + C(rank)', df, return_type = 'dataframe')
X.head()
>  Intercept  C(rank)[T.2]  C(rank)[T.3]  C(rank)[T.4]  gre   gpa
0          1             0             1             0  380  3.61
1          1             0             1             0  660  3.67
2          1             0             0             0  800  4.00
3          1             0             0             1  640  3.19
4          1             0             0             1  520  2.93

# Output from scikit-learn
model = LogisticRegression(fit_intercept = False)
mdl = model.fit(X, y)
model.coef_
> array([[-1.35417783, -0.71628751, -1.26038726, -1.49762706,  0.00169198,
     0.13992661]]) 
# corresponding to predictors [Intercept, rank_2, rank_3, rank_4, gre, gpa]

# Output from statsmodels
logit = sm.Logit(y, X)
logit.fit().params
> Optimization terminated successfully.
     Current function value: 0.573147
     Iterations 6
Intercept      -3.989979
C(rank)[T.2]   -0.675443
C(rank)[T.3]   -1.340204
C(rank)[T.4]   -1.551464
gre             0.002264
gpa             0.804038
dtype: float64

からの出力statsmodelsは、idre Webサイトに表示されているものと同じですが、scikit-learnが異なる係数セットを生成する理由がわかりません。いくつかの異なる損失関数を最小化しますか?実装を説明するドキュメントはありますか?

回答:


28

これを理解するための手がかりは、scikit-learn推定からのパラメーター推定が、statsmodelsカウンターパートよりも一様に大きさが小さいことです。これにより、scikit-learnが何らかの種類のパラメーターの正規化を適用していると思われるかもしれません。scikit-learn documentationを読むことでこれを確認できます

scikit-learnで正則化をオフにする方法はありませんが、チューニングパラメーターCを大きな値に設定することにより、正則化を無効にすることができます。あなたの場合の仕組みは次のとおりです。

# module imports
from patsy import dmatrices
import pandas as pd
from sklearn.linear_model import LogisticRegression
import statsmodels.discrete.discrete_model as sm

# read in the data & create matrices
df = pd.read_csv("http://www.ats.ucla.edu/stat/data/binary.csv")
y, X = dmatrices('admit ~ gre + gpa + C(rank)', df, return_type = 'dataframe')

# sklearn output
model = LogisticRegression(fit_intercept = False, C = 1e9)
mdl = model.fit(X, y)
model.coef_

# sm
logit = sm.Logit(y, X)
logit.fit().params

説明ありがとうございます!この正規化された結果ではglmnet、R のパッケージを使用して結果を複製しようとしましたが、同じ係数を取得できませんでした。glmnetのコスト関数はsklearnと比べてわずかに異なりますがalpha=0glmnet(l2-penaltyのみを使用することを意味する)setに設定1/(N*lambda)=Cしても、同じ結果は得られませんか?
ハリケール

私の直感は私が費用関数の両方の条件を分ける場合ということであるglmnetことでlambdaある、と対数尤度のフォントで新しい定数を設定1/(N*lambda)していることに等しいsklearn、2つのコスト関数が同一になる、または私は何かが足りないのですか?
ハリケール

@hurrikale新しい質問をして、ここにリンクして、見てみましょう。
tchakravarty

ありがとう!ここに質問を投稿しました
ハリケール

scikit-learnの正則化をオフにする最良の方法は、を設定することだと思いますpenalty='none'
Nzbuu

3

もう1つの違いは、fit_intercept = Falseを設定したことです。これは事実上異なるモデルです。Statsmodelにインターセプトが含まれていることがわかります。インターセプトがないと、フィーチャの予想される重みが確実に変わります。以下を試して、どのように比較されるかを確認してください

model = LogisticRegression(C=1e9)

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.