Как формируется прогноз матча MLB на сайте podii.ru: анализ данных, метрики и формулы
На сайте podii.ru реализован автоматизированный инструмент для прогнозирования матчей Главной лиги бейсбола (MLB), основанный на статистических данных игроков, современных аналитических метриках и математических моделях. Этот веб-интерфейс позволяет пользователю выбрать команды и стартовых питчеров, после чего система рассчитывает ожидаемое количество ранов (runs) и вероятность победы для каждой команды.
В основе системы — комбинация данных о бэттерах (ударниках) и питчерах (подавальщиках), с использованием ключевых сабметрик аналитики бейсбола, таких как wOBA, xFIP, ISO, K%, BABIP и других. Ниже мы подробно разберём, как происходит прогноз, какие данные используются и по каким формулам рассчитываются ключевые показатели.
1. Источники данных
Прогноз строится на основе нескольких JSON-файлов, загружаемых при запуске приложения:
Splits Leaderboard Data vs LHP.json
— статистика бэттеров против леворуких питчеров.Splits Leaderboard Data vs RHP.json
— статистика бэттеров против праворуких питчеров.Splits Leaderboard Data as SP.json
— данные стартовых питчеров (SP).pitcherRL.json
— информация о том, левша (L) или правша (R) каждый питчер.filelist.json
— список файлов с дополнительной статистикой.
Данные кэшируются в localStorage
браузера для ускорения повторного доступа.
Ключевые метрики
Метрика | Описание |
---|---|
wOBA (Weighted On-Base Average) | Взвешенный показатель выхода на базу. Учитывает ценность каждого действия (сингл, дабл и т.д.) с поправкой на лёгкость выполнения. Стандартный показатель качества бэттера. |
ISO (Isolated Power) | Показатель чистой силы: разница между слаггингом (SLG) и средним процентом хитов (AVG). Чем выше ISO, тем больше экстра-базовых хитов у игрока. |
K% | Процент страйкаутов от общего числа аутов. |
BB% | Процент выходов на базу по мячам. |
K/9 | Среднее количество страйкаутов за 9 иннингов. |
BB/9 | Среднее количество пас walk за 9 иннингов. |
HR/9 | Среднее количество хоум-ранов за 9 иннингов. |
LOB% (Left On Base %) | Процент бегунов, оставленных на базах. Показывает способность питчера «выбывать» в критических ситуациях. |
xFIP (Expected Fielding Independent Pitching) | Ожидаемый показатель эффективности питчера, исключающий влияние защиты. Основан на K, BB, HR и парк-факторе. Более устойчив, чем FIP. |
BABIP (Batting Average on Balls in Play) | Процент хитов при мячах, попавших в игру (исключая HR). В среднем около 0.300. Отклонения могут указывать на удачу или неудачу. |
2. Формирование состава бэттеров
Система автоматически выбирает топ-9 бэттеров каждой команды, наиболее эффективных против питчера противоположной руки.
Логика выбора:
function getBattersForPitcher(team, pitcher) {
const isLefty = pitcher.Throws === 'L';
const sourceStats = isLefty ? batterStatsVsLHP : batterStatsVsRHP;
return allPlayers
.filter(p => p.Tm === team && p.PA > 1)
.map(b => { /* подмена статистики на сплит против LHP/RHP */ })
.filter(b => typeof b.wOBA === 'number')
.sort((a, b) => b.wOBA - a.wOBA)
.slice(0, 9);
}
- Если питчер — левша, берутся данные из
vs LHP
. - Если правша — из
vs RHP
. - Игроки сортируются по wOBA (в порядке убывания).
- Выбираются первые 9 игроков с минимум 1 питч-апом (PA).
⚠️ Пользователь может вручную отредактировать состав, перетаскивая игроков или заменяя их из пула.
3. Прогноз количества ранов (predictRuns)
Основная формула прогноза ранов учитывает силу бэттеров, качество питчера и домашнее поле.
Формула:
function predictRuns(batters, pitcher, isHomeTeam = false, parkFactor = 1.0) {
// Веса для порядка в баттинг-линии (1-9)
const weights = [1.2, 1.2, 1.2, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0];
const totalWeight = weights.reduce((sum, w) => sum + w, 0);
// Средневзвешенные показатели бэттеров
const avgwOBA = batters.reduce((sum, b, i) => sum + (b.wOBA || 0) * weights[i], 0) / totalWeight;
const avgISO = batters.reduce((sum, b, i) => sum + (b.ISO || 0) * weights[i], 0) / totalWeight;
const avgKPercent = batters.reduce((sum, b, i) => sum + (b['K%'] || 0) * weights[i], 0) / totalWeight;
const avgBBPercent = batters.reduce((sum, b, i) => sum + (b['BB%'] || 0) * weights[i], 0) / totalWeight;
// Лиговые средние (для нормализации)
const leagueAvgwOBA = 0.315;
const leagueAvgISO = 0.150;
const leagueAvgKPercent = 0.200;
const leagueAvgBBPercent = 0.080;
// Лиговые средние для питчеров
const leagueAvgK9 = 8.0;
const leagueAvgBB9 = 3.0;
const leagueAvgHR9 = 1.0;
const leagueAvgLOB = 0.700;
// Базовое количество ранов (4.5 — среднее в MLB)
let runs = 4.5
+ (avgwOBA - leagueAvgwOBA) * 20 // влияние wOBA
+ (avgISO - leagueAvgISO) * 10 // влияние силы
- (avgKPercent - leagueAvgKPercent) * 10 // влияние K%
+ (avgBBPercent - leagueAvgBBPercent) * 10 // влияние BB%
- ((pitcher['K/9'] || leagueAvgK9) - leagueAvgK9) * 0.3 // питчер K/9
+ ((pitcher['BB/9'] || leagueAvgBB9) - leagueAvgBB9) * 0.2 // питчер BB/9
- ((pitcher['HR/9'] || leagueAvgHR9) - leagueAvgHR9) * 0.5 // питчер HR/9
+ ((pitcher['LOB%'] || leagueAvgLOB) - leagueAvgLOB) * 2; // питчер LOB%
// Корректировки
runs *= parkFactor; // парк-фактор
if (isHomeTeam) runs *= 1.05; // бонус за домашнее поле
return Math.max(1.0, Math.min(10, runs)); // ограничение от 1 до 10
}
Пояснение:
- Первые три бэттера получают повышенный вес (1.2), так как они чаще выходят на питч.
- wOBA — главный показатель: отклонение от лигового среднего умножается на 20.
- ISO — учитывает силу атаки.
- K% и BB% — корректируют результат: высокий K% снижает раны, высокий BB% увеличивает.
- Питчерские метрики:
- Чем выше K/9, тем лучше (уменьшает раны).
- Чем выше BB/9 и HR/9, тем хуже.
- Чем выше LOB%, тем лучше (больше бегунов оставлено).
- Домашнее поле даёт +5% к ранам.
- Парк-фактор пока фиксирован (1.0), но в будущем может учитывать стадион.
4. Вероятность победы (calculateWinProbability)
Расчёт вероятности победы основан на модели Питагора (Pythagorean Expectation), адаптированной для бейсбола.
Формула:
function calculateWinProbability(runsScored, runsAllowed, pitcher, batters, isHomeTeam = false) {
const avgBatterBABIP = batters.reduce((sum, b) => sum + (b.BABIP || 0), 0) / batters.length;
const leagueAvgBABIP = 0.300;
const babipAdjustment = (avgBatterBABIP - leagueAvgBABIP) * 5;
const exponent = 1.83;
const adjustedRunsScored = runsScored * (1 + babipAdjustment / 100);
const ratio = Math.pow(adjustedRunsScored, exponent);
const total = ratio + Math.pow(runsAllowed, exponent);
let pct = (ratio / total) * 100;
if (isHomeTeam) pct = Math.min(95, pct * 1.1); // бонус за домашнее поле
return isFinite(pct) ? pct : 50;
}
Пояснение:
- Используется экспонента 1.83 — стандартная для MLB.
- BABIP-коррекция: если средний BABIP бэттеров выше 0.300, предполагается, что они «везучи», и их ожидаемые раны корректируются вверх.
- Домашнее поле: +10% к вероятности (но не более 95%).
5. Визуализация и публикация
После расчёта система:
- Отображает таблицы бэттеров с ключевыми метриками.
- Строит график (через Chart.js) с двумя наборами данных:
- Ожидаемые раны (столбцы зелёный/красный).
- Вероятность победы (столбцы синий/оранжевый).
- Позволяет опубликовать прогноз в WordPress через API.
- Автоматически сохраняет результат в Google Таблицу через Google Apps Script.
Заключение
Прогноз на podii.ru — это гибридная модель, сочетающая:
- Сплит-статистику (wOBA против LHP/RHP),
- Современные метрики (xFIP, wOBA, ISO),
- Математические модели (Питагорова оценка, взвешенные средние),
- Контекстные поправки (домашнее поле, порядок в линии).
Система не использует машинное обучение, но эффективно применяет принципы саберметрики, что делает прогнозы объективными и воспроизводимыми. Возможность ручного редактирования состава добавляет гибкости и позволяет учитывать травмы, формы игроков и тактические решения менеджеров.
Таким образом, podii.ru предлагает доступный, прозрачный и аналитически обоснованный инструмент для прогнозирования матчей MLB — от идеи до реализации в одном веб-приложении.