为什么MNLogit返回 "classes_num - 1 "参数,如何获得所有参数?

问题描述 投票:0回答:1

如果我有几个班级,即3个,我希望得到3个广义线性回归系数数组,例如 sklearn.linear_model.LogisticRegression 不过 statsmodels.discrete.discrete_model.MNLogit 提供classes_num - 1系数(在本例中为-2)。

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

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个类的回归系数?

python scikit-learn statsmodels
1个回答
1
投票

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

缺失类的对数被假定为零。演示一下。

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 = 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]])

和模型的预测相吻合

重申一下:你无法找到这些系数。对第一类使用常数对数为零。你也找不到特征对第一类的影响有多大。这其实是一个不恰当的问题:特征不可能对参考类有影响,因为参考类从来没有被直接预测过。系数告诉你的是,与参考类相比,某类的对数概率,因某一特征的单位增加而变化多少。


0
投票

预测的概率必须在类上加起来为1。所以,我们为了施加这个约束,在完整模型中松开一个自由参数。

参考类的预测概率是1减去所有其他类的概率之和。

这类似于二进制的情况,我们没有成功和失败的单独参数,因为一个概率只是一个减去另一个概率。

© www.soinside.com 2019 - 2024. All rights reserved.