# 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 (RESOLVED) 1. **历史数据量是否足够支撑高级优化?** - 当前默认200期统计,二阶马尔可夫和关联规则挖掘建议500期+ - 需检查数据库中实际可用的历史期数 - 推荐: 查询 `SELECT COUNT(*) FROM fa_history` 确认数据量 - **Resolution:** 11-05 Task 3 设置100期阈值,数据不足时回退一阶马尔可夫,已在plan中处理 2. **权重优化结果如何持久化?** - 选项A: 存储到 `application/extra/predict.php` 配置文件 - 选项B: 存储到数据库配置表 - 选项C: 每次预测时动态计算(性能成本高) - **Resolution:** 11-04 采用选项C(动态计算)+ 返回结果给前端展示,不持久化。设计决策:避免过拟合特定时间段,每次获取最新优化结果 3. **置信度阈值如何定义?** - 当前假设: >=70%为高,50-70%为中,<50%为低 - 需根据实际回测数据调整阈值 - **Resolution:** 11-02 Task 1 明确阈值定义:>=70%高(绿色)、50-70%中(橙色)、<50%低(红色),前端11-03使用相同映射 4. **前端如何展示新增的回测指标(NDCG、MRR)?** - 需设计用户友好的展示方式 - 可考虑简化为"预测质量评分"单一指标 - **Resolution:** 11-03 Task 2 实现百分比显示 + 柱状图:NDCG@5/MRR以百分比展示,命中分布以柱状图可视化 --- ## Metadata **Confidence breakdown:** - 现有代码分析: HIGH — 直接阅读代码确认 - 回测指标扩展: HIGH — 基于成熟的推荐系统评估指标 - 置信度评估: MEDIUM — 实现方案可行,效果需验证 - 转移概率增强: MEDIUM — 理论可行,需回测验证效果 - 权重训练: MEDIUM — 方法成熟,但需足够数据支撑 - 组合特征挖掘: LOW — 需大量数据和验证 - 数据维度扩展: LOW — 新维度有效性不确定 **Research date:** 2026-05-01 **Valid until:** 30 days (算法优化方向相对稳定,但具体参数需定期验证)