Files
PolyHermes/NBA.md
WrBug e9e1111df9 feat: 实现 NBA 量化交易系统
- 后端实现:
  - 实现 NBA 比赛数据服务,从 Polymarket API 获取数据
  - 实现数据库存储和增量拉取逻辑(优先从 DB 获取,数据不足时增量拉取)
  - 使用 sports_market_types 参数直接筛选 moneyline 类型
  - 实现分页拉取逻辑(基于 gameStartTime 和 createdAt)
  - 移除 nba_markets 相关的外键约束(V12 迁移)
  - 修复数据拉取逻辑:超过 3 天的数据不拉取

- 前端实现:
  - 实现策略创建/编辑/列表页面
  - 实现交易信号展示页面和统计页面
  - 修复重复请求问题(使用 useCallback 包装 fetchGames)
  - 支持选择单场比赛进行配置
  - 使用西8区时间格式化显示

- 数据库:
  - 创建 NBA 量化交易相关表(V11 迁移)
  - 移除外键约束(V12 迁移)

- 文档:
  - 添加产品需求文档、技术方案、算法文档等
2025-12-13 08:05:08 +08:00

43 KiB
Raw Permalink Blame History

NBA 比赛胜负分析框架

一、 赛前预测核心要点

预测比赛结束时的结果。

核心变量 (权重最高)

  1. 核心球星状态: 球队头号球星的近期数据、健康状况、是否有轮休可能。
  • 量化指标:
    • 近期 5 场平均 PER (Player Efficiency Rating)
    • 近期 5 场真实命中率 (TS%) 与赛季平均的差值
    • 近期 5 场使用率 (USG%) 变化
    • 伤病报告状态 (健康/出战成疑/缺席)
    • 轮休概率 (基于赛程密度和历史轮休模式)
  1. 关键阵容完整度: 除球星外,第二当家、重要首发或第六人是否缺席。
  • 量化指标:
    • 缺失球员的 VORP (Value Over Replacement Player)
    • 缺失球员的 BPM (Box Plus/Minus)
    • 阵容完整度评分 = 1 - (缺失球员总VORP / 球队总VORP)
    • 替补深度评分 (基于替补球员的平均 PER)
  1. 球队近期势头: 双方近 5-10 场的战绩,是否处于连胜或连败中。
  • 量化指标:
    • 近 5 场/10 场胜率
    • 连胜/连败场次
    • 近期净效率值变化趋势 (与赛季平均对比)
    • 近期对手平均实力 (SRS - Simple Rating System)

团队实力与风格维度 (基本盘和打法)

攻防效率定位

  1. 进攻效率 (每百回合得分) 联盟排名
  2. 防守效率 (每百回合失分) 联盟排名
  3. 净效率值 (攻防效率差): 真实战力核心指标

比赛风格特征

  1. 节奏: 喜快还是喜慢
  2. 生命线: 球队极度依赖的赢球方式
  3. 关键数据: 篮板 (前场板)、失误控制、内线得分、三分产出与效率

对位与相克关系 (突破口)

  1. 球星对位: 一方是否有球员能在防守端有效限制对方头牌。
  • 量化指标:
    • 历史对位数据: 防守球员对位进攻球员时的限制效果
    • 对位效率差 = (对位时进攻球员TS% - 赛季平均TS%)
    • 对位得分差 = (对位时平均得分 - 赛季平均得分)
    • 防守球员的 DRPM (Defensive Real Plus-Minus)
  1. 阵容克制: 内线强队 VS 外线投射型球队;防守强队 VS 进攻单一球队。
  • 量化指标:
    • 内线得分占比 vs 对手内线防守效率
    • 三分出手占比 vs 对手三分防守效率
    • 快攻得分占比 vs 对手快攻防守效率
    • 风格匹配度评分 (基于历史对战数据)
  1. 风格喜好: 对方是否恰好擅长打击我方的弱点。
  • 量化指标:
    • 对手进攻效率 vs 我方防守效率 (按进攻类型分类)
    • 弱点暴露度 = (对手擅长进攻方式得分占比) × (我方该方式防守效率排名)

赛程与外部因素

  1. 主客场与旅行: 球队是主场以逸待劳,还是历经长途客场之旅的最后一站。
  • 量化指标:
    • 主客场胜率差 (主场胜率 - 客场胜率)
    • 旅行距离 (英里) 和时区变化
    • 连续客场场次
    • 休息天数 (距离上一场比赛的天数)
  1. 背靠背作战: 是否有球队是背靠背第二场?球员体能会受影响。
  • 量化指标:
    • 背靠背第二场历史胜率 (vs 正常比赛胜率)
    • 背靠背第二场平均净效率值变化
    • 体能影响系数 = -0.05 × (背靠背标识)
  1. 赛程难度: 球队近期的对手是强是弱?战绩是否存在"水分"。
  • 量化指标:
    • 近期对手平均 SRS (Simple Rating System)
    • 近期对手平均净效率值
    • 赛程强度排名 (联盟排名)
    • 战绩"水分"系数 = (实际胜率 - 预期胜率) / 预期胜率
  1. 战意与特殊情节: 是否是季后赛卡位关键战、恩怨对决或复仇之战。
  • 量化指标:
    • 季后赛卡位关键度 (基于当前排名和剩余场次)
    • 历史恩怨得分 (基于近期对战记录和冲突事件)
    • 复仇动机 (上次对战是否失利)

其他因素

  • “临场”与“偶然性”: 突发伤病、临场手感、裁判尺度、关键球的偶然性。

批注[§★威★§1]: 该部分内容需要结合球队历史数据及球队详细分析数据,量化到个人。


二、 赛中实时预测:剩余比赛进程走向

核心公式:剩余时间预期净胜分 = f(当前分差, 剩余时间, 球队实力, 比赛状态, 环境因素...)

实时比赛状态

  1. 核心变量: 当前分差、剩余比赛时间 (精确到秒)、当前节次、球权归属。
  2. 关键数据: 分差/剩余时间比 (即“每分钟需要追几分”)、是否有加时。

