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

获取分类数据AIC/BIC值时遇ValueError:endog为多列数组

二元分类变量拟合OLS模型触发ValueError的解决方法

问题场景

我有一个700行×2列的DataFrame,两列均为取值为Yes/No的category类型数据。尝试用statsmodels的ols公式C(Private) ~ C(Elite)拟合模型以获取AIC/BIC值时,报错:

ValueError: endog has evaluated to an array with multiple columns that has shape (700, 2)

即使将Yes/No替换为1/0并转为数值类型,仍出现相同错误。

可复现示例代码

import pandas as pd

df = pd.DataFrame(columns=['Private','Elite'])
df[''] = ['Abilene Christian University', 'Center for Creative Studies', 'Florida Institute of Technology', 
          'LaGrange College', 'Muhlenberg College', 'Saint Mary-of-the-Woods College', 'Union College KY']

df = df.set_index('')
df['Private'] = 'Yes'
df['Elite'] = 'No'

for x in df.columns:
    df[x] = df[x].astype('category')

df_train = df.copy(deep=True)

报错的拟合代码

from statsmodels.formula.api import ols

fit = ols('C(Private) ~ C(Elite)', data=df_train).fit()
fit.summary()

数值转换后仍报错的代码

from statsmodels.formula.api import ols

df_train = df_train.replace('Yes', int(1))
df_train = df_train.replace('No', int(0))

for x in df_train.columns:
    df_train[x] = pd.to_numeric(df_train[x])

fit = ols('C(Private) ~ C(Elite)', data=df_train).fit()
fit.summary()

错误原因

核心问题在于:对二元分类变量使用C()函数时,statsmodels会默认生成虚拟变量矩阵(多列),而OLS模型的因变量(endog)要求是单列数据,不能是多列矩阵。比如C(Private)会把Yes/No分类转为两列(如Private_Yes和Private_No),导致因变量形状变为(700,2),触发报错。

解决方法

方法1:直接使用数值列作为因变量(无需C()包裹)

如果已经将分类值转为1/0的数值类型,直接用列名作为因变量即可,不需要用C()包裹:

from statsmodels.formula.api import ols

# 简化数值转换
df_train = df_train.replace({'Yes': 1, 'No': 0})
df_train = df_train.apply(pd.to_numeric)

# 直接使用列名作为因变量
fit = ols('Private ~ C(Elite)', data=df_train).fit()
print(fit.summary())
print(f"AIC: {fit.aic}, BIC: {fit.bic}")

方法2:为分类因变量指定参考类别

如果要保留category类型,可以在C()中通过reference参数指定参考类别,让statsmodels只生成单一对比列,确保因变量为单列:

from statsmodels.formula.api import ols

# 指定参考类别,避免生成多列
fit = ols('C(Private, reference="No") ~ C(Elite)', data=df_train).fit()
print(fit.summary())
print(f"AIC: {fit.aic}, BIC: {fit.bic}")

更优模型选择:逻辑回归

对于二元因变量的场景,OLS模型的假设(因变量连续)并不适配,更推荐使用Logit逻辑回归模型,该模型专为二元分类任务设计,同样能输出AIC/BIC值:

from statsmodels.formula.api import logit

# 拟合Logit模型(需确保因变量为0/1数值)
df_train = df_train.replace({'Yes':1, 'No':0})
df_train = df_train.apply(pd.to_numeric)

fit_logit = logit('Private ~ C(Elite)', data=df_train).fit()
print(fit_logit.summary())
print(f"AIC: {fit_logit.aic}, BIC: {fit_logit.bic}")

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.22 17:09:23