# Estimating Team Strength and Map Win Probabilities for Dota 2

Translate public rankings and form into inputs for `calculate_dota2_probs.py`. Prefer the **logistic / rating_diff** path for most work. Use the Poisson kill-lead path as a second opinion when average kills or GPM are stable.

## 1. Baseline from Rankings (Primary Signal)

Primary source: **DLTV World Ranking** (https://dltv.org/ranking).

- Points difference is the strongest single pre-match signal for established rosters.
- Rough calibration (pro scene 2025–2026):
  - Every ~80–100 DLTV points ≈ +0.03 to +0.04 map win probability.
  - Or convert via Elo-style: treat points gap as rating_diff and use `--rating_diff`.
- Simple formula (starting point):

```
base_map_p_A = 0.50 + (points_A - points_B) / 2500
```

Clamp later. For teams far outside top 20 or with brand-new cores, prefer recent form win-rate conversion instead.

Alternative ranking sources (cross-check): Dotabuff team rankings, OpenDota, community Elo lists.

## 2. Recent Form & Win-Rate Adjustment

From team pages (Dotabuff / OpenDota / STRATZ last 20–40 games or ~3 months):

- Overall win rate difference is useful but noisy.
- Prefer series results (Bo3/Bo5) over individual maps when available.
- Adjustment (add to base_map_p):

```
form_adj = (winrate_A - winrate_B) * 0.20   # conservative
```

- Weight more recent results higher (last 5–8 series matter most).
- Discount heavily if roster has changed (new mid, new offlane, stand-in support).

Typical total map_p after ranking + form: 0.47–0.58 for most competitive matches. Rarely go outside 0.40–0.70 without extreme evidence.

## 3. Head-to-Head, Motivation & Context Tweaks

Small additive adjustments (±0.01–0.04):

- Strong H2H on current patch → +0.02–0.03 for the historical winner.
- Must-win / lower-bracket pressure, home crowd (rare), fatigue after long travel.
- Patch fit: some teams thrive on specific patches (e.g., heavy push, late-game, specific hero pools). Note current patch number and recent meta shifts.
- Roster continuity: if 4–5 players have played together >30 games, confidence increases; stand-ins reduce it.

## 4. Draft / Post-Ban Adjustment (High Value When Available)

Pre-draft estimates ignore the largest source of variance. Once heroes are known:

- Look up recent hero win rates on the current patch (STRATZ, Dotabuff, Spectral).
- Known hard counters or lane dominance (e.g., offlane vs hard carry matchup).
- Typical draft edge: ±0.03–0.08 on map_p depending on how one-sided the draft looks.
- Document the delta explicitly: “Draft favors A by ~+0.05 (strong mid + offlane counter)”.

If only partial draft (bans only), use smaller adjustments.

## 5. Optional Poisson Kill / Net-Worth Lead Path

When team average kills or GPM are reliable:

1. Extract recent average kills per game (or GPM) for both teams.
2. Feed into script with `--kills_a` `--kills_b --poisson_lead`.
3. The script models kills ~ Poisson(λ), computes lead distribution, then maps lead → win probability via logistic.
4. Use the resulting map_p as a cross-check or average it with the ranking-based estimate when both are high quality.

Gold-lead version (manual): if you have expected net-worth difference at ~20–25 min, convert roughly:
- +5k ≈ ~60%, +10k ≈ ~72–75%, +15k ≈ ~85% (very approximate; varies by patch and game length).

## 6. Radiant / Dire Side

Radiant historically holds a small edge (patch-dependent, often 50.5–52.5%). When side is known or can be assigned:

```
final_map_p = clamp(map_p + radiant_adv, 0.01, 0.99)
```

Typical radiant_adv = +0.01 to +0.025. Script supports `--radiant_adv`.

## 7. Series Conversion

Once you have a map_p (or list of map_ps):

- Bo1 = map_p
- Bo2 / Bo3 / Bo5 → use the script’s exact DP (independent maps).
- Real series have sequential information and draft adaptation; independence is a practical upper-bound approximation on favorite’s win probability.

Always report score distribution (2-0 / 2-1 etc.) and run sensitivity (±0.03–0.05 on map_p).

## 8. Calibration & Shrinkage Rules

- Sample size < 12 recent games or new core → shrink map_p halfway toward 0.50.
- Conflicting signals (ranking favors A, recent form favors B) → average or widen the range.
- Extreme values (>0.70 or <0.30) require strong evidence (huge ranking gap + dominant form + favorable draft).
- Always state confidence: High (stable top teams, rich data, post-draft), Medium, Low (stand-ins, sparse samples, early patch).

## Limitations

- Draft is the dominant unmodeled factor pre-game.
- Individual player variance and “hero pool depth” are only partially captured by form.
- Patch changes can invalidate older data within days.
- The logistic and Poisson-lead models are strong baselines, not oracles. Combine with qualitative scouting.