球队真实能力 (赛季平均值,可动态调整)

  1. 攻防效率: 球队每百回合净胜分。
  2. 比赛节奏: 球队平均每 48 分钟回合数 (用于估算剩余进攻回合数)。
  3. 风格特质:
    1. 三分能力: 擅长三分的球队有短时间内爆发追分的能力。
    2. 造罚球能力: 能稳定造犯规的球队追分方式更稳健。
    3. 关键球表现: 球队在最后 5 分钟、分差 5 分以内的攻防效率。

球员与阵容在场状态 (动态权重)

  1. 球星在场情况: 追分阶段,球队核心是否在场上。
  2. 阵容攻防属性: 当前场上阵容是偏进攻还是偏防守。
  3. 球员体能/犯规: 核心球员的犯规次数、已上场时间。
  4. 手感热度: 可采用滚动窗口统计数据 (近 10 个回合的命中率)。

比赛环境与动量 (心理与局势因子)

  1. 主客场: 主场球队通常有更高的“裁判哨倾向”和气势加成。
  2. 势头: 可量化为过去几个回合的净胜分。
  3. 暂停与挑战: 剩余的暂停次数。

批注[§★威★§2]: 该部分内容需结合历史数据及临场数据,量化到个人。


三、 预测模型构建的三个阶段

阶段一:基线模型 - 基于历史概率的“速查表”

批注[§★威★§3]: 速查表作为当前情况的历史依据,只能作参照。

  1. 数据准备: 收集大量历史比赛数据,切割出每一个 (分差, 剩余时间) 的组合瞬间 (如: 落后 10 分,剩余 5 分钟)。
  2. 概率统计: 统计在所有历史同类瞬间中,最终翻盘获胜的比例,以及最终分差的平均值/分布。
  3. 应用: 查询当前情况所属的历史瞬间组,直接得出历史翻盘概率和平均追回分差。

阶段二:进阶模型 - 基于球队能力调整的预测

批注[§★威★§4]: 结合球队真实数据对预测进行校正。

在基线模型上,引入球队实力因子进行校正。

  1. 计算公式 (简化示例) 预期追回分差 = 基线模型平均追回分差 × (实力系数A / 实力系数B)
  2. 实力系数: 可采用两队赛季平均的百回合净胜分差。实力系数 = 球队净效率值 - 联盟平均值
  3. 应用示例: 假设基线模型显示落后 10 分 (剩余 5 分钟) 平均能追回 6 分。若追分方净效率强于对手 10%,则调整后的预期追回分差 = 6 × 1.1 = 6.6 分。

阶段三:高级模型 - 机器学习动态预测

批注[§★威★§5]: 动态数据实时分析更新预测。

  1. 模型选择: 适合的算法包括梯度提升决策树 (XGBoost, LightGBM) 或随机森林。
  2. 特征工程: 综合上述所有变量,构建数百个特征。
  • 时间特征 (5-10 个):
    • 剩余时间 (秒、分钟)
    • 当前节次 (1-4, 加时)
    • 是否加时
    • 剩余暂停次数 (主队、客队)
    • 是否最后 5 分钟
    • 是否最后 2 分钟
    • 是否最后 1 分钟
  • 分差特征 (10-15 个):
    • 当前分差 (绝对值、带符号)
    • 分差变化率 (过去 N 回合)
    • 最大分差 (本场比赛)
    • 分差/剩余时间比
    • 分差是否在 5 分以内
    • 分差是否在 10 分以内
    • 分差趋势 (扩大/缩小/持平)
  • 球队基础特征 (20-30 个):
    • 球队净效率值 (赛季平均、近期平均)
    • 进攻效率排名
    • 防守效率排名
    • 比赛节奏 (Pace)
    • 三分出手占比
    • 三分命中率
    • 罚球率 (FTA/FGA)
    • 前场篮板率
    • 失误率
    • 关键时刻 (Clutch) 攻防效率
  • 球员在场特征 (30-50 个):
    • 在场球员总 PER
    • 在场球员平均真实命中率
    • 核心球星是否在场 (0/1)
    • 核心球星本场 TS%
    • 核心球星本场使用率
    • 核心球星犯规次数
    • 核心球星已上场时间
    • 阵容 Net Rating (当前阵容)
    • 阵容高度 (平均身高)
    • 阵容经验 (平均年龄或球龄)
  • 实时状态特征 (20-30 个):
    • 过去 5/10/15 回合净胜分
    • 过去 N 回合命中率
    • 过去 N 回合三分命中率
    • 过去 N 回合失误数
    • 势头评分 (基于近期净胜分)
    • 手感热度 (滚动窗口命中率)
  • 环境特征 (10-15 个):
    • 主客场 (0/1)
    • 休息天数
    • 是否背靠背
    • 旅行距离
    • 时区变化
    • 赛程强度 (近期对手平均实力)
  • 历史对位特征 (15-20 个):
    • 本赛季对战记录
    • 历史对战净效率值
    • 对位限制效果 (核心球员对位数据)
    • 风格匹配度
  • 交互特征 (50-100 个):
    • 分差 × 剩余时间
    • 球队实力差 × 剩余时间
    • 势头 × 剩余时间
    • 各种特征之间的乘积和比值
  • 特征总数: 建议 150-300 个特征,通过特征选择筛选出最重要的 50-100 个
  1. 目标变量:
    • 分类任务: 预测本场比赛最终是否翻盘 (是/否)。
    • 回归任务: 预测比赛结束时的最终分差。
    • 最佳实践: 两个任务同时进行,用分类概率评估翻盘可能性,用回归值评估预期追回分数。
  2. 实时预测: 模型在比赛中每隔一个回合 (或每分钟) 重新运行一次,输入最新的实时数据,输出更新的预测概率和分差。

四、 模块化预测框架详解

核心:计算追分方在剩余时间内预期能比对手多得的分数(预期追回分差 E)。

核心公式: 预期追回分差 (E) = (基础追分潜力 × W1 + 实时状态系数 × W2) × 时间调整系数 + 随机波动项

