diff --git a/bot_listener.py b/bot_listener.py
index d02f6b9e..ee644e7d 100644
--- a/bot_listener.py
+++ b/bot_listener.py
@@ -174,6 +174,43 @@ def analyze_weather_trend(weather_data, temp_symbol, city_name=None):
msg2 = f"⚡ 预报偏低:确定性预报 {om_today}{temp_symbol} 低于集合90%下限,更可能接近 {ens_median}{temp_symbol}。"
ai_features.append(msg2)
+ # === 数学概率计算(基于集合预报正态分布拟合)===
+ import math as _math
+ # 用 P10/P90 反推标准差: P10 = median - 1.28*sigma, P90 = median + 1.28*sigma
+ sigma = (ens_p90 - ens_p10) / 2.56
+ if sigma < 0.1: sigma = 0.1 # 防止除以零
+ mu = ens_median # 以集合中位数为中心
+
+ # 如果 DEB 融合值或多模型均值存在,用它们微调中心
+ if forecast_median is not None:
+ mu = (ens_median + forecast_median) / 2 # 取集合中位数和模型中位数的均值
+
+ # 简化的正态 CDF (不依赖 scipy)
+ def _norm_cdf(x, m, s):
+ return 0.5 * (1 + _math.erf((x - m) / (s * _math.sqrt(2))))
+
+ # 计算每个 WU 整数区间 [N-0.5, N+0.5) 的概率
+ center = round(mu)
+ candidates = range(center - 2, center + 3) # 5 个候选整数
+ probs = {}
+ for n in candidates:
+ p = _norm_cdf(n + 0.5, mu, sigma) - _norm_cdf(n - 0.5, mu, sigma)
+ if p > 0.01: # 只保留概率 > 1% 的
+ probs[n] = p
+
+ # 归一化
+ total_p = sum(probs.values())
+ if total_p > 0:
+ probs = {k: v / total_p for k, v in probs.items()}
+
+ # 格式化输出(按概率从高到低排列)
+ sorted_probs = sorted(probs.items(), key=lambda x: x[1], reverse=True)
+ prob_parts = [f"{int(t)}{temp_symbol}({p*100:.0f}%)" for t, p in sorted_probs[:4]]
+ if prob_parts:
+ prob_str = " | ".join(prob_parts)
+ insights.append(f"🎲 结算概率:{prob_str}")
+ ai_features.append(f"🎲 数学概率分布:{prob_str}")
+
# === 实测已超预报 & 趋势输出 ===
if max_so_far is not None and forecast_high is not None:
if max_so_far > forecast_high + 0.5:
diff --git a/src/analysis/ai_analyzer.py b/src/analysis/ai_analyzer.py
index 41c6d9d4..68bde736 100644
--- a/src/analysis/ai_analyzer.py
+++ b/src/analysis/ai_analyzer.py
@@ -38,11 +38,7 @@ def get_ai_analysis(weather_insights: str, city_name: str, temp_symbol: str) ->
2. **阻碍因子**:由于高湿度(>80%)、降水或全阴天气导致的升温失速。
3. **结算推演**:根据我提供给你的【博弈区间】以及【当前所处时段(是否过了最热期)】推断并告诉我最终结算温度落在哪个区间的希望更大。
4. **结算边界**:如果当前温度处于 X.5 这种进位/舍位边缘,需特别预警。
-5. **概率估算(极其重要,务必仔细推理)**:
- - WU 结算规则:实测最高温四舍五入到整数。即 X.5 以上进位,X.5 以下舍去。例如:3.5°C→4°C,3.4°C→3°C。
- - 你必须先判断 DEB 融合值和各模型预报落在哪个 WU 取整区间内。例如 DEB=3.6°C 落在 [3.5, 4.5) 区间,对应 WU 结算 4°C。
- - 然后综合集合预报 P10-P90 区间覆盖了哪些 WU 取整区间,按覆盖比例分配概率。
- - 最终给出 2-4 个 WU 结算整数温度的概率(必须加起来 = 100%)。
+5. **概率参考**:我已经通过数学模型计算好了结算概率分布(见【气象特征与事实】中的"数学概率分布"),请在你的逻辑分析中参考它来判断最终结算方向。
【输出要求】
1. **禁止废话**,整体控制在 200 字以内。
@@ -51,7 +47,6 @@ def get_ai_analysis(weather_insights: str, city_name: str, temp_symbol: str) ->
🤖 Groq AI 决策
- 🎲 盘口: [必须明确指出最热时段(如:预计最热在 14:00-16:00)以及当前的博弈区间(如:锁定在 27°C 或 28°C 之间博弈)。若已明确降温,请直接给出死盘结论。]
- 💡 逻辑: [用 2-3 句话深度分析:①当前机场实测的风速风向和云量对升温的促进/阻碍;②结合辐射、暖平流等动力因子判断温度还有多少上升空间;③最终是否能达到预报值。不要泛泛而谈,请使用具体数值。]
-- 📊 概率: [列出最可能的 2-4 个 WU 结算整数温度及概率。注意:概率应反映实测最高温落入对应取整区间的可能性。格式:4°C(55%) | 3°C(35%) | 5°C(10%)]
- 🎯 置信度: [1-10]/10
"""