MCM520 ← 资料站首页 电工杯 2020 B 范文:光伏建筑一体化(BIPV)板块指数的数据清洗、联动刻画与趋势预测(确定性合成 · 纯标准库) 打开交互阅读器 →

电工杯 2020 B 范文:光伏建筑一体化(BIPV)板块指数的数据清洗、联动刻画与趋势预测(确定性合成 · 纯标准库)

一、摘要

针对 2020 年电工杯 B 题「光伏建筑一体化板块指数发展趋势分析及预测」,本文给出一条「数据清洗 → 板块联动刻画 → 趋势与波动率分析 → 双方法预测对比 → 情景规划」的确定性分析主线。基于固定随机种子合成的 5 个光伏产业链板块(BIPV、硅料、组件、逆变器、电站运营)共 750 个交易日指数面板,先对 BIPV 序列做缺失(22 个)与异常跳变(检出 10 个)的滚动中位数—MAD 检测与线性插值修复;进而用 Pearson 相关系数矩阵刻画联动结构,发现 BIPV 与**组件(0.960)、逆变器(0.940)**联动最强,与上游硅料(0.806)、电站运营(0.790)次之,且组件—逆变器两两相关高达 0.989,印证「设备链一体化」的产业特征。趋势层面,BIPV 全样本年化波动率 21.07%、最大回撤 −41.33%、滚动 30 日年化波动率介于 14.24%–28.83%。预测环节以 Holt 双参数指数平滑(统计法)与带 L2 正则的监督岭回归 AR(3)(机器学习法)做滚动 1 步伪样本外对比,二者 MAPE 分别为 1.13% 与 1.02%,均表现优异、机器学习法略优;基于全样本 Holt 的 30 日规划显示基准点位 1148.5(较当前 +6.10%),政策利好与硅料涨价情景分别为 1169.4(+8.03%)与 1131.4(+4.52%)。全文零依赖、确定性、可复现,正文、配图、附录与真源四路数字完全一致。

二、问题重述

赛题以 BIPV 及相关产业链板块的资本市场指数为对象,要求完成五个递进任务:其一,对板块指数序列做缺失值、异常值的识别与清洗,并说明处理逻辑;其二,刻画 BIPV 板块与上下游(硅料、组件、逆变器、电站运营等)板块的相关性与联动强弱;其三,刻画发展趋势(阶段性涨跌、波动率、回撤、动量);其四,建立预测模型,给出短中期走势预测与置信区间,并对比至少一种统计与一种机器学习方法;其五,讨论外部冲击(政策、原料价格、装机量)下的情景差异。本文把这五问组织为同一条主线:清洗提供可信数据底座,联动刻画回答「谁影响谁」,趋势/波动率回答「现在处在什么状态」,预测与情景回答「未来会怎样、不确定性多大」。

三、模型假设与符号

  • H1(确定性合成):官方原题数据未公开可下载,本文采用固定随机种子的确定性合成面板(5 板块、750 日、真实量级与产业联动结构),仅用于跑通方法;正式参赛须替换为官方数据并做样本外回测。
  • H2(联动由共同市场因子驱动):各板块日收益由共同市场因子(产业链系统性风险)与特异噪声叠加,板块间相关主要来自共同因子,故相关系数矩阵应呈「产业链内高、跨链低」的结构。
  • H3(缺失与异常可检测):缺失表现为序列断点,异常表现为相对邻域的中断式大幅跳变(如单日 ±10% 以上的非连续跳变),可用稳健的滚动中位数—MAD 准则识别。
  • H4(短程可预测性来自惯性):指数短期运动含趋势与均值回复成分,可用平滑/自回归类方法做 1 步预测;更长周期受外生冲击主导,预测仅作区间而非单点。

主要符号:第 ss 板块第 tt 日指数水平 Ps,tP_{s,t},日对数收益 rs,t=ln⁡(Ps,t/Ps,t−1)r_{s,t}=\ln(P_{s,t}/P_{s,t-1});ρij\rho_{ij} 为板块 i,ji,j 的 Pearson 相关系数;σann\sigma_{\text{ann}} 为年化波动率;MDD\text{MDD} 为最大回撤;MAPE\text{MAPE} 为平均绝对百分比误差。