公式说明:

  • 随机波动项 ε 应该在时间调整之后添加,因为随机性影响的是最终的分差结果,而不是追分潜力本身
  • 另一种可选形式: E = [(F-base × W1 + F-live × W2) × f(T)] + ε,其中 ε 在每次蒙特卡洛模拟中独立生成

批注[§★威★§7]: 核心: 在剩余时间内预期追回分差。

第一步:定义与计算输入模块

1. 基础追分潜力 (F-base)

  • 球队实力系数 (S): 使用两队赛季平均的净效率值差。
    • 计算公式: S = (追分方净效率值 - 对手净效率值) / 归一化因子
    • 归一化方法:
      • 方法一 (Z-score): S = (净效率差) / (联盟净效率标准差),通常范围 [-2, 2]
      • 方法二 (Min-Max): S = (净效率差 - 最小差) / (最大差 - 最小差) × 2 - 1,范围 [-1, 1]
      • 方法三 (简单缩放): S = 净效率差 / 10,例如净效率差 3.0 → S = 0.3
    • 示例: 追分方净效率 +5.0,对手 +2.0,净效率差 = 3.0
      • Z-score 法: 假设联盟标准差 = 5.0,则 S = 3.0 / 5.0 = 0.6
      • 简单缩放: S = 3.0 / 10 = 0.3
  • 阵容对位系数 (L): 评估当前在场阵容的优劣势。
    • 计算公式: L = (追分方阵容 Net Rating - 对手阵容 Net Rating) / 归一化因子
    • 归一化方法: 同实力系数 S,使用 Z-score 或 Min-Max 归一化
    • 数据来源:
      • 当前阵容本赛季的 Net Rating (每百回合净胜分)
      • 如果阵容数据不足,使用球队平均 Net Rating × 阵容调整系数
    • 示例: 追分方阵容 Net Rating = +8.0,对手 = +5.0,差值为 3.0
      • 归一化后: L = 3.0 / 10 = 0.3 (使用简单缩放)
  • F-base 小计: F-base = S + L
  • 注意: S 和 L 在相加前必须确保使用相同的归一化方法,且量级相近
  • 推荐做法: 两者都使用 Z-score 归一化,或都使用 Min-Max 归一化到 [-1, 1] 范围
  • 权重调整 (可选): 如果 S 和 L 的重要性不同,可以使用加权和: F-base = α × S + (1-α) × L,其中 α 通常取 0.6-0.7

2. 实时状态系数 (F-live)

  • 势头动量 (M): 计算过去 N 个回合 (如 10 回合) 的净胜分,并归一化。
    • 计算公式: M = (过去N回合净胜分) / (N × 平均单回合得分)
    • 归一化方法:
      • 方法一: M = (净胜分) / (N × 2.0),假设平均单回合得分约 2.0 分
      • 方法二: 使用历史数据统计,计算过去 N 回合净胜分的 Z-score
      • 方法三: M = tanh(净胜分 / (N × 1.5)),使用双曲正切函数将值限制在 [-1, 1]
    • 示例: 过去 10 回合净胜 +8 分
      • 方法一: M = 8 / (10 × 2.0) = 0.4
      • 方法三: M = tanh(8 / 15) = tanh(0.533) ≈ 0.49
    • 动态窗口: N 值可根据比赛阶段调整
      • 比赛早期: N = 15-20 回合
      • 比赛后期: N = 8-10 回合
      • 关键时刻: N = 5-8 回合
  • 球星爆发因子 (P): 核心球星在本场比赛的真实命中率 (TS%) 是否远高于赛季平均值。
    • 计算公式: P = (本场TS% - 赛季平均TS%) / 100
    • 归一化方法:
      • 直接使用百分比差值,范围通常在 [-0.3, 0.3]
      • 使用 tanh 函数限制: P = tanh((TS%差值) / 15)
    • 示例: 本场 TS% = 65%,赛季平均 = 55%,差值为 10 个百分点
      • 直接法: P = 10 / 100 = 0.1
      • tanh 法: P = tanh(10 / 15) = tanh(0.667) ≈ 0.58
    • 多球星情况: 如果有多个核心球星,取加权平均
      • P = Σ(球员P值 × 球员使用率权重)
  • F-live 小计: F-live = M + P

3. 随机波动项 (ε)

  • 符合特定分布 (如均值为 0,方差可调的正态分布) 的随机数,用于模拟无法预测的偶发事件 (争议判罚、意外失误、神奇进球)。每次模拟时随机生成。
  • 分布选择:
    • 正态分布: ε ~ N(0, σ²),其中 σ 为方差
    • t 分布: 适用于尾部更厚的分布 (极端事件更多)
    • 经验分布: 基于历史数据的实际分差波动分布
  • 方差 (σ²) 的确定:
    • 方法一: 基于历史数据统计
      • 收集所有历史比赛在相同 (分差, 剩余时间) 条件下的实际追回分差
      • 计算实际追回分差与模型预测值的残差
      • 残差的标准差即为 σ
    • 方法二: 分阶段设置
      • 比赛早期: σ = 2.0 (不确定性较大)
      • 比赛中期: σ = 1.5
      • 比赛后期: σ = 1.0 (时间越少,随机性影响越小)
      • 关键时刻: σ = 0.8
    • 方法三: 基于分差动态调整
      • 大分差: σ 较大 (追分难度大,波动也大)
      • 小分差: σ 较小 (接近的比赛,随机性影响相对较小)
  • 蒙特卡洛模拟参数:
    • 模拟次数: 建议 10,000 - 100,000 次 (平衡精度和计算时间)
    • 随机种子: 固定种子用于可重复性,或使用时间种子用于随机性
    • 置信区间: 通常使用 90% 或 95% 置信区间

