一、回归模型的核心假设回顾#
在开始分析假设违反之前,我们需要明确线性回归的四个核心假设(Gauss-Markov条件):
-
线性性:自变量与因变量呈线性关系
-
独立性:误差项之间相互独立
-
同方差性:误差项的方差恒定
-
正态性:误差项服从正态分布
当这些假设被违反时,模型的参数估计和统计推断将不可靠。
二、残差分析:诊断模型问题的关键#
2.1 残差的正态性检验#
Jarque-Bera检验原理:
其中S为偏度,K为峰度。当数据服从正态分布时,JB统计量服从χ²分布。
code
from statsmodels.stats.stattools import jarque_bera
# 生成正态分布残差示例
residuals_normal = np.random.normal(0, 1, 100)
jb_stat, pvalue, _, _ = jarque_bera(residuals_normal)
print(f"正态残差的p值: {pvalue:.4f}")
# 生成非正态残差示例
residuals_nonnormal = np.random.poisson(5, 100)
jb_stat, pvalue, _, _ = jarque_bera(residuals_nonnormal)
print(f"非正态残差的p值: {pvalue:.4f}")2.2 异方差性(Heteroskedasticity)#
概念解析#
异方差性指误差项的方差随自变量的变化而变化,会导致:
-
参数估计仍无偏但不再有效
-
标准误估计有偏,影响假设检验
Breusch-Pagan检验步骤:
-
用OLS估计原始模型,得到残差
-
用残差平方对自变量回归
-
计算LM统计量:LM = 0.5 * ESS ~ χ²(k)
code
import yfinance as yf
from statsmodels.stats.diagnostic import het_breuschpagan
# 下载苹果公司股票数据
data = yf.download('AAPL', start='2020-01-01', end='2023-01-01')
data['Return'] = data['Close'].pct_change().dropna()
X = sm.add_constant(np.arange(len(data))[1:]) # 时间趋势项
model = sm.OLS(data['Return'].iloc[1:], X).fit()
# 进行BP检验
bp_test = het_breuschpagan(model.resid, X)
print(f"BP检验p值: {bp_test[1]:.4f}")解决方案:稳健标准误#
code
# 比较普通标准误与稳健标准误
print("普通标准误:", model.bse)
robust_model = model.get_robustcov_results(cov_type='HC3')
print("稳健标准误:", robust_model.bse)2.3 自相关(Autocorrelation)#
Durbin-Watson检验#
DW统计量范围:
-
0-2:正自相关
-
2-4:负自相关
-
2附近:无自相关
code
from statsmodels.stats.stattools import durbin_watson
dw = durbin_watson(model.resid)
print(f"DW统计量: {dw:.2f}")Newey-West校正#
code
# 应用Newey-West标准误
newey_model = model.get_robustcov_results(cov_type='HAC', maxlags=3)
print(newey_model.summary())三、多重共线性检测与处理#
3.1 方差膨胀因子(VIF)#
是第j个自变量对其他自变量的决定系数
code
from statsmodels.stats.outliers_influence import variance_inflation_factor
# 示例:检测标普500与纳斯达克指数的共线性
data = yf.download(['^GSPC', '^IXIC'], start='2020-01-01', end='2023-01-01')['Close']
X = sm.add_constant(data[['^GSPC', '^IXIC']])
vifs = [variance_inflation_factor(X.values, i) for i in range(X.shape[1])]
print(f"VIF值: {vifs[1:]}")3.2 解决方案实践#
-
剔除高相关变量(如保留标普500指数,剔除纳斯达克)
-
主成分分析(PCA)降维
-
增大样本量
四、综合案例:Anscombe四重奏的现代重现#
code
# 获取四个不同模式的数据集
datasets = sm.datasets.get_rdataset("anscombe").data
fig, axes = plt.subplots(2, 2, figsize=(12, 8))
for i, (ax, dataset) in enumerate(zip(axes.flat, datasets.values())):
x = dataset['x']
y = dataset['y']
model = sm.OLS(y, sm.add_constant(x)).fit()
ax.scatter(x, y)
ax.plot(x, model.predict(), color='red')
ax.set_title(f'Dataset {i+1}\nR²={model.rsquared:.2f}')
plt.tight_layout()五、实践练习#
-
下载特斯拉(TSLA)和通用汽车(GM)的股票数据,分析它们的收益率是否存在异方差性
-
对苹果公司日收益率建立时间趋势模型,检测并校正自相关问题
-
计算道琼斯指数成分股之间的VIF值,找出共线性最高的三只股票
code
# 练习1示例代码
data = yf.download(['TSLA', 'GM'], start='2020-01-01', end='2023-01-01')
returns = data['Close'].pct_change().dropna()
# 构建回归模型
X = sm.add_constant(returns['TSLA'])
model = sm.OLS(returns['GM'], X).fit()
# 进行异方差检验
_, pvalue, _, _ = het_breuschpagan(model.resid, X)
print(f"Breusch-Pagan检验p值: {pvalue:.4f}")通过系统性地诊断和处理这些假设违反问题,可以显著提高回归模型的可靠性和解释力。实践中建议建立标准化的诊断流程,在建模后自动进行假设检验并生成诊断报告。