8b2590c5b5
- 完成Phase 11: predictV3算法优化研究文档,涵盖6个优化方向的技术分析 - 实现置信度评估功能,提供历史命中率、得分分布、多维度一致性置信度指标 - 扩展回测指标体系,新增NDCG@K、MRR、命中率分布等排名质量评估指标 - 优化转移概率算法,引入二阶马尔可夫链和多属性联合转移增强预测准确性 - 设计权重训练机制,支持网格搜索和遗传算法进行数据驱动的参数优化 - 集成组合特征挖掘功能,采用关联规则和序列模式发现号码间潜在关联 - 实现完整的前端交互界面,支持预测结果显示、置信度展示和回测验证功能 - 建立性能优化策略,包括预计算缓存、批量计算和降级策略保障响应速度
346 lines
12 KiB
Markdown
346 lines
12 KiB
Markdown
---
|
||
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种具体配置和超时保护)
|
||
|
||
<read_first>
|
||
- 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 方法)
|
||
</read_first>
|
||
|
||
<action>
|
||
在 `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 供前端判断
|
||
</action>
|
||
|
||
<acceptance_criteria>
|
||
- grep 正则匹配: `_optimizeWeightsGridSearch\s*\(` 在 History.php 中存在
|
||
- grep 匹配: `$weightConfigs` 数组包含5个配置项
|
||
- grep 匹配: `$timeoutSeconds` 参数在方法签名中存在
|
||
- grep 匹配: `$timedOut` 变量在方法中存在
|
||
- grep 匹配: `combined_score` 在返回结果中存在
|
||
- grep 匹配: `config_type` 在结果中存在
|
||
- 方法调用 `_runBacktestV3` 进行回测
|
||
- 方法包含函数级注释说明优化目标和配置类型
|
||
</acceptance_criteria>
|
||
|
||
### Task 2: 新增权重优化接口入口(含参数验证和超时警告)
|
||
|
||
<read_first>
|
||
- 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 方法)
|
||
</read_first>
|
||
|
||
<action>
|
||
在 `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 允许无权限访问
|
||
</action>
|
||
|
||
<acceptance_criteria>
|
||
- grep 匹配: `optimizeWeights` 在 noNeedRight 数组中存在
|
||
- grep 正则匹配: `public function optimizeWeights\s*\(` 在 controller 中存在
|
||
- grep 匹配: `$timeoutSeconds` 在方法中存在
|
||
- grep 匹配: `$result['timed_out']` 在方法中存在
|
||
- 方法调用 `$this->model->_optimizeWeightsGridSearch`
|
||
- 方法包含函数级注释
|
||
</acceptance_criteria>
|
||
|
||
## 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` |