亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

邏輯回歸 scikit-learn 與 statsmodels 的系數

邏輯回歸 scikit-learn 與 statsmodels 的系數

慕沐林林 2022-12-06 16:41:42
當使用這兩個 API 執行邏輯回歸時,它們會給出不同的系數。即使是這個簡單的例子,它在系數方面也不會產生相同的結果。我遵循關于同一主題的舊建議的建議,例如在 sklearn 中為參數 C 設置一個大值,因為它使懲罰幾乎消失(或設置 penalty="none")。import pandas as pdimport numpy as npimport sklearn as skfrom sklearn.linear_model import LogisticRegressionimport statsmodels.api as smn = 200x = np.random.randint(0, 2, size=n)y = (x > (0.5 + np.random.normal(0, 0.5, n))).astype(int)display(pd.crosstab( y, x ))max_iter = 100#### Statsmodelsres_sm = sm.Logit(y, x).fit(method="ncg", maxiter=max_iter)print(res_sm.params)#### Scikit-Learnres_sk = LogisticRegression( solver='newton-cg', multi_class='multinomial', max_iter=max_iter, fit_intercept=True, C=1e8 )res_sk.fit( x.reshape(n, 1), y )print(res_sk.coef_)例如,我只是運行上面的代碼并獲得 1.72276655 的 statsmodels 和 1.86324749 的 sklearn。當多次運行時,它總是給出不同的系數(有時比其他系數更接近,但無論如何)。因此,即使使用那個玩具示例,兩個 API 也會給出不同的系數(因此比值比),并且對于真實數據(此處未顯示),它幾乎會“失控”......我錯過了什么嗎?我怎樣才能產生相似的系數,例如至少在逗號后的一兩個數字?
查看完整描述

1 回答

?
翻閱古今

TA貢獻1780條經驗 獲得超5個贊

您的代碼存在一些問題。

首先,您在此處顯示的兩個模型并不相同:盡管您適合 scikit-learn LogisticRegressionfit_intercept=True這是默認設置),但您不會使用 statsmodels 模型;來自 statsmodels文檔

默認情況下不包含攔截,應由用戶添加???code>statsmodels.tools.add_constant。

這似乎是一個常見的混淆點 - 例如scikit-learn 和 statsmodels - 哪個 R 平方是正確的?(也有自己的答案)。

另一個問題是,盡管您處于二元分類設置中,但您要求multi_class='multinomial'在您的 中LogisticRegression,但事實并非如此。

第三個問題是,正如相關的交叉驗證線程邏輯回歸:Scikit Learn vs Statsmodels中所解釋的那樣:

沒有辦法在 scikit-learn 中關閉正則化,但是您可以通過將調整參數 C 設置為較大的數字來使其無效。

這使得這兩個模型在原則上再次不可比,但您已經通過設置在此處成功解決了這個問題C=1e8。事實上,從那時起(2016 年),scikit-learn 確實添加了一種關閉正則化的方法penalty='none',根據文檔,通過設置 since :

如果為“無”(liblinear 求解器不支持),則不應用正則化。

現在應該將其視為關閉正則化的規范方法。

因此,將這些更改合并到您的代碼中,我們有:

np.random.seed(42) # for reproducibility


#### Statsmodels

# first artificially add intercept to x, as advised in the docs:

x_ = sm.add_constant(x)

res_sm = sm.Logit(y, x_).fit(method="ncg", maxiter=max_iter) # x_ here

print(res_sm.params)

這給出了結果:


Optimization terminated successfully.

         Current function value: 0.403297

         Iterations: 5

         Function evaluations: 6

         Gradient evaluations: 10

         Hessian evaluations: 5

[-1.65822763  3.65065752]

數組的第一個元素是截距,第二個元素是 的系數x。而對于 scikit 學習,我們有:


#### Scikit-Learn


res_sk = LogisticRegression(solver='newton-cg', max_iter=max_iter, fit_intercept=True, penalty='none')

res_sk.fit( x.reshape(n, 1), y )

print(res_sk.intercept_, res_sk.coef_)

結果是:


[-1.65822806] [[3.65065707]]

在機器的數字精度范圍內,這些結果實際上是相同的。


對不同的值重復該過程np.random.seed()不會改變上面顯示的結果的本質。


查看完整回答
反對 回復 2022-12-06
  • 1 回答
  • 0 關注
  • 228 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號