Python基于statsmodels做MNLogit建模仅显示7类目标变量中的6类
核心结论
你遇到的两类类别缺失问题,不属于模型参数配置遗漏,是训练集类别采样不完整 + Statsmodels MNLogit的内置输出规则共同导致的。
问题根源拆解
- 编码后输出仅显示1-6类:OrdinalEncoder默认对排序后的类别从0开始顺次映射,原始7个quality类别(3、4、5、6、7、8、9)正常编码结果为0-6。你看到输出缺失最低类别的原因,是随机拆分的训练集中没有编码值为0对应的样本(也就是原始值为3的白葡萄酒样本)。
- 不编码直接训练时输出仅显示4-9类:逻辑和上述情况完全一致,无分层随机拆分时,所有原始值为3的样本刚好被全部分配到测试集,训练集中不存在该类样本。
Statsmodels的
MNLogit内置规则明确:模型仅会对训练输入Y中实际存在样本的类别输出拟合结果,不会自动保留完整的类别全集。只要某个类别在训练集Y中0样本占比,模型就会直接跳过该类的计算和结果输出。
代码内的隐藏问题
reduced_data.dropna()未将执行结果赋值回原变量,该行代码实际不生效。- 定义
model_1的drop语句缺少闭合右括号,会直接触发语法错误。 - 白葡萄酒数据集本身类别分布极度不均衡:原始数据中quality=3的样本仅20个,quality=9的样本仅5个,占比极低,无分层随机拆分时极易出现小样本类别完全落在测试集的情况。
- 可通过一行代码直接验证问题:拆分数据集后打印
Y_train.unique(),输出的类别集合会和模型summary展示的类别完全一致。
修复方案
- 拆分数据集时新增分层采样参数,保证拆分后训练集、测试集的类别分布和原始数据完全匹配,避免小样本类别被单边分配:
X_train, X_test, Y_train, Y_test = train_test_split( model_1.drop(columns=['quality']), model_1['quality'], test_size=0.25, random_state=2, stratify=model_1['quality'] # 新增分层参数 ) - 无需刻意对quality字段做OrdinalEncoder编码,
MNLogit本身支持任意整数、字符串格式的类别值,只要训练集包含对应类别的样本,就会正常输出拟合结果。 - 补全代码中缺失的括号,将无效果的
dropna行改为带赋值的写法:reduced_data = reduced_data.dropna()。
内容的提问来源于stack exchange,提问作者Number1Rock
相关产品推荐
相关产品推荐

