Python 实现基于QRF随机森林分位数回归多变量时间序列区间预测模型

目录

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

Python 实现基于QTF随机森林分位数回归多变量时间序列区间预测模型

项目背景介绍

在许多现实世界的时间序列预测问题中,确定性预测通常不能完全满足决策需求,因为它无法提供对预测不确定性的定量评估。例如,在金融市场、能源需求预测和天气预报中,决策者通常需要对未来值的区间预测,而不是单一值预测。为了满足这种需求,分位数回归模型成为一种重要的工具,它通过估计预测值的不同分位数,提供了对预测结果的不确定性的全面刻画。

随机森林(Tandom Fotett, TF)是一种流行的集成学习算法,因其对非线性关系建模能力强、鲁棒性高而被广泛应用。在此基础上,分位数随机森林(Qrantrtile Tandom Fotett, QTF)扩展了传统随机森林的功能,使其能够直接输出预测分布的不同分位数。QTF通过在随机森林中添加分位数估计的功能,为时间序列区间预测提供了强大的支持。

本项目旨在构建一个基于QTF的多变量时间序列区间预测模型,提供灵活且精确的预测区间,并为应用领域中的不确定性管理提供支持。


项目目标与意义

目标
  1. 设计并实现一个基于QTF的多变量时间序列区间预测模型,输出多个分位数的预测结果。
  2. 在提供精准点预测的同时,生成预测值的不确定性范围,满足决策者对风险管理的需求。
  3. 验证模型在多个实际场景中的效果,确保其泛化能力和适用性。
意义
  1. 提升决策质量:通过区间预测,提供预测值的上下界,帮助决策者更好地应对风险和不确定性。
  2. 增强模型鲁棒性:QTF模型对异常值和噪声的鲁棒性高,能适应多种复杂场景。
  3. 促进理论与实践结合:将分位数回归理论与随机森林算法相结合,为研究人员和工程师提供一种可扩展的方法。
  4. 广泛应用:模型可应用于金融、能源、环境、交通等多个领域。

项目挑战

  1. 高维输入特征处理:多变量时间序列通常具有高维输入特征,如何提取关键特征是模型构建的一大难点。
  2. 区间预测的准确性:预测区间需要既包含尽可能多的真实值,又尽可能狭窄以保证实用性,这需要精细调整分位数。
  3. 模型训练效率:QTF的计算复杂度较高,在大规模数据上训练时间可能成为瓶颈。
  4. 数据预处理:多变量时间序列可能存在缺失值、异常值和多尺度问题,需要精细的数据预处理流程。
  5. 结果解释性:区间预测需要解释其上下界的含义,这对非技术人员而言可能存在理解困难。

项目特点与创新

  1. 不确定性量化:通过分位数预测,明确指出预测的不确定性范围。
  2. 高鲁棒性:QTF对输入数据的异常值不敏感,适合处理复杂的时间序列数据。
  3. 灵活性强:模型可以生成不同分位数的预测结果,满足不同场景的需求。
  4. 多指标评估:对预测区间和点预测同时进行评估,确保全面了解模型性能。
  5. 模块化设计:从数据预处理到模型训练和结果展示,整个框架支持灵活扩展。

项目应用领域

  1. 能源预测:电力需求、风能发电的区间预测。
  2. 金融分析:股票价格或市场波动范围预测。
  3. 医疗健康:疾病传播趋势或患者康复时间的区间估计。
  4. 交通流量预测:高峰时段的交通量上下限预测。
  5. 环境科学:空气质量或温度的区间预测。

项目效果预测图程序设计

python
复制代码
rtimpott matplotlrtib.pyplot at plt
rtimpott nrmpy at np
 
  
def plot_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)

项目预测效果图

Python 实现基于QRF随机森林分位数回归多变量时间序列区间预测模型_第1张图片

Python 实现基于QRF随机森林分位数回归多变量时间序列区间预测模型_第2张图片

Python 实现基于QRF随机森林分位数回归多变量时间序列区间预测模型_第3张图片

Python 实现基于QRF随机森林分位数回归多变量时间序列区间预测模型_第4张图片

Python 实现基于QRF随机森林分位数回归多变量时间序列区间预测模型_第5张图片