4. 时间调整系数 (f(T))

  • 将潜力转化为具体分数。原理:追分机会与剩余时间并非线性关系。
  • 常用函数形式: f(T) = (T / 48)^k,其中 k 为衰减指数,T 为剩余分钟数。
  • k 值的确定方法:
    1. 历史数据拟合:
      • 收集过去 5 个赛季的所有比赛数据
      • 对每个 (分差, 剩余时间) 组合,统计实际追回分差
      • 使用非线性回归拟合 k 值: 实际追回分差 = a × (T/48)^k + b
      • 分阶段拟合: 第一节 (k₁)、第二节 (k₂)、第三节 (k₃)、第四节 (k₄)、最后 5 分钟 (k₅)
    2. 分阶段 k 值参考 (需根据实际数据调整):
      • 第一节: k ≈ 1.0 (接近线性)
      • 第二节: k ≈ 0.95
      • 第三节: k ≈ 0.90
      • 第四节: k ≈ 0.85
      • 最后 5 分钟: k ≈ 0.80 (时间越少,追分难度非线性增加)
    3. 分差调整:
      • 大分差 (≥15分): k 值可适当降低 (0.75~0.85),因为大分差追分更困难
      • 小分差 (<5分): k 值可适当提高 (0.85~0.95),因为小分差更容易逆转
    4. 动态调整:
      • 根据实时比赛数据,每赛季重新拟合 k 值
      • 考虑不同球队风格对 k 值的影响 (快节奏球队 k 值可能略高)

第二步:权重分配与动态调整

权重 (W1, W2) 不是固定的,应随比赛进程动态变化。

  • 比赛早期 (第一节): W1 (基础潜力) 权重高 (如 0.7)W2 (实时状态) 权重低 (0.3)。样本小,球队基本盘更重要。
  • 比赛后期 (第四节): W2 权重急剧升高 (可达 0.6 以上),W1 降低。当前手感和势头决定一切。
  • 关键时刻 (最后 5 分钟): 可以引入球队关键时刻攻防效率数据来修正 F-base 或直接作为高权重特征。

权重动态调整公式 (推荐):

  • 基于剩余时间:
    • W2 = min(0.3 + (48 - T) / 48 × 0.4, 0.7),其中 T 为剩余分钟数
    • W1 = 1 - W2
  • 基于节次:
    • 第一节: W1 = 0.7, W2 = 0.3
    • 第二节: W1 = 0.6, W2 = 0.4
    • 第三节: W1 = 0.5, W2 = 0.5
    • 第四节: W1 = 0.4, W2 = 0.6
    • 最后 5 分钟: W1 = 0.3, W2 = 0.7
  • 基于分差 (可选调整):
    • 大分差 (≥15分): 适当提高 W1 (基础实力更重要)
    • 小分差 (<5分): 适当提高 W2 (实时状态更重要)

第三步:实施路径与模拟

1. 建立离线模型 (基础版)

  • 用 Excel 或 Python,手动输入关键变量 (S, M, P 等)。
  • 运行公式,得到单次预测的预期追回分差 E。
  • 决策: 如果 E ≥ 当前分差 X,则模型认为“有机会翻盘”。

2. 引入蒙特卡洛模拟 (进阶版)

  • 由于存在随机项 ε,单次计算意义不大。需要进行上万次模拟。
  • 在每次模拟中,为 ε 生成随机数,并运行公式,得到一个 E 值。
  • 模拟流程:
    1. 设置模拟参数:
      • 模拟次数: N = 10,000 (建议最小值) 或 100,000 (高精度)
      • 随机波动项方差: σ (根据比赛阶段和分差确定)
      • 随机种子: 可选,用于可重复性
    2. 循环 N 次:
      • 生成随机数: ε ~ N(0, σ²)
      • 计算: E = (F-base × W1 + F-live × W2) × f(T) + ε
      • 记录 E 值
      • 注意: 随机波动项应在时间调整之后添加,反映最终结果的随机性
    3. 统计分析:
      • 计算 E ≥ X 的次数,翻盘概率 = (E ≥ X 的次数) / N
      • 计算 E 的平均值: E_mean = ΣE / N
      • 计算 E 的标准差: E_std = sqrt(Σ(E - E_mean)² / N)
      • 计算分位数: 5%, 25%, 50%, 75%, 95%
  • 统计结果:
    • 所有模拟结果中 E ≥ X 的比例,即为动态翻盘概率
    • 所有 E 的平均值,即为预期追回分差的期望值
    • E 的标准差,反映预测的不确定性。
    • 90% 置信区间: [E_5%, E_95%],表示有 90% 的概率 E 落在此区间。
    • 分差变化区间预测: [当前分差 - E_95%, 当前分差 - E_5%]

3. 全自动实时模拟 (终极版)

  • 通过 API 实时获取比赛数据 (Play-by-Play)。
  • 自动化计算 M, P 等实时特征。
  • 每 30 秒或每个回合结束后,自动触发一次蒙特卡洛模拟,输出更新的概率和预期分差。

系统架构建议:

  • 数据层:
    • 实时数据获取服务 (API 轮询或 WebSocket)
    • 数据缓存层 (Redis) 存储最近 N 分钟的数据
    • 数据存储层 (PostgreSQL/MongoDB) 存储历史数据
  • 计算层:
    • 特征计算服务 (实时计算 M, P 等特征)
    • 模型预测服务 (加载模型,执行预测)
    • 蒙特卡洛模拟服务 (并行计算,可分布式部署)
  • 服务层:
    • API 网关 (统一接口)
    • 预测结果缓存 (避免重复计算)
    • 结果存储服务 (保存预测历史)
  • 监控层:
    • 系统健康监控 (API 可用性、延迟)
    • 模型性能监控 (预测准确率、置信度)
    • 告警系统 (异常情况通知)

性能优化建议:

  • 并行计算: 蒙特卡洛模拟使用多线程或分布式计算
  • 结果缓存: 相同输入条件的预测结果缓存 10-30 秒
  • 模型优化: 使用模型压缩技术 (量化、剪枝) 减少推理时间
  • 异步处理: 非关键路径使用异步处理,提高响应速度

五、 应用示例

示例 1:比赛最后 3 分钟落后 10 分

假设条件:

模块 参数 假设值 说明
F-base 球队实力系数 (S) 0.4 追分方实力稍强且阵容略占优
F-live 势头动量 (M) -0.1 过去几分钟势头稍差
权重 W1 (基础) 0.4 比赛末期,实时状态权重大
W2 (实时) 0.6
时间 时间调整系数 f(3) ≈ 0.13 f(T) = (3/48)^0.9
随机项 ε 0 (暂定) 首次计算忽略

