Все материалы
AIкейспродвинутый

Google Flu Trends: почему модель предсказывала поиск, а не грипп

Разбор Google Flu Trends: как прокси-метрика из поисковых запросов разошлась с данными CDC, почему простой прогноз по старым официальным данным оказался точнее и какими проверками поймать такую же зависимость метрики от собственного интерфейса.

КейсПрактика25 октября 2026 г.15 мин
Содержание статьи

Зимой 2012/13 две оценки одной и той же величины расходились примерно вдвое. Google Flu Trends показывал долю визитов к врачу с симптомами гриппа существенно выше, чем сеть наблюдений CDC, на исторических данных которой он и был обучен. Инженерно ничего не падало: запросы приходили, коэффициенты считались, график обновлялся на неделю-две раньше официальной статистики. Разошлось другое — то, что модель измеряла, и то, чем её проверяли. Обучали связь «ищут про симптомы — идут к врачу», а предсказывала модель поисковое поведение, которое менялось само: от новостей, от подсказок в строке поиска, от изменений продукта. Дальше — в какой момент сигнал разошёлся с предметом и какие проверки из этого следуют для метрики, которую в вашем продукте создаёт ваш же интерфейс.

Коротко

Это кейс не про плохую модель и не про бесполезность поиска как сигнала, а про режим использования: быстрый прокси поставили на место измеряемой величины и оставили без независимой сверки.

  • Target модели — показатель CDC, признаки — частота запросов. Между ними не механизм, а совпадение на истории.
  • Признаки отбирали по корреляции из огромного набора кандидатов, поэтому часть описывала зиму и новости.
  • В 2009 году модель пропустила внесезонную вспышку, в сезоне 2012/13 систематически завышала оценки.
  • Простые прогнозы по лагированным данным CDC были точнее, а лучший результат давала комбинация с поиском.
  • Миллионы наблюдений сжимают разброс оценки и не трогают её смещение.
  • Перенос на продукт: внешний якорь, состав источников события, устойчивость связи во времени.

Модель предсказывала поисковый интерес, а не заболеваемость

Google Flu Trends появился в 2008 году и решал задачу скорости. Американская система наблюдения ILINet собирает от сети врачей долю визитов с гриппоподобными симптомами и публикует недельную цифру с задержкой около недели-двух, а потом уточняет её. Поисковые запросы доступны в тот же день: если связь устойчива, оценка текущей недели появляется раньше официальной.

В публикации в Nature 2009 года (Ginsberg и соавторы) описан способ построения: из примерно 50 миллионов самых частых запросов отобрали около 45, по которым модель лучше всего воспроизводила исторические региональные ряды CDC.

Обратите внимание, что стояло в правой части уравнения. Не диагноз и не тест на грипп — частота того, что люди набирают в поиске. Модель знала только о поисковом поведении и о том, что в прошлые зимы оно шло рядом с кривой CDC. Пригодность такого прокси держится на том, что связь с предметом не меняется.

Первый вопрос к любому прокси

Назовите отдельно предмет измерения и то, что лежит в данных. «Доля визитов к врачу» и «частота запросов о симптомах» — разные величины, между ними цепочка допущений, а не знак равенства.

Сорок пять запросов из пятидесяти миллионов — это подгонка, а не механизм

Когда перебираете десятки миллионов временных рядов и оставляете совпавшие с целевым, часть отобранного совпала случайно или по третьей причине: гриппозный сезон — это зима, а зимой растёт и всё остальное зимнее. В разборе Лазера и соавторов приводится показательный пример: среди коррелирующих кандидатов попадались запросы вроде школьного баскетбола.

Корреляционный отбор не различает причины, по которым человек набрал фразу. Один заболел, второй прочитал новость, третьему поиск подсказал продолжение. Для модели это одинаковые единицы в числителе, а для предмета измерения — разные события, и их пропорция не обязана сохраняться из года в год.

Вторая часть проблемы — чем проверяли: проверочный отрезок брали из той же эпохи поиска, с тем же интерфейсом и тем же медийным режимом. Разделение по времени помогает, только если в holdout попал другой режим.

Сначала модель не увидела пандемию, потом завысила сезон вдвое

