--- phase: 11-predictv3 plan: 04 type: execute wave: 1 depends_on: [] files_modified: - application/admin/model/History.php - application/admin/controller/History.php autonomous: true requirements: - PRED-04 must_haves: truths: - "用户可以通过接口获取最优权重配置" - "系统返回基于历史回测的权重优化结果" - "优化结果包含各权重配置的命中率、NDCG评估" - "网格搜索有超时保护机制" artifacts: - path: "application/admin/model/History.php" provides: "权重网格搜索优化方法" contains: "_optimizeWeightsGridSearch" - path: "application/admin/controller/History.php" provides: "权重优化接口入口" contains: "optimizeWeights" key_links: - from: "optimizeWeights controller" to: "_optimizeWeightsGridSearch model" via: "method call" --- # Phase 11 - Plan 04: 权重网格搜索优化 ## Objective 实现权重网格搜索优化功能,通过预定义权重组合批量回测,找出最优权重配置,提升算法预测准确性。 **Purpose:** 当前权重为手动配置,缺乏数据驱动优化。网格搜索是一种成熟的参数优化方法,能基于历史回测数据找到更优权重组合。 **Output:** `History.php` 新增 `_optimizeWeightsGridSearch` 方法,`History.php` controller 新增 `optimizeWeights` 接口入口。 ## Tasks ### Task 1: 实现权重网格搜索方法(含5种具体配置和超时保护) - D:\code\php\amlhc\application\admin\model\History.php (line 2094-2113, 默认权重配置) - D:\code\php\amlhc\application\admin\model\History.php (line 3495-3556, _runBacktestV3 方法) 在 `History.php` 类末尾新增权重网格搜索优化方法: ```php /** * 权重网格搜索优化 * * 优化目标定义: * - 综合评估得分 = hit_rate * 0.6 + ndcg_5 * 100 * 0.4 * - 命中率权重60%,NDCG权重40% * - 返回综合得分最高的权重配置 * * 5种预定义权重配置: * - 配置1: 遗漏优先型 - omit_regression权重最高(0.25) * - 配置2: 转移概率优先型 - transition_prob权重最高(0.25) * - 配置3: 走势方向优先型 - trend_direction权重最高(0.25) * - 配置4: 平衡型 - 各维度权重较均衡 * - 配置5: 组合特征优先型 - combination权重最高(0.20) * * @param int $periods 统计期数,范围50-500 * @param int $backtestCount 回测期数,范围10-100 * @param int $timeoutSeconds 超时限制秒数,默认60秒 * @return array {best_weights: [], best_hit_rate: float, best_ndcg: float, all_results: [], timed_out: bool} */ private function _optimizeWeightsGridSearch($periods = 200, $backtestCount = 50, $timeoutSeconds = 60) { // 超时保护:记录开始时间 $startTime = microtime(true); $timedOut = false; // 5种预定义权重配置(具体权重值明确) $weightConfigs = [ // 配置1: 遗漏优先型 - 遗漏回归权重最高 [ 'omit_regression' => 0.25, // 遗漏回归权重25% 'freq_regression' => 0.12, // 频率回归权重12% 'transition_prob' => 0.15, // 转移概率权重15% 'trend_direction' => 0.12, // 走势方向权重12% 'oddeven_balance' => 0.08, // 单双平衡权重8% 'bigsmall_balance' => 0.08, // 大小平衡权重8% 'zone_balance' => 0.05, // 区域平衡权重5% 'color_balance' => 0.05, // 波色平衡权重5% 'combination' => 0.10 // 组合特征权重10% ], // 配置2: 转移概率优先型 - 转移概率权重最高 [ 'omit_regression' => 0.15, 'freq_regression' => 0.10, 'transition_prob' => 0.25, // 转移概率权重25%(最高) 'trend_direction' => 0.12, 'oddeven_balance' => 0.08, 'bigsmall_balance' => 0.08, 'zone_balance' => 0.04, 'color_balance' => 0.04, 'combination' => 0.14 ], // 配置3: 走势方向优先型 - 走势方向权重最高 [ 'omit_regression' => 0.12, 'freq_regression' => 0.10, 'transition_prob' => 0.15, 'trend_direction' => 0.25, // 走势方向权重25%(最高) 'oddeven_balance' => 0.08, 'bigsmall_balance' => 0.08, 'zone_balance' => 0.04, 'color_balance' => 0.04, 'combination' => 0.12 ], // 配置4: 平衡型(默认配置)- 各维度权重较均衡 [ 'omit_regression' => 0.18, 'freq_regression' => 0.12, 'transition_prob' => 0.18, 'trend_direction' => 0.14, 'oddeven_balance' => 0.08, 'bigsmall_balance' => 0.08, 'zone_balance' => 0.04, 'color_balance' => 0.04, 'combination' => 0.10 ], // 配置5: 组合特征优先型 - 组合特征权重最高 [ 'omit_regression' => 0.15, 'freq_regression' => 0.10, 'transition_prob' => 0.15, 'trend_direction' => 0.12, 'oddeven_balance' => 0.06, 'bigsmall_balance' => 0.06, 'zone_balance' => 0.03, 'color_balance' => 0.03, 'combination' => 0.20 // 组合特征权重20%(最高) ] ]; $bestWeights = []; $bestHitRate = 0; $bestNdcg = 0; $bestCombinedScore = 0; $allResults = []; // 执行每种配置的回测(添加超时检查) foreach ($weightConfigs as $configIdx => $weights) { // 超时检查:超过限制时间则停止 $elapsedTime = microtime(true) - $startTime; if ($elapsedTime > $timeoutSeconds) { $timedOut = true; break; } // 执行回测 $backtest = $this->_runBacktestV3($periods, $weights, $backtestCount); $hitRate = $backtest['hit_rate'] ?? 0; $ndcg = $backtest['ndcg_5'] ?? 0; $avgRank = $backtest['avg_rank'] ?? 0; $mrr = $backtest['mrr'] ?? 0; // 综合评估得分:命中率60% + NDCG40% $combinedScore = $hitRate * 0.6 + $ndcg * 100 * 0.4; $result = [ 'config_name' => $configIdx + 1, 'config_type' => ['遗漏优先型', '转移概率优先型', '走势方向优先型', '平衡型', '组合特征优先型'][$configIdx], 'weights' => $weights, 'hit_rate' => $hitRate, 'avg_rank' => $avgRank, 'ndcg_5' => $ndcg, 'mrr' => $mrr, 'combined_score' => round($combinedScore, 2), 'total_hits' => $backtest['total_hits'] ?? 0 ]; $allResults[] = $result; // 更新最优配置 if ($combinedScore > $bestCombinedScore) { $bestCombinedScore = $combinedScore; $bestHitRate = $hitRate; $bestNdcg = $ndcg; $bestWeights = $weights; } } // 按综合得分降序排序结果 usort($allResults, function($a, $b) { return $b['combined_score'] - $a['combined_score']; }); return [ 'best_weights' => $bestWeights, 'best_hit_rate' => $bestHitRate, 'best_ndcg' => $bestNdcg, 'best_combined_score' => round($bestCombinedScore, 2), 'all_results' => $allResults, 'periods' => $periods, 'backtest_count' => $backtestCount, 'timeout_seconds' => $timeoutSeconds, 'timed_out' => $timedOut, 'elapsed_time' => round(microtime(true) - $startTime, 2) ]; } ``` 实现要点: - **5种具体权重配置**:每种配置的权重值在代码中明确列出 - **优化目标明确**:综合得分 = hit_rate*0.6 + ndcg_5*100*0.4 - **超时保护**:添加 $timeoutSeconds 参数,默认60秒,超时后停止剩余配置测试 - **配置类型命名**:遗漏优先型、转移概率优先型、走势方向优先型、平衡型、组合特征优先型 - 返回 timed_out 标志和 elapsed_time 供前端判断 - grep 正则匹配: `_optimizeWeightsGridSearch\s*\(` 在 History.php 中存在 - grep 匹配: `$weightConfigs` 数组包含5个配置项 - grep 匹配: `$timeoutSeconds` 参数在方法签名中存在 - grep 匹配: `$timedOut` 变量在方法中存在 - grep 匹配: `combined_score` 在返回结果中存在 - grep 匹配: `config_type` 在结果中存在 - 方法调用 `_runBacktestV3` 进行回测 - 方法包含函数级注释说明优化目标和配置类型 ### Task 2: 新增权重优化接口入口(含参数验证和超时警告) - D:\code\php\amlhc\application\admin\controller\History.php (line 25, noNeedRight 数组) - D:\code\php\amlhc\application\admin\controller\History.php (line 460-489, predictV3 方法) 在 `History.php` controller 中: 1. 将 `optimizeWeights` 添加到 `noNeedRight` 数组(约 line 25): 找到: ```php protected $noNeedRight = ['missingNum', 'trendData', ..., 'predictV3']; ``` 在 `predictV3` 后添加 `'optimizeWeights'`: ```php protected $noNeedRight = ['missingNum', 'trendData', ..., 'predictV3', 'optimizeWeights']; ``` 2. 在 `predictV3` 方法后(约 line 489 之后)新增 `optimizeWeights` 方法: ```php /** * 权重网格搜索优化接口 * 执行多权重配置回测,返回最优权重组合 * * 参数说明: * - periods: 统计期数,范围50-500,默认200 * - backtest: 回测期数,范围10-100,默认30 * - timeout: 超时秒数,范围10-120,默认60 * * 返回说明: * - best_weights: 最优权重配置 * - best_hit_rate: 最优配置命中率 * - all_results: 所有配置测试结果 * - timed_out: 是否超时中断 */ public function optimizeWeights() { if ($this->request->isAjax()) { // 参数验证 $periods = $this->request->get('periods', 200, 'intval'); if ($periods < 50 || $periods > 500) { $this->error('期数范围必须在 50-500 之间'); } $backtestCount = $this->request->get('backtest', 30, 'intval'); if ($backtestCount < 10 || $backtestCount > 100) { $backtestCount = 30; // 使用默认值而非报错 } $timeoutSeconds = $this->request->get('timeout', 60, 'intval'); if ($timeoutSeconds < 10 || $timeoutSeconds > 120) { $timeoutSeconds = 60; // 使用默认值 } // 执行优化 $result = $this->model->_optimizeWeightsGridSearch($periods, $backtestCount, $timeoutSeconds); // 超时警告提示 $message = '优化完成'; if ($result['timed_out']) { $message = '优化超时中断,已完成' . count($result['all_results']) . '种配置测试'; } $this->success($message, null, $result); } } ``` 实现要点: - 接口参数:periods(统计期数)、backtest(回测期数)、timeout(超时秒数) - 参数范围验证,超出范围时使用默认值或报错 - 返回最优权重配置及所有测试结果 - 超时时返回警告消息和已完成的测试数量 - 需添加到 noNeedRight 允许无权限访问 - grep 匹配: `optimizeWeights` 在 noNeedRight 数组中存在 - grep 正则匹配: `public function optimizeWeights\s*\(` 在 controller 中存在 - grep 匹配: `$timeoutSeconds` 在方法中存在 - grep 匹配: `$result['timed_out']` 在方法中存在 - 方法调用 `$this->model->_optimizeWeightsGridSearch` - 方法包含函数级注释 ## Verification 执行权重优化接口验证返回结果: ```bash curl -s "http://127.0.0.1:8000/admin/history/optimizeWeights?periods=200&backtest=20&timeout=60" | grep -E "best_weights|best_hit_rate|best_ndcg|all_results|timed_out|config_type" ``` 预期结果:返回 JSON 中包含 best_weights、best_hit_rate、best_ndcg、all_results、timed_out、config_type 字段。 ## Success Criteria 1. `_optimizeWeightsGridSearch` 方法已实现,包含 5 种预定义权重配置(权重值明确) 2. 优化目标明确:综合得分 = hit_rate*0.6 + ndcg_5*100*0.4 3. 超时保护机制已添加,默认60秒 4. `optimizeWeights` controller 接口已实现,含参数验证 5. 接口能正常返回最优权重配置及测试结果 6. 超时时返回警告消息 7. 所有新增方法包含函数级注释 ## Output 完成后创建 `.planning/phases/11-predictv3/11-04-SUMMARY.md`