查看全集:💎Quantopia量化分析56讲
线性回归的基本形式:
残差 = 观测值 - 预测值
其中:
残差项的三个重要假设:
# 生成非线性数据示例
n = 50
X = np.linspace(0, 10, n)
Y = 2*X + 3*np.sin(X) + np.random.normal(0, 1, n)
model = sm.OLS(Y, sm.add_constant(X)).fit()
plt.scatter(model.predict(), model.resid)
plt.axhline(0, color='r', linestyle='--')
当残差呈现规律性分布时(如抛物线型),提示可能存在非线性关系。
Breusch-Pagan检验实现:
bp_test = smd.het_breuschpagan(residuals, model.model.exog)
print(f"P值:{bp_test[1]:.4f}")
if bp_test[1] < 0.05:
print("存在异方差性")
else:
print("满足同方差假设")
处理方法对比表:
方法 | 适用场景 | 注意事项 |
差分法 | 时间序列数据 | 改变数据维度 |
对数变换 | 正数数据 | 解释系数需逆变换 |
Box-Cox变换 | 非正态分布数据 | λ参数需优化选择 |
Ljung-Box检验示例:
lb_test = smd.acorr_ljungbox(residuals, lags=10)
print(f"最大P值:{lb_test[1].max():.4f}")
if any(lb_test[1] < 0.05):
print("存在自相关")
else:
print("无显著自相关")
import yfinance as yf
# 获取数据
start = '2020-01-01'
end = '2021-01-01'
tsla = yf.download('TSLA', start=start, end=end)['Close']
spy = yf.download('SPY', start=start, end=end)['Close']
# 计算收益率
returns = pd.DataFrame({
'TSLA': tsla.pct_change().dropna(),
'SPY': spy.pct_change().dropna()
})
# 回归模型
X = sm.add_constant(returns['SPY'])
model = sm.OLS(returns['TSLA'], X).fit()
# 残差诊断图
fig, axes = plt.subplots(1,2, figsize=(12,5))
axes[0].scatter(model.predict(), model.resid)
axes[0].axhline(0, color='r')
axes[1].plot(model.resid)
# 异方差检验
bp_test = smd.het_breuschpagan(model.resid, model.model.exog)
print(f"异方差检验P值:{bp_test[1]:.4f}")
# 自相关检验
lb_test = smd.acorr_ljungbox(model.resid, lags=5)
print(f"自相关检验P值:{lb_test[1][-1]:.4f}")
关键提示:当使用Box-Cox变换时,注意数据必须为正数,可使用公式:\frac{y^\lambda - 1}{\lambda} & \lambda \neq 0 \\ \ln(y) & \lambda = 0 \end{cases} $ 这是Box-Cox变换的数学表达式,其中: - y 是原始数据 - λ (lambda) 是变换参数 - 当 λ = 0 时,变换等价于取自然对数 - 当 λ ≠ 0 时,使用 (y^λ - 1)/λ 进行变换 重要注意事项: - 原始数据 y 必须为正数 - 这种变换可以帮助改善数据的正态性和方差齐性 - λ 的选择通常基于最大似然估计
以下为Box-Cox变换的公式:
通过系统性的残差分析,可以有效验证模型假设,提升回归结果的可靠性。建议每次建立回归模型后,至少进行残差图的视觉检查和基本的统计检验。