单次模拟计算(忽略 ε): E = (0.4 * 0.4 + (-0.1) * 0.6) * 0.13 = (0.16 - 0.06) * 0.13 = 0.013

结论: 模型基于当前条件仅预期追回 0.013 分,远低于 10 分的分差,翻盘希望渺茫。

蒙特卡洛模拟补充说明:

  • 假设随机波动项方差 σ = 1.0 (比赛后期)
  • 进行 10,000 次模拟,每次生成 ε ~ N(0, 1.0²)
  • 模拟结果统计:
    • 预期追回分差期望值: E_mean ≈ 0.013 + 0 = 0.013 (随机项均值为 0)
    • 但考虑到随机性,实际 E 值分布: E ~ N(0.013, 1.0²)
    • 翻盘概率: P(E ≥ 10) = P(Z ≥ (10-0.013)/1.0) ≈ P(Z ≥ 9.99) ≈ 0%
    • 如果方差更大 (如 σ = 2.0),则 P(E ≥ 10) ≈ 0.0001% (几乎不可能)
  • 修正: 原结论中提到的 0.5% 翻盘概率和 2.5 分期望值需要更大的随机波动 (σ > 3.0) 才能实现,这在现实中不太合理
  • 更合理的结论: 在 σ = 1.0 的情况下,翻盘概率 < 0.01%,表明需要极端随机事件(如连续多个三分、对手多次失误)才可能翻盘

示例 2:预测第三节最后 5 分钟(落后15分)到节末的追分情况

输入参数表:

模块 参数 假设值 说明
F-base 球队实力系数 (S) 0.15 追分方净效率比对手每百回合多赢1.5分
阵容对位系数 (L) 0.0 双方阵容均衡
F-base 小计 0.15 F-base = S + L
F-live 势头动量 (M) -0.2 落后15分,近期势头在对手一方
球星爆发因子 (P) 0.0 无球星极度反常火热
F-live 小计 -0.2 F-live = M + P
权重与时间 W1 (基础) 0.5 中后期,基本盘与实时状态并重
W2 (实时) 0.5
剩余时间 (T) 5 分钟
时间系数 f(5) ≈ 0.175 f(T) = (5/48)^0.9
随机项 ε 0 (暂定) 首次计算忽略

计算过程:

  1. 综合潜力值 = (0.15 * 0.5) + (-0.2 * 0.5) + 0 = 0.075 - 0.1 = -0.025
  2. 预期追回分差 (E) = -0.025 * 0.175 ≈ -0.004

加入随机波动项 ε 并进行蒙特卡洛模拟后,可能的输出:

输出指标 模拟可能结果示例 含义解读
预期追回分差平均值 约 -0.5 分到 +1.5 分 系统性追回大量分数的可能性很低
追回至少15分(扳平)的概率 低于 0.1% 本节结束时翻盘的概率微乎其微
分差变化区间 (90%置信区间) 从扩大5分到缩小7分 最可能结果仍是较大分差进入第四节

批注[§★威★§6]: 该内容需要对比赛内容进行阶段切割,分析阶段性比分差情况。


六、 数据源与数据获取

数据需求清单

1. 历史比赛数据

  • 数据内容:
    • 比赛基本信息: 日期、主客场、比分、分差
    • 每节比分和分差变化
    • Play-by-Play 数据 (每个回合的详细记录)
    • 球队统计数据: 得分、篮板、助攻、失误等
  • 数据来源:
    • NBA Stats API (官方数据,免费但有限制)
    • Basketball Reference (历史数据完整)
    • ESPN API (实时数据)
    • 第三方数据服务: Sportradar, Stats Perform

2. 球队统计数据

  • 数据内容:
    • 进攻效率、防守效率、净效率值
    • 比赛节奏 (Pace)
    • 各项技术统计排名
    • 关键时刻 (Clutch) 数据
  • 更新频率: 每场比赛后更新

3. 球员统计数据

  • 数据内容:
    • 基础数据: 得分、篮板、助攻等
    • 高级数据: PER, TS%, BPM, VORP, DRPM
    • 对位数据: 球员之间的对位效果
    • 阵容数据: 不同阵容组合的 Net Rating
  • 更新频率: 每场比赛后更新

4. 实时比赛数据

  • 数据内容:
    • 实时比分和分差
    • Play-by-Play 实时更新
    • 球员在场情况
    • 暂停和挑战信息
  • 数据来源:
    • NBA Stats API (实时端点)
    • ESPN API
    • 第三方实时数据服务
  • 更新频率: 每 30 秒或每个回合

免费 API 数据覆盖分析

NBA Stats API (官方免费 API)

  • 基础 URL: https://stats.nba.com/stats/
  • 免费访问: 是,但需要设置正确的请求头
  • 请求限制: 无官方限制,但建议控制频率 (建议 < 10 请求/秒)
数据覆盖情况

可直接获取的数据:

  1. 比赛基本信息:

    • /scoreboard: 赛程、比分、主客场
    • /boxscore: 比赛统计、每节比分
    • /playbyplay: Play-by-Play 数据 (每个回合)
    • 满足需求: 历史比赛数据、实时比赛状态、分差变化
  2. 球队统计数据:

    • /teamdashboardbygeneralsplits: 球队基础统计
    • /teamdashboardbyclutch: 关键时刻数据
    • /teamdashboardbyteamperformance: 球队表现数据
    • 满足需求: 进攻效率、防守效率、净效率值、比赛节奏 (Pace)、关键时刻数据
  3. 球员统计数据:

    • /playerdashboardbygeneralsplits: 球员基础统计
    • /playergamelog: 球员单场数据
    • 满足需求: 得分、篮板、助攻、真实命中率 (TS%)、使用率 (USG%)
  4. 实时数据:

    • /boxscore: 实时比分 (需要轮询)
    • /playbyplay: 实时 Play-by-Play (需要轮询)
    • 满足需求: 实时分差、剩余时间、当前节次、球员在场情况

