oilverse-api / frontend /src /pages /P6ModelValidation.jsx
孙家明
deploy: OilVerse for HuggingFace (Node.js 18 fix)
fab9847
Raw
History Blame Contribute Delete
9.1 kB
import { useState, useEffect } from 'react';
import { useApp } from '../context/AppContext';
import StatCard from '../components/StatCard';
import { fetchAblation } from '../api';
import './Pages.css';
export default function P6ModelValidation() {
const { evalData: ev } = useApp();
const [ablation, setAblation] = useState([]);
useEffect(() => { fetchAblation().then(setAblation).catch(() => {}); }, []);
return (
<div className="page">
<div className="page-header">
<h2>🔬 模型验证与方法论</h2>
<p>回测 · 消融实验 · 创新叙事</p>
</div>
<div className="cards-grid cards-4">
<StatCard label="1M 覆盖率" value={`${ev.cov_1m}%`} />
<StatCard label="Vol RMSE" value={ev.vol_rmse} subtitle="EWMA ~0.10" />
<StatCard label="Vol 相关性" value={`+${ev.vol_corr}`} />
<StatCard label="测试月数" value={ev.n} />
</div>
<div className="story">
<h4>第一幕:传统方向预测的失败</h4>
<p>月频涨跌方向预测(XGBoost + 605特征 × 60月窗口):<br/>
• DA=47.9% &lt; Always-Up 57.1%<br/>
• AUC=0.41, MCC=-0.17(负相关)<br/>
• 概率排序完全反向:最低桶(Q1)实际上涨率 64.7%</p>
</div>
<div className="story">
<h4>第二幕:根因诊断</h4>
<p><strong>p &gt;&gt; n</strong>:605特征 × 60样本 = 10:1 过拟合<br/>
• 校准层做 1-prob hack<br/>
• 基准0/1信号占ensemble 44.5%<br/>
• 方向函数有实现 bug</p>
</div>
<div className="story">
<h4>第三幕:范式转换 → 风险因子框架</h4>
<p>"猜涨跌"对企业银行无意义。我们转向:<br/>
<strong>区间预测</strong>:80%覆盖 1M/3M<br/>
<strong>因子归因</strong>:什么在驱动油价<br/>
<strong>Regime识别</strong>:当前处于哪种宏观格局<br/>
<strong>行业映射</strong>:风险如何传导<br/>
结果:覆盖{ev.cov_1m}%, Vol corr=+{ev.vol_corr}</p>
</div>
<div className="card" style={{background:'linear-gradient(135deg,rgba(6,182,212,.10),rgba(6,182,212,.05))', border:'1px solid rgba(6,182,212,.3)'}}>
<h3>📡 另类数据创新: 多源情绪因子融合</h3>
<p style={{opacity:.85,marginBottom:'1rem'}}>AKShare真实API · SiliconFlow LLM情绪评分 · VIX衍生恐惧指数</p>
<div style={{display:'grid',gridTemplateColumns:'1fr 1fr',gap:'1.2rem'}}>
<div>
<h4 style={{color:'#06b6d4',marginBottom:'.6rem'}}>三源数据管道</h4>
<div style={{fontFamily:'monospace',fontSize:'.85rem',lineHeight:'1.8',background:'rgba(0,0,0,.2)',padding:'1rem',borderRadius:'.5rem'}}>
<div>📊 AKShare API <span style={{color:'#06b6d4'}}>← 密歇根消费者信心</span></div>
<div>&nbsp;&nbsp;<span style={{color:'#94a3b8'}}>603个月真实数据</span></div>
<div>🤖 SiliconFlow LLM <span style={{color:'#06b6d4'}}>← Qwen2.5-7B</span></div>
<div>&nbsp;&nbsp;<span style={{color:'#94a3b8'}}>32个油价历史事件评分</span></div>
<div>📈 VIX + 动量 <span style={{color:'#06b6d4'}}>← 市场恐惧指数</span></div>
<div>&nbsp;&nbsp;</div>
<div>🔄 融入 Walk-Forward Pipeline</div>
</div>
</div>
<div>
<h4 style={{color:'#06b6d4',marginBottom:'.6rem'}}>新增因子</h4>
<div style={{fontSize:'.9rem',lineHeight:'1.9'}}>
<div>📊 <strong>consumer_confidence</strong>: 消费者信心z-score <span style={{color:'#ef4444'}}>r = -0.01</span></div>
<div>😨 <strong>market_fear_index</strong>: VIX衍生恐惧指数 <span style={{color:'#10b981'}}>r = +0.18</span></div>
<div>🤖 <strong>event_sentiment</strong>: LLM事件情绪 <span style={{color:'#10b981'}}>r = +0.01</span></div>
</div>
<h4 style={{color:'#06b6d4',margin:'.8rem 0 .4rem'}}>创新价值</h4>
<div style={{fontSize:'.85rem',lineHeight:'1.7',color:'var(--muted)'}}>
<div><strong>真实API数据</strong>: AKShare可验证的消费者信心</div>
<div><strong>AI情绪评分</strong>: LLM对油价事件量化打分</div>
<div><strong>全覆盖</strong>: 1990-2026 无缺失</div>
</div>
</div>
</div>
</div>
<div className="card" style={{background:'linear-gradient(135deg,rgba(99,102,241,.12),rgba(139,92,246,.08))', border:'1px solid rgba(99,102,241,.3)'}}>
<h3>🧠 前沿技术: Temporal Fusion Transformer (TFT)</h3>
<p style={{opacity:.85,marginBottom:'1rem'}}>Google Research 2021 · 学术引用 3000+ · 时序预测 SOTA</p>
<div style={{display:'grid',gridTemplateColumns:'1fr 1fr',gap:'1.2rem'}}>
<div>
<h4 style={{color:'#a78bfa',marginBottom:'.6rem'}}>模型架构</h4>
<div style={{fontFamily:'monospace',fontSize:'.85rem',lineHeight:'1.8',background:'rgba(0,0,0,.2)',padding:'1rem',borderRadius:'.5rem'}}>
<div>📥 Input (24月回看窗口)</div>
<div>&nbsp;&nbsp;</div>
<div>🔀 Variable Selection Network</div>
<div>&nbsp;&nbsp;<span style={{color:'#a78bfa'}}>← 自动学习因子重要性</span></div>
<div>🔄 LSTM Encoder-Decoder</div>
<div>&nbsp;&nbsp;</div>
<div>👁️ Multi-Head Temporal Attention</div>
<div>&nbsp;&nbsp;<span style={{color:'#a78bfa'}}>← 识别关键时间步</span></div>
<div>📊 Quantile Output [Q10, Q50, Q90]</div>
</div>
</div>
<div>
<h4 style={{color:'#a78bfa',marginBottom:'.6rem'}}>核心创新点</h4>
<div style={{fontSize:'.9rem',lineHeight:'1.9'}}>
<div><strong>Variable Selection</strong>: 端到端学习因子权重, 超越人工特征工程</div>
<div><strong>Temporal Attention</strong>: 自动发现历史关键时段</div>
<div><strong>多分位数</strong>: 原生支持 Q10/Q50/Q90, 与 QR/CQR 框架天然融合</div>
<div><strong>轻量化部署</strong>: 17K 参数, 1.3s/步, CPU 可运行</div>
</div>
<h4 style={{color:'#a78bfa',margin:'.8rem 0 .4rem'}}>集成策略</h4>
<div style={{display:'flex',gap:'.5rem',flexWrap:'wrap'}}>
<span style={{padding:'.3rem .8rem',background:'rgba(59,130,246,.2)',borderRadius:'1rem',fontSize:'.85rem'}}>QR 50%</span>
<span style={{padding:'.3rem .8rem',background:'rgba(34,197,94,.2)',borderRadius:'1rem',fontSize:'.85rem'}}>LGB 25%</span>
<span style={{padding:'.3rem .8rem',background:'rgba(139,92,246,.3)',borderRadius:'1rem',fontSize:'.85rem',fontWeight:600}}>TFT 25%</span>
</div>
</div>
</div>
</div>
<div className="card">
<h3>方法论对比矩阵</h3>
<table className="data-table">
<thead><tr><th>方法</th><th>类型</th><th>角色</th><th>1M Coverage</th><th>WIS</th><th>优势</th></tr></thead>
<tbody>
<tr style={{background:'rgba(139,92,246,.08)'}}><td><strong>TFT (Transformer)</strong></td><td>🧠 Deep Learning</td><td>集成成员</td><td></td><td></td><td>Attention + Variable Selection</td></tr>
<tr><td>Quantile Regression</td><td>统计学习</td><td>主模型</td><td>{ev.cov_1m}%</td><td>{ev.wis_1m}</td><td>可解释、稳定</td></tr>
<tr><td>Conformal QR</td><td>校准框架</td><td>覆盖保证</td><td>{ev.cqr_cov}%</td><td>{ev.cqr_wis}</td><td>分布自由覆盖保证</td></tr>
<tr><td>LightGBM Quantile</td><td>集成学习</td><td>非线性</td><td>{ev.lgb_cov}%</td><td>{ev.lgb_wis}</td><td>树模型非线性捕捉</td></tr>
<tr><td>Historical Quantile</td><td>基线</td><td>对照</td><td>~75%</td><td>{ev.naive_wis}</td><td>无模型</td></tr>
</tbody>
</table>
</div>
<div className="card">
<h3>消融实验(真实数据)</h3>
<table className="data-table">
<thead><tr><th>实验</th><th>参数</th><th>Coverage</th><th>WIS</th><th>测试月数</th></tr></thead>
<tbody>
{ablation.map((a, i) => (
<tr key={i} style={a.param === 'ALL' ? { fontWeight: 700, background: 'rgba(59,130,246,.08)' } : {}}>
<td>{a.type === 'factor_group' ? (a.param === 'ALL' ? '★ 全部因子' : '✖ ' + a.param_label) : a.type === 'window' ? '训练窗口' : ''}</td>
<td>{a.param_label || a.param}</td>
<td>{(a.cov * 100).toFixed(1)}%</td>
<td>{a.wis}</td>
<td>{a.n}</td>
</tr>
))}
</tbody>
</table>
</div>
</div>
);
}