Python事件研究分析遇阻:无法将date作为自变量构建预测模型
事件研究分析代码修正方案
原代码核心问题
- 变量名错误:公式中使用了不存在的
variable列,实际数据列名为units。 - 日期类型不兼容:statsmodels公式接口无法直接处理
datetime类型变量,需转换为数值型(如距起始日的天数)。 - 切片与数据修改风险:未将
date设为索引导致日期切片可能失效,直接修改切片后的DataFrame会触发SettingWithCopyWarning。 - 预测数据缺失:调用
m.predict()时未传入观测数据集,模型无法生成对应预测值。
修正后的完整代码
import pandas as pd import numpy as np import statsmodels.formula.api as smf import seaborn as sns import matplotlib.pyplot as plt # 样本数据 units = [0.916301354, 0.483947819, 0.551258976, 0.147971439, 0.617461504, 0.957460424, 0.905076453, 0.274261518, 0.861609383, 0.285914819, 0.989686616, 0.86614591, 0.074250832, 0.209507105, 0.082518752, 0.215795111, 0.953852132, 0.768329343, 0.380686392, 0.623940323, 0.155944248, 0.495745862, 0.0845513, 0.519966471, 0.706618333, 0.872300766, 0.70769554, 0.760616731, 0.213847926, 0.703866155, 0.802862491, 0.52468101, 0.352283626, 0.128962646, 0.684358794, 0.360520106, 0.889978575, 0.035806225, 0.15459103, 0.227742501, 0.06248614, 0.903500165, 0.13851151, 0.664684486, 0.011042697, 0.86353796, 0.971852899, 0.487774978, 0.547767217, 0.153629408, 0.076994094, 0.230693561, 0.961345948] begin_date = '2022-8-01' df = pd.DataFrame({'date': pd.date_range(begin_date, periods=len(units)), 'units': units}) # 设置date为索引,方便日期切片 df = df.set_index('date') # 创建估计数据集和观测数据集,避免SettingWithCopyWarning est_data = df['2022-08-01':'2022-08-30'].copy() obs_data = df['2022-09-01':'2022-09-14'].copy() # 生成数值型时间变量:距起始日的天数 start_date = est_data.index.min() est_data['days_since_start'] = (est_data.index - start_date).dt.days obs_data['days_since_start'] = (obs_data.index - start_date).dt.days # 拟合OLS模型:用days_since_start预测units m = smf.ols('units ~ days_since_start', data=est_data).fit() # 计算均值调整的异常收益(AR_mean) mean_units = est_data['units'].mean() obs_data['AR_mean'] = obs_data['units'] - mean_units # 计算模型调整的异常收益(AR_risk):传入obs_data生成预测值 obs_data['risk_pred'] = m.predict(obs_data) obs_data['AR_risk'] = obs_data['units'] - obs_data['risk_pred'] # 可视化结果 sns.lineplot(x=obs_data.index, y=obs_data['AR_risk']) plt.title('Model-Adjusted Abnormal Returns') plt.xlabel('Date') plt.ylabel('Abnormal Return') plt.xticks(rotation=45) plt.tight_layout() plt.show()
关键修改说明
- 日期处理:将
date设为索引后,日期切片更可靠;新增days_since_start列,把datetime转换为整数天数,解决statsmodels无法直接处理日期的问题。 - 变量名修正:将公式中的
variable改为实际列名units。 - 数据复制:用
.copy()生成独立数据集,避免修改原数据时的警告。 - 预测逻辑:调用
m.predict(obs_data)传入观测数据,确保模型能基于相同的自变量生成预测值。
内容的提问来源于stack exchange,提问作者josephbags
相关产品推荐
相关产品推荐