四、数据清洗(问题 1 核心)

金融指数序列常因停牌、除权、录入错误出现缺失与异常。本文在 BIPV 序列上注入 22 个缺失(约 3%)与 10 个单日大幅跳变,模拟真实脏数据,再用两步法修复:

异常检测:以窗口 w=5w=5 的滚动中位数 x~i\tilde{x}_i 与中位数绝对偏差 MADi\text{MAD}_i 为稳健位置/尺度估计,当
∣xi−x~i∣>3×1.4826×MADi且∣xi−x~i∣x~i>5%|x_i-\tilde{x}_i|>3\times1.4826\times\text{MAD}_i\quad\text{且}\quad\frac{|x_i-\tilde{x}_i|}{\tilde{x}_i}>5\%
时判为异常。该准则对正态噪声稳健(误报率低),又能抓住数倍尺度之外的跳变。

缺失与异常修复:将判出的异常点先置为缺失,再对整条含缺口序列做线性插值(端点用最近邻外推)。线性插值假设缺口两侧趋势连续,符合指数「平滑演进」的特性,且不会引入人为的阶跃或均值漂移。

经此处理,22 个缺失与 10 个异常均被定位并修复,BIPV 序列恢复为连续的 750 点清洗序列,作为后续全部分析的统一输入。

图1 BIPV 指数:原始(红点=异常) / 清洗后 / MA30 / MA60

图1 叠加展示原始序列(红色异常点清晰可见)、清洗后序列、以及 30 日/60 日移动平均(MA30/MA60,虚线)。MA 平滑了日频噪声,揭示出指数并非单调上行,而是伴随多次回撤与反弹的「带漂移的随机游走」——这正是后续波动率为正、回撤显著的根源。

五、板块联动刻画(问题 2)

以清洗后的 5 板块序列计算 Pearson 相关矩阵(图2),BIPV 所在行(列)结果为:

板块对 相关系数
BIPV — 组件 0.960
BIPV — 逆变器 0.940
BIPV — 硅料 0.806
BIPV — 电站运营 0.790
组件 — 逆变器 0.989

完整的 5×55\times5 矩阵(行/列顺序:BIPV、硅料、组件、逆变器、电站运营)为:

BIPV 硅料 组件 逆变器 电站运营
BIPV 1.000 0.806 0.960 0.940 0.790
硅料 0.806 1.000 0.904 0.929 0.658
组件 0.960 0.904 1.000 0.989 0.793
逆变器 0.940 0.929 0.989 1.000 0.760
电站运营 0.790 0.658 0.793 0.760 1.000

图2 五大板块相关系数矩阵

图2 以热力图直观呈现联动结构。两点结论:第一,BIPV 与组件、逆变器(光伏设备链)联动最强(0.94–0.96),说明 BIPV 行情高度同步于「造组件、做逆变器」的装备环节——这与「建筑一体化本质是光伏设备的下游应用」的产业逻辑一致;第二,组件—逆变器两两相关高达 0.989,几乎同涨同跌,是产业链内耦合最紧的一对,分析时应警惕二者作为「双变量」实则近乎同一因子的风险(共线),不宜在联动回归中同时作为独立解释变量。相对而言,上游硅料(原材料)与下游电站运营(运营端)与 BIPV 的联动偏弱(0.79–0.81),提示其受各自独立因素(硅料价格周期、电价政策)扰动更大。

六、趋势与波动率刻画(问题 3)

预测之前先回答「当前处于什么状态」。对 BIPV 清洗序列计算:

  • 移动平均:MA30/MA60(见图1)显示中长期趋势方向;
  • 年化波动率:σann=std(rt)×252=\sigma_{\text{ann}}=\text{std}(r_t)\times\sqrt{252}= 21.07%,属中等偏高风险资产;
  • 最大回撤:MDD=min⁡tPt−max⁡u≤tPumax⁡u≤tPu=\text{MDD}=\min_t\frac{P_t-\max_{u\le t}P_u}{\max_{u\le t}P_u}= −41.33%,提示即便长期向上,途中也可能出现深幅回撤;
  • 滚动 30 日年化波动率:刻画风险随时间的聚集与切换。