Первое расхождение случилось весной 2009 года: вспышка H1N1 пришла вне сезонного окна, и оценки, построенные на связке «зима — грипп», к этому готовы не были. Модель пересобрали, и это показывает природу конструкции: чтобы поправить прокси, нужно уже знать правильный ответ из другого источника.

Второе стало публичным. В феврале 2013 года Nature сообщил, что GFT показывает более чем двукратную по сравнению с CDC долю визитов с гриппоподобными симптомами. Через год разбор в Science — «The Parable of Google Flu: Traps in Big Data Analysis» — описал это не как неудачную неделю, а как устойчивое смещение: с августа 2011 по сентябрь 2013 года оценки были завышены в 100 неделях из 108.

Сто недель из ста восьми важнее величины ошибки на пике: случайный шум дал бы примерно равное число промахов вверх и вниз, а односторонний промах означает, что поменялось определение считаемой величины.

Хронология расхождения по публичным разборам
КогдаЧто с оценкойКак объясняют
весна 2009внесезонная вспышка H1N1 прошла мимо моделисвязь выучена на зимних сезонах
февраль 2013выше данных CDC более чем вдвое (Nature)новостной фон и влияние самого поиска
2011–2013завышение в 100 неделях из 108 (Science, 2014)смещение, а не разовая ошибка
2015публикация текущих оценок прекращенасигнал передан исследовательским группам

Прогноз по данным CDC двух-трёхнедельной давности оказался точнее большой модели

Самая неприятная часть разбора в Science — не описание ошибки, а сравнение. Простые модели на официальных данных CDC двух-трёхнедельной давности давали более точную оценку текущей недели, чем GFT: инерция старых, но правильно измеренных данных обыгрывала свежий сигнал из миллионов запросов.

Там же второй результат, который часто забывают: лучше всего работала комбинация — поисковый сигнал плюс лагированные официальные данные. Прокси содержал информацию, которой в отчётах CDC не было. Его ошибка была не в наличии, а в одиночестве.

Рабочее правило отсюда короткое: прежде чем показывать модель как улучшение, посчитайте на том же периоде наивного соперника.

Поиск менялся сам, и метрика менялась без всякой эпидемии

Дальше начинается объяснение, а не измерение, и это стоит проговорить прямо: причины расхождения восстановлены по косвенным признакам, изнутри продукта их никто не показывал. Основная версия состоит из двух частей, и обе для аналитика практичны.

Первая — сам продукт. Поиск за эти годы менялся: подсказки при наборе, блоки связанных запросов, изменения в выдаче. Если интерфейс предлагает продолжение «симптомы гриппа» человеку, набравшему «симптомы», частота запроса растёт без единого нового больного. Признак модели оказался частью продукта, который не согласовывает релизы с измерительной системой.

Вторая — медийная. Сезон 2012/13 широко освещался, а публичные оценки GFT сами были новостью: человек читает о тяжёлом сезоне, идёт искать симптомы, запрос попадает в модель, оценка растёт. Такому контуру не нужно, чтобы заболеваемость выросла, — достаточно внимания к теме.

Связь между запросом и болезнью не была константой, а модель считала её постоянной.

Объём данных уменьшает разброс и не трогает смещение

Ошибка оценки раскладывается на две части: разброс и систематический сдвиг. Размер выборки работает только с первой. Миллионы запросов делают недельную оценку стабильной — интервал узкий, график гладкий, повторный замер даёт почти то же число. Если величина измеряет не то, что нужно, уверенность в неправильном ответе растёт вместе с объёмом данных.

Выглядит это обманчиво спокойно: смещённая метрика с большой выборкой ведёт себя как надёжная — без скачков, с сезонностью, воспроизводимо. Поэтому смещение ловят не статистикой внутри метрики, а сверкой с чем-то снаружи.

Отсюда порядок приоритетов: сначала определение и состав, потом источник, и только потом размер выборки и значимость.

Из чего состоит ошибка оценки
MSE = смещение² + разброс, где разброс ≈ σ² / n

Рост n сжимает второе слагаемое и не касается первого. Прокси, завышающий на 30%, на выборке в сто раз больше завышает так же — только с более узким интервалом вокруг неправильного числа.

