Как работает новая версия Онлайн Прогноз

Как формируется прогноз матча 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 — от идеи до реализации в одном веб-приложении.

Прокрутить вверх