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

零膨胀泊松/负二项回归MAE计算报错及模型不收敛问题解决

零膨胀回归:维度不匹配与模型收敛问题解决方案

一、维度不匹配问题的根本解决方法

直接拆分原始数据集后用dmatrices分别处理训练/测试集,容易出现特征维度不一致(比如训练集有某类别哑变量,测试集没有),导致维度不匹配错误。正确流程是先统一生成全量设计矩阵,再拆分训练测试集:

import statsmodels.api as sm
import pandas as pd
from sklearn.model_selection import train_test_split

# 定义模型公式
formula = "目标变量 ~ 特征1 + 特征2 + 特征3"
# 先对全量数据生成设计矩阵和目标向量,确保特征维度统一
y_full, X_full = sm.dmatrices(formula, data=你的数据集, return_type='dataframe')

# 再拆分训练测试集
X_train, X_test, y_train, y_test = train_test_split(X_full, y_full, test_size=0.2, random_state=42)

二、模型不收敛的排查与解决策略

模型不收敛通常和数据特性、模型设置、特征质量有关,按以下步骤逐一排查:

1. 验证数据是否适合零膨胀模型

零膨胀模型只适用于**零值占比高(通常>15%)+ 过度离散(方差远大于均值)**的数据,先做基础统计:

# 统计零值占比
zero_ratio = len(你的数据集[你的数据集['目标变量'] == 0]) / len(你的数据集)
print(f"零值占比: {zero_ratio:.2f}")

# 统计均值和方差
mean_y = 你的数据集['目标变量'].mean()
var_y = 你的数据集['目标变量'].var()
print(f"目标变量均值: {mean_y:.2f}, 方差: {var_y:.2f}")
  • 如果方差接近均值:改用普通泊松回归即可,零膨胀模型没必要
  • 如果零值占比<10%:零膨胀模型的结构会导致参数估计不稳定,建议放弃或合并稀疏类别

2. 手动指定模型初始参数

statsmodels默认的初始参数可能无法引导模型收敛,先拟合普通模型获取合理初始值:

import numpy as np

# 先拟合普通泊松回归,用其参数作为ZIP模型计数部分的初始值
poisson_base = sm.Poisson(y_train, X_train).fit()
# 拟合ZIP模型,指定初始参数(计数部分参数+膨胀部分初始值0)
zip_model = sm.ZeroInflatedPoisson(
    y_train, X_train, inflation='logit'
).fit(start_params=np.append(poisson_base.params, 0))

# 零膨胀负二项回归同理,先用普通负二项回归获取初始值
nb_base = sm.NegativeBinomial(y_train, X_train).fit()
zinb_model = sm.ZeroInflatedNegativeBinomialP(
    y_train, X_train, inflation='logit'
).fit(start_params=np.append(nb_base.params, 0))

3. 优化特征质量

  • 消除多重共线性:用相关系数矩阵检查高度相关的特征(相关系数>0.7),删除其中一个
    corr_matrix = 你的数据集.corr()
    # 筛选高度相关特征
    high_corr = corr_matrix.where(np.triu(np.ones(corr_matrix.shape), k=1).astype(bool))
    high_corr_features = [column for column in high_corr.columns if any(high_corr[column].abs() > 0.7)]
    # 删除高相关特征
    你的数据集 = 你的数据集.drop(high_corr_features, axis=1)
    
  • 标准化数值特征:当特征尺度差异过大时,会影响优化器收敛,对数值特征做标准化:
    from sklearn.preprocessing import StandardScaler
    
    # 只对数值特征标准化
    num_features = 你的数据集.select_dtypes(include=['int64', 'float64']).columns.drop('目标变量')
    scaler = StandardScaler()
    你的数据集[num_features] = scaler.fit_transform(你的数据集[num_features])
    

4. 调整优化器参数

默认优化器可能无法处理复杂数据,尝试更换优化器或增加迭代次数:

# 更换为牛顿共轭梯度法,增加迭代次数
zip_model = sm.ZeroInflatedPoisson(
    y_train, X_train, inflation='logit'
).fit(method='ncg', maxiter=1000, disp=True)

可选优化器:'bfgs'、'powell'、'lbfgs',disp=True可以查看迭代过程,帮助判断收敛情况。

5. 处理异常值

目标变量或特征中的极端值会干扰参数估计,用箱线图识别并处理:

import matplotlib.pyplot as plt

# 查看目标变量箱线图
plt.boxplot(你的数据集['目标变量'])
plt.show()

# 删除超过3倍标准差的异常值
y_mean = 你的数据集['目标变量'].mean()
y_std = 你的数据集['目标变量'].std()
你的数据集 = 你的数据集[np.abs(你的数据集['目标变量'] - y_mean) <= 3 * y_std]

三、正确计算MAE的注意事项

零膨胀模型的预测值是零值概率与计数均值的加权结果,直接用predict()方法指定which='mean'即可得到最终预测值,再计算MAE:

from sklearn.metrics import mean_absolute_error

# ZIP模型预测
zip_pred = zip_model.predict(X_test, which='mean')
# 计算MAE
zip_mae = mean_absolute_error(y_test, zip_pred)

# 零膨胀负二项回归同理
zinb_pred = zinb_model.predict(X_test, which='mean')
zinb_mae = mean_absolute_error(y_test, zinb_pred)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.16 18:05:57