feat: replace AI-computed probability with math-based normal distribution from ensemble data

This commit is contained in:
2569718930@qq.com
2026-02-27 14:24:17 +08:00
parent 37949c222c
commit ef9cd4c9d4
2 changed files with 38 additions and 6 deletions
+37
View File
@@ -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"🎲 <b>结算概率</b>{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:
+1 -6
View File
@@ -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) ->
🤖 <b>Groq AI 决策</b>
- 🎲 盘口: [必须明确指出最热时段(如:预计最热在 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
"""