docs(predictV3): 添加predictV3算法优化研究文档和前端功能实现
- 完成Phase 11: predictV3算法优化研究文档,涵盖6个优化方向的技术分析 - 实现置信度评估功能,提供历史命中率、得分分布、多维度一致性置信度指标 - 扩展回测指标体系,新增NDCG@K、MRR、命中率分布等排名质量评估指标 - 优化转移概率算法,引入二阶马尔可夫链和多属性联合转移增强预测准确性 - 设计权重训练机制,支持网格搜索和遗传算法进行数据驱动的参数优化 - 集成组合特征挖掘功能,采用关联规则和序列模式发现号码间潜在关联 - 实现完整的前端交互界面,支持预测结果显示、置信度展示和回测验证功能 - 建立性能优化策略,包括预计算缓存、批量计算和降级策略保障响应速度
This commit is contained in:
@@ -0,0 +1,278 @@
|
||||
---
|
||||
phase: 11-predictv3
|
||||
plan: 03
|
||||
type: execute
|
||||
wave: 2
|
||||
depends_on:
|
||||
- 11-01
|
||||
- 11-02
|
||||
files_modified:
|
||||
- public/assets/js/backend/history.js
|
||||
autonomous: true
|
||||
requirements:
|
||||
- PRED-01
|
||||
- PRED-02
|
||||
must_haves:
|
||||
truths:
|
||||
- "用户可以在预测弹窗中看到每个号码的置信度百分比"
|
||||
- "用户可以在回测结果区域看到 NDCG@5 和 MRR 指标"
|
||||
- "用户可以看到各排名位置的命中分布柱状图"
|
||||
- "用户可以看到数据不足时的警告提示"
|
||||
artifacts:
|
||||
- path: "public/assets/js/backend/history.js"
|
||||
provides: "置信度和新回测指标前端展示"
|
||||
contains: "renderPredict|confidence|ndcg_5|mrr|hit_distribution|data_warning"
|
||||
key_links:
|
||||
- from: "renderPredict"
|
||||
to: "backtest.ndcg_5, backtest.mrr, confidence, backtest.data_warning"
|
||||
via: "property access in rendering logic"
|
||||
---
|
||||
|
||||
# Phase 11 - Plan 03: 前端展示优化
|
||||
|
||||
## Objective
|
||||
|
||||
更新前端 `renderPredict` 方法,展示新增的置信度指标和扩展的回测指标(NDCG、MRR、命中分布、数据警告)。
|
||||
|
||||
**Purpose:** 后端已计算置信度和新回测指标,前端需要将这些数据可视化呈现给用户,提升预测结果的可读性和决策辅助价值。
|
||||
|
||||
**Output:** `history.js` 中的 `renderPredict` 方法扩展,新增置信度展示区域和回测指标扩展展示。
|
||||
|
||||
## Tasks
|
||||
|
||||
### Task 1: 添加置信度展示区域(含数据警告提示)
|
||||
|
||||
<read_first>
|
||||
- D:\code\php\amlhc\public\assets\js\backend\history.js (line 1700-1871, renderPredict 方法)
|
||||
</read_first>
|
||||
|
||||
<action>
|
||||
在 `renderPredict` 方法中,找到以下变量声明位置(约 line 1701):
|
||||
|
||||
```javascript
|
||||
var predictions = data.predictions || [];
|
||||
var analysis = data.analysis || {};
|
||||
var hitInfo = data.hit_info || null;
|
||||
var actualResult = data.actual_result || null;
|
||||
var backtest = data.backtest || null;
|
||||
```
|
||||
|
||||
在 `backtest` 声明后添加 `confidence` 变量:
|
||||
|
||||
```javascript
|
||||
var confidence = data.confidence || null;
|
||||
```
|
||||
|
||||
然后在回测验证结果展示区域(约 line 1732-1751)之前,插入置信度展示区域:
|
||||
|
||||
在 line 1732 之前(即 `// 回测验证结果` 注释之前)插入:
|
||||
|
||||
```javascript
|
||||
// 置信度评估展示(V2和V3版本)
|
||||
if (confidence && (version === 'v2' || version === 'v3')) {
|
||||
html += '<div style="background:#fff8e1;border:1px solid #ffb300;border-radius:6px;padding:12px;margin-bottom:15px;">';
|
||||
html += '<div style="font-size:13px;font-weight:bold;color:#ff8f00;margin-bottom:8px;"><i class="fa fa-star-half-o"></i> 预测置信度评估</div>';
|
||||
|
||||
// 数据警告提示(数据不足时显示)
|
||||
if (confidence.data_warning) {
|
||||
html += '<div style="font-size:11px;color:#d32f2f;background:#ffebee;padding:6px;border-radius:4px;margin-bottom:8px;"><i class="fa fa-exclamation-triangle"></i> ' + confidence.data_warning + '</div>';
|
||||
}
|
||||
|
||||
html += '<div style="display:flex;gap:20px;align-items:center;">';
|
||||
html += '<div style="text-align:center;"><div style="font-size:24px;font-weight:bold;color:#ff8f00;">' + confidence.overall_confidence + '%</div><div style="font-size:12px;color:#666;">整体置信度</div></div>';
|
||||
|
||||
// 各排名置信度(使用得分集中度维度)
|
||||
if (confidence.confidence_scores && confidence.confidence_scores.length > 0) {
|
||||
html += '<div style="display:flex;gap:8px;">';
|
||||
for (var i = 0; i < confidence.confidence_scores.length; i++) {
|
||||
var cs = confidence.confidence_scores[i];
|
||||
// 阈值定义:>=70%高(绿)、50-70%中(橙)、<50%低(红)
|
||||
var confLevel = cs.confidence >= 70 ? '高' : (cs.confidence >= 50 ? '中' : '低');
|
||||
var confColor = cs.confidence >= 70 ? '#4caf50' : (cs.confidence >= 50 ? '#ff9800' : '#f44336');
|
||||
html += '<div style="text-align:center;padding:5px;background:#fff;border-radius:4px;">';
|
||||
html += '<div style="font-size:14px;font-weight:bold;color:' + confColor + ';">' + cs.confidence + '%</div>';
|
||||
html += '<div style="font-size:10px;color:#999;">#' + cs.rank + '</div>';
|
||||
html += '</div>';
|
||||
}
|
||||
html += '</div>';
|
||||
}
|
||||
html += '</div></div>';
|
||||
}
|
||||
```
|
||||
|
||||
实现要点:
|
||||
- 整体置信度以大数字展示,各排名置信度以小卡片形式横向排列
|
||||
- 置信度分三级:高(>=70%, 绿色)、中(50-70%, 橙色)、低(<50%, 红色)
|
||||
- 只在 V2 和 V3 版本中显示
|
||||
- 新增 data_warning 展示:数据不足时显示红色警告提示
|
||||
</action>
|
||||
|
||||
<acceptance_criteria>
|
||||
- grep 匹配: `confidence.overall_confidence` 在 history.js renderPredict 方法中存在
|
||||
- grep 匹配: `confidence.confidence_scores` 在 history.js renderPredict 方法中存在
|
||||
- grep 匹配: `confidence.data_warning` 在 history.js renderPredict 方法中存在
|
||||
- grep 匹配: `confLevel` 和 `confColor` 变量在 history.js 中存在
|
||||
- 置信度展示区域在回测验证结果之前显示
|
||||
</acceptance_criteria>
|
||||
|
||||
### Task 2: 扩展回测指标展示区域(含数据警告和命中分布柱状图)
|
||||
|
||||
<read_first>
|
||||
- D:\code\php\amlhc\public\assets\js\backend\history.js (line 1732-1751, 回测验证结果展示区域)
|
||||
</read_first>
|
||||
|
||||
<action>
|
||||
在 `renderPredict` 方法中,找到回测验证结果展示区域(约 line 1732-1751),现有代码展示命中率、命中次数、平均排名三个指标。
|
||||
|
||||
找到以下代码段:
|
||||
|
||||
```javascript
|
||||
html += '<div style="display:flex;gap:20px;">';
|
||||
html += '<div style="text-align:center;"><div style="font-size:24px;font-weight:bold;color:#2196f3;">' + backtest.hit_rate + '%</div><div style="font-size:12px;color:#666;">命中率(Top5)</div></div>';
|
||||
html += '<div style="text-align:center;"><div style="font-size:24px;font-weight:bold;color:#4caf50;">' + backtest.total_hits + '/' + backtest.total_tests + '</div><div style="font-size:12px;color:#666;">命中次数</div></div>';
|
||||
html += '<div style="text-align:center;"><div style="font-size:24px;font-weight:bold;color:#ff9800;">' + (backtest.avg_rank || '—') + '</div><div style="font-size:12px;color:#666;">平均排名</div></div>';
|
||||
html += '</div>';
|
||||
```
|
||||
|
||||
替换为:
|
||||
|
||||
```javascript
|
||||
// 回测数据警告提示
|
||||
if (backtest.data_warning) {
|
||||
html += '<div style="font-size:11px;color:#d32f2f;background:#ffebee;padding:6px;border-radius:4px;margin-bottom:8px;"><i class="fa fa-exclamation-triangle"></i> ' + backtest.data_warning + '</div>';
|
||||
}
|
||||
|
||||
html += '<div style="display:flex;gap:15px;flex-wrap:wrap;">';
|
||||
html += '<div style="text-align:center;padding:8px;"><div style="font-size:22px;font-weight:bold;color:#2196f3;">' + backtest.hit_rate + '%</div><div style="font-size:11px;color:#666;">命中率(Top5)</div></div>';
|
||||
html += '<div style="text-align:center;padding:8px;"><div style="font-size:22px;font-weight:bold;color:#4caf50;">' + backtest.total_hits + '/' + backtest.total_tests + '</div><div style="font-size:11px;color:#666;">命中次数</div></div>';
|
||||
html += '<div style="text-align:center;padding:8px;"><div style="font-size:22px;font-weight:bold;color:#ff9800;">' + (backtest.avg_rank || '—') + '</div><div style="font-size:11px;color:#666;">平均排名</div></div>';
|
||||
|
||||
// 新增指标:NDCG@5 和 MRR(百分比展示)
|
||||
if (backtest.ndcg_5 !== undefined) {
|
||||
html += '<div style="text-align:center;padding:8px;"><div style="font-size:22px;font-weight:bold;color:#9c27b0;">' + (backtest.ndcg_5 * 100).toFixed(1) + '%</div><div style="font-size:11px;color:#666;">NDCG@5</div></div>';
|
||||
}
|
||||
if (backtest.mrr !== undefined) {
|
||||
html += '<div style="font-size:22px;font-weight:bold;color:#00bcd4;">' + (backtest.mrr * 100).toFixed(1) + '%</div><div style="font-size:11px;color:#666;">MRR</div></div>';
|
||||
}
|
||||
|
||||
// 转移概率阶数显示(来自11-05的transition_order字段)
|
||||
if (analysis && analysis.transition_order !== undefined) {
|
||||
html += '<div style="text-align:center;padding:8px;"><div style="font-size:22px;font-weight:bold;color:#607d8b;">' + analysis.transition_order + '阶</div><div style="font-size:11px;color:#666;">转移概率</div></div>';
|
||||
}
|
||||
html += '</div>';
|
||||
|
||||
// 命中分布柱状图(使用rank_1..rank_5键名)
|
||||
if (backtest.hit_distribution && Object.keys(backtest.hit_distribution).length > 0) {
|
||||
var distribution = backtest.hit_distribution;
|
||||
var maxHit = 0;
|
||||
// 找最大值用于计算柱状图高度比例
|
||||
for (var r = 1; r <= 5; r++) {
|
||||
var key = 'rank_' + r;
|
||||
if (distribution[key] > maxHit) {
|
||||
maxHit = distribution[key];
|
||||
}
|
||||
}
|
||||
|
||||
html += '<div style="margin-top:10px;font-size:11px;color:#666;">命中分布(各排名命中次数):</div>';
|
||||
html += '<div style="display:flex;gap:8px;align-items:flex-end;height:60px;margin-top:5px;padding:5px;background:#f5f5f5;border-radius:4px;">';
|
||||
for (var r = 1; r <= 5; r++) {
|
||||
var key = 'rank_' + r;
|
||||
var hitCount = distribution[key] || 0;
|
||||
var barHeight = maxHit > 0 ? (hitCount / maxHit * 45) : 0;
|
||||
var barColor = hitCount > 0 ? '#4caf50' : '#e0e0e0';
|
||||
html += '<div style="text-align:center;min-width:50px;">';
|
||||
html += '<div style="height:' + barHeight + 'px;background:' + barColor + ';border-radius:2px 2px 0 0;width:35px;margin:0 auto;"></div>';
|
||||
html += '<div style="font-size:10px;color:#666;margin-top:2px;">#' + r + '</div>';
|
||||
html += '<div style="font-size:11px;color:#333;font-weight:bold;">' + hitCount + '</div>';
|
||||
html += '</div>';
|
||||
}
|
||||
html += '</div>';
|
||||
}
|
||||
```
|
||||
|
||||
实现要点:
|
||||
- NDCG@5 和 MRR 以百分比形式展示(乘100后保留1位小数)
|
||||
- 命中分布以简单柱状图展示,排名1-5横向排列
|
||||
- 柱状图高度按最大命中次数比例计算
|
||||
- 使用 rank_1..rank_5 键名格式解析分布数据
|
||||
- 新增 data_warning 展示:回测数据不足时显示警告
|
||||
- 转移概率阶数从 analysis.transition_order 获取(而非 backtest)
|
||||
</action>
|
||||
|
||||
<acceptance_criteria>
|
||||
- grep 匹配: `backtest.ndcg_5` 在 history.js renderPredict 方法中存在
|
||||
- grep 匹配: `backtest.mrr` 在 history.js renderPredict 方法中存在
|
||||
- grep 匹配: `backtest.hit_distribution` 在 history.js renderPredict 方法中存在
|
||||
- grep 匹配: `backtest.data_warning` 在 history.js renderPredict 方法中存在
|
||||
- grep 匹配: `rank_1|rank_2|rank_3|rank_4|rank_5` 在命中分布解析中存在
|
||||
- grep 匹配: `analysis.transition_order` 在 history.js renderPredict 方法中存在
|
||||
- 命中分布柱状图使用 div 元素实现
|
||||
</acceptance_criteria>
|
||||
|
||||
### Task 3: 在预测号码卡片中显示置信度(含得分集中度展示)
|
||||
|
||||
<read_first>
|
||||
- D:\code\php\amlhc\public\assets\js\backend\history.js (line 1828-1866, 预测号码列表渲染)
|
||||
</read_first>
|
||||
|
||||
<action>
|
||||
在预测号码列表渲染区域(约 line 1828-1866),找到号码卡片渲染代码:
|
||||
|
||||
在现有得分显示后添加置信度显示。找到以下代码段:
|
||||
|
||||
```javascript
|
||||
html += '<div style="font-size:11px;color:#2e7d32;font-weight:bold;">得分:' + p.score + '</div>';
|
||||
```
|
||||
|
||||
替换为:
|
||||
|
||||
```javascript
|
||||
html += '<div style="font-size:11px;color:#2e7d32;font-weight:bold;">得分:' + p.score + '</div>';
|
||||
|
||||
// 显示置信度(V3版本)
|
||||
if (version === 'v3' && confidence && confidence.confidence_scores) {
|
||||
var csForNum = confidence.confidence_scores.find(function(c) { return c.num === p.num; });
|
||||
if (csForNum) {
|
||||
// 阈值定义:>=70%高(绿)、50-70%中(橙)、<50%低(红)
|
||||
var confLevel = csForNum.confidence >= 70 ? '高' : (csForNum.confidence >= 50 ? '中' : '低');
|
||||
var confColor = csForNum.confidence >= 70 ? '#4caf50' : (csForNum.confidence >= 50 ? '#ff9800' : '#f44336');
|
||||
html += '<div style="font-size:10px;"><span style="color:' + confColor + ';font-weight:bold;">置信度:' + confLevel + '</span> <span style="color:#666;">(' + csForNum.confidence + '%)</span></div>';
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
实现要点:
|
||||
- 在号码卡片中显示置信度等级(高/中/低)和具体百分比
|
||||
- 使用与整体置信度展示相同的颜色映射阈值
|
||||
- 只在 V3 版本中显示
|
||||
- 置信度字段使用 score_concentration(得分集中度)维度
|
||||
</action>
|
||||
|
||||
<acceptance_criteria>
|
||||
- grep 匹配: `csForNum` 变量在 history.js 中存在
|
||||
- grep 匹配: `置信度:` 在号码卡片渲染代码中存在
|
||||
- 置信度显示在得分下方
|
||||
- grep 匹配: `csForNum.confidence` 在号码卡片渲染中存在
|
||||
</acceptance_criteria>
|
||||
|
||||
## Verification
|
||||
|
||||
1. 打开 history 页面,点击"智能预测"按钮
|
||||
2. 使用 V3 版本执行预测,验证:
|
||||
- 置信度评估区域是否显示
|
||||
- 数据不足时是否显示警告提示
|
||||
- 回测结果中是否显示 NDCG@5、MRR、命中分布柱状图
|
||||
- 预测号码卡片中是否显示置信度等级和百分比
|
||||
|
||||
## Success Criteria
|
||||
|
||||
1. `renderPredict` 方法已更新,新增置信度展示区域
|
||||
2. 回测结果展示区域已扩展,包含 NDCG@5、MRR、命中分布、数据警告
|
||||
3. 预测号码卡片显示置信度等级和百分比
|
||||
4. 命中分布使用 rank_1..rank_5 键名格式解析
|
||||
5. 所有新增展示样式与原有 UI 风格一致
|
||||
6. 数据警告以红色背景突出显示
|
||||
|
||||
## Output
|
||||
|
||||
完成后创建 `.planning/phases/11-predictv3/11-03-SUMMARY.md`
|
||||
Reference in New Issue
Block a user