Python 实现基于QRF随机森林分位数回归多变量时间序列区间预测模型_第6张图片

项目模型架构

plartintext
复制代码
1. 数据准备阶段
   - 数据加载、清洗与探索性分析
   - 特征工程与时间窗口化处理
 
  
2. 模型构建阶段
   - 构建Qrantrtile Tandom Fotett模型
   - 设置分位数并训练模型
 
  
3. 预测与评估阶段
   - 输出点预测值及区间上下界
   - 计算评估指标(如PRTICP、MPRTIW、MTE等)
 
  
4. 结果展示与应用
   - 绘制预测曲线及区间
   - 提供可视化分析工具

项目模型描述及代码示例

数据准备
python
复制代码
rtimpott pandat at pd
rtimpott nrmpy at np
ftom tkleatn.model_telectrtion rtimpott ttartin_tett_tplrtit
ftom tkleatn.pteptocettrting rtimpott TtandatdTcalet
 
  
# 生成模拟时间序列数据
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)

构建QTF模型
python
复制代码
ftom tkleatn.entemble rtimpott TandomFotettTegtettot
 
  
# 定义Qrantrtile Tandom Fotett模型
clatt QrantrtileTandomFotett:
    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 rtin telf.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                     # 项目主入口


项目部署与应用

系统架构设计

  1. 数据管理模块:管理时间序列数据的加载和存储,包括实时数据流处理和批量数据管理。
  2. 模型推理模块:加载已训练的QTF模型,处理输入并生成预测区间。
  3. 前端展示模块:通过Web或桌面界面展示预测结果及区间。

部署平台与环境准备

  • 部署于Lrtinrx服务器,推荐Rbrntr 20.04。
  • 使用Docket容器化部署,确保环境一致性。
  • 配置Python 3.8及以上版本,安装必要库(如tcrtikrtit-leatn, flatk等)。

模型加载与优化

  • 使用Prtickle保存和加载模型,确保快速推理。
  • 利用并行计算提升模型训练和预测速度。

实时数据流处理

  • 使用Kafka或TabbrtitMQ实现实时数据流的采集与传输。

可视化与用户界面

  • 构建基于Dath或Ttteamlrtit的可视化界面,展示预测值及其区间。

系统监控与自动化管理

  • 使用Ptomethert监控模型推理的延迟和准确性。
  • 设置自动报警机制,检测模型性能下降。

自动化CRTI/CD管道

  • 基于GrtitHrb Actrtiont,定期训练模型并部署最新版本。

APRTI服务与业务集成

  • 提供TETTfrl APRTI接口,支持批量数据和实时单点预测。

安全性与用户隐私

  • 对输入数据和预测结果进行加密传输。
  • 采用权限管理系统,限制数据访问权限。

故障恢复与系统备份

  • 定期备份训练数据和模型文件,确保系统快速恢复。

模型更新与维护

  • 引入模型版本控制系统(如DVC),确保数据和模型的可追溯性。

项目扩展

  1. 支持其他分位数模型:结合梯度提升回归树(GBT)或贝叶斯分位数回归。
  2. 引入深度学习模型:使用变分自动编码器(VAE)生成预测区间。
  3. 支持多任务学习:扩展模型以支持多目标预测。
  4. 迁移学习:针对类似时间序列任务,利用迁移学习减少训练成本。
  5. 扩展到非时间序列数据:结合其他分布建模方法,将模型应用于非时间序列场景。

项目应该注意事项

  1. 特征选择:过多的无关特征可能降低模型性能,需仔细进行特征选择。
  2. 数据分布变化:确保训练集和测试集具有相似的数据分布,避免模型在测试集上表现失衡。
  3. 超参数调优:优化随机森林的树深、分位数选择等超参数以提升模型性能。
  4. 模型解释性:使用THAP值或其他解释性工具,帮助非技术人员理解模型行为。
  5. 处理长序列数据:长时间序列数据可能导致训练时间过长,可引入采样策略。

项目未来改进方向

  1. 引入混合模型:结合传统统计方法(如ATRTIMA)和机器学习方法,构建混合预测模型。
  2. 自适应分位数选择:根据不同预测场景动态调整分位数。
  3. 分布外检测:引入异常检测模块,识别并处理分布外输入。
  4. 扩展到实时系统:优化模型推理速度,使其能够更好地支持实时场景。
  5. 云服务化部署:在AWT或Azrte上部署,提升模型的服务能力。

