8b2590c5b5
- 完成Phase 11: predictV3算法优化研究文档,涵盖6个优化方向的技术分析 - 实现置信度评估功能,提供历史命中率、得分分布、多维度一致性置信度指标 - 扩展回测指标体系,新增NDCG@K、MRR、命中率分布等排名质量评估指标 - 优化转移概率算法,引入二阶马尔可夫链和多属性联合转移增强预测准确性 - 设计权重训练机制,支持网格搜索和遗传算法进行数据驱动的参数优化 - 集成组合特征挖掘功能,采用关联规则和序列模式发现号码间潜在关联 - 实现完整的前端交互界面,支持预测结果显示、置信度展示和回测验证功能 - 建立性能优化策略,包括预计算缓存、批量计算和降级策略保障响应速度
13 KiB
13 KiB
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 |
|
|
true |
|
|
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>
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 匹配:
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>
找到以下代码段:
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>
在现有得分显示后添加置信度显示。找到以下代码段:
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
- 打开 history 页面,点击"智能预测"按钮
- 使用 V3 版本执行预测,验证:
- 置信度评估区域是否显示
- 数据不足时是否显示警告提示
- 回测结果中是否显示 NDCG@5、MRR、命中分布柱状图
- 预测号码卡片中是否显示置信度等级和百分比
Success Criteria
renderPredict方法已更新,新增置信度展示区域- 回测结果展示区域已扩展,包含 NDCG@5、MRR、命中分布、数据警告
- 预测号码卡片显示置信度等级和百分比
- 命中分布使用 rank_1..rank_5 键名格式解析
- 所有新增展示样式与原有 UI 风格一致
- 数据警告以红色背景突出显示
Output
完成后创建 .planning/phases/11-predictv3/11-03-SUMMARY.md