首页 > 解决方案 > 为什么 MNLogit 返回 `classes_num - 1` 参数以及如何获取它们?

问题描述

如果我有几个类,即 3。我期望得到 3 个广义线性回归系数数组,如sklearn.linear_model.LogisticRegressionstatsmodels.discrete.discrete_model.MNLogit提供 classes_num - 1 个系数(在这种情况下 - 2)。

例子:

import statsmodels.api as st
from sklearn.linear_model import LogisticRegression


iris = st.datasets.get_rdataset('iris','datasets')

y = iris.data.Species
x = iris.data.iloc[:, :-1]
mdl = st.MNLogit(y, x)
# mdl_fit = mdl.fit()
mdl_fit = mdl.fit(method='bfgs' , maxiter=1000)
print(mdl_fit.params.shape)  # (4, 2)

model = LogisticRegression(fit_intercept = False, C = 1e9)
mdl = model.fit(x, y)
print(model.coef_.shape)  # (3, 4)

我应该如何使用 MNLogit 获得所有 3 个类的回归系数?

标签: pythonscikit-learnstatsmodels

解决方案


不计算这些系数以强制模型的可识别性。换句话说,不计算它们可以确保其他类的系数是唯一的。如果您有三组系数,则有无数个模型可以给出相同的预测,但系数的值不同。如果您想知道标准误差、p 值等,这很糟糕。

缺失类的 logit 假定为零。演示:

mm = st.MNLogit(
    np.random.randint(1, 5, size=(100,)),
    np.random.normal(size=(100, 3))
)

res = mm.fit()
xt = np.random.normal(size=(2, 3))
res.predict(xt)

结果是:

array([[0.19918096, 0.34265719, 0.21307297, 0.24508888],
       [0.33974178, 0.21649687, 0.20971884, 0.23404251]])

现在这些是logits,加上第一类的零

logits = np.hstack([np.zeros((xt.shape[0], 1)), xt.dot(res.params)])

array([[ 0.        ,  0.54251673,  0.06742093,  0.20740715],
       [ 0.        , -0.45060978, -0.4824181 , -0.37268309]])

以及通过 softmax 的预测:

np.exp(logits) / (np.sum(np.exp(logits), axis=1, keepdims=1))

array([[0.19918096, 0.34265719, 0.21307297, 0.24508888],
       [0.33974178, 0.21649687, 0.20971884, 0.23404251]])

与模型的预测相匹配。

重申一下:你找不到那些系数。对第一类使用常数 logit 为零。而且你找不到对第一类有多少影响的特征。这实际上是一个病态的问题:特征不能对参考类产生影响,因为参考类永远不会被直接预测。系数告诉您的是,与参考类相比,给定类的对数几率由于特定特征的单位增加而发生了多少变化。


推荐阅读