From 44448ae1e82dd3f03e8c0cbde4554a169f011eb8 Mon Sep 17 00:00:00 2001 From: leon <916117771@qq.com> Date: Fri, 1 May 2026 11:38:40 +0800 Subject: [PATCH] =?UTF-8?q?docs(11):=20research=20phase=20-=20predictV3?= =?UTF-8?q?=E7=AE=97=E6=B3=95=E4=BC=98=E5=8C=96=E6=96=B9=E5=90=91=E8=B0=83?= =?UTF-8?q?=E7=A0=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 研究内容: - 现有V3算法架构分析(9维度评分系统) - 6个优化方向技术方案(数据维度扩展/转移概率增强/权重训练/置信度评估/回测指标扩展/组合特征挖掘) - 实现优先级排序与风险评估 - 代码示例与性能优化建议 --- .planning/phases/11-predictv3/11-RESEARCH.md | 881 +++++++++++++++++++ 1 file changed, 881 insertions(+) create mode 100644 .planning/phases/11-predictv3/11-RESEARCH.md diff --git a/.planning/phases/11-predictv3/11-RESEARCH.md b/.planning/phases/11-predictv3/11-RESEARCH.md new file mode 100644 index 0000000..8bd1139 --- /dev/null +++ b/.planning/phases/11-predictv3/11-RESEARCH.md @@ -0,0 +1,881 @@ +# Phase 11: predictV3算法优化 - Research + +**Researched:** 2026-05-01 +**Domain:** 彩票号码预测算法优化 / 多维度评分系统增强 +**Confidence:** MEDIUM (基于代码分析 + 训练知识,部分技术方案需要进一步验证) + +## Summary + +现有 V3 预测算法已实现 9 个评分维度和动态权重调整机制,核心技术栈为 PHP + ThinkPHP 5.x,采用马尔可夫链转移概率、经验分布函数、走势分析等方法进行号码预测。优化方向涵盖:数据维度扩展、转移概率增强、权重训练、置信度评估、回测指标扩展、组合特征挖掘六个领域。 + +**Primary recommendation:** 优先实现置信度评估和回测指标扩展,这两个方向对用户体验提升最直接;权重训练和转移概率增强可作为中期优化目标;组合特征挖掘和数据维度扩展需要更多历史数据支撑,适合长期迭代。 + +## Architectural Responsibility Map + +| Capability | Primary Tier | Secondary Tier | Rationale | +|------------|-------------|----------------|-----------| +| 预测计算核心 | Backend (PHP Model) | — | 复杂统计计算、历史数据分析在服务端完成 | +| 回测验证 | Backend (PHP Model) | — | 需要批量查询历史数据,服务端性能最优 | +| 权重配置 | Frontend (JS) + Backend | Backend | 前端提供UI配置,后端存储默认值并验证 | +| 置信度展示 | Frontend (JS) | Backend | 后端计算置信度,前端负责可视化呈现 | +| 组合特征挖掘 | Backend (PHP Model) | — | 数据密集型计算,服务端执行效率高 | + +## Technical Analysis + +### 现有 V3 算法架构 + +**核心入口方法:** `getPredictionV3($periods = 200, $weights = [], $targetExpect = '', $skipBacktest = false, $backtestCount = 50)` + +**9个评分维度及其实现:** + +| 维度 | 方法 | 核心技术 | 当前权重(默认) | +|------|------|----------|----------------| +| 遗漏回归 | `_calcOmitScoreEmpirical()` | 经验累积分布函数(CDF),百分位排名映射 | 0.18 | +| 频率回归 | `_calcFreqScoreAdvanced()` | 频率比率 + 回归窗口判断 + 卡方检验 | 0.12 | +| 转移概率 | `_calcTransitionScore()` | 一阶马尔可夫链,拉普拉斯平滑处理 | 0.18 | +| 单双平衡 | `_calcOddEvenScore()` | 连续性反转预测 + 比例失衡回归 | 0.08 | +| 大小平衡 | `_calcBigSmallScore()` | 同单双逻辑,大小阈值25 | 0.08 | +| 走势方向 | `_calcTrendDirectionScore()` | 上升/下降/跳跃趋势识别,强度加权 | 0.14 | +| 区域平衡 | 内联计算 | 5区域分布比例失衡回归 | 0.04 | +| 波色平衡 | 内联计算 | 红蓝绿三色分布失衡回归 | 0.04 | +| 组合特征 | `_calcCombinationScore()` | 属性组合、相邻号码共现、前3期模式 | 0.10 | + +**动态权重调整:** `_adjustWeightsDynamic()` 根据走势强度、遗漏分布、单双/大小连续性实时调整权重并归一化。 + +**回测机制:** `_runBacktestV3()` 执行最近N期历史验证,输出命中率(Top5)、平均排名、详细记录。 + +### 代码结构优势 + +1. **模块化设计:** 每个维度独立方法,便于单独优化和测试 +2. **预计算优化:** 号码属性索引(zoneMap, colorKeyMap, tailMap等)在主循环外预构建 +3. **参数化配置:** 权重可前端传入,支持用户自定义 +4. **回测验证:** 内置历史验证机制,可评估算法有效性 + +### 代码结构局限 + +1. **一阶马尔可夫:** 转移概率仅考虑上一期状态,未利用更长的历史序列 +2. **固定评分函数:** 各维度评分逻辑硬编码,缺乏数据驱动的参数调优 +3. **无置信度输出:** 预测结果只有排名,无置信度指标 +4. **回测指标单一:** 仅命中率+平均排名,缺少NDCG、MRR等排名质量指标 +5. **组合特征简单:** 仅考虑±2相邻共现和前3期模式,挖掘深度不足 + +--- + +## Optimization Recommendations + +### 方向1: 数据维度扩展 + +**目标:** 添加新的有效评分维度,丰富预测信号来源 + +**推荐新增维度:** + +| 维度 | 技术方案 | 实现复杂度 | 预期收益 | +|------|----------|------------|----------| +| **时间周期性** | 分析开奖日期的周期规律(周几、月份)对号码分布的影响 | 低 | 中 | +| **生肖序列** | 将生肖映射为数值序列,分析生肖转移规律 | 低 | 中 | +| **跨期关联** | 分析前N期(3-5期)号码组合对当前期的联合影响 | 中 | 中-高 | +| **号码距离** | 计算候选号码与最近5期开奖号码的平均距离特征 | 低 | 低-中 | +| **连号特征** | 统计历史连号出现频率,预测连号概率 | 低 | 低 | + +**实现建议:** + +```php +// 示例: 时间周期性分析方法 +/** + * 分析时间周期性特征 + * @param array $history 历史数据(含openTime) + * @return array {weekday_stats: [], month_stats: []} + */ +private function _analyzeTimeCycle($history) +{ + $weekdayCount = array_fill(0, 7, []); // 周一到周日 + $monthCount = array_fill(1, 12, []); // 1-12月 + + foreach ($history as $row) { + $num = (int)$row['num7']; + $weekday = date('N', strtotime($row['openTime'])); // 1-7 + $month = date('n', strtotime($row['openTime'])); // 1-12 + + if (!isset($weekdayCount[$weekday][$num])) { + $weekdayCount[$weekday][$num] = 0; + } + $weekdayCount[$weekday][$num]++; + + if (!isset($monthCount[$month][$num])) { + $monthCount[$month][$num] = 0; + } + $monthCount[$month][$num]++; + } + + return [ + 'weekday_stats' => $weekdayCount, + 'month_stats' => $monthCount + ]; +} +``` + +**注意事项:** +- 新维度需在 `_adjustWeightsDynamic()` 中添加相应的动态调整逻辑 +- 权重初始值需谨慎设置,避免过度稀释现有有效维度 +- 维度数量增加可能导致权重分配稀疏,需考虑维度重要性排序 + +**置信度:** MEDIUM [ASSUMED] - 基于训练知识,时间周期性在实际预测场景中效果需验证 + +--- + +### 方向2: 转移概率增强 + +**目标:** 改进现有一阶马尔可夫链,提升转移概率预测准确性 + +**推荐增强方案:** + +| 方案 | 技术细节 | 实现复杂度 | 预期收益 | +|------|----------|------------|----------| +| **二阶马尔可夫链** | 考虑前两期状态联合决定当前转移概率,状态空间扩大但预测更精准 | 中 | 中-高 | +| **多属性联合转移** | 同时考虑单双+大小的联合状态转移(4状态),而非单独计算 | 中 | 中 | +| **衰减权重转移** | 近期转移权重更高,历史久远的转移权重衰减 | 低 | 低-中 | +| **条件转移概率** | 在特定条件下(如遗漏超过阈值)调整转移概率分布 | 中 | 中 | + +**二阶马尔可夫链实现思路:** + +```php +/** + * 构建二阶马尔可夫转移矩阵 + * @param array $history 历史数据(降序) + * @param string $type 类型:zone/tail/head + * @return array {matrix: [], prob_matrix: [], state_totals: []} + */ +private function _getTransitionMatrix2ndOrder($history, $type) +{ + $historyAsc = array_reverse($history); + $numCategories = $type === 'tail' ? 10 : 5; + + // 状态空间: (prev1, prev2) -> current,共 numCategories^2 个前置状态 + $matrix = []; + $stateTotals = []; + + // 初始化矩阵结构 + for ($i = 0; $i < $numCategories; $i++) { + for ($j = 0; $j < $numCategories; $j++) { + $stateKey = $i . '-' . $j; + $matrix[$stateKey] = array_fill(0, $numCategories, 0); + $stateTotals[$stateKey] = 0; + } + } + + $getIdx = $this->_getCategoryIdxFunction($type); + + // 统计二阶转移 + for ($i = 0; $i < count($historyAsc) - 2; $i++) { + $prev1 = $getIdx((int)$historyAsc[$i]['num7']); + $prev2 = $getIdx((int)$historyAsc[$i + 1]['num7']); + $current = $getIdx((int)$historyAsc[$i + 2]['num7']); + + if ($prev1 < 0 || $prev2 < 0 || $current < 0) continue; + + $stateKey = $prev1 . '-' . $prev2; + $matrix[$stateKey][$current]++; + $stateTotals[$stateKey]++; + } + + // 拉普拉斯平滑处理 + $probMatrix = []; + foreach ($matrix as $stateKey => $counts) { + $smoothTotal = $stateTotals[$stateKey] + $numCategories; + $probMatrix[$stateKey] = []; + for ($j = 0; $j < $numCategories; $j++) { + $probMatrix[$stateKey][$j] = ($counts[$j] + 1) / $smoothTotal; + } + } + + return [ + 'matrix' => $matrix, + 'prob_matrix' => $probMatrix, + 'state_totals' => $stateTotals, + 'num_categories' => $numCategories + ]; +} +``` + +**注意事项:** +- 二阶马尔可夫状态空间指数增长(5^2=25或10^2=100),历史数据不足时概率估计不稳定 +- 需保留一阶方法作为数据不足时的fallback +- 可结合现有 `_getTransitionMatrix()` 形成混合策略 + +**置信度:** MEDIUM [ASSUMED] - 二阶马尔可夫在理论上更精准,但实际效果需回测验证 + +--- + +### 方向3: 权重训练 + +**目标:** 实现数据驱动的权重优化,替代手动调参 + +**推荐方案:** + +| 方案 | 技术细节 | 实现复杂度 | 适用场景 | +|------|----------|------------|----------| +| **历史回测网格搜索** | 预定义权重组合网格,批量回测选择最优组合 | 低 | 快速验证,适合初期 | +| **遗传算法优化** | 定义权重基因,通过选择/交叉/变异迭代优化 | 中 | 复杂权重空间探索 | +| **时间段分层权重** | 不同时间段使用不同权重配置(强趋势/弱趋势/跳跃) | 低 | 适应动态场景 | +| **梯度下降优化** | 定义损失函数(命中率),迭代调整权重 | 高 | 需要大量回测数据 | + +**网格搜索实现思路:** + +```php +/** + * 权重网格搜索优化 + * @param int $periods 统计期数 + * @param int $backtestCount 回测期数 + * @param int $steps 每个权重的搜索步数 + * @return array {best_weights: [], best_hit_rate: float, all_results: []} + */ +private function _optimizeWeightsGridSearch($periods = 200, $backtestCount = 50, $steps = 5) +{ + $weightKeys = ['omit_regression', 'freq_regression', 'transition_prob', + 'oddeven_balance', 'bigsmall_balance', 'trend_direction', + 'zone_balance', 'color_balance', 'combination']; + + $bestWeights = []; + $bestHitRate = 0; + $allResults = []; + + // 简化: 固定部分权重,仅优化核心权重组合 + // 实际实现需考虑组合爆炸问题,可采用分层搜索或随机采样 + $baseConfigs = [ + // 配置1: 遗漏优先 + ['omit_regression' => 0.25, 'freq_regression' => 0.15, 'transition_prob' => 0.20, 'trend_direction' => 0.15], + // 配置2: 转移优先 + ['omit_regression' => 0.15, 'freq_regression' => 0.10, 'transition_prob' => 0.25, 'trend_direction' => 0.12], + // 配置3: 走势优先 + ['omit_regression' => 0.12, 'freq_regression' => 0.10, 'transition_prob' => 0.15, 'trend_direction' => 0.25], + ]; + + foreach ($baseConfigs as $config) { + $weights = array_merge($config, [ + 'oddeven_balance' => 0.08, + 'bigsmall_balance' => 0.08, + 'zone_balance' => 0.04, + 'color_balance' => 0.04, + 'combination' => 0.08 + ]); + + // 归一化权重 + $total = array_sum($weights); + foreach ($weights as $key => $value) { + $weights[$key] = $value / $total; + } + + // 执行回测 + $backtest = $this->_runBacktestV3($periods, $weights, $backtestCount); + $hitRate = $backtest['hit_rate']; + + $allResults[] = [ + 'weights' => $weights, + 'hit_rate' => $hitRate, + 'avg_rank' => $backtest['avg_rank'] + ]; + + if ($hitRate > $bestHitRate) { + $bestHitRate = $hitRate; + $bestWeights = $weights; + } + } + + return [ + 'best_weights' => $bestWeights, + 'best_hit_rate' => $bestHitRate, + 'all_results' => $allResults + ]; +} +``` + +**注意事项:** +- 网格搜索组合爆炸问题严重,需采用分层搜索或启发式采样 +- 权重优化结果依赖历史数据量,数据不足时优化不可靠 +- 需定期重新优化,避免过拟合特定时间段 +- 可将优化结果存储到配置文件,供前端默认加载 + +**置信度:** HIGH [CITED: 机器学习参数优化最佳实践] - 网格搜索和遗传算法是成熟的参数优化方法 + +--- + +### 方向4: 置信度评估 + +**目标:** 为预测结果提供置信度指标,帮助用户判断预测可靠性 + +**推荐置信度来源:** + +| 来源 | 计算方法 | 实现复杂度 | 信息价值 | +|------|----------|------------|----------| +| **历史命中率置信度** | 基于相同排名位置的历史命中率统计 | 低 | 高 | +| **得分分布置信度** | 当前预测得分与历史命中号码得分分布的距离 | 中 | 中 | +| **多维度一致性置信度** | 各维度得分方向的一致程度(是否都指向同一号码) | 中 | 中 | +| **回测稳定性置信度** | 多批次回测命中率的方差(稳定性越高置信度越高) | 低 | 高 | + +**置信度计算实现:** + +```php +/** + * 计算预测置信度 + * @param array $predictions 预测结果数组 + * @param array $backtest 回测结果 + * @param array $scoresAll 所有号码得分详情 + * @return array {confidence_scores: [], overall_confidence: float} + */ +private function _calculateConfidence($predictions, $backtest, $scoresAll) +{ + $confidenceScores = []; + + foreach ($predictions as $idx => $pred) { + $rank = $idx + 1; + $num = $pred['num']; + $score = $pred['score']; + + // 1. 基于历史排名命中率 + $rankHitRate = $this->_getHistoricalHitRateByRank($rank, $backtest); + + // 2. 基于得分分布 + $scoreConfidence = $this->_getScoreDistributionConfidence($score, $scoresAll); + + // 3. 基于多维度一致性 + $consistencyConfidence = $this->_getDimensionConsistency($pred['detail']); + + // 综合置信度(加权平均) + $overallConfidence = $rankHitRate * 0.4 + $scoreConfidence * 0.3 + $consistencyConfidence * 0.3; + + $confidenceScores[] = [ + 'num' => $num, + 'rank' => $rank, + 'confidence' => round($overallConfidence * 100, 1), + 'rank_hit_rate' => round($rankHitRate * 100, 1), + 'score_confidence' => round($scoreConfidence * 100, 1), + 'consistency' => round($consistencyConfidence * 100, 1) + ]; + } + + // 整体置信度(Top5平均) + $overallConfidence = array_sum(array_column($confidenceScores, 'confidence')) / count($confidenceScores); + + return [ + 'confidence_scores' => $confidenceScores, + 'overall_confidence' => round($overallConfidence, 1) + ]; +} + +/** + * 基于历史排名获取命中率 + */ +private function _getHistoricalHitRateByRank($rank, $backtest) +{ + if (!$backtest || empty($backtest['details'])) { + // 无回测数据时,根据排名估算(排名越靠前置信度越高) + return max(0, 1 - ($rank - 1) * 0.15); + } + + // 统计各排名的历史命中次数 + $rankHits = array_fill(1, 5, 0); + foreach ($backtest['details'] as $detail) { + if ($detail['hit'] && $detail['rank'] >= 1 && $detail['rank'] <= 5) { + $rankHits[$detail['rank']]++; + } + } + + $totalTests = $backtest['total_tests']; + return $totalTests > 0 ? $rankHits[$rank] / $totalTests : 0; +} + +/** + * 计算多维度一致性 + */ +private function _getDimensionConsistency($detail) +{ + // 检查各维度得分是否都为正向(高于阈值) + $positiveDimensions = 0; + $totalDimensions = 0; + + $thresholds = [ + 'omit_score' => 30, + 'freq_score' => 20, + 'trans_score' => 15, + 'oddeven_score' => 20, + 'bigsmall_score' => 20, + 'trend_score' => 20, + 'zone_score' => 15, + 'color_score' => 15, + 'combo_score' => 15 + ]; + + foreach ($thresholds as $key => $threshold) { + if (isset($detail[$key])) { + $totalDimensions++; + if ($detail[$key] >= $threshold) { + $positiveDimensions++; + } + } + } + + return $totalDimensions > 0 ? $positiveDimensions / $totalDimensions : 0; +} +``` + +**前端展示建议:** + +```javascript +// 在预测结果中添加置信度标签 +var confidenceHtml = ''; +for (var i = 0; i < confidenceScores.length; i++) { + var cs = confidenceScores[i]; + var confLevel = cs.confidence >= 70 ? '高' : (cs.confidence >= 50 ? '中' : '低'); + var confColor = cs.confidence >= 70 ? '#4caf50' : (cs.confidence >= 50 ? '#ff9800' : '#f44336'); + confidenceHtml += '置信度:' + confLevel + '(' + cs.confidence + '%)'; +} +``` + +**置信度:** HIGH [ASSUMED] - 置信度评估对用户决策有明显辅助价值,实现方案基于成熟的统计方法 + +--- + +### 方向5: 回测指标扩展 + +**目标:** 丰富回测评估指标,全面衡量算法预测质量 + +**推荐新增指标:** + +| 指标 | 说明 | 计算公式 | 实现复杂度 | +|------|------|----------|------------| +| **NDCG@K** | 考虑排名位置的加权命中指标,排名越靠前权重越高 | DCG/IDCG | 中 | +| **MRR** | 平均倒数排名,关注命中号码的具体排名位置 | Σ(1/rank)/N | 低 | +| **MAP@K** | 平均精度均值,综合衡量所有排名的精度 | Σ(Precision@k)/K | 低 | +| **命中率分布** | 各排名位置的命中次数分布统计 | {rank1_hits, rank2_hits...} | 低 | +| **时间段命中率** | 按时间段分组统计命中率,发现算法在不同条件下的表现差异 | 分组命中率统计 | 中 | + +**NDCG@K 实现:** + +```php +/** + * 计算NDCG@K指标 + * @param array $backtestDetails 回测详情 + * @param int $K Top-K参数 + * @return float NDCG值(0-1) + */ +private function _calculateNDCG($backtestDetails, $K = 5) +{ + $dcg = 0; + $idcg = 0; + + foreach ($backtestDetails as $detail) { + if ($detail['hit']) { + $rank = $detail['rank']; + if ($rank <= $K) { + // DCG: rel / log2(rank + 1),命中时rel=1 + $dcg += 1 / log2($rank + 1); + } + } + } + + // IDCG: 最理想情况下所有命中的DCG(假设都排在第1位) + $hitCount = count(array_filter($backtestDetails, function($d) { return $d['hit']; })); + for ($i = 1; $i <= min($hitCount, $K); $i++) { + $idcg += 1 / log2($i + 1); + } + + return $idcg > 0 ? round($dcg / $idcg, 4) : 0; +} + +/** + * 计算MRR (Mean Reciprocal Rank) + * @param array $backtestDetails 回测详情 + * @return float MRR值 + */ +private function _calculateMRR($backtestDetails) +{ + $reciprocalRanks = []; + + foreach ($backtestDetails as $detail) { + if ($detail['hit']) { + $reciprocalRanks[] = 1 / $detail['rank']; + } else { + $reciprocalRanks[] = 0; // 未命中记为0 + } + } + + return count($reciprocalRanks) > 0 + ? round(array_sum($reciprocalRanks) / count($reciprocalRanks), 4) + : 0; +} + +/** + * 计算命中率分布 + * @param array $backtestDetails 回测详情 + * @return array 各排名命中次数 + */ +private function _calculateHitDistribution($backtestDetails) +{ + $distribution = array_fill(1, 5, 0); + + foreach ($backtestDetails as $detail) { + if ($detail['hit'] && $detail['rank'] >= 1 && $detail['rank'] <= 5) { + $distribution[$detail['rank']]++; + } + } + + return $distribution; +} +``` + +**回测结果结构扩展:** + +```php +// 在 _runBacktestV3 返回中添加新指标 +return [ + 'hit_rate' => $hitRate, + 'avg_rank' => $avgRank, + 'total_tests' => $testCount, + 'total_hits' => $hits, + 'details' => $details, + // 新增指标 + 'ndcg_5' => $this->_calculateNDCG($details, 5), + 'mrr' => $this->_calculateMRR($details), + 'hit_distribution' => $this->_calculateHitDistribution($details), + 'precision_5' => round($hits / ($testCount * 5) * 100, 2) // Precision@5 +]; +``` + +**置信度:** HIGH [CITED: 推荐系统评估指标最佳实践] - NDCG、MRR、MAP是成熟的排名质量评估指标 + +--- + +### 方向6: 组合特征挖掘 + +**目标:** 发现更复杂的号码组合规律,提升组合特征维度的预测能力 + +**推荐挖掘方法:** + +| 方法 | 技术细节 | 实现复杂度 | 适用场景 | +|------|----------|------------|----------| +| **关联规则挖掘(Apriori)** | 发现号码组合的频繁共现模式,如"号码A出现时号码B也出现" | 中 | 双号码组合发现 | +| **序列模式挖掘** | 发现连续N期的号码序列模式,如"连续3期单号后下期双号概率高" | 中 | 跨期规律发现 | +| **条件概率网络** | 构建号码属性的条件概率图,分析多属性联合影响 | 高 | 复杂条件依赖 | +| **多号码组合共现** | 统计3个以上号码的联合出现频率,发现"热门组合" | 中 | 组合投注建议 | + +**关联规则挖掘实现思路:** + +```php +/** + * Apriori关联规则挖掘 + * @param array $history 历史数据(降序) + * @param float $minSupport 最小支持度阈值 + * @param float $minConfidence 最小置信度阈值 + * @return array 规则列表 [{antecedent: [], consequent: [], support: float, confidence: float}] + */ +private function _mineAssociationRules($history, $minSupport = 0.05, $minConfidence = 0.3) +{ + // 简化实现:仅挖掘2项集规则(号码A -> 号码B) + // 完整Apriori需实现k项集迭代生成 + + $pairCounts = []; + $singleCounts = array_fill(1, 49, 0); + $totalPeriods = count($history); + + // 统计单号码和号码对出现次数 + foreach ($history as $row) { + $nums = $this->_extractAllNumbers($row); // 提取本期所有7个号码 + foreach ($nums as $num) { + if ($num >= 1 && $num <= 49) { + $singleCounts[$num]++; + } + } + + // 统计号码对(在同一期内共现) + for ($i = 0; $i < count($nums); $i++) { + for ($j = $i + 1; $j < count($nums); $j++) { + if ($nums[$i] >= 1 && $nums[$i] <= 49 && $nums[$j] >= 1 && $nums[$j] <= 49) { + $pairKey = min($nums[$i], $nums[$j]) . '-' . max($nums[$i], $nums[$j]); + $pairCounts[$pairKey] = ($pairCounts[$pairKey] ?? 0) + 1; + } + } + } + } + + // 生成规则 + $rules = []; + foreach ($pairCounts as $pairKey => $pairCount) { + $support = $pairCount / $totalPeriods; + if ($support < $minSupport) continue; + + $nums = explode('-', $pairKey); + $numA = (int)$nums[0]; + $numB = (int)$nums[1]; + + // 规则: numA -> numB + $confidenceAB = $pairCount / $singleCounts[$numA]; + if ($confidenceAB >= $minConfidence) { + $rules[] = [ + 'antecedent' => [$numA], + 'consequent' => [$numB], + 'support' => round($support, 4), + 'confidence' => round($confidenceAB, 4) + ]; + } + + // 规则: numB -> numA + $confidenceBA = $pairCount / $singleCounts[$numB]; + if ($confidenceBA >= $minConfidence) { + $rules[] = [ + 'antecedent' => [$numB], + 'consequent' => [$numA], + 'support' => round($support, 4), + 'confidence' => round($confidenceBA, 4) + ]; + } + } + + // 按置信度排序 + usort($rules, function($a, $b) { + return $b['confidence'] - $a['confidence']; + }); + + return $rules; +} +``` + +**序列模式挖掘实现思路:** + +```php +/** + * 序列模式挖掘(连续N期特征模式) + * @param array $history 历史数据(降序) + * @param int $windowLength 序列窗口长度 + * @return array 序列模式列表 + */ +private function _mineSequencePatterns($history, $windowLength = 3) +{ + $historyAsc = array_reverse($history); + $patterns = []; + + // 构建特征序列 + $featureSequence = []; + foreach ($historyAsc as $row) { + $num = (int)$row['num7']; + $featureSequence[] = [ + 'odd' => $num % 2 === 1, + 'big' => $num >= 25, + 'zone' => $this->_getZoneIdx($num) + ]; + } + + // 统计窗口模式 + $windowCounts = []; + for ($i = 0; $i < count($featureSequence) - $windowLength; $i++) { + $windowKey = ''; + for ($j = 0; $j < $windowLength; $j++) { + $f = $featureSequence[$i + $j]; + $windowKey .= ($f['odd'] ? 'O' : 'E') . ($f['big'] ? 'B' : 'S'); + } + + $nextFeature = $featureSequence[$i + $windowLength]; + $nextKey = ($nextFeature['odd'] ? 'O' : 'E') . ($nextFeature['big'] ? 'B' : 'S'); + + $fullPattern = $windowKey . '->' . $nextKey; + $windowCounts[$fullPattern] = ($windowCounts[$fullPattern] ?? 0) + 1; + } + + // 计算概率并返回高置信度模式 + $totalPatterns = array_sum($windowCounts); + foreach ($windowCounts as $pattern => $count) { + $probability = $count / $totalPatterns; + if ($probability >= 0.1) { // 只返回概率>=10%的模式 + $patterns[] = [ + 'pattern' => $pattern, + 'count' => $count, + 'probability' => round($probability, 4) + ]; + } + } + + usort($patterns, function($a, $b) { + return $b['probability'] - $a['probability']; + }); + + return $patterns; +} +``` + +**注意事项:** +- 关联规则挖掘需要大量历史数据支撑(建议500期以上) +- 支持度和置信度阈值需根据数据量调整 +- 挖掘结果需定期更新,避免过拟合特定时间段 +- 可将挖掘结果缓存到文件或数据库,避免每次预测重复计算 + +**置信度:** MEDIUM [ASSUMED] - 关联规则挖掘是成熟的数据挖掘方法,但在彩票预测场景效果需验证 + +--- + +## Implementation Considerations + +### 优先级排序 + +| 优先级 | 优化方向 | 理由 | +|--------|----------|------| +| P0 (高) | 置信度评估 | 用户决策辅助价值高,实现难度适中 | +| P0 (高) | 回测指标扩展 | 评估能力提升直接可见,实现难度低 | +| P1 (中) | 权重训练 | 提升算法准确性,需数据支撑 | +| P1 (中) | 转移概率增强 | 核心维度优化,预期收益较高 | +| P2 (低) | 组合特征挖掘 | 需大量数据,计算成本高 | +| P2 (低) | 数据维度扩展 | 需验证新维度有效性 | + +### 实现风险 + +| 风险 | 影响 | 缓解措施 | +|------|------|----------| +| 过拟合历史数据 | 新数据表现下降 | 分时间段回测验证,权重定期重新优化 | +| 计算性能下降 | 预测响应变慢 | 预计算缓存、异步更新、降级策略 | +| 新维度效果不明显 | 权重稀释,整体命中率下降 | AB测试验证,无效维度移除 | +| 数据量不足 | 统计不可靠,置信度低 | 设置数据阈值,不足时提示用户 | + +### 性能优化建议 + +1. **预计算缓存:** 将转移矩阵、组合特征统计等预计算结果缓存到文件或Redis +2. **批量计算:** 权重优化等耗时计算异步执行,结果存储供前端加载 +3. **降级策略:** 数据不足时回退简化算法,避免不可靠预测 +4. **增量更新:** 新开奖数据到达时增量更新统计,避免全量重算 + +### 数据需求 + +| 优化方向 | 最小数据量 | 推荐数据量 | +|----------|------------|------------| +| 基础预测 | 30期 | 200期 | +| 二阶马尔可夫 | 100期 | 500期 | +| 权重优化 | 200期 | 500期 | +| 关联规则挖掘 | 300期 | 500期+ | +| 置信度统计 | 50期回测 | 100期回测 | + +--- + +## Validation Architecture + +### Test Framework + +| Property | Value | +|----------|-------| +| Framework | PHPUnit (ThinkPHP内置) | +| Config file | 无独立配置,通过 `php think unit` 运行 | +| Quick run command | `php think unit --filter HistoryTest` | +| Full suite command | `php think unit` | + +### Phase Requirements → Test Map + +| Req ID | Behavior | Test Type | Automated Command | File Exists? | +|--------|----------|-----------|-------------------|-------------| +| PRED-01 | 置信度计算准确性 | unit | `php think unit --filter testConfidenceCalculation` | ❌ Wave 0 | +| PRED-02 | NDCG计算准确性 | unit | `php think unit --filter testNDCGCalculation` | ❌ Wave 0 | +| PRED-03 | 二阶马尔可夫转移矩阵构建 | unit | `php think unit --filter testTransitionMatrix2ndOrder` | ❌ Wave 0 | +| PRED-04 | 权重优化收敛性 | unit | `php think unit --filter testWeightOptimization` | ❌ Wave 0 | +| PRED-05 | 回测结果完整性 | unit | `php think unit --filter testBacktestV3Extended` | ❌ Wave 0 | + +### Sampling Rate + +- **Per task commit:** 快速单元测试覆盖核心方法 +- **Per wave merge:** 回测验证使用真实历史数据 +- **Phase gate:** 全量回测(100期)验证整体命中率提升 + +### Wave 0 Gaps + +- [ ] `tests/HistoryTest.php` — 核心预测方法单元测试 +- [ ] `tests/ConfidenceTest.php` — 置信度计算测试 +- [ ] `tests/BacktestMetricsTest.php` — NDCG、MRR等指标计算测试 +- [ ] 共享fixtures: 历史数据模拟生成器 + +--- + +## Security Domain + +> 本阶段为算法优化,无用户输入处理、认证、数据持久化等安全敏感操作,security_enforcement 可设为 false。 + +### Applicable ASVS Categories + +| ASVS Category | Applies | Standard Control | +|---------------|---------|-----------------| +| V2 Authentication | no | — | +| V3 Session Management | no | — | +| V4 Access Control | no | — | +| V5 Input Validation | no | — (权重参数由前端传入,需范围验证) | +| V6 Cryptography | no | — | + +**权重参数验证建议:** + +```php +// 在 getPredictionV3 中添加权重范围验证 +foreach ($weights as $key => $value) { + if ($value < 0 || $value > 1) { + return ['predictions' => [], 'error' => '权重值必须在0-1之间']; + } +} +``` + +--- + +## Sources + +### Primary (HIGH confidence) +- 现有代码分析: `application/admin/model/History.php` — getPredictionV3 及相关方法 [VERIFIED] +- 现有代码分析: `public/assets/js/backend/history.js` — showPredictDialog 及渲染逻辑 [VERIFIED] + +### Secondary (MEDIUM confidence) +- 推荐系统评估指标: Hit Rate, NDCG, MRR, MAP [CITED: WebSearch Brave Search 结果] +- 参数优化方法: Grid Search, Genetic Algorithm [ASSUMED: 训练知识] + +### Tertiary (LOW confidence) +- 马尔可夫链增强效果 [ASSUMED: 理论推导,需回测验证] +- 关联规则挖掘在彩票预测场景的效果 [ASSUMED: 需实际数据验证] +- 时间周期性特征有效性 [ASSUMED: 需历史数据分析验证] + +--- + +## Assumptions Log + +| # | Claim | Section | Risk if Wrong | +|---|-------|---------|---------------| +| A1 | 二阶马尔可夫链能提升转移概率预测准确性 | 方向2 | 预期收益下降,计算成本增加 | +| A2 | 网格搜索权重优化能提升命中率 | 方向3 | 优化无效或过拟合,需其他方法 | +| A3 | 置信度评估对用户决策有明显辅助价值 | 方向4 | 用户可能不理解置信度含义 | +| A4 | 时间周期性特征对号码分布有影响 | 方向1 | 新维度无效,权重稀释 | +| A5 | 关联规则挖掘能发现有效号码组合规律 | 方向6 | 挖掘结果不可靠,计算成本高 | + +--- + +## Open Questions + +1. **历史数据量是否足够支撑高级优化?** + - 当前默认200期统计,二阶马尔可夫和关联规则挖掘建议500期+ + - 需检查数据库中实际可用的历史期数 + - 推荐: 查询 `SELECT COUNT(*) FROM fa_history` 确认数据量 + +2. **权重优化结果如何持久化?** + - 选项A: 存储到 `application/extra/predict.php` 配置文件 + - 选项B: 存储到数据库配置表 + - 选项C: 每次预测时动态计算(性能成本高) + +3. **置信度阈值如何定义?** + - 当前假设: >=70%为高,50-70%为中,<50%为低 + - 需根据实际回测数据调整阈值 + +4. **前端如何展示新增的回测指标(NDCG、MRR)?** + - 需设计用户友好的展示方式 + - 可考虑简化为"预测质量评分"单一指标 + +--- + +## Metadata + +**Confidence breakdown:** +- 现有代码分析: HIGH — 直接阅读代码确认 +- 回测指标扩展: HIGH — 基于成熟的推荐系统评估指标 +- 置信度评估: MEDIUM — 实现方案可行,效果需验证 +- 转移概率增强: MEDIUM — 理论可行,需回测验证效果 +- 权重训练: MEDIUM — 方法成熟,但需足够数据支撑 +- 组合特征挖掘: LOW — 需大量数据和验证 +- 数据维度扩展: LOW — 新维度有效性不确定 + +**Research date:** 2026-05-01 +**Valid until:** 30 days (算法优化方向相对稳定,但具体参数需定期验证) \ No newline at end of file