簡體   English   中英

是否有類似於 R 的 brglm 的東西來幫助使用 statsmodels Logit 處理 Python 中的准分離?

[英]Is there something similar to R's brglm to help deal with quasi-separation in Python using statsmodels Logit?

我正在使用 statsmodels 中的 Logit 創建回歸模型。

我收到錯誤:LinAlgError:奇異矩陣,然后當我從數據集中一次刪除 1 個變量時,我終於收到了另一個錯誤:PerfectSeparationError:檢測到完美分離,結果不可用。

我懷疑原始錯誤(LinAlgError)與完美分離有關,因為我在 R 中遇到了同樣的問題並使用 brglm 解決了它(偏差減少了 glm)。

我有一個布爾 y 變量和 23 個數字和布爾 x 變量。

我已經運行了一個 VIF 函數來刪除任何具有高多重共線性分數的變量(我從 26 個變量開始)。

我嘗試使用 firth_regression.py 來解釋完美分離,但出現內存錯誤:MemoryError。( https://gist.github.com/johnlees/3e06380965f367e4894ea20fbae2b90d

我已經嘗試過來自 sklearn 的 LogisticRegression,但無法獲得對我不利的 p 值。

我什至嘗試從我的數據集中一次刪除 1 個變量。 當我只剩下 4 個變量(我有 23 個)時,我得到了 PerfectSeparationError:檢測到完美分離,結果不可用。

有沒有人經歷過這種情況,你如何解決它?

感謝任何建議!

    X = df.loc[:, df.columns != 'VehicleMake']
    y = df.iloc[:,0]
    # Split data
    X_train, X_test, y_train, y_test = skl.model_selection.train_test_split(X, y, test_size=0.3)

有問題的代碼:

    # Perform logistic regression and get p values
    logit_model = sm.Logit(y_train, X_train.astype(float))
    result = logit_model.fit()

這是我嘗試的 firth_regression ,它給我帶來了內存錯誤:

# For the firth_regression
import sys
import warnings
import math
import statsmodels
from scipy import stats
import statsmodels.formula.api as smf


def firth_likelihood(beta, logit):
    return -(logit.loglike(beta) + 0.5*np.log(np.linalg.det(-logit.hessian(beta))))

step_limit=1000
convergence_limit=0.0001

logit_model = smf.Logit(y_train, X_train.astype(float))

start_vec = np.zeros(X.shape[1])

beta_iterations = []
beta_iterations.append(start_vec)
for i in range(0, step_limit):
    pi = logit_model.predict(beta_iterations[i])
    W = np.diagflat(np.multiply(pi, 1-pi))
    var_covar_mat = np.linalg.pinv(-logit_model.hessian(beta_iterations[i]))

    # build hat matrix
    rootW = np.sqrt(W)
    H = np.dot(np.transpose(X_train), np.transpose(rootW))
    H = np.matmul(var_covar_mat, H)
    H = np.matmul(np.dot(rootW, X), H)

    # penalised score
    U = np.matmul(np.transpose(X_train), y - pi + np.multiply(np.diagonal(H), 0.5 - pi))
    new_beta = beta_iterations[i] + np.matmul(var_covar_mat, U)

    # step halving
    j = 0
    while firth_likelihood(new_beta, logit_model) > firth_likelihood(beta_iterations[i], logit_model):
        new_beta = beta_iterations[i] + 0.5*(new_beta - beta_iterations[i])
        j = j + 1
        if (j > step_limit):
            sys.stderr.write('Firth regression failed\n')
            None

    beta_iterations.append(new_beta)
    if i > 0 and (np.linalg.norm(beta_iterations[i] - beta_iterations[i-1]) < convergence_limit):
        break

return_fit = None
if np.linalg.norm(beta_iterations[i] - beta_iterations[i-1]) >= convergence_limit:
    sys.stderr.write('Firth regression failed\n')
else:
# Calculate stats
    fitll = -firth_likelihood(beta_iterations[-1], logit_model)
    intercept = beta_iterations[-1][0]
    beta = beta_iterations[-1][1:].tolist()
    bse = np.sqrt(np.diagonal(-logit_model.hessian(beta_iterations[-1])))

    return_fit = intercept, beta, bse, fitll
#print(return_fit)

我通過將 logit 回歸中的默認方法更改為方法 ='bfgs' 來解決我的問題。

result = logit_model.fit(method = 'bfgs')

這個問題遲到了幾年,但我正在使用 R logistf 包和Heinze and Schemper, 2002中詳述的過程來實現 Firth 邏輯回歸的 Python 實現 與您鏈接的要點相比,存在一些實現差異,使其內存效率更高,並且 p 值是使用懲罰似然比檢驗計算的。 我將不勝感激任何反饋!

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM