AI添加时间特征并训练模型
编辑
0
2025-06-27

提示词
以日期为index的DataFrame,包含每日的收盘价,现在需要将index中的月份提取出来,并转换为哑变量,作为新的特征保存到DataFrame中,然后检查添加的结果,请给出示例代码。
答案
import pandas as pd
import numpy as np
# 创建示例数据(假设df是包含日期索引和收盘价的DataFrame)
# dates = pd.date_range(start='2023-01-01', end='2023-12-31', freq='D')
# prices = np.random.uniform(1800, 2000, len(dates)).round(2)
# df = pd.DataFrame({'收盘价': prices}, index=dates)
df = pd.read_excel('黄金连续.xlsx')
#将日期设置为index,并只保留收盘价
df.set_index('日期', inplace=True)
df = df[['收盘价']]
# 1. 从日期索引中提取月份 [1,2,3](@ref)
print("原始数据前5行:")
print(df.head(), end='\n\n')
# 2. 提取月份(1-12)
df['月份'] = df.index.month # 直接使用datetime索引的month属性[2,3](@ref)
# 3. 将月份转换为哑变量 [3,5](@ref)
month_dummies = pd.get_dummies(
df['月份'],
prefix='month',
prefix_sep='_',
dtype=int # 指定为整数类型节省内存
)
# 4. 将哑变量添加到原始DataFrame
df = pd.concat([df, month_dummies], axis=1)
# 5. 检查添加结果
print("添加月份特征后的数据:")
print(df.head(), end='\n\n')
print("月份统计分布:")
print(df['月份'].value_counts().sort_index(), end='\n\n')
print("哑变量特征示例:")
print(df[['月份'] + list(month_dummies.columns)].head(10), end='\n\n')
# 6. 可视化月份分布
import matplotlib.pyplot as plt
plt.figure(figsize=(14, 6))
# 月度收盘价分布
plt.subplot(1, 2, 1)
df.groupby('月份')['收盘价'].mean().plot(kind='bar', color='skyblue')
plt.title('各月平均收盘价')
plt.xlabel('月份')
plt.ylabel('平均价格')
# 月份频数分布
plt.subplot(1, 2, 2)
df['月份'].value_counts().sort_index().plot(kind='pie', autopct='%1.1f%%')
plt.title('月份分布比例')
plt.ylabel('')
plt.tight_layout()
plt.show()
代码都是ai写的。
结果:
建模
提示词
简化代码再描述
# Python代码
# df是黄金期货行情DataFrame
df = pd.read_excel('黄金连续.xlsx')
#将日期设置为index,并只保留收盘价
df.set_index('日期', inplace=True)
df = df[['收盘价']]
# 特征工程
df['Month'] = df.index.month
dummies = pd.get_dummies(df['Month'], prefix='Month', dtype='int')
df = pd.concat([df, dummies], axis=1)
#为了使大家可以看到数据处理结果,我们检查下
df.tail()
现在我们使用上面添加了时间特征的DataFrame创建线性回归模型,并用滚动时间序列交叉验证法评估模型的MAPE,最后将结果进行可视化,请给出示例代码。
答案
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from sklearn.linear_model import LinearRegression
from sklearn.model_selection import TimeSeriesSplit
from sklearn.metrics import mean_absolute_error
# 1. 特征工程扩展(添加滞后特征)
for lag in [1, 3, 5, 7]:
df[f'Lag_{lag}'] = df['收盘价'].shift(lag)
# 添加技术指标特征
df['MA5'] = df['收盘价'].rolling(5).mean().shift(1) # 5日移动平均(避免泄露)
df['MA20'] = df['收盘价'].rolling(20).mean().shift(1) # 20日移动平均
df['Volatility'] = df['收盘价'].rolling(10).std().shift(1) # 波动率
df['Price_Change'] = df['收盘价'].pct_change().shift(1) * 100 # 价格变化率
# 目标变量(预测次日收盘价)
df['Target'] = df['收盘价'].shift(-1)
# 删除含NaN的行
df_clean = df.dropna().copy()
# 2. 定义特征和目标变量
features = [col for col in df_clean.columns if col not in ['收盘价', 'Target', 'Month']]
target = 'Target'
# 3. 滚动时间序列交叉验证
tscv = TimeSeriesSplit(n_splits=5)
predictions = []
actuals = []
dates = []
mape_values = []
print("开始滚动交叉验证...")
for train_index, test_index in tscv.split(df_clean):
# 数据分割
train = df_clean.iloc[train_index]
test = df_clean.iloc[test_index]
# 训练模型
model = LinearRegression()
model.fit(train[features], train[target])
# 预测
test_pred = model.predict(test[features])
# 存储结果
predictions.extend(test_pred)
actuals.extend(test[target].values)
dates.extend(test.index)
# 计算MAPE(过滤零值)
mask = test[target] != 0
mape = mean_absolute_error(
test.loc[mask, target],
test_pred[mask]
) / np.mean(test.loc[mask, target]) * 100
mape_values.append(mape)
print(f"子集MAPE: {mape:.2f}%")
# 4. 结果汇总
results = pd.DataFrame({
'Date': dates,
'Actual': actuals,
'Predicted': predictions
}).set_index('Date').sort_index()
# 整体MAPE计算
mask = results['Actual'] != 0
overall_mape = mean_absolute_error(
results.loc[mask, 'Actual'],
results.loc[mask, 'Predicted']
) / np.mean(results.loc[mask, 'Actual']) * 100
print(f"\n整体MAPE: {overall_mape:.2f}%")
# 5. 可视化分析
plt.figure(figsize=(16, 10))
# 5.1 价格曲线对比
plt.subplot(2, 1, 1)
plt.plot(results.index, results['Actual'], 'b-', label='实际价格', alpha=0.8, lw=1.5)
plt.plot(results.index, results['Predicted'], 'r--', label='预测价格', lw=1.2)
plt.fill_between(results.index,
results['Predicted'] * 0.97,
results['Predicted'] * 1.03,
color='pink', alpha=0.3, label='±3%误差带')
plt.title(f'黄金期货价格预测 (MAPE={overall_mape:.2f}%)', fontsize=14)
plt.ylabel('价格', fontsize=12)
plt.legend()
plt.grid(alpha=0.2)
# 5.2 误差分布分析
plt.subplot(2, 1, 2)
errors = (results['Predicted'] - results['Actual']) / results['Actual'] * 100
plt.bar(results.index, errors,
color=np.where(errors >= 0, 'coral', 'seagreen'),
alpha=0.7, width=0.8)
plt.axhline(0, color='black', ls='--', lw=0.8)
plt.title('每日预测误差分布', fontsize=12)
plt.ylabel('百分比误差(%)', fontsize=10)
plt.ylim(-15, 15)
plt.grid(alpha=0.2)
plt.tight_layout()
plt.savefig('gold_price_forecast.png', dpi=300)
plt.show()
# 6. 模型系数分析
coef_df = pd.DataFrame({
'Feature': features,
'Coefficient': model.coef_
}).sort_values('Coefficient', key=abs, ascending=False)
print("\n特征重要性Top 10:")
print(coef_df.head(10))
# 可视化系数
plt.figure(figsize=(10, 6))
top_features = coef_df.head(10).sort_values('Coefficient', ascending=True)
plt.barh(top_features['Feature'], top_features['Coefficient'], color='teal')
plt.title('线性回归模型特征系数Top 10', fontsize=14)
plt.xlabel('系数值', fontsize=12)
plt.grid(axis='x', alpha=0.3)
plt.tight_layout()
plt.show()
结果:
- 0
- 0
-
赞助
支付宝
微信
-
分享