Публичные оценки закрыли, а сигнал остался — как одна из входных переменных

В 2015 году Google перестал публиковать текущие оценки Flu Trends и перешёл к передаче данных исследовательским группам. Это не «идея оказалась пустой», а смена роли: из самостоятельного публичного показателя сигнал стал одним из признаков внутри моделей, рядом с официальными данными наблюдения и регулярной перекалибровкой.

Для аналитика это и есть рабочая развязка кейса. Быстрый прокси полезен, пока у него три свойства: он не единственный источник, у него есть медленный независимый якорь, и связь между ними регулярно пересчитывается. Уберите любое из трёх — получите ту же конструкцию, которая дала 100 завышений из 108 недель.

У вас та же конструкция: метрику создаёт ваш собственный интерфейс

Масштаб другой, схема та же. Почти в каждом продукте есть метрика, числитель которой производят не только пользователи, но и поверхности самого продукта: подсказки в поиске, блок рекомендаций, письмо, пуш, чеклист онбординга. Такая метрика растёт от релиза и выглядит как рост интереса.

Частый случай на маркетплейсах — поисковый спрос по категории. Команда поиска добавляет автодополнение и блок «похожие запросы», и запросов с нужным словом за две недели становится на треть больше. Если на сигнале стоит закупка, вы закупаете под подсказку. Метрика посчитана правильно, и выросли обе её части: подсказки видят все, поэтому прибавляет и число уникальных искавших.

Второй случай — поддержка как индикатор проблем. Добавили кнопку «сообщить о проблеме» на экран оплаты, обращения выросли в полтора раза, это зачли как деградацию платежей. Логи шлюза показывают неизменную долю отказов: изменилось удобство жалобы, а не надёжность.

Метрики, которые частично производит интерфейс
МетрикаЧто двигает её без изменения поведенияВнешний якорь
запросы по категорииавтодополнение, блок похожих запросовоплаченные заказы категории
просмотры товараблок рекомендаций на главнойкорзины с органического входа
DAUпуш и рассылка в день замерасессии не по ссылке из письма
обращения в поддержкуновая кнопка жалобы на экранеотказы в логах шлюза
activation rateчеклист, подсказывающий действиевозврат к задаче на второй неделе

Внешний якорь — это источник, который ничего не знает про ваш интерфейс

Якорь не обязан быть быстрым, полным и красивым. У него одно обязательное свойство: он производится другим процессом, с другой целью, и изменение вашего экрана на него не влияет. Деньги в биллинге существуют для бухгалтерии, отгрузки — для склада, коды ответа — для платёжного провайдера.

Внутренняя витрина того же события якорем не является, даже если лежит в другой схеме. Если оба числа выходят из одного потока событий, они разъедутся одинаково, и сверка покажет согласие там, где его нет: берут вторую метрику вместо второго источника.

Полнота тоже не обязательна — якорю достаточно пересекаться с прокси по времени и сегменту. Опрос пятидесяти пользователей в месяц, недельная выгрузка из 1С, звонки по двадцати отказам: этого хватает, чтобы заметить, что отношение поехало.

  • Биллинг и бухгалтерия — для выручки, заказов, подписок и возвратов.
  • Склад, логистика, коды ответа провайдера — для операций и сбоев.
  • Звонки и обращения с ручной разметкой — для причин, которых нет в событиях.
  • Короткий регулярный опрос — для того, что не оставляет следа в логах.
  • Правило отбора: якорь не меняется, когда вы меняете интерфейс.

Проверка первая: смотрите состав события, а не только его количество

Первая проверка занимает один запрос и отвечает, кто произвёл рост. Разложите событие по точке входа, поверхности и версии клиента и смотрите на доли, а не на абсолютное число. Рост запросов при неизменном числе искавших и растущей доле входа из подсказки — это интерфейс. Рост и в числе людей, и в действиях на человека при стабильных долях — ближе к поведению.

Разрез по точке входа заводят заранее: если в событии нет поля «откуда пришёл этот запрос», задним числом его не восстановить. Минимальный набор атрибутов — поверхность, точка входа, версия клиента, признак кампании.