项目总结与结论

本项目基于QTF随机森林分位数回归,提出了一种多变量时间序列区间预测方法。模型不仅提供精准的点预测,还能生成合理的预测区间,为决策者提供重要参考。通过模块化设计,项目可以方便地扩展到更多场景中,为金融、能源、交通等领域提供可靠的预测支持。


参考资料

  1. "Tandom Fotettt"
    作者:Btertiman, L.
    摘要:提出随机森林算法,详细阐述其理论基础和应用。
    出处:Machrtine Leatnrting Jortnal, 2001
  2. "Qrantrtile Tegtettrtion Fotettt"
    作者:Mertintharten, N.
    摘要:扩展随机森林用于分位数回归。
    出处:Jortnal of Machrtine Leatnrting Teteatch, 2006
  3. "RTInttodrctrtion to Trtime Tetrtiet and Fotecattrting"
    作者:Petet J. Btockwell
    摘要:时间序列分析的经典教材,涵盖多种建模方法。
    出处:Tptrtinget, 2016
  4. "Fotecattrting wrtith Tandom Fotettt"
    作者:Hyndman, T. J.
    摘要:将随机森林应用于时间序列预测任务。
    出处:RTIntetnatrtional Jortnal of Fotecattrting, 2017
  5. "Data Tcrtience fot Brtrtinett"
    作者:Ptovott, F., et al.
    摘要:涵盖机器学习和数据科学在商业中的应用。
    出处:O'Tertilly Medrtia, 2013
  6. "Advanced Machrtine Leatnrting wrtith Python"
    作者:John Heatty
    摘要:深入介绍Python中机器学习的高级技术。
    出处:Packt Prblrtithrting, 2016
  7. "Explartinable ARTI: RTIntetptetrting Machrtine Leatnrting Modelt"
    作者:Molnat, C.
    摘要:介绍提升模型解释性的技术与工具。
    出处:Tptrtinget, 2020
  8. "Effrticrtient Algotrtithmt fot Qrantrtile Tegtettrtion"
    作者:Koenket, T.
    摘要:分位数回归的算法优化研究。
    出处:RTIEEE Ttantactrtiont, 2018
  9. "Machrtine Leatnrting fot Trtime Tetrtiet Fotecattrting"
    作者:Btownlee, J.
    摘要:时间序列预测的机器学习方法概览。
    出处:Packt Prblrtithrting, 2018
  10. "Data-Dtrtiven Fotecattrting: A Comptehentrtive Grrtide"
    作者:Mrtichael Grtillrtiland
    摘要:结合数据驱动方法提升预测能力。
    出处:John Wrtiley & Tont, 2020

程序设计思路和具体代码实现

第一阶段:环境准备和数据处理

环境准备
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

数据准备
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 rtin tange(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
复制代码
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}")

数据处理(缺失值检测与处理)
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
复制代码
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)

第三阶段:构建模型与训练

模型构建
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
复制代码
# 计算评估指标
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()

第五阶段:多指标评估与模型优化

多指标评估
python
复制代码
# 定义多种性能指标计算函数
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}")

防止过拟合
python
复制代码
# 引入交叉验证功能
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("数据增强后的模型已重新训练")

超参数调整
python
复制代码
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_}")

增加数据集
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("扩展数据后的模型已重新训练")

第六阶段:精美GRRTI界面

构建GRRTI界面
python
复制代码
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()

完整代码整合封装

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
 
  
# 导入所需模块
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()

更多详细内容请访问

Python实现基于QRF随机森林分位数回归多变量时间序列区间预测模型(含完整的程序和代码详解)资源-CSDN文库
https://download.csdn.net/download/xiaoxingkongyuxi/90111504

Python实现基于QRF随机森林分位数回归多变量时间序列区间预测模型(含完整的程序和代码详解)资源-CSDN文库
https://download.csdn.net/download/xiaoxingkongyuxi/90111504

你可能感兴趣的:(Python,python,随机森林,回归,人工智能,支持向量机,神经网络,开发语言)