You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用statsmodels进行有序逻辑回归预测及准确率计算问题

解决有序逻辑回归预测的准确率计算问题及模型差异说明

一、准确率计算报错的解决方案

你遇到的ValueError是因为statsmodels的OrderedModel.predict返回的是每个样本对应各类别的概率分布,而非直接的类别标签,且维度为三维数组((n_samples, 1, n_classes)),无法直接和y_test的类别标签计算准确率。修正步骤如下:

修正后的完整代码

import numpy as np
from sklearn import metrics
from sklearn.model_selection import train_test_split
from statsmodels.miscmodels.ordinal_model import OrderedModel

y = df['quality']
X = df[['chlorides', 'sulphates']]
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.4, random_state=20)

# 修正拟合方法的笔误:bgfs → bfgs
mod_probe = OrderedModel(y_train, X_train, distr='logit')
res_log = mod_probe.fit(method='bfgs')

# 生成预测概率并调整维度
predicted = res_log.model.predict(res_log.params, np.array(X_test)[:, None])
pred_probs = predicted.squeeze(axis=1)  # 转为(n_samples, n_classes)的二维数组

# 获取训练集排序后的类别(确保和概率输出顺序对应)
sorted_classes = np.sort(y_train.unique())
# 取概率最大的类别作为预测标签
predicted_labels = sorted_classes[np.argmax(pred_probs, axis=1)]

# 计算并输出准确率
accuracy = metrics.accuracy_score(y_test, predicted_labels)
print(f"准确率: {accuracy:.4f}")

关键细节说明

  • squeeze(axis=1)用于移除多余的维度,将三维概率数组转为标准的二维格式
  • np.argmax(pred_probs, axis=1)找到每个样本概率最高的类别索引,再通过sorted_classes映射回实际的quality值(必须保证类别顺序和模型输出的概率顺序一致)

二、与SciKit-Learn LogisticRegression结果差异大的原因

两者结果差异大是模型本质不同导致的,并非代码错误:

  • statsmodels OrderedModel:是有序逻辑回归,假设目标变量quality的1-10分存在明确的顺序关系,模型拟合类别间的阈值,通过累积概率预测类别。
  • sklearn LogisticRegression:默认是多分类无序逻辑回归(multi_class='auto',类别数>2时自动使用multinomial模式),假设各个quality类别之间独立、无顺序,每个类别单独拟合回归系数。

若需公平对比

如果要让两者模型假设一致,可选择以下两种方式:

  1. 在statsmodels中使用多分类无序逻辑回归:

    from statsmodels.discrete.discrete_model import MNLogit
    mod_mn = MNLogit(y_train, X_train)
    res_mn = mod_mn.fit(method='bfgs')
    # 预测类别
    pred_mn_labels = res_mn.predict(X_test).idxmax(axis=1)
    

    此时结果会和sklearn的LogisticRegression(multi_class='multinomial', solver='lbfgs')接近。

  2. 在sklearn中实现有序逻辑回归:
    使用第三方库sklearn-ordinal(需先安装:pip install sklearn-ordinal),示例代码:

    from ordinal_regression import OrdinalLogisticRegression
    clf = OrdinalLogisticRegression()
    clf.fit(X_train, y_train)
    pred_ord_labels = clf.predict(X_test)
    

内容的提问来源于stack exchange,提问作者AntikM

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.23 03:44:53