Порог держите простым: доля любого источника сдвинулась больше чем на 10 процентных пунктов за две недели — сигнал считается неподтверждённым, пока не сверен с якорем.

sqlКто произвёл рост: люди, частота или подсказки
select
  date_trunc('week', occurred_at) as week,
  count(*)                        as searches,
  count(distinct user_id)         as searchers,
  round(1.0 * count(*) / count(distinct user_id), 2) as per_user,
  round(100.0 * count(*) filter (where entry_point = 'suggest') / count(*), 1) as suggest_share,
  round(100.0 * count(*) filter (where entry_point = 'manual')  / count(*), 1) as manual_share
from search_events
where occurred_at >= current_date - interval '180 days'
group by 1
order by 1;

Проверка вторая: отношение прокси к якорю на скользящем окне

Вторая проверка следит не за метрикой, а за связью. Считайте по неделям отношение прокси к якорю — например, уникальных искавших категорию к оплатившим в ней — и сравнивайте с уровнем предыдущих недель. Пока отношение в коридоре, прокси читается как оценка предмета. Когда уезжает, изменился прибор.

Порог выбирайте по собственному шуму, а не по красивому числу. На небольших объёмах недельное отношение гуляет само, поэтому база считается по 8–12 неделям, а срабатыванием считается выход за ±20% два раза подряд. Одна неделя за границей — повод посмотреть, две — повод не ставить на сигнал решение.

То же отношение считайте по крупным сегментам: мобильный и десктоп, новые и старые, каждая большая категория. Интерфейсные изменения приходят в один сегмент первыми.

Модельный пример: прокси и якорь расходятся после релиза подсказок

Числа условные, взяты ради формы сигнала: оба ряда приведены к 100 на первой неделе. Релиз подсказок на пятой неделе поднимает прокси на треть, заказы остаются на прежнем тренде. Отношение между рядами уезжает и не возвращается.

Поисковый прокси, индексОплаченные заказы, индекс
sqlОтношение прокси к якорю против своей же базы
with proxy as (
  select date_trunc('week', occurred_at) as week,
         count(distinct user_id)         as searchers
  from search_events
  where query_category = 'electronics'
  group by 1
),
anchor as (
  select date_trunc('week', paid_at) as week,
         count(distinct user_id)     as buyers
  from orders
  where category = 'electronics'
    and status = 'paid'
  group by 1
),
joined as (
  select p.week,
         p.searchers,
         a.buyers,
         1.0 * p.searchers / nullif(a.buyers, 0) as ratio
  from proxy  as p
  join anchor as a using (week)
)
select week,
       searchers,
       buyers,
       round(ratio, 2) as ratio,
       round(avg(ratio) over (order by week
                              rows between 12 preceding and 1 preceding), 2) as ratio_base,
       round(100.0 * (ratio / nullif(avg(ratio) over (order by week
                              rows between 12 preceding and 1 preceding), 0) - 1), 1) as deviation_pct
from joined
order by week;

Проверка третья: календарь релизов лежит в той же таблице, что метрика

Большая часть необъяснимых изменений метрики объясняется одной строкой из чужого релиз-плана. Чтобы она нашлась за минуту, нужен скучный артефакт: таблица с датой, поверхностью, описанием изменения и владельцем. В неё попадают не только фичи, но всё, что двигает поведение: подсказки, рекомендации, сортировка выдачи, тексты писем, расписание пушей, онбординг.

Дальше таблица соединяется с недельным рядом метрики и отмечается на графике. Разбор скачка начинается с вопроса «что выпустили на этой неделе», и это экономит больше времени, чем любая статистика. Журнала нет — заведите с текущей недели, прошлое восстанавливать не обязательно.

Полезная добавка — оставить поверхность, до которой подсказки и рекомендации не доходят: один вход, один сегмент, один город. Не ради чистоты эксперимента, а чтобы был канал, где метрика не зависит от интерфейсных изменений.

Минимальная версия журнала

Дата, поверхность, что изменилось, владелец, ожидаемое влияние. Пять колонок и одна строка на релиз — этого хватает, чтобы разбор начинался с факта, а не с версий.

Проверка четвёртая: наивный прогноз как обязательный соперник

