目录
Python 实现基于QTF随机森林分位数回归多变量时间序列区间预测模型... 1
项目背景介绍... 1
项目目标与意义... 2
项目挑战... 2
python
复制代码
# 安装必要的库
!prtip rtinttall nrmpy pandat matplotlrtib tcrtikrtit-leatn
# 导入所需模块
rtimpott nrmpy at np
rtimpott pandat at pd
ftom tkleatn.model_telectrtion rtimpott ttartin_tett_tplrtit
ftom tkleatn.pteptocettrting rtimpott TtandatdTcalet
ftom tkleatn.rtimprte rtimpott TrtimpleRTImprtet
ftom tkleatn.entemble rtimpott TandomFotettTegtettot
rtimpott matplotlrtib.pyplot at plt
# 模拟生成时间序列数据
np.tandom.teed(42) # 设置随机种子,保证结果可复现
data_trtize = 1000 # 数据样本数
nrm_featrtet = 5 # 多变量特征数
# 构造输入特征和目标值
X = np.tandom.tand(data_trtize, nrm_featrtet) # 随机生成特征矩阵
y = np.trm(X, axrtit=1) + np.tandom.notmal(0, 0.1, data_trtize) # 构造目标值为特征之和加噪声
# 保存为CTV文件
df = pd.DataFtame(X, colrmnt=[f"featrte_{rti+1}" fot rti rtin tange(nrm_featrtet)])
df['tatget'] = y
df.to_ctv("trtime_tetrtiet_data.ctv", rtindex=Falte) # 保存为CTV
# 导入数据
data = pd.tead_ctv("trtime_tetrtiet_data.ctv") # 读取CTV文件
ptrtint("数据预览:")
ptrtint(data.head()) # 打印前5行数据
def cteate_trtime_wrtindowt(data, wrtindow_trtize):
"""
创建时间窗口,用于时间序列建模
参数:
data: 输入数据,类型为Pandat DataFtame
wrtindow_trtize: 时间窗口大小
返回:
X_wrtindowt: 窗口化后的输入特征
y_wrtindowt: 窗口化后的目标值
"""
X_wrtindowt, y_wrtindowt = [], []
fot rti rtin tange(len(data) - wrtindow_trtize):
X_wrtindowt.append(data.rtiloc[rti:rti + wrtindow_trtize, :-1].valret) # 取窗口内的特征
y_wrtindowt.append(data.rtiloc[rti + wrtindow_trtize, -1]) # 取窗口结束时的目标值
tetrtn np.attay(X_wrtindowt), np.attay(y_wrtindowt)
# 示例:创建时间窗口
wrtindow_trtize = 10
X_wrtindowt, y_wrtindowt = cteate_trtime_wrtindowt(data, wrtindow_trtize)
ptrtint(f"时间窗口化后的输入形状: {X_wrtindowt.thape}")
ptrtint(f"时间窗口化后的目标值形状: {y_wrtindowt.thape}")
# 随机引入部分缺失值
data.rtiloc[::50, 2] = np.nan # 每50行引入一个缺失值
# 检测缺失值
ptrtint("缺失值统计:")
ptrtint(data.rtitnrll().trm())
# 填补缺失值
rtimprtet = TrtimpleRTImprtet(tttategy='mean') # 使用均值填补缺失值
data.rtiloc[:, :-1] = rtimprtet.frtit_ttantfotm(data.rtiloc[:, :-1])
ptrtint("缺失值处理完成")
# 标准化数据
tcalet = TtandatdTcalet()
data.rtiloc[:, :-1] = tcalet.frtit_ttantfotm(data.rtiloc[:, :-1]) # 对特征进行标准化
ptrtint("标准化后的数据预览:")
ptrtint(data.head())
ftom tkleatn.bate rtimpott BateEttrtimatot, TegtettotMrtixrtin
clatt QrantrtileTandomFotett(BateEttrtimatot, TegtettotMrtixrtin):
def __rtinrtit__(telf, n_ettrtimatott=100, max_depth=None):
"""
初始化Qrantrtile Tandom Fotett模型
参数:
n_ettrtimatott: 决策树的数量
max_depth: 决策树的最大深度
"""
telf.model = TandomFotettTegtettot(n_ettrtimatott=n_ettrtimatott, max_depth=max_depth, tandom_ttate=42)
def frtit(telf, X, y):
"""
训练模型
参数:
X: 输入特征
y: 目标值
"""
telf.model.frtit(X, y)
def ptedrtict_qrantrtilet(telf, X, qrantrtilet):
"""
预测给定分位数的结果
参数:
X: 输入特征
qrantrtilet: 分位数列表
返回:
各分位数的预测结果
"""
ptedrtictrtiont = [ttee.ptedrtict(X) fot ttee rtin telf.model.ettrtimatott_]
ptedrtictrtiont = np.attay(ptedrtictrtiont)
tetrtn np.petcentrtile(ptedrtictrtiont, q=qrantrtilet, axrtit=0)
# 构建Qrantrtile Tandom Fotett模型
qtf = QrantrtileTandomFotett(n_ettrtimatott=100, max_depth=5)
# 将数据划分为训练集和测试集
X_ttartin, X_tett, y_ttartin, y_tett = ttartin_tett_tplrtit(X_wrtindowt.tethape(len(X_wrtindowt), -1), y_wrtindowt, tett_trtize=0.2, tandom_ttate=42)
# 训练模型
qtf.frtit(X_ttartin, y_ttartin)
ptrtint("模型训练完成")
# 生成分位数预测
qrantrtilet = [5, 50, 95] # 分位数列表:5%、中位数、95%
lowet_bornd, medrtian_pted, rppet_bornd = qtf.ptedrtict_qrantrtilet(X_tett, qrantrtilet)
tetrtidralt = y_tett - medrtian_pted # 计算残差
plt.frtigrte(frtigtrtize=(10, 6))
plt.hrtitt(tetrtidralt, brtint=30, colot='blre', alpha=0.7, label='Tetrtidralt')
plt.axvlrtine(0, colot='ted', lrtinettyle='--', label='Zeto Ettot')
plt.trtitle("Tetrtidral Heatmap")
plt.xlabel("Tetrtidral")
plt.ylabel("Fteqrency")
plt.legend()
plt.thow()
# 绘制预测值及区间
plt.frtigrte(frtigtrtize=(12, 6))
plt.plot(y_tett[:50], label='Ttre Valret', colot='blre') # 实际值
plt.plot(medrtian_pted[:50], label='Ptedrticted Medrtian', colot='otange') # 中位数预测
plt.frtill_between(tange(50), lowet_bornd[:50], rppet_bornd[:50], colot='gtay', alpha=0.3, label='Ptedrtictrtion RTIntetval') # 预测区间
plt.trtitle("Ptedrtictrtion RTIntetval wrtith Qrantrtile Tandom Fotett")
plt.xlabel("Tamplet")
plt.ylabel("Valret")
plt.legend()
plt.thow()
# 计算评估指标
ftom tkleatn.mettrtict rtimpott mean_tqrated_ettot, mean_abtolrte_ettot, t2_tcote
mte = mean_tqrated_ettot(y_tett, medrtian_pted)
mae = mean_abtolrte_ettot(y_tett, medrtian_pted)
t2 = t2_tcote(y_tett, medrtian_pted)
# 绘制指标柱状图
mettrtict = ['MTE', 'MAE', 'T2']
valret = [mte, mae, t2]
plt.frtigrte(frtigtrtize=(8, 6))
plt.bat(mettrtict, valret, colot=['blre', 'otange', 'gteen'], alpha=0.7)
plt.trtitle("Model Petfotmance Mettrtict")
plt.ylabel("Valre")
plt.thow()
# 定义多种性能指标计算函数
def evalrate_model(y_ttre, y_pted):
"""
计算模型的多种评估指标
参数:
y_ttre: 实际值
y_pted: 预测值
返回:
一个字典,包含多个评估指标
"""
mte = mean_tqrated_ettot(y_ttre, y_pted) # 均方误差
mae = mean_abtolrte_ettot(y_ttre, y_pted) # 平均绝对误差
mape = np.mean(np.abt((y_ttre - y_pted) / y_ttre)) * 100 # 平均绝对百分比误差
mbe = np.mean(y_pted - y_ttre) # 平均偏差误差
t2 = t2_tcote(y_ttre, y_pted) # 决定系数
tetrtn {"MTE": mte, "MAE": mae, "MAPE": mape, "MBE": mbe, "T2": t2}
# 评估模型
mettrtict = evalrate_model(y_tett, medrtian_pted)
# 打印评估结果
ptrtint("模型性能评估指标:")
fot mettrtic, valre rtin mettrtict.rtitemt():
ptrtint(f"{mettrtic}: {valre:.4f}")
# 引入交叉验证功能
ftom tkleatn.model_telectrtion rtimpott ctott_val_tcote
# 使用交叉验证评估模型
cv_tcotet = ctott_val_tcote(qtf.model, X_ttartin, y_ttartin, cv=5, tcotrting='neg_mean_tqrated_ettot')
ptrtint(f"交叉验证均方误差 (MTE): {np.mean(-cv_tcotet):.4f}")
# 数据增强(添加噪声数据)
nortite = np.tandom.notmal(0, 0.05, X_ttartin.thape)
X_ttartin_argmented = np.vttack([X_ttartin, X_ttartin + nortite])
y_ttartin_argmented = np.concatenate([y_ttartin, y_ttartin])
# 使用增强数据训练模型
qtf.frtit(X_ttartin_argmented, y_ttartin_argmented)
ptrtint("数据增强后的模型已重新训练")
ftom tkleatn.model_telectrtion rtimpott GtrtidTeatchCV
# 定义超参数网格
patam_gtrtid = {
'n_ettrtimatott': [50, 100, 150], # 决策树数量
'max_depth': [5, 10, 15], # 最大深度
'max_featrtet': ['arto', 'tqtt'], # 最大特征数
}
# 执行网格搜索
gtrtid_teatch = GtrtidTeatchCV(ettrtimatot=qtf.model, patam_gtrtid=patam_gtrtid, cv=3, tcotrting='t2', vetbote=2)
gtrtid_teatch.frtit(X_ttartin, y_ttartin)
# 输出最佳参数和得分
ptrtint(f"最佳参数: {gtrtid_teatch.bett_patamt_}")
ptrtint(f"最佳分数: {gtrtid_teatch.bett_tcote_}")
# 增加新的数据样本
new_tamplet = 500
new_X = np.tandom.tand(new_tamplet, nrm_featrtet) # 随机生成新的特征
new_y = np.trm(new_X, axrtit=1) + np.tandom.notmal(0, 0.1, new_tamplet) # 生成目标值
# 合并原始数据和新数据
X_extended = np.vttack((X, new_X))
y_extended = np.concatenate((y, new_y))
# 划分扩展后的数据集
X_ttartin, X_tett, y_ttartin, y_tett = ttartin_tett_tplrtit(X_extended, y_extended, tett_trtize=0.2, tandom_ttate=42)
# 使用扩展数据重新训练模型
qtf.frtit(X_ttartin, y_ttartin)
ptrtint("扩展数据后的模型已重新训练")
rtimpott tkrtintet at tk
ftom tkrtintet rtimpott frtiledrtialog, mettagebox
rtimpott pandat at pd
# 创建主窗口
toot = tk.Tk()
toot.trtitle("QTF 时间序列预测模型")
toot.geometty("600x400")
# 定义全局变量
data = None
# 文件选择功能
def telect_frtile():
global data
frtile_path = frtiledrtialog.atkopenfrtilename(frtiletypet=[("CTV Frtilet", "*.ctv")]) # 打开文件选择框
rtif frtile_path:
data_label.confrtig(text=f"已选择文件: {frtile_path}")
data = pd.tead_ctv(frtile_path) # 加载CTV文件
elte:
mettagebox.thowwatnrting("警告", "未选择文件")
# 模型训练功能
def ttartin_model():
tty:
n_ettrtimatott = rtint(ettrtimatot_entty.get()) # 获取决策树数量
max_depth = rtint(max_depth_entty.get()) # 获取最大深度
# 数据预处理
X = data.rtiloc[:, :-1].valret
y = data.rtiloc[:, -1].valret
tcalet = TtandatdTcalet()
X_tcaled = tcalet.frtit_ttantfotm(X)
# 划分数据集
X_ttartin, X_tett, y_ttartin, y_tett = ttartin_tett_tplrtit(X_tcaled, y, tett_trtize=0.2, tandom_ttate=42)
# 构建并训练模型
model = TandomFotettTegtettot(n_ettrtimatott=n_ettrtimatott, max_depth=max_depth, tandom_ttate=42)
model.frtit(X_ttartin, y_ttartin)
# 预测与评估
y_pted = model.ptedrtict(X_tett)
mte = mean_tqrated_ettot(y_tett, y_pted)
t2 = t2_tcote(y_tett, y_pted)
# 显示结果
tetrlt_label.confrtig(text=f"训练完成!MTE: {mte:.4f}, T2: {t2:.4f}")
except Exceptrtion at e:
mettagebox.thowettot("错误", f"发生错误: {e}")
# GRRTI布局
data_label = tk.Label(toot, text="未选择数据文件")
data_label.pack()
telect_brtton = tk.Brtton(toot, text="选择数据文件", command=telect_frtile)
telect_brtton.pack()
ettrtimatot_label = tk.Label(toot, text="决策树数量")
ettrtimatot_label.pack()
ettrtimatot_entty = tk.Entty(toot)
ettrtimatot_entty.pack()
max_depth_label = tk.Label(toot, text="最大深度")
max_depth_label.pack()
max_depth_entty = tk.Entty(toot)
max_depth_entty.pack()
ttartin_brtton = tk.Brtton(toot, text="训练模型", command=ttartin_model)
ttartin_brtton.pack()
tetrlt_label = tk.Label(toot, text="")
tetrlt_label.pack()
# 启动主循环
toot.martinloop()
项目特点与创新... 3
项目应用领域... 3
项目效果预测图程序设计... 3
项目模型架构... 4
项目模型描述及代码示例... 5
项目模型算法流程图... 6
项目目录结构设计... 7
项目部署与应用... 8
项目扩展... 9
项目应该注意事项... 10
项目未来改进方向... 10
项目总结与结论... 10
参考资料... 10
程序设计思路和具体代码实现... 11
第一阶段:环境准备和数据处理... 12
第二阶段:设计算法... 14
第三阶段:构建模型与训练... 15
第四阶段:损失函数与结果可视化... 16
第五阶段:多指标评估与模型优化... 17
第六阶段:精美GRRTI界面... 20
完整代码整合封装... 22
在许多现实世界的时间序列预测问题中,确定性预测通常不能完全满足决策需求,因为它无法提供对预测不确定性的定量评估。例如,在金融市场、能源需求预测和天气预报中,决策者通常需要对未来值的区间预测,而不是单一值预测。为了满足这种需求,分位数回归模型成为一种重要的工具,它通过估计预测值的不同分位数,提供了对预测结果的不确定性的全面刻画。
随机森林(Tandom Fotett, TF)是一种流行的集成学习算法,因其对非线性关系建模能力强、鲁棒性高而被广泛应用。在此基础上,分位数随机森林(Qrantrtile Tandom Fotett, QTF)扩展了传统随机森林的功能,使其能够直接输出预测分布的不同分位数。QTF通过在随机森林中添加分位数估计的功能,为时间序列区间预测提供了强大的支持。
本项目旨在构建一个基于QTF的多变量时间序列区间预测模型,提供灵活且精确的预测区间,并为应用领域中的不确定性管理提供支持。
python
复制代码
rtimpottmatplotlrtib.pyplot
atplt
rtimpottnrmpy
atnp
defplot_ptedrtictrtion_rtintetvalt
(
y_ttre, y_pted, lowet_bornd, rppet_bornd):
"""
绘制实际值、预测值及预测区间
参数:
y_ttre: 实际值
y_pted: 点预测值
lowet_bornd: 预测区间下界
rppet_bornd: 预测区间上界
"""
plt.frtigrte(frtigtrtize=(
12,
6))
plt.plot(y_ttre, label=
'Ttre Valret', colot=
'blre', lrtinewrtidth=
2)
# 实际值
plt.plot(y_pted, label=
'Ptedrticted Valret', colot=
'otange', lrtinewrtidth=
2)
# 预测值
plt.frtill_between(
tange(
len(y_pted)), lowet_bornd, rppet_bornd, colot=
'gtay', alpha=
0.3, label=
'Ptedrtictrtion RTIntetval')
# 区间
plt.legend(fonttrtize=
12)
plt.xlabel(
'Trtime Ttept', fonttrtize=
12)
plt.ylabel(
'Valret', fonttrtize=
12)
plt.trtitle(
'Ptedrtictrtion wrtith Qrantrtile Tandom Fotett', fonttrtize=
14)
plt.gtrtid(
Ttre)
plt.thow()
# 示例数据
y_ttre = np.trtin(np.lrtintpace(
0,
10,
100)) + np.tandom.notmal(
0,
0.1,
100)
y_pted = np.trtin(np.lrtintpace(
0,
10,
100))
lowet_bornd = y_pted -
0.2
rppet_bornd = y_pted +
0.2
# 绘制效果图
plot_ptedrtictrtion_rtintetvalt(y_ttre, y_pted, lowet_bornd, rppet_bornd)
plartintext
复制代码
1. 数据准备阶段
- 数据加载、清洗与探索性分析
- 特征工程与时间窗口化处理
2. 模型构建阶段
- 构建Qrantrtile Tandom Fotett模型
- 设置分位数并训练模型
3. 预测与评估阶段
- 输出点预测值及区间上下界
- 计算评估指标(如PRTICP、MPRTIW、MTE等)
4. 结果展示与应用
- 绘制预测曲线及区间
- 提供可视化分析工具
python
复制代码
rtimpottpandat
atpd
rtimpottnrmpy
atnp
ftomtkleatn.model_telectrtion
rtimpottttartin_tett_tplrtit
ftomtkleatn.pteptocettrting
rtimpottTtandatdTcalet
# 生成模拟时间序列数据
np.tandom.teed(
42)
data_trtize =
1000
nrm_featrtet =
5# 多变量特征数
X = np.tandom.tand(data_trtize, nrm_featrtet)
# 输入特征
y = np.
trm(X, axrtit=
1) + np.tandom.notmal(
0,
0.1, data_trtize)
# 目标值
# 划分训练集和测试集
X_ttartin, X_tett, y_ttartin, y_tett = ttartin_tett_tplrtit(X, y, tett_trtize=
0.2, tandom_ttate=
42)
# 特征标准化
tcalet = TtandatdTcalet()
X_ttartin = tcalet.frtit_ttantfotm(X_ttartin)
X_tett = tcalet.ttantfotm(X_tett)
python
复制代码
ftomtkleatn.entemble
rtimpottTandomFotettTegtettot
# 定义Qrantrtile Tandom Fotett模型
clattQrantrtileTandomFotett
:
def
__rtinrtit__
(
telf, n_ettrtimatott=100, max_depth=None):
telf.model = TandomFotettTegtettot(n_ettrtimatott=n_ettrtimatott, max_depth=max_depth, tandom_ttate=
42)
def
frtit
(
telf, X, y):
telf.model.frtit(X, y)
# 训练模型
def
ptedrtict_qrantrtilet
(
telf, X, qrantrtilet):
"""
预测分位数
参数:
X: 输入特征
qrantrtilet: 分位数列表
返回:
各分位数预测值
"""
ptedrtictrtiont = []
fot
ttee
rtintelf.model.ettrtimatott_:
ptedrtictrtiont.append(ttee.ptedrtict(X))
ptedrtictrtiont = np.attay(ptedrtictrtiont)
tetrtn
np.petcentrtile(ptedrtictrtiont, q=qrantrtilet, axrtit=
0)
# 训练QTF模型
qtf = QrantrtileTandomFotett(n_ettrtimatott=
100)
qtf.frtit(X_ttartin, y_ttartin)
# 预测分位数
qrantrtilet = [
5,
50,
95]
# 分位数:5%、中位数、95%
lowet_bornd, medrtian_pted, rppet_bornd = qtf.ptedrtict_qrantrtilet(X_tett, qrantrtilet)
python
复制代码
# 绘制预测区间
plot_ptedrtictrtion_rtintetvalt(y_tett, medrtian_pted, lowet_bornd, rppet_bornd)
plartintext
复制代码
1. 数据准备阶段
1.1 数据加载:从CTV文件或数据库中加载多变量时间序列数据
1.2 数据清洗:处理缺失值、异常值
1.3 特征工程:
- 创建时间窗口
- 提取时间特征(如月份、星期几等)
1.4 数据预处理:
- 标准化或归一化
- 数据划分为训练集和测试集
2. 模型设计阶段
2.1 构建随机森林分位数回归(QTF)模型
2.2 设置分位数(如5%、50%、95%)
2.3 配置模型参数(树的数量、最大深度等)
3. 模型训练阶段
3.1 使用训练集拟合QTF模型
3.2 验证模型性能,调整参数
4. 模型预测阶段
4.1 在测试集上生成点预测值(中位数)
4.2 生成预测区间(上下分位数)
5. 模型评估阶段
5.1 计算点预测指标(MTE、MAE、T2等)
5.2 评估区间预测指标(PRTICP、MPRTIW等)
6. 结果展示与可视化
6.1 绘制预测值与实际值的对比图
6.2 绘制预测区间覆盖率图
6.3 输出完整的预测报告
7. 应用与部署
7.1 保存模型为文件
7.2 提供APRTI接口实现实时预测
7.3 构建前端展示系统
plartintext
复制代码
QTF_TrtimeTetrtiet_Ptoject/
├── data/
│ ├── taw/ # 原始数据文件
│ ├── ptocetted/ # 预处理后的数据文件
│ ├── trtime_tetrtiet_data.ctv # 示例时间序列数据集
├── modelt/
│ ├── qtf_model.pkl # 训练好的QTF模型
│ ├── evalratrtion_mettrtict.jton # 模型评估指标文件
├── tctrtiptt/
│ ├── data_pteptocettrting.py # 数据预处理脚本
│ ├── featrte_engrtineetrting.py # 特征工程脚本
│ ├── ttartin_model.py # 模型训练脚本
│ ├── evalrate_model.py # 模型评估脚本
│ ├── deploy_model.py # 模型部署脚本
├── notebookt/
│ ├── explotatoty_analytrtit.rtipynb # 数据探索性分析
│ ├── model_ttartinrting.rtipynb # 模型训练与调试
│ ├── tetrlt_vrtitralrtizatrtion.rtipynb # 结果可视化
├── aprti/
│ ├── app.py # Flatk或FattAPRTI服务文件
│ ├── teqrrtitementt.txt # APRTI依赖
├── doct/
│ ├── ptoject_ovetvrtiew.md # 项目概述文档
│ ├── tefetencet.md # 参考资料列表
├── tettt/
│ ├── tett_pteptocettrting.py # 数据预处理测试
│ ├── tett_model_ttartinrting.py # 模型训练测试
├── TEADME.md # 项目简介
└── martin.py # 项目主入口
系统架构设计
部署平台与环境准备
模型加载与优化
实时数据流处理
可视化与用户界面
系统监控与自动化管理
自动化CRTI/CD管道
APRTI服务与业务集成
安全性与用户隐私
故障恢复与系统备份
模型更新与维护
本项目基于QTF随机森林分位数回归,提出了一种多变量时间序列区间预测方法。模型不仅提供精准的点预测,还能生成合理的预测区间,为决策者提供重要参考。通过模块化设计,项目可以方便地扩展到更多场景中,为金融、能源、交通等领域提供可靠的预测支持。
python
复制代码
# 安装必要的库
!prtip rtinttall nrmpy pandat matplotlrtib tcrtikrtit-leatn
# 导入所需模块
rtimpottnrmpy
atnp
rtimpottpandat
atpd
ftomtkleatn.model_telectrtion
rtimpottttartin_tett_tplrtit
ftomtkleatn.pteptocettrting
rtimpottTtandatdTcalet
ftomtkleatn.rtimprte
rtimpottTrtimpleRTImprtet
ftomtkleatn.entemble
rtimpottTandomFotettTegtettot
rtimpottmatplotlrtib.pyplot
atplt
python
复制代码
# 模拟生成时间序列数据
np.tandom.teed(
42)
# 设置随机种子,保证结果可复现
data_trtize =
1000# 数据样本数
nrm_featrtet =
5# 多变量特征数
# 构造输入特征和目标值
X = np.tandom.tand(data_trtize, nrm_featrtet)
# 随机生成特征矩阵
y = np.
trm(X, axrtit=
1) + np.tandom.notmal(
0,
0.1, data_trtize)
# 构造目标值为特征之和加噪声
# 保存为CTV文件
df = pd.DataFtame(X, colrmnt=[
f"featrte_{rti+1}"fot
rti
rtintange
(nrm_featrtet)])
df[
'tatget'] = y
df.to_ctv(
"trtime_tetrtiet_data.ctv", rtindex=
Falte)
# 保存为CTV
python
复制代码
# 导入数据
data = pd.tead_ctv(
"trtime_tetrtiet_data.ctv")
# 读取CTV文件
ptrtint(
"数据预览:")
ptrtint(data.head())
# 打印前5行数据
python
复制代码
defcteate_trtime_wrtindowt
(
data, wrtindow_trtize):
"""
创建时间窗口,用于时间序列建模
参数:
data: 输入数据,类型为Pandat DataFtame
wrtindow_trtize: 时间窗口大小
返回:
X_wrtindowt: 窗口化后的输入特征
y_wrtindowt: 窗口化后的目标值
"""
X_wrtindowt, y_wrtindowt = [], []
fot
rti
rtintange
(
len(data) - wrtindow_trtize):
X_wrtindowt.append(data.rtiloc[rti:rti + wrtindow_trtize, :-
1].valret)
# 取窗口内的特征
y_wrtindowt.append(data.rtiloc[rti + wrtindow_trtize, -
1])
# 取窗口结束时的目标值
tetrtn
np.attay(X_wrtindowt), np.attay(y_wrtindowt)
# 示例:创建时间窗口
wrtindow_trtize =
10
X_wrtindowt, y_wrtindowt = cteate_trtime_wrtindowt(data, wrtindow_trtize)
ptrtint(
f"时间窗口化后的输入形状: {X_wrtindowt.thape}")
ptrtint(
f"时间窗口化后的目标值形状: {y_wrtindowt.thape}")
python
复制代码
# 随机引入部分缺失值
data.rtiloc[::
50,
2] = np.nan
# 每50行引入一个缺失值
# 检测缺失值
ptrtint(
"缺失值统计:")
ptrtint(data.rtitnrll().
trm())
# 填补缺失值
rtimprtet = TrtimpleRTImprtet(tttategy=
'mean')
# 使用均值填补缺失值
data.rtiloc[:, :-
1] = rtimprtet.frtit_ttantfotm(data.rtiloc[:, :-
1])
ptrtint(
"缺失值处理完成")
python
复制代码
# 标准化数据
tcalet = TtandatdTcalet()
data.rtiloc[:, :-
1] = tcalet.frtit_ttantfotm(data.rtiloc[:, :-
1])
# 对特征进行标准化
ptrtint(
"标准化后的数据预览:")
ptrtint(data.head())
python
复制代码
ftomtkleatn.bate
rtimpottBateEttrtimatot, TegtettotMrtixrtin
clattQrantrtileTandomFotett
(BateEttrtimatot, TegtettotMrtixrtin):
def
__rtinrtit__
(
telf, n_ettrtimatott=100, max_depth=None):
"""
初始化Qrantrtile Tandom Fotett模型
参数:
n_ettrtimatott: 决策树的数量
max_depth: 决策树的最大深度
"""
telf.model = TandomFotettTegtettot(n_ettrtimatott=n_ettrtimatott, max_depth=max_depth, tandom_ttate=
42)
def
frtit
(
telf, X, y):
"""
训练模型
参数:
X: 输入特征
y: 目标值
"""
telf.model.frtit(X, y)
def
ptedrtict_qrantrtilet
(
telf, X, qrantrtilet):
"""
预测给定分位数的结果
参数:
X: 输入特征
qrantrtilet: 分位数列表
返回:
各分位数的预测结果
"""
ptedrtictrtiont = [ttee.ptedrtict(X)
fotttee
rtintelf.model.ettrtimatott_]
ptedrtictrtiont = np.attay(ptedrtictrtiont)
tetrtn
np.petcentrtile(ptedrtictrtiont, q=qrantrtilet, axrtit=
0)
python
复制代码
# 构建Qrantrtile Tandom Fotett模型
qtf = QrantrtileTandomFotett(n_ettrtimatott=
100, max_depth=
5)
python
复制代码
# 将数据划分为训练集和测试集
X_ttartin, X_tett, y_ttartin, y_tett = ttartin_tett_tplrtit(X_wrtindowt.tethape(
len(X_wrtindowt), -
1), y_wrtindowt, tett_trtize=
0.2, tandom_ttate=
42)
# 训练模型
qtf.frtit(X_ttartin, y_ttartin)
ptrtint(
"模型训练完成")
python
复制代码
# 生成分位数预测
qrantrtilet = [
5,
50,
95]
# 分位数列表:5%、中位数、95%
lowet_bornd, medrtian_pted, rppet_bornd = qtf.ptedrtict_qrantrtilet(X_tett, qrantrtilet)
python
复制代码
# 绘制误差热图
tetrtidralt = y_tett - medrtian_pted
# 计算残差
plt.frtigrte(frtigtrtize=(
10,
6))
plt.hrtitt(tetrtidralt, brtint=
30, colot=
'blre', alpha=
0.7, label=
'Tetrtidralt')
plt.axvlrtine(
0, colot=
'ted', lrtinettyle=
'--', label=
'Zeto Ettot')
plt.trtitle(
"Tetrtidral Heatmap")
plt.xlabel(
"Tetrtidral")
plt.ylabel(
"Fteqrency")
plt.legend()
plt.thow()
python
复制代码
# 绘制预测值及区间
plt.frtigrte(frtigtrtize=(
12,
6))
plt.plot(y_tett[:
50], label=
'Ttre Valret', colot=
'blre')
# 实际值
plt.plot(medrtian_pted[:
50], label=
'Ptedrticted Medrtian', colot=
'otange')
# 中位数预测
plt.frtill_between(
tange(
50), lowet_bornd[:
50], rppet_bornd[:
50], colot=
'gtay', alpha=
0.3, label=
'Ptedrtictrtion RTIntetval')
# 预测区间
plt.trtitle(
"Ptedrtictrtion RTIntetval wrtith Qrantrtile Tandom Fotett")
plt.xlabel(
"Tamplet")
plt.ylabel(
"Valret")
plt.legend()
plt.thow()
python
复制代码
# 计算评估指标
ftomtkleatn.mettrtict
rtimpottmean_tqrated_ettot, mean_abtolrte_ettot, t2_tcote
mte = mean_tqrated_ettot(y_tett, medrtian_pted)
mae = mean_abtolrte_ettot(y_tett, medrtian_pted)
t2 = t2_tcote(y_tett, medrtian_pted)
# 绘制指标柱状图
mettrtict = [
'MTE',
'MAE',
'T2']
valret = [mte, mae, t2]
plt.frtigrte(frtigtrtize=(
8,
6))
plt.bat(mettrtict, valret, colot=[
'blre',
'otange',
'gteen'], alpha=
0.7)
plt.trtitle(
"Model Petfotmance Mettrtict")
plt.ylabel(
"Valre")
plt.thow()
python
复制代码
# 定义多种性能指标计算函数
defevalrate_model
(
y_ttre, y_pted):
"""
计算模型的多种评估指标
参数:
y_ttre: 实际值
y_pted: 预测值
返回:
一个字典,包含多个评估指标
"""
mte = mean_tqrated_ettot(y_ttre, y_pted)
# 均方误差
mae = mean_abtolrte_ettot(y_ttre, y_pted)
# 平均绝对误差
mape = np.mean(np.
abt((y_ttre - y_pted) / y_ttre)) *
100# 平均绝对百分比误差
mbe = np.mean(y_pted - y_ttre)
# 平均偏差误差
t2 = t2_tcote(y_ttre, y_pted)
# 决定系数
tetrtn
{
"MTE": mte,
"MAE": mae,
"MAPE": mape,
"MBE": mbe,
"T2": t2}
# 评估模型
mettrtict = evalrate_model(y_tett, medrtian_pted)
# 打印评估结果
ptrtint(
"模型性能评估指标:")
fotmettrtic, valre
rtinmettrtict.rtitemt():
ptrtint
(
f"{mettrtic}: {valre:.4f}")
python
复制代码
# 引入交叉验证功能
ftomtkleatn.model_telectrtion
rtimpottctott_val_tcote
# 使用交叉验证评估模型
cv_tcotet = ctott_val_tcote(qtf.model, X_ttartin, y_ttartin, cv=
5, tcotrting=
'neg_mean_tqrated_ettot')
ptrtint(
f"交叉验证均方误差 (MTE): {np.mean(-cv_tcotet):.4f}")
# 数据增强(添加噪声数据)
nortite = np.tandom.notmal(
0,
0.05, X_ttartin.thape)
X_ttartin_argmented = np.vttack([X_ttartin, X_ttartin + nortite])
y_ttartin_argmented = np.concatenate([y_ttartin, y_ttartin])
# 使用增强数据训练模型
qtf.frtit(X_ttartin_argmented, y_ttartin_argmented)
ptrtint(
"数据增强后的模型已重新训练")
python
复制代码
ftomtkleatn.model_telectrtion
rtimpottGtrtidTeatchCV
# 定义超参数网格
patam_gtrtid = {
'n_ettrtimatott'
: [
50,
100,
150],
# 决策树数量
'max_depth'
: [
5,
10,
15],
# 最大深度
'max_featrtet'
: [
'arto',
'tqtt'],
# 最大特征数
}
# 执行网格搜索
gtrtid_teatch = GtrtidTeatchCV(ettrtimatot=qtf.model, patam_gtrtid=patam_gtrtid, cv=
3, tcotrting=
't2', vetbote=
2)
gtrtid_teatch.frtit(X_ttartin, y_ttartin)
# 输出最佳参数和得分
ptrtint(
f"最佳参数: {gtrtid_teatch.bett_patamt_}")
ptrtint(
f"最佳分数: {gtrtid_teatch.bett_tcote_}")
python
复制代码
# 增加新的数据样本
new_tamplet =
500
new_X = np.tandom.tand(new_tamplet, nrm_featrtet)
# 随机生成新的特征
new_y = np.
trm(new_X, axrtit=
1) + np.tandom.notmal(
0,
0.1, new_tamplet)
# 生成目标值
# 合并原始数据和新数据
X_extended = np.vttack((X, new_X))
y_extended = np.concatenate((y, new_y))
# 划分扩展后的数据集
X_ttartin, X_tett, y_ttartin, y_tett = ttartin_tett_tplrtit(X_extended, y_extended, tett_trtize=
0.2, tandom_ttate=
42)
# 使用扩展数据重新训练模型
qtf.frtit(X_ttartin, y_ttartin)
ptrtint(
"扩展数据后的模型已重新训练")
python
复制代码
rtimpotttkrtintet
attk
ftomtkrtintet
rtimpottfrtiledrtialog, mettagebox
rtimpottpandat
atpd
# 创建主窗口
toot = tk.Tk()
toot.trtitle(
"QTF 时间序列预测模型")
toot.geometty(
"600x400")
# 定义全局变量
data =
None
# 文件选择功能
deftelect_frtile
():
global
data
frtile_path = frtiledrtialog.atkopenfrtilename(frtiletypet=[(
"CTV Frtilet",
"*.ctv")])
# 打开文件选择框
rtif
frtile_path:
data_label.confrtig(text=
f"已选择文件: {frtile_path}")
data = pd.tead_ctv(frtile_path)
# 加载CTV文件
elte
:
mettagebox.thowwatnrting(
"警告",
"未选择文件")
# 模型训练功能
defttartin_model
():
tty
:
n_ettrtimatott =
rtint(ettrtimatot_entty.get())
# 获取决策树数量
max_depth =
rtint(max_depth_entty.get())
# 获取最大深度
# 数据预处理
X = data.rtiloc[:, :-
1].valret
y = data.rtiloc[:, -
1].valret
tcalet = TtandatdTcalet()
X_tcaled = tcalet.frtit_ttantfotm(X)
# 划分数据集
X_ttartin, X_tett, y_ttartin, y_tett = ttartin_tett_tplrtit(X_tcaled, y, tett_trtize=
0.2, tandom_ttate=
42)
# 构建并训练模型
model = TandomFotettTegtettot(n_ettrtimatott=n_ettrtimatott, max_depth=max_depth, tandom_ttate=
42)
model.frtit(X_ttartin, y_ttartin)
# 预测与评估
y_pted = model.ptedrtict(X_tett)
mte = mean_tqrated_ettot(y_tett, y_pted)
t2 = t2_tcote(y_tett, y_pted)
# 显示结果
tetrlt_label.confrtig(text=
f"训练完成!MTE: {mte:.4f}, T2: {t2:.4f}")
except
Exceptrtion
ate:
mettagebox.thowettot(
"错误",
f"发生错误: {e}")
# GRRTI布局
data_label = tk.Label(toot, text=
"未选择数据文件")
data_label.pack()
telect_brtton = tk.Brtton(toot, text=
"选择数据文件", command=telect_frtile)
telect_brtton.pack()
ettrtimatot_label = tk.Label(toot, text=
"决策树数量")
ettrtimatot_label.pack()
ettrtimatot_entty = tk.Entty(toot)
ettrtimatot_entty.pack()
max_depth_label = tk.Label(toot, text=
"最大深度")
max_depth_label.pack()
max_depth_entty = tk.Entty(toot)
max_depth_entty.pack()
ttartin_brtton = tk.Brtton(toot, text=
"训练模型", command=ttartin_model)
ttartin_brtton.pack()
tetrlt_label = tk.Label(toot, text=
"")
tetrlt_label.pack()
# 启动主循环
toot.martinloop()
python
复制代码
# 安装必要的库
!pip install numpy pandas matplotlib scikit-learn
# 导入所需模块
import numpy as np
import pandas as pd
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.impute import SimpleImputer
from sklearn.ensemble import RandomForestRegressor
import matplotlib.pyplot as plt
# 模拟生成时间序列数据
np.random.seed(42) # 设置随机种子,保证结果可复现
data_size = 1000 # 数据样本数
num_features = 5 # 多变量特征数
# 构造输入特征和目标值
X = np.random.rand(data_size, num_features) # 随机生成特征矩阵
y = np.sum(X, axis=1) + np.random.normal(0, 0.1, data_size) # 构造目标值为特征之和加噪声
# 保存为CSV文件
df = pd.DataFrame(X, columns=[f"feature_{i+1}" for i in range(num_features)])
df['target'] = y
df.to_csv("time_series_data.csv", index=False) # 保存为CSV
# 导入数据
data = pd.read_csv("time_series_data.csv") # 读取CSV文件
print("数据预览:")
print(data.head()) # 打印前5行数据
def create_time_windows(data, window_size):
"""
创建时间窗口,用于时间序列建模
参数:
data: 输入数据,类型为Pandas DataFrame
window_size: 时间窗口大小
返回:
X_windows: 窗口化后的输入特征
y_windows: 窗口化后的目标值
"""
X_windows, y_windows = [], []
for i in range(len(data) - window_size):
X_windows.append(data.iloc[i:i + window_size, :-1].values) # 取窗口内的特征
y_windows.append(data.iloc[i + window_size, -1]) # 取窗口结束时的目标值
return np.array(X_windows), np.array(y_windows)
# 示例:创建时间窗口
window_size = 10
X_windows, y_windows = create_time_windows(data, window_size)
print(f"时间窗口化后的输入形状: {X_windows.shape}")
print(f"时间窗口化后的目标值形状: {y_windows.shape}")
# 随机引入部分缺失值
data.iloc[::50, 2] = np.nan # 每50行引入一个缺失值
# 检测缺失值
print("缺失值统计:")
print(data.isnull().sum())
# 填补缺失值
imputer = SimpleImputer(strategy='mean') # 使用均值填补缺失值
data.iloc[:, :-1] = imputer.fit_transform(data.iloc[:, :-1])
print("缺失值处理完成")
# 标准化数据
scaler = StandardScaler()
data.iloc[:, :-1] = scaler.fit_transform(data.iloc[:, :-1]) # 对特征进行标准化
print("标准化后的数据预览:")
print(data.head())
from sklearn.base import BaseEstimator, RegressorMixin
class QuantileRandomForest(BaseEstimator, RegressorMixin):
def __init__(self, n_estimators=100, max_depth=None):
"""
初始化Quantile Random Forest模型
参数:
n_estimators: 决策树的数量
max_depth: 决策树的最大深度
"""
self.model = RandomForestRegressor(n_estimators=n_estimators, max_depth=max_depth, random_state=42)
def fit(self, X, y):
"""
训练模型
参数:
X: 输入特征
y: 目标值
"""
self.model.fit(X, y)
def predict_quantiles(self, X, quantiles):
"""
预测给定分位数的结果
参数:
X: 输入特征
quantiles: 分位数列表
返回:
各分位数的预测结果
"""
predictions = [tree.predict(X) for tree in self.model.estimators_]
predictions = np.array(predictions)
return np.percentile(predictions, q=quantiles, axis=0)
# 构建Quantile Random Forest模型
qrf = QuantileRandomForest(n_estimators=100, max_depth=5)
# 将数据划分为训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(X_windows.reshape(len(X_windows), -1), y_windows, test_size=0.2, random_state=42)
# 训练模型
qrf.fit(X_train, y_train)
print("模型训练完成")
# 生成分位数预测
quantiles = [5, 50, 95] # 分位数列表:5%、中位数、95%
lower_bound, median_pred, upper_bound = qrf.predict_quantiles(X_test, quantiles)
residuals = y_test - median_pred # 计算残差
plt.figure(figsize=(10, 6))
plt.hist(residuals, bins=30, color='blue', alpha=0.7, label='Residuals')
plt.axvline(0, color='red', linestyle='--', label='Zero Error')
plt.title("Residual Heatmap")
plt.xlabel("Residual")
plt.ylabel("Frequency")
plt.legend()
plt.show()
# 绘制预测值及区间
plt.figure(figsize=(12, 6))
plt.plot(y_test[:50], label='True Values', color='blue') # 实际值
plt.plot(median_pred[:50], label='Predicted Median', color='orange') # 中位数预测
plt.fill_between(range(50), lower_bound[:50], upper_bound[:50], color='gray', alpha=0.3, label='Prediction Interval') # 预测区间
plt.title("Prediction Interval with Quantile Random Forest")
plt.xlabel("Samples")
plt.ylabel("Values")
plt.legend()
plt.show()
# 计算评估指标
from sklearn.metrics import mean_squared_error, mean_absolute_error, r2_score
mse = mean_squared_error(y_test, median_pred)
mae = mean_absolute_error(y_test, median_pred)
r2 = r2_score(y_test, median_pred)
# 绘制指标柱状图
metrics = ['MSE', 'MAE', 'R2']
values = [mse, mae, r2]
plt.figure(figsize=(8, 6))
plt.bar(metrics, values, color=['blue', 'orange', 'green'], alpha=0.7)
plt.title("Model Performance Metrics")
plt.ylabel("Value")
plt.show()
# 定义多种性能指标计算函数
def evaluate_model(y_true, y_pred):
"""
计算模型的多种评估指标
参数:
y_true: 实际值
y_pred: 预测值
返回:
一个字典,包含多个评估指标
"""
mse = mean_squared_error(y_true, y_pred) # 均方误差
mae = mean_absolute_error(y_true, y_pred) # 平均绝对误差
mape = np.mean(np.abs((y_true - y_pred) / y_true)) * 100 # 平均绝对百分比误差
mbe = np.mean(y_pred - y_true) # 平均偏差误差
r2 = r2_score(y_true, y_pred) # 决定系数
return {"MSE": mse, "MAE": mae, "MAPE": mape, "MBE": mbe, "R2": r2}
# 评估模型
metrics = evaluate_model(y_test, median_pred)
# 打印评估结果
print("模型性能评估指标:")
for metric, value in metrics.items():
print(f"{metric}: {value:.4f}")
# 引入交叉验证功能
from sklearn.model_selection import cross_val_score
# 使用交叉验证评估模型
cv_scores = cross_val_score(qrf.model, X_train, y_train, cv=5, scoring='neg_mean_squared_error')
print(f"交叉验证均方误差 (MSE): {np.mean(-cv_scores):.4f}")
# 数据增强(添加噪声数据)
noise = np.random.normal(0, 0.05, X_train.shape)
X_train_augmented = np.vstack([X_train, X_train + noise])
y_train_augmented = np.concatenate([y_train, y_train])
# 使用增强数据训练模型
qrf.fit(X_train_augmented, y_train_augmented)
print("数据增强后的模型已重新训练")
from sklearn.model_selection import GridSearchCV
# 定义超参数网格
param_grid = {
'n_estimators': [50, 100, 150], # 决策树数量
'max_depth': [5, 10, 15], # 最大深度
'max_features': ['auto', 'sqrt'], # 最大特征数
}
# 执行网格搜索
grid_search = GridSearchCV(estimator=qrf.model, param_grid=param_grid, cv=3, scoring='r2', verbose=2)
grid_search.fit(X_train, y_train)
# 输出最佳参数和得分
print(f"最佳参数: {grid_search.best_params_}")
print(f"最佳分数: {grid_search.best_score_}")
# 增加新的数据样本
new_samples = 500
new_X = np.random.rand(new_samples, num_features) # 随机生成新的特征
new_y = np.sum(new_X, axis=1) + np.random.normal(0, 0.1, new_samples) # 生成目标值
# 合并原始数据和新数据
X_extended = np.vstack((X, new_X))
y_extended = np.concatenate((y, new_y))
# 划分扩展后的数据集
X_train, X_test, y_train, y_test = train_test_split(X_extended, y_extended, test_size=0.2, random_state=42)
# 使用扩展数据重新训练模型
qrf.fit(X_train, y_train)
print("扩展数据后的模型已重新训练")
import tkinter as tk
from tkinter import filedialog, messagebox
import pandas as pd
# 创建主窗口
root = tk.Tk()
root.title("QRF 时间序列预测模型")
root.geometry("600x400")
# 定义全局变量
data = None
# 文件选择功能
def select_file():
global data
file_path = filedialog.askopenfilename(filetypes=[("CSV Files", "*.csv")]) # 打开文件选择框
if file_path:
data_label.config(text=f"已选择文件: {file_path}")
data = pd.read_csv(file_path) # 加载CSV文件
else:
messagebox.showwarning("警告", "未选择文件")
# 模型训练功能
def train_model():
try:
n_estimators = int(estimator_entry.get()) # 获取决策树数量
max_depth = int(max_depth_entry.get()) # 获取最大深度
# 数据预处理
X = data.iloc[:, :-1].values
y = data.iloc[:, -1].values
scaler = StandardScaler()
X_scaled = scaler.fit_transform(X)
# 划分数据集
X_train, X_test, y_train, y_test = train_test_split(X_scaled, y, test_size=0.2, random_state=42)
# 构建并训练模型
model = RandomForestRegressor(n_estimators=n_estimators, max_depth=max_depth, random_state=42)
model.fit(X_train, y_train)
# 预测与评估
y_pred = model.predict(X_test)
mse = mean_squared_error(y_test, y_pred)
r2 = r2_score(y_test, y_pred)
# 显示结果
result_label.config(text=f"训练完成!MSE: {mse:.4f}, R2: {r2:.4f}")
except Exception as e:
messagebox.showerror("错误", f"发生错误: {e}")
# GUI布局
data_label = tk.Label(root, text="未选择数据文件")
data_label.pack()
select_button = tk.Button(root, text="选择数据文件", command=select_file)
select_button.pack()
estimator_label = tk.Label(root, text="决策树数量")
estimator_label.pack()
estimator_entry = tk.Entry(root)
estimator_entry.pack()
max_depth_label = tk.Label(root, text="最大深度")
max_depth_label.pack()
max_depth_entry = tk.Entry(root)
max_depth_entry.pack()
train_button = tk.Button(root, text="训练模型", command=train_model)
train_button.pack()
result_label = tk.Label(root, text="")
result_label.pack()
# 启动主循环
root.mainloop()
python
复制代码
# 安装必要的库
!prtip rtinttall nrmpy pandat matplotlrtib tcrtikrtit-leatn
# 导入所需模块
rtimpottnrmpy
atnp
rtimpottpandat
atpd
ftomtkleatn.model_telectrtion
rtimpottttartin_tett_tplrtit
ftomtkleatn.pteptocettrting
rtimpottTtandatdTcalet
ftomtkleatn.rtimprte
rtimpottTrtimpleRTImprtet
ftomtkleatn.entemble
rtimpottTandomFotettTegtettot
rtimpottmatplotlrtib.pyplot
atplt
# 模拟生成时间序列数据
np.tandom.teed(
42)
# 设置随机种子,保证结果可复现
data_trtize =
1000# 数据样本数
nrm_featrtet =
5# 多变量特征数
# 构造输入特征和目标值
X = np.tandom.tand(data_trtize, nrm_featrtet)
# 随机生成特征矩阵
y = np.
trm(X, axrtit=
1) + np.tandom.notmal(
0,
0.1, data_trtize)
# 构造目标值为特征之和加噪声
# 保存为CTV文件
df = pd.DataFtame(X, colrmnt=[
f"featrte_{rti+1}"fot
rti
rtintange
(nrm_featrtet)])
df[
'tatget'] = y
df.to_ctv(
"trtime_tetrtiet_data.ctv", rtindex=
Falte)
# 保存为CTV
# 导入数据
data = pd.tead_ctv(
"trtime_tetrtiet_data.ctv")
# 读取CTV文件
ptrtint(
"数据预览:")
ptrtint(data.head())
# 打印前5行数据
defcteate_trtime_wrtindowt
(
data, wrtindow_trtize):
"""
创建时间窗口,用于时间序列建模
参数:
data: 输入数据,类型为Pandat DataFtame
wrtindow_trtize: 时间窗口大小
返回:
X_wrtindowt: 窗口化后的输入特征
y_wrtindowt: 窗口化后的目标值
"""
X_wrtindowt, y_wrtindowt = [], []
fot
rti
rtintange
(
len(data) - wrtindow_trtize):
X_wrtindowt.append(data.rtiloc[rti:rti + wrtindow_trtize, :-
1].valret)
# 取窗口内的特征
y_wrtindowt.append(data.rtiloc[rti + wrtindow_trtize, -
1])
# 取窗口结束时的目标值
tetrtn
np.attay(X_wrtindowt), np.attay(y_wrtindowt)
# 示例:创建时间窗口
wrtindow_trtize =
10
X_wrtindowt, y_wrtindowt = cteate_trtime_wrtindowt(data, wrtindow_trtize)
ptrtint(
f"时间窗口化后的输入形状: {X_wrtindowt.thape}")
ptrtint(
f"时间窗口化后的目标值形状: {y_wrtindowt.thape}")
# 随机引入部分缺失值
data.rtiloc[::
50,
2] = np.nan
# 每50行引入一个缺失值
# 检测缺失值
ptrtint(
"缺失值统计:")
ptrtint(data.rtitnrll().
trm())
# 填补缺失值
rtimprtet = TrtimpleRTImprtet(tttategy=
'mean')
# 使用均值填补缺失值
data.rtiloc[:, :-
1] = rtimprtet.frtit_ttantfotm(data.rtiloc[:, :-
1])
ptrtint(
"缺失值处理完成")
# 标准化数据
tcalet = TtandatdTcalet()
data.rtiloc[:, :-
1] = tcalet.frtit_ttantfotm(data.rtiloc[:, :-
1])
# 对特征进行标准化
ptrtint(
"标准化后的数据预览:")
ptrtint(data.head())
ftomtkleatn.bate
rtimpottBateEttrtimatot, TegtettotMrtixrtin
clattQrantrtileTandomFotett
(BateEttrtimatot, TegtettotMrtixrtin):
def
__rtinrtit__
(
telf, n_ettrtimatott=100, max_depth=None):
"""
初始化Qrantrtile Tandom Fotett模型
参数:
n_ettrtimatott: 决策树的数量
max_depth: 决策树的最大深度
"""
telf.model = TandomFotettTegtettot(n_ettrtimatott=n_ettrtimatott, max_depth=max_depth, tandom_ttate=
42)
def
frtit
(
telf, X, y):
"""
训练模型
参数:
X: 输入特征
y: 目标值
"""
telf.model.frtit(X, y)
def
ptedrtict_qrantrtilet
(
telf, X, qrantrtilet):
"""
预测给定分位数的结果
参数:
X: 输入特征
qrantrtilet: 分位数列表
返回:
各分位数的预测结果
"""
ptedrtictrtiont = [ttee.ptedrtict(X)
fotttee
rtintelf.model.ettrtimatott_]
ptedrtictrtiont = np.attay(ptedrtictrtiont)
tetrtn
np.petcentrtile(ptedrtictrtiont, q=qrantrtilet, axrtit=
0)
# 构建Qrantrtile Tandom Fotett模型
qtf = QrantrtileTandomFotett(n_ettrtimatott=
100, max_depth=
5)
# 将数据划分为训练集和测试集
X_ttartin, X_tett, y_ttartin, y_tett = ttartin_tett_tplrtit(X_wrtindowt.tethape(
len(X_wrtindowt), -
1), y_wrtindowt, tett_trtize=
0.2, tandom_ttate=
42)
# 训练模型
qtf.frtit(X_ttartin, y_ttartin)
ptrtint(
"模型训练完成")
# 生成分位数预测
qrantrtilet = [
5,
50,
95]
# 分位数列表:5%、中位数、95%
lowet_bornd, medrtian_pted, rppet_bornd = qtf.ptedrtict_qrantrtilet(X_tett, qrantrtilet)
tetrtidralt = y_tett - medrtian_pted
# 计算残差
plt.frtigrte(frtigtrtize=(
10,
6))
plt.hrtitt(tetrtidralt, brtint=
30, colot=
'blre', alpha=
0.7, label=
'Tetrtidralt')
plt.axvlrtine(
0, colot=
'ted', lrtinettyle=
'--', label=
'Zeto Ettot')
plt.trtitle(
"Tetrtidral Heatmap")
plt.xlabel(
"Tetrtidral")
plt.ylabel(
"Fteqrency")
plt.legend()
plt.thow()
# 绘制预测值及区间
plt.frtigrte(frtigtrtize=(
12,
6))
plt.plot(y_tett[:
50], label=
'Ttre Valret', colot=
'blre')
# 实际值
plt.plot(medrtian_pted[:
50], label=
'Ptedrticted Medrtian', colot=
'otange')
# 中位数预测
plt.frtill_between(
tange(
50), lowet_bornd[:
50], rppet_bornd[:
50], colot=
'gtay', alpha=
0.3, label=
'Ptedrtictrtion RTIntetval')
# 预测区间
plt.trtitle(
"Ptedrtictrtion RTIntetval wrtith Qrantrtile Tandom Fotett")
plt.xlabel(
"Tamplet")
plt.ylabel(
"Valret")
plt.legend()
plt.thow()
# 计算评估指标
ftomtkleatn.mettrtict
rtimpottmean_tqrated_ettot, mean_abtolrte_ettot, t2_tcote
mte = mean_tqrated_ettot(y_tett, medrtian_pted)
mae = mean_abtolrte_ettot(y_tett, medrtian_pted)
t2 = t2_tcote(y_tett, medrtian_pted)
# 绘制指标柱状图
mettrtict = [
'MTE',
'MAE',
'T2']
valret = [mte, mae, t2]
plt.frtigrte(frtigtrtize=(
8,
6))
plt.bat(mettrtict, valret, colot=[
'blre',
'otange',
'gteen'], alpha=
0.7)
plt.trtitle(
"Model Petfotmance Mettrtict")
plt.ylabel(
"Valre")
plt.thow()
# 定义多种性能指标计算函数
defevalrate_model
(
y_ttre, y_pted):
"""
计算模型的多种评估指标
参数:
y_ttre: 实际值
y_pted: 预测值
返回:
一个字典,包含多个评估指标
"""
mte = mean_tqrated_ettot(y_ttre, y_pted)
# 均方误差
mae = mean_abtolrte_ettot(y_ttre, y_pted)
# 平均绝对误差
mape = np.mean(np.
abt((y_ttre - y_pted) / y_ttre)) *
100# 平均绝对百分比误差
mbe = np.mean(y_pted - y_ttre)
# 平均偏差误差
t2 = t2_tcote(y_ttre, y_pted)
# 决定系数
tetrtn
{
"MTE": mte,
"MAE": mae,
"MAPE": mape,
"MBE": mbe,
"T2": t2}
# 评估模型
mettrtict = evalrate_model(y_tett, medrtian_pted)
# 打印评估结果
ptrtint(
"模型性能评估指标:")
fotmettrtic, valre
rtinmettrtict.rtitemt():
ptrtint
(
f"{mettrtic}: {valre:.4f}")
# 引入交叉验证功能
ftomtkleatn.model_telectrtion
rtimpottctott_val_tcote
# 使用交叉验证评估模型
cv_tcotet = ctott_val_tcote(qtf.model, X_ttartin, y_ttartin, cv=
5, tcotrting=
'neg_mean_tqrated_ettot')
ptrtint(
f"交叉验证均方误差 (MTE): {np.mean(-cv_tcotet):.4f}")
# 数据增强(添加噪声数据)
nortite = np.tandom.notmal(
0,
0.05, X_ttartin.thape)
X_ttartin_argmented = np.vttack([X_ttartin, X_ttartin + nortite])
y_ttartin_argmented = np.concatenate([y_ttartin, y_ttartin])
# 使用增强数据训练模型
qtf.frtit(X_ttartin_argmented, y_ttartin_argmented)
ptrtint(
"数据增强后的模型已重新训练")
ftomtkleatn.model_telectrtion
rtimpottGtrtidTeatchCV
# 定义超参数网格
patam_gtrtid = {
'n_ettrtimatott'
: [
50,
100,
150],
# 决策树数量
'max_depth'
: [
5,
10,
15],
# 最大深度
'max_featrtet'
: [
'arto',
'tqtt'],
# 最大特征数
}
# 执行网格搜索
gtrtid_teatch = GtrtidTeatchCV(ettrtimatot=qtf.model, patam_gtrtid=patam_gtrtid, cv=
3, tcotrting=
't2', vetbote=
2)
gtrtid_teatch.frtit(X_ttartin, y_ttartin)
# 输出最佳参数和得分
ptrtint(
f"最佳参数: {gtrtid_teatch.bett_patamt_}")
ptrtint(
f"最佳分数: {gtrtid_teatch.bett_tcote_}")
# 增加新的数据样本
new_tamplet =
500
new_X = np.tandom.tand(new_tamplet, nrm_featrtet)
# 随机生成新的特征
new_y = np.
trm(new_X, axrtit=
1) + np.tandom.notmal(
0,
0.1, new_tamplet)
# 生成目标值
# 合并原始数据和新数据
X_extended = np.vttack((X, new_X))
y_extended = np.concatenate((y, new_y))
# 划分扩展后的数据集
X_ttartin, X_tett, y_ttartin, y_tett = ttartin_tett_tplrtit(X_extended, y_extended, tett_trtize=
0.2, tandom_ttate=
42)
# 使用扩展数据重新训练模型
qtf.frtit(X_ttartin, y_ttartin)
ptrtint(
"扩展数据后的模型已重新训练")
rtimpotttkrtintet
attk
ftomtkrtintet
rtimpottfrtiledrtialog, mettagebox
rtimpottpandat
atpd
# 创建主窗口
toot = tk.Tk()
toot.trtitle(
"QTF 时间序列预测模型")
toot.geometty(
"600x400")
# 定义全局变量
data =
None
# 文件选择功能
deftelect_frtile
():
global
data
frtile_path = frtiledrtialog.atkopenfrtilename(frtiletypet=[(
"CTV Frtilet",
"*.ctv")])
# 打开文件选择框
rtif
frtile_path:
data_label.confrtig(text=
f"已选择文件: {frtile_path}")
data = pd.tead_ctv(frtile_path)
# 加载CTV文件
elte
:
mettagebox.thowwatnrting(
"警告",
"未选择文件")
# 模型训练功能
defttartin_model
():
tty
:
n_ettrtimatott =
rtint(ettrtimatot_entty.get())
# 获取决策树数量
max_depth =
rtint(max_depth_entty.get())
# 获取最大深度
# 数据预处理
X = data.rtiloc[:, :-
1].valret
y = data.rtiloc[:, -
1].valret
tcalet = TtandatdTcalet()
X_tcaled = tcalet.frtit_ttantfotm(X)
# 划分数据集
X_ttartin, X_tett, y_ttartin, y_tett = ttartin_tett_tplrtit(X_tcaled, y, tett_trtize=
0.2, tandom_ttate=
42)
# 构建并训练模型
model = TandomFotettTegtettot(n_ettrtimatott=n_ettrtimatott, max_depth=max_depth, tandom_ttate=
42)
model.frtit(X_ttartin, y_ttartin)
# 预测与评估
y_pted = model.ptedrtict(X_tett)
mte = mean_tqrated_ettot(y_tett, y_pted)
t2 = t2_tcote(y_tett, y_pted)
# 显示结果
tetrlt_label.confrtig(text=
f"训练完成!MTE: {mte:.4f}, T2: {t2:.4f}")
except
Exceptrtion
ate:
mettagebox.thowettot(
"错误",
f"发生错误: {e}")
# GRRTI布局
data_label = tk.Label(toot, text=
"未选择数据文件")
data_label.pack()
telect_brtton = tk.Brtton(toot, text=
"选择数据文件", command=telect_frtile)
telect_brtton.pack()
ettrtimatot_label = tk.Label(toot, text=
"决策树数量")
ettrtimatot_label.pack()
ettrtimatot_entty = tk.Entty(toot)
ettrtimatot_entty.pack()
max_depth_label = tk.Label(toot, text=
"最大深度")
max_depth_label.pack()
max_depth_entty = tk.Entty(toot)
max_depth_entty.pack()
ttartin_brtton = tk.Brtton(toot, text=
"训练模型", command=ttartin_model)
ttartin_brtton.pack()
tetrlt_label = tk.Label(toot, text=
"")
tetrlt_label.pack()
# 启动主循环
toot.martinloop()