⚠️ 需要计算的数据 (API 不直接提供,但可通过基础数据计算):

  1. PER (Player Efficiency Rating):

    • API 不提供
    • 替代方案: 使用公式计算 PER = (得分 + 篮板 + 助攻 + 抢断 + 盖帽 - 失误 - 投篮不中 - 罚球不中) / 上场时间 × 系数
    • 参考: PER 计算公式
  2. BPM (Box Plus/Minus):

    • API 不提供
    • 替代方案: 使用简化版本,基于基础统计计算,或使用 Basketball Reference 爬取
  3. VORP (Value Over Replacement Player):

    • API 不提供
    • 替代方案: 基于 BPM 和上场时间计算,或使用 Basketball Reference 爬取
  4. DRPM (Defensive Real Plus-Minus):

    • API 不提供
    • 替代方案: 使用防守效率排名或防守统计作为代理指标
  5. 阵容 Net Rating:

    • API 不直接提供阵容组合数据
    • 替代方案:
      • 使用球队平均 Net Rating × 阵容调整系数
      • 阵容调整系数 = Σ(球员在场时球队净效率值 - 球队平均净效率值) / 阵容球员数
      • 或使用 /lineups 端点 (如果可用) 获取阵容数据
  6. 对位数据:

    • API 不提供球员对位数据
    • 替代方案:
      • 使用防守球员的防守统计 (抢断、盖帽、防守篮板) 作为代理
      • 或基于历史比赛数据,统计特定对位的效果

无法获取的数据 (需要替代方案):

  1. 伤病报告和轮休信息:

    • API 不提供
    • 替代方案:
      • 从 NBA 官网或 ESPN 爬取伤病报告
      • 或使用 Twitter API 监控球队官方账号
      • 或手动维护伤病数据库
  2. 旅行距离和时区变化:

    • API 不提供
    • 替代方案:
      • 使用 Google Maps API 计算城市间距离 (免费额度充足)
      • 或维护城市坐标和时区数据库
  3. 历史恩怨和特殊情节:

    • API 不提供
    • 替代方案: 基于历史对战记录和新闻数据手动标注

Basketball Reference (免费爬取)

  • 数据格式: HTML 页面
  • 优势:
    • 历史数据完整 (可追溯到 1946 年)
    • 提供高级数据 (PER, BPM, VORP, DRPM)
    • 完全免费
  • 劣势:
    • 需要爬虫解析
    • 有反爬虫机制 (需要控制频率)
    • 实时数据更新较慢
  • 建议:
    • 用于获取历史数据和高级统计数据
    • 建议使用 requests + BeautifulSoupScrapy
    • 控制请求频率 (建议 < 1 请求/秒)
    • 缓存已获取的数据,避免重复请求

数据获取策略建议

阶段一: 历史数据收集 (一次性)

  1. 使用 Basketball Reference 爬取过去 3-5 个赛季的历史数据
  2. 获取高级统计数据 (PER, BPM, VORP 等)
  3. 存储到本地数据库

阶段二: 实时数据更新 (持续)

  1. 使用 NBA Stats API 获取实时比赛数据
  2. 每 30 秒轮询一次 (比赛进行时)
  3. 计算实时特征 (M, P 等)

阶段三: 数据补充 (按需)

  1. 伤病信息: 手动维护或爬取 NBA 官网
  2. 旅行距离: 使用 Google Maps API 或维护静态数据库
  3. 高级统计: 定期从 Basketball Reference 更新

数据需求对照表

数据需求 来源 获取方式 难度 备注
赛前预测数据
比赛基本信息 NBA Stats API 直接获取 简单 /scoreboard, /boxscore
球队进攻/防守效率 NBA Stats API 直接获取 简单 /teamdashboardbygeneralsplits
球队净效率值 NBA Stats API 直接获取 简单 计算: 进攻效率 - 防守效率
比赛节奏 (Pace) NBA Stats API 直接获取 简单 /teamdashboardbygeneralsplits
球员基础统计 NBA Stats API 直接获取 简单 /playerdashboardbygeneralsplits
球员真实命中率 (TS%) NBA Stats API 计算 中等 基于得分、投篮次数、罚球次数计算
球员使用率 (USG%) NBA Stats API 计算 中等 基于投篮、失误、罚球计算
PER Basketball Reference 爬取或计算 较难 公式复杂,建议爬取
BPM Basketball Reference 爬取 较难 需要爬取,或使用简化版本
VORP Basketball Reference 爬取 较难 基于 BPM 计算,建议爬取
DRPM Basketball Reference 爬取 较难 需要爬取,或用防守统计代理
阵容 Net Rating NBA Stats API 计算 中等 基于球员在场数据计算
对位数据 - 计算或爬取 较难 基于历史数据统计,或爬取
伤病报告 NBA 官网 爬取 较难 需要爬取或手动维护
旅行距离 Google Maps API 计算 简单 免费额度充足
背靠背信息 NBA Stats API 计算 简单 基于赛程计算
赛中实时数据
实时比分和分差 NBA Stats API 直接获取 简单 /boxscore (轮询)
剩余时间 NBA Stats API 直接获取 简单 /boxscore
当前节次 NBA Stats API 直接获取 简单 /boxscore
Play-by-Play NBA Stats API 直接获取 简单 /playbyplay (轮询)
球员在场情况 NBA Stats API 直接获取 简单 /playbyplay
暂停次数 NBA Stats API 直接获取 简单 /boxscore
势头动量 (M) NBA Stats API 计算 中等 基于 Play-by-Play 计算
球星爆发因子 (P) NBA Stats API 计算 中等 基于本场 TS% 和赛季平均计算

难度说明:

  • 简单: 直接 API 调用或简单计算
  • 中等: 需要数据处理和计算
  • 较难: 需要爬取或复杂计算

