Files
amlhc/.planning/phases/11-predictv3/11-03-PLAN.md
T
916117771 8b2590c5b5 docs(predictV3): 添加predictV3算法优化研究文档和前端功能实现
- 完成Phase 11: predictV3算法优化研究文档,涵盖6个优化方向的技术分析
- 实现置信度评估功能,提供历史命中率、得分分布、多维度一致性置信度指标
- 扩展回测指标体系,新增NDCG@K、MRR、命中率分布等排名质量评估指标
- 优化转移概率算法,引入二阶马尔可夫链和多属性联合转移增强预测准确性
- 设计权重训练机制,支持网格搜索和遗传算法进行数据驱动的参数优化
- 集成组合特征挖掘功能,采用关联规则和序列模式发现号码间潜在关联
- 实现完整的前端交互界面,支持预测结果显示、置信度展示和回测验证功能
- 建立性能优化策略,包括预计算缓存、批量计算和降级策略保障响应速度
2026-05-01 23:17:24 +08:00

13 KiB
Raw Blame History

phase, plan, type, wave, depends_on, files_modified, autonomous, requirements, must_haves
phase plan type wave depends_on files_modified autonomous requirements must_haves
11-predictv3 03 execute 2
11-01
11-02
public/assets/js/backend/history.js
true
PRED-01
PRED-02
truths artifacts key_links
用户可以在预测弹窗中看到每个号码的置信度百分比
用户可以在回测结果区域看到 NDCG@5 和 MRR 指标
用户可以看到各排名位置的命中分布柱状图
用户可以看到数据不足时的警告提示
path provides contains
public/assets/js/backend/history.js 置信度和新回测指标前端展示 renderPredict|confidence|ndcg_5|mrr|hit_distribution|data_warning
from to via
renderPredict backtest.ndcg_5, backtest.mrr, confidence, backtest.data_warning 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>
在 `renderPredict` 方法中,找到以下变量声明位置(约 line 1701):
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 变量:

var confidence = data.confidence || null;

然后在回测验证结果展示区域(约 line 1732-1751)之前,插入置信度展示区域:

在 line 1732 之前(即 // 回测验证结果 注释之前)插入:

// 置信度评估展示(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 展示:数据不足时显示红色警告提示

<acceptance_criteria>

  • grep 匹配: confidence.overall_confidence 在 history.js renderPredict 方法中存在
  • grep 匹配: confidence.confidence_scores 在 history.js renderPredict 方法中存在
  • grep 匹配: confidence.data_warning 在 history.js renderPredict 方法中存在
  • grep 匹配: confLevelconfColor 变量在 history.js 中存在
  • 置信度展示区域在回测验证结果之前显示 </acceptance_criteria>

Task 2: 扩展回测指标展示区域(含数据警告和命中分布柱状图)

<read_first>

  • D:\code\php\amlhc\public\assets\js\backend\history.js (line 1732-1751, 回测验证结果展示区域) </read_first>
在 `renderPredict` 方法中,找到回测验证结果展示区域(约 line 1732-1751),现有代码展示命中率、命中次数、平均排名三个指标。

找到以下代码段:

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>';

替换为:

// 回测数据警告提示
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

<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>
在预测号码列表渲染区域(约 line 1828-1866),找到号码卡片渲染代码:

在现有得分显示后添加置信度显示。找到以下代码段:

html += '<div style="font-size:11px;color:#2e7d32;font-weight:bold;">得分:' + p.score + '</div>';

替换为:

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(得分集中度)维度

<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