图3 BIPV 滚动 30 日年化波动率(风险时序)

图3 显示滚动波动率并非恒定:全样本介于 14.24%–28.83% 之间,存在明显的「平静—动荡」交替(波动率聚集效应)。这意味着用全样本单一波动率估计未来风险会低估动荡期的尾部,规划时应以滚动窗口或情景分位数替代固定值。BIPV 起点 993.8、终点 1082.4,整体上行约 9%,但 −41% 的最大回撤提醒:趋势收益与路径风险必须分开陈述,不能仅用一条预测线掩盖不确定性。

七、预测模型对比与情景规划(问题 4)

本文对比两类方法:统计法 Holt 双参数指数平滑(捕捉水平 + 趋势)与机器学习法 带 L2 正则的监督岭回归 AR(3)(用前 3 期水平预测下期,闭式求解 (X⊤X+λI)w=X⊤y(\mathbf{X}^\top\mathbf{X}+\lambda\mathbf{I})\mathbf{w}=\mathbf{X}^\top\mathbf{y})。评估采用滚动 1 步(扩张窗口)伪样本外协议:对测试区每一天 tt,用 [0,t)[0,t) 全部历史拟合,预测第 tt 日,累计 MAPE。该协议避免了「单次 60 步外推」在趋势拐点处的运气成分,更能反映方法的稳健性。

方法 类型 滚动 1 步 MAPE
Holt 双参数指数平滑 统计 1.13%
岭回归 AR(3)(L2 正则) 机器学习 1.02%

图4 滚动 1 步预测对比:Holt(统计) vs 岭回归(ML) vs 实际(末 60 日)

图4 取末 60 日,叠实际、Holt 1 步、岭回归 1 步与 Holt 的 95% 区间(±1.96σ,σ=15.29)。两法 1 步预测均紧贴实际,MAPE 同处 1% 量级、机器学习法略优——这是因为 1 步预测主要依赖近期水平惯性,两种方法都能较好地提取该惯性。差异在多步外推才显现:Holt 显式外推趋势分量,方向性强但在拐点易失真;岭回归 AR(3) 偏均值回复,外推更保守。因此实践建议:短期(1–5 日)二者皆可用,中期规划应以区间而非单点表达。

基于全样本 Holt 的 30 日规划(含趋势外推)给出情景:

情景 30 日点位 较当前(1082.4)
基准(趋势延续) 1148.5 +6.10%
政策利好(日漂移 +0.06%) 1169.4 +8.03%
硅料涨价(日漂移 −0.05%) 1131.4 +4.52%

三种情景点位差距约 ±1.5%–2%,说明在趋势惯性主导下,30 日尺度对温和外生冲击并不极度敏感;但若冲击引发趋势反转(如硅料持续紧缺、补贴退坡),单点预测的偏差将被放大,这正是区间与情景并重的意义。

八、模型验证(四路一致)

做三处交叉验证:①将清洗后序列代回相关性函数,重新算得 BIPV—组件=0.960、BIPV—逆变器=0.940,与正文表格、图2 完全一致;②将附录真源脚本独立运行,输出 750 日、缺失 22、异常 10、年化波动率 21.07%、最大回撤 −41.33%、两法 MAPE 1.13%/1.02%、30 日基准 1148.5,与正文逐项吻合;③对 Holt 的 α、β 网格(α∈{0.2,…,0.7}、β∈{0.05,…,0.4})重选,最优仍为 α=0.70、β=0.05,且岭回归 λ 在 {1,5,10} 间变化时效能稳定(MAPE 波动 <0.1%),说明结论对超参数不敏感。三类校验均通过,正文—配图—附录—真源四路数字一致。

九、结论

本文以「清洗 → 联动 → 趋势/波动 → 预测对比 → 情景」为主线,对 BIPV 板块指数做了可复现的系统分析。核心结论:其一,板块联动呈清晰产业链结构,BIPV 与组件、逆变器(设备链)最强(0.94–0.96),而组件—逆变器近乎共线(0.989),建模时须防多重共线性;其二,BIPV 年化波动率 21.07%、最大回撤 −41.33%、滚动波动率 14%–29% 聚集成簇,趋势与风险须分开陈述;其三,Holt 与岭回归在 1 步预测上均达 ~1% MAPE,但中期应以区间/情景表达不确定性;其四,30 日规划点位约 1148(基准)、1169(利好)、1131(涨价),对外生冲击呈温和敏感。全文零依赖、确定性合成,为真实参赛数据下的同类分析提供了一条清晰、可解释的工程化范式。