免费 API 使用注意事项

  1. 请求频率控制:

    • NBA Stats API: 建议 < 10 请求/秒
    • Basketball Reference: 建议 < 1 请求/秒
    • 使用请求队列和延迟机制
  2. 请求头设置 (NBA Stats API):

    headers = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36',
        'Referer': 'https://www.nba.com/',
        'Accept': 'application/json'
    }
    
  3. 数据缓存:

    • 历史数据: 永久缓存
    • 实时数据: 缓存 30-60 秒
    • 统计数据: 缓存到下次比赛后更新
  4. 错误处理:

    • 实现重试机制 (指数退避)
    • 处理 API 临时不可用的情况
    • 记录失败请求,后续补全数据

数据存储建议

数据库选择

  • PostgreSQL: 适合结构化数据,支持复杂查询
  • MongoDB: 适合 Play-by-Play 等非结构化数据
  • Redis: 用于缓存实时数据和计算结果
  • 时序数据库 (InfluxDB/TimescaleDB): 适合存储时间序列数据 (如实时分差变化)

数据表设计 (示例)

  • games: 比赛基本信息
  • game_stats: 比赛统计数据
  • play_by_play: 回合数据
  • team_stats: 球队统计数据
  • player_stats: 球员统计数据
  • lineup_stats: 阵容统计数据
  • predictions: 预测结果存储

数据质量保证

  • 数据验证规则:
    • 比分合理性检查 (单节得分不超过 50 分,单场得分不超过 200 分)
    • 时间戳连续性检查
    • 球员在场时间合理性 (不超过比赛总时间)
    • 统计数据一致性 (得分 = 两分 + 三分 + 罚球)
  • 缺失值处理策略:
    • 对位数据缺失: 使用防守球员 DRPM 和进攻球员 ORPM 作为代理
    • 阵容 Net Rating 缺失: 使用球队平均 Net Rating × 阵容调整系数
    • 实时数据延迟: 使用最近一次有效数据,并标记数据时效性
    • 历史数据缺失: 使用赛季平均值或联盟平均值填充

七、 实施路线图

阶段一: 数据收集与基线模型 (1-2 个月)

1.1 数据收集

  • 接入 NBA Stats API 或第三方数据源
  • 收集过去 3-5 个赛季的历史比赛数据
  • 建立数据存储和更新机制
  • 数据清洗和预处理

1.2 基线模型实现

  • 实现历史概率速查表
  • (分差, 剩余时间) 组合统计翻盘概率
  • 建立查询接口,支持实时查询

1.3 验证与优化

  • 使用历史数据验证模型准确性
  • 计算模型评估指标 (准确率、AUC 等)
  • 优化数据分组粒度 (分差区间、时间区间)

阶段二: 进阶模型开发 (2-3 个月)

2.1 球队能力调整

  • 实现球队实力系数计算
  • 实现阵容对位系数计算
  • 实现归一化函数
  • 在基线模型基础上加入能力调整

2.2 实时状态计算

  • 实现势头动量 (M) 计算
  • 实现球星爆发因子 (P) 计算
  • 实现实时特征提取

2.3 时间调整系数拟合

  • 使用历史数据拟合 k 值
  • 分阶段 (按节次) 拟合 k 值
  • 验证 k 值的合理性

阶段三: 蒙特卡洛模拟 (1-2 个月)

3.1 模拟框架实现

  • 实现随机波动项生成
  • 实现蒙特卡洛模拟核心逻辑
  • 实现统计结果计算 (概率、期望值、置信区间)

3.2 性能优化

  • 优化模拟速度 (并行计算、向量化)
  • 实现结果缓存机制
  • 优化内存使用

3.3 验证与调优

  • 使用历史数据验证模拟结果
  • 调整随机波动项方差
  • 优化模拟次数 (平衡精度和速度)

阶段四: 机器学习模型 (3-4 个月)

4.1 特征工程

  • 实现所有特征的计算逻辑
  • 特征选择和重要性分析
  • 特征标准化和归一化

4.2 模型训练

  • 数据准备和划分 (训练集、验证集、测试集)
  • 模型选择和超参数调优
  • 模型训练和评估

4.3 模型部署

  • 模型序列化和加载
  • 实时预测接口开发
  • 模型更新和重训练机制
  • 模型版本管理 (使用 MLflow 或类似工具)
  • A/B 测试框架搭建
  • 模型解释性工具集成 (SHAP/LIME)

阶段五: 全自动实时系统 (2-3 个月)

5.1 实时数据接入

  • 实现实时数据获取 (API 轮询或 WebSocket)
  • 实现数据解析和存储
  • 实现数据质量检查

5.2 自动化预测

  • 实现自动触发预测 (每 30 秒或每回合)
  • 实现预测结果存储和展示
  • 实现异常处理和告警

5.3 系统优化

  • 性能优化 (延迟、吞吐量)
  • 系统监控和日志
  • 用户体验优化
  • 实现降级策略 (API 失败时的备用方案)
  • 实现限流和熔断机制
  • 建立数据备份和恢复机制

总体时间估算

  • MVP 版本 (阶段一 + 阶段二基础): 3-4 个月
  • 完整版本 (所有阶段): 12-18 个月 (考虑数据获取、模型调试和优化时间)

八、 模型评估指标

分类任务评估 (翻盘预测)

1. 准确率 (Accuracy)

  • 定义: (正确预测数) / (总预测数)
  • 目标: > 60% (基准线为 50%)

2. 精确率 (Precision) 和召回率 (Recall)

  • 精确率: (预测翻盘且实际翻盘) / (预测翻盘总数)
  • 召回率: (预测翻盘且实际翻盘) / (实际翻盘总数)
  • 目标: 精确率 > 55%, 召回率 > 50%

3. F1 分数

  • 定义: F1 = 2 × (精确率 × 召回率) / (精确率 + 召回率)
  • 目标: > 0.52

4. AUC-ROC

  • 定义: ROC 曲线下面积,衡量模型区分能力
  • 目标: > 0.65 (基准线为 0.5)

5. 校准度 (Calibration)

  • 定义: 预测概率与实际概率的一致性
  • 方法: Brier Score, Calibration Plot
  • 目标: Brier Score < 0.25

回归任务评估 (分差预测)

1. 平均绝对误差 (MAE)

  • 定义: MAE = Σ|预测值 - 实际值| / N
  • 目标: < 3.0 分