Если на прокси стоит прогноз, у него должен быть соперник, которого не стыдно показать в отчёте. Наивные модели считаются за полчаса и показывают, сколько качества даёт сама инерция ряда, а сколько добавила ваша конструкция.

Считайте все варианты на одном периоде, который не участвовал в настройке, и показывайте ошибки рядом. Разница в пределах десятой доли — повод оставить наивный вариант: он проще и не ломается от смены интерфейса. Разница заметная — повод описать, за счёт чего она получилась.

Отдельно смотрите на знак ошибки по неделям. Ровный баланс промахов вверх и вниз — нормальный шум. Односторонний перекос, как 100 недель из 108, — это уже не точность, а определение: считается не та величина.

Наивные соперники, с которыми сравнивают прогноз
СоперникКак считаетсяЧто проверяет
последнее значениепрогноз недели = факт прошлойесть ли что-то кроме инерции
сезонный наивта же неделя год назад с поправкой на трендне выдаётся ли сезонность за предсказание
среднее за 4 неделисреднее последних четырёх значенийустойчивость к выбросам
якорь с лагомподтверждённые данные двух недель назаддаёт ли скорость выигрыш в точности

Что из этой истории не переносится на продукт с 3 000 DAU

Главное отличие стоит назвать честно: у GFT был независимый национальный измеритель, с которым можно сверяться каждую неделю. У локального продукта такого реестра нет, и роль якоря приходится собирать из биллинга, склада, логов провайдера и ручной разметки. Решение о том, какой источник считается правдой, принимают люди, а не данные.

Второе отличие — природа риска. На больших объёмах мешает не шум, а смещение. На трёх тысячах активных пользователей недельное отношение прокси к якорю гуляет само, и резкий порог даст поток ложных тревог: отсюда база по 8–12 неделям и срабатывание по двум неделям подряд.

Третье — инструменты. Ни отбор признаков из миллионов кандидатов, ни платформа экспериментов тут не нужны. Переносятся привычки: назвать предмет измерения отдельно от данных, держать независимый якорь, вести журнал релизов, сравнивать с наивным прогнозом.

С чего начать на этой неделе

Возьмите одну метрику, на которой стоит регулярное решение — закупка, бюджет канала, приоритет бэклога. Выпишите для неё два предложения: что она измеряет по смыслу и что физически лежит в её числителе. Если во второй фразе появляются подсказки, рекомендации, письма или кнопки, дальше нужен якорь.

Затем соберите три запроса: состав события по точке входа, отношение к якорю по неделям и соединение с журналом релизов. История Google Flu Trends полезна именно этим: ошибка была не в объёме данных и не в математике, а в отсутствии второго, независимого взгляда на ту же величину.

  • Назовите предмет измерения и содержимое числителя разными фразами.
  • Выберите якорь, который не меняется от ваших релизов.
  • Добавьте в событие точку входа и поверхность, если их там нет.
  • Заведите журнал релизов с этой недели и отмечайте его на графиках.
  • Сравните прогноз с наивным и смотрите на знак ошибки, а не только на размер.
Продолжить чтение
Вся библиотека
Продуктовая аналитика30 октября 2026 г.20 мин

Airbnb и смещения в экспериментах: почему группы не независимы

Интерференция между вариантами в маркетплейсе: как перетекание спроса, длинный цикл решения и реакция предложения искажают A/B-тест, и какими проверками это видно на своих данных.

Читать материал
Продуктовая аналитика29 октября 2026 г.16 мин

Эксперименты Booking.com: дисциплина решений вместо значимости

Как устроена культура A/B-тестов Booking.com и какая у масштаба обратная сторона: множественные сравнения, эффект новизны, пересечение тестов и локальная оптимизация одного экрана. Что из этого переносится в команду на 3–10 тестов в квартал.

Читать материал
Продуктовая аналитика28 октября 2026 г.16 мин

Spotify: почему хороший эксперимент не обязан выиграть

Spotify публично считает learning rate 64% при win rate 12%: как устроен их критерий «эксперимент с обучением», почему нейтральный тест без мощности не считается знанием и что записать в карточку до старта, чтобы отрицательный результат стал решением.

Читать материал