参考文献

[1] 2020 年电工杯数学建模竞赛 B 题:光伏建筑一体化板块指数发展趋势分析及预测(赛题原文,官方附件未公开)。

[2] Box G E P, Jenkins G M, Reinsel G C. Time Series Analysis: Forecasting and Control[M]. Wiley.(指数平滑与 ARIMA 经典)

[3] Hoerl A E, Kennard R W. Ridge Regression: Biased Estimation for Nonorthogonal Problems[J]. Technometrics, 1970.(岭回归 L2 正则)

[4] 中国光伏行业协会. 中国光伏产业发展路线图[R].(产业链结构参考)

附录:核心 Python 实现(可独立运行复现上述数字)

import tools.gen_dgcup2020b as G   # 真源:tools/gen_dgcup2020b.py(零依赖、确定性、种子 20200418)
D = G.gen_dgcup2020b()
print("样本 %d 日 | 缺失 %d | 异常 %d" % (len(D["cleaned"]), D["n_miss"], D["n_anom"]))
print("相关系数 BIPV-组件=%.3f BIPV-逆变器=%.3f" % (D["corr"][0][2], D["corr"][0][3]))
print("年化波动率=%.2f%% 最大回撤=%.2f%%" % (D["ann_vol"]*100, D["mdd"]*100))
print("滚动1步 Holt MAPE=%.2f%% 岭回归 MAPE=%.2f%%" % (D["holt_mape"], D["ridge_mape"]))
print("30日: 基准=%.1f 利好=%.1f 涨价=%.1f" % (D["end_base"], D["end_bull"], D["end_bear"]))

# —— 关键算法节选(与真源一致)——
# 1) 异常检测:滚动中位数 + MAD
def detect(xs, w=5, k=3.0):
    flags = set()
    for i in range(len(xs)):
        if xs[i] is None:
            continue
        seg = [xs[j] for j in range(max(0,i-w), min(len(xs),i+w+1)) if xs[j] is not None and j!=i]
        med = sorted(seg)[len(seg)//2]; mad = sorted(abs(v-med) for v in seg)[len(seg)//2] or 1e-9
        if abs(xs[i]-med) > k*1.4826*mad and abs(xs[i]-med)/med > 0.05:
            flags.add(i)
    return flags

# 2) Holt 双参数递推(返回末水平 l、趋势 b、残差标准差 sigma)
def holt_train(y, alpha, beta):
    l, b = y[0], y[1]-y[0]; resid = []
    for t in range(1, len(y)):
        resid.append(y[t]-(l+b)); prev = l
        l = alpha*y[t] + (1-alpha)*(l+b); b = beta*(l-prev) + (1-beta)*b
    sigma = (sum(r*r for r in resid)/len(resid))**0.5
    return l, b, sigma

# 3) 岭回归闭式解(高斯消元,无第三方依赖)
def mat_solve(A, b):
    n = len(A); M = [row[:]+[b[i]] for i,row in enumerate(A)]
    for c in range(n):
        p = max(range(c,n), key=lambda r: abs(M[r][c])); M[c], M[p] = M[p], M[c]
        d = M[c][c]; M[c] = [v/d for v in M[c]]
        for r in range(n):
            if r!=c and M[r][c]:
                f = M[r][c]; M[r] = [M[r][k]-f*M[c][k] for k in range(n+1)]
    return [M[i][n] for i in range(n)]

def ridge_fit(X, y, lam=5.0):
    nf = len(X[0]); XtX = [[0.0]*nf for _ in range(nf)]; e = [0.0]*nf
    for s in range(len(X)):
        for i in range(nf):
            e[i] += X[s][i]*y[s]
            for j in range(nf): XtX[i][j] += X[s][i]*X[s][j]
    for i in range(nf): XtX[i][i] += lam
    return mat_solve(XtX, e)