2. 均方根误差 (RMSE)

  • 定义: RMSE = sqrt(Σ(预测值 - 实际值)² / N)
  • 目标: < 4.0 分

3. 平均绝对百分比误差 (MAPE)

  • 定义: MAPE = Σ|(预测值 - 实际值) / 实际值| / N × 100%
  • 目标: < 30%

概率预测评估

1. Brier Score

  • 定义: BS = Σ(预测概率 - 实际结果)² / N
  • 范围: [0, 1],越小越好
  • 目标: < 0.25

2. Log Loss

  • 定义: Log Loss = -Σ[y × log(p) + (1-y) × log(1-p)] / N
  • 范围: [0, ∞),越小越好
  • 目标: < 0.7

模型对比基准

1. 基线模型

  • 历史概率速查表
  • 准确率目标: > 55%

2. 进阶模型

  • 基线模型 + 球队能力调整
  • 准确率目标: > 58%

3. 机器学习模型

  • 完整特征工程 + XGBoost/LightGBM
  • 准确率目标: > 60%

九、 注意事项与局限性

数据局限性

  1. 数据质量:

    • 历史数据可能存在缺失或错误
    • 实时数据可能有延迟
    • 需要建立数据质量检查机制
  2. 数据覆盖:

    • 某些特征 (如对位数据、阵容数据) 可能不完整
    • 需要处理缺失值
  3. 数据时效性:

    • 球队和球员状态会随时间变化
    • 需要定期更新模型和数据

模型局限性

  1. 过拟合风险:

    • 特征过多可能导致过拟合
    • 需要使用交叉验证和正则化
  2. 样本不平衡:

    • 翻盘情况相对较少,可能导致模型偏向预测"不翻盘"
    • 需要使用采样技术 (SMOTE, 过采样等)
  3. 外推能力:

    • 模型基于历史数据训练,可能无法预测极端情况
    • 需要设置合理的预测范围

实际应用注意事项

  1. 实时性要求:

    • 预测需要在短时间内完成 (建议 < 1 秒)
    • 需要优化计算性能
  2. 系统稳定性:

    • API 可能不稳定,需要实现重试和降级机制
    • 需要监控系统健康状态
  3. 用户体验:

    • 预测结果需要清晰易懂
    • 需要提供置信区间和不确定性说明
  4. 合规性:

    • 如果用于投注或交易,需要遵守相关法律法规
    • 需要明确说明模型的局限性和风险

十、 关键问题与改进建议

发现的问题

1. 公式逻辑问题

  • 问题: 原公式中随机波动项的位置可能不合理
  • 修正: 随机波动项应在时间调整之后添加,即 E = (F-base × W1 + F-live × W2) × f(T) + ε
  • 理由: 随机性影响的是最终分差结果,而不是追分潜力本身

2. 归一化方法选择

  • 问题: 提供了多种归一化方法,但未说明选择标准
  • 建议:
    • 统一使用 Z-score 归一化(推荐),便于解释和比较
    • 或使用 Min-Max 归一化到 [-1, 1],便于控制范围
    • 避免在同一模型中混用不同归一化方法

3. 权重确定方法

  • 问题: 权重 W1 和 W2 的调整规则不够明确
  • 改进: 提供了基于剩余时间和节次的动态调整公式

4. 数据获取可行性

  • 问题: 某些数据(如对位数据、阵容 Net Rating、高级统计)可能难以获取
  • 解决方案 (基于免费 API):
    • 对位数据:
      • 如果历史对位数据不足,使用防守球员的防守统计(抢断、盖帽、防守篮板)作为代理
      • 或基于历史比赛数据,统计特定对位的效果(需要积累数据)
    • 阵容 Net Rating:
      • 使用球队平均 Net Rating × 阵容调整系数
      • 阵容调整系数 = Σ(球员在场时球队净效率值 - 球队平均净效率值) / 阵容球员数
      • 或从 Basketball Reference 爬取阵容数据
    • 高级统计 (PER, BPM, VORP, DRPM):
      • 优先从 Basketball Reference 爬取(一次性收集历史数据)
      • 或使用简化公式计算(精度略低但可用)
    • 伤病信息:
      • 从 NBA 官网或 ESPN 爬取
      • 或使用 Twitter API 监控球队官方账号(免费额度有限)
      • 或手动维护伤病数据库

5. 模型评估目标值

  • 问题: 评估指标的目标值缺乏依据
  • 建议:
    • 目标值应该基于基线模型(随机猜测或简单规则)的表现来确定
    • 建议先运行基线模型,获得基准性能,再设定合理的提升目标(如提升 5-10%)

6. 特征数量过多

  • 问题: 150-300 个特征可能导致过拟合
  • 建议:
    • 使用特征选择技术(如 LASSO、特征重要性排序)
    • 考虑使用降维技术(PCA、ICA
    • 建议最终使用 50-100 个最重要的特征

7. 时间估算可能过于乐观

  • 问题: 9-14 个月可能低估了数据获取和模型调试的时间
  • 建议:
    • 数据获取阶段可能需要额外 1-2 个月(API 接入、数据清洗)
    • 模型调试和优化可能需要额外 2-3 个月
    • 建议总时间估算为 12-18 个月

补充建议

1. 添加数据验证机制

  • 数据质量检查: 异常值检测、缺失值处理、数据一致性验证
  • 实时数据验证: API 响应时间监控、数据延迟检测、数据完整性检查

2. 模型解释性

  • 使用 SHAP 值或 LIME 解释模型预测
  • 提供特征重要性排序
  • 可视化关键特征对预测结果的影响

3. A/B 测试框架

  • 设计 A/B 测试来验证模型效果
  • 对比不同模型版本的表现
  • 收集用户反馈并迭代改进

4. 风险控制

  • 设置预测置信度阈值,低于阈值时不给出预测
  • 监控模型性能,如果准确率下降超过阈值,触发告警
  • 实现模型回滚机制

6. 法律和伦理考虑

  • 如果用于投注,需要遵守相关法律法规
  • 数据使用需要遵守隐私保护规定
  • 模型预测结果的使用需要明确免责声明