残差图中漏斗形→异方差,u/倒u形→欠拟合缺非线性项,斜线→系统偏差或变量遗漏,边缘离群点→异常值;需用statsmodels检验正态性与自相关,改进应基于残差形态而非仅提升r²。

残差图怎么看:哪些形状说明模型有问题
残差图(residuals vs. fitted)不是用来“看热闹”的,关键看散点是否随机分布在水平线 y=0 附近。如果出现明显模式,基本能定位问题类型:
- 漏斗形(残差随拟合值增大而发散)→ 异方差性,
LinearRegression的标准误失效,predict()区间不可靠 - U形或倒U形曲线 → 模型欠拟合,很可能缺非线性项(比如没加
x**2或np.log(x)) - 斜线趋势(残差系统性上升/下降)→ 模型存在系统性偏差,可能是关键变量遗漏,或目标变量需变换(如用
np.log(y)替代原始y) - 边缘聚集大量离群残差点 → 数据中存在强异常值,
RANSACRegressor或TheilSenRegressor比LinearRegression更鲁棒
用 statsmodels 快速检验残差正态性与自相关
sklearn 不提供残差诊断统计量,必须切到 statsmodels。重点不是“是否严格正态”,而是判断是否严重偏离——影响置信区间和假设检验可靠性。
核心检查项:
-
sm.stats.diagnostic.acorr_ljungbox(resid, lags=1):返回p-value,若 ARIMA 或加入滞后特征) -
sm.stats.stattools.adfuller(resid):检验残差是否平稳,p-value > 0.05表示非平稳,原始模型可能伪回归 -
sm.stats.diagnostic.kstest_normal(resid):比直方图更定量,但对样本量敏感;小样本下优先看 Q-Q 图(sm.qqplot(resid))
注意:resid 必须是训练集上的残差,且未中心化(即用 y_train - model.predict(X_train)),否则检验失效。
安全 Python 代码沙箱:在隔离的沙箱中执行任意 Python 代码,预装 requests、NumPy、pandas 库。返回 stdout、stderr。
改进模型时别只盯着 R²:先看残差分布再选方法
R² 提高不等于预测更稳。当残差呈现异方差或厚尾时,应切换损失函数或模型结构:
- 残差绝对值大时波动剧烈 → 改用
HuberRegressor(loss='huber', epsilon=1.35),比LinearRegression对离群点鲁棒 - 残差明显右偏(正残差远多于负残差)→ 尝试分位数回归:
QuantileRegressor(quantile=0.5)(中位数回归),不依赖正态假设 - 残差在低拟合值区域过小、高拟合值区域过大 → 用
TransformedTargetRegressor(transformer=PowerTransformer(), regressor=LinearRegression())自动对y做幂变换 - 残差存在局部结构(如周期性起伏)→ 不要硬加高阶多项式,先用
SHAP或partial_dependence查看特征边际效应,确认是否该引入分段变量或交互项
验证改进是否真实有效:用残差重采样做稳健评估
常规的 train/test split 容易掩盖残差结构问题。尤其当测试集残差恰好“看起来很随机”时,可能只是偶然。
更可靠的做法:
- 对训练残差做 bootstrap 重采样(
np.random.choice(resid_train, size=len(resid_train), replace=True)),加到预测值上生成新 y,再重新拟合模型,观察 R² 和 MAE 的分布宽度 —— 若 MAE 标准差 > 0.1×均值,说明原始模型稳定性差 - 用
sklearn.model_selection.RepeatedKFold(n_splits=5, n_repeats=3)而非单次分割,观察各折残差图形态是否一致;若某折总出现 U 形,说明模型对特定数据子集敏感 - 保存每折的残差向量,做聚类(如
DBSCAN)看是否存在稳定残差模式簇 —— 这往往对应未被捕捉的子群体(例如某类用户、某时间段)
真正难的不是画出残差图,而是把残差的形状语言翻译成模型结构动作。同一张图,有人看到“需要加个平方项”,有人只看到“R²还行”。这种翻译能力来自反复对照残差形态与改动之间的因果反馈,没有捷径。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!










