Почему Маркетологи прибегают к экспериментам с Квазигеолифтами? (И как их планировать)

Автор: Дмитрий Иванов [Команда P9X]

~8 минут чтения

Краткая выжимка статьи о Quasi Geo-Lift

Суть метода

Quasi Geo-Lift — это подход для измерения ROI маркетинговых кампаний через геолокационные эксперименты, используя синтетические контрольные группы. Не требует рандомизации пользователей или пиксельного отслеживания.

Три типа Geo-тестов

  • РКИ на платформе (VK, Google) — стандартный вариант, если доступен.
  • Geo-RCT — города случайно распределяются между тестом и контролем.
  • Квазиэксперимент (основной фокус) — выбираете города сами, синтетический контроль строится из исторических данных других городов.

Почему квазиэксперимент удобнее

  • ✓ Работает с меньшим количеством географических единиц (3–5 городов)
  • ✓ Можно запустить ретроспективно (после запуска кампании)
  • ✓ Нет привязки к платформам типа VK или Google
  • ✓ Полный контроль: выбираете, где, когда и как тестировать

Структура ABCDE

  • (A) Оценка — определяете, что измеряете (lift, CPIC, чистую прибыль)
  • (B) Бюджет — рассчитываете минимальный расход, чтобы обнаружить нужный эффект (MDE)
  • (C) Конструирование — выбираете обработанные и контрольные города, операционные ограничения
  • (D) Доставка — переводите результаты в бизнес-метрики (ATT → CPIC → прибыль)
  • (E) Оценка — калибруете MMM/MTA, запускаете плацебо-тесты, масштабируете на новые рынки

Пример (Bolt)

  • 13 городов Польши, ежедневные данные с 2022 года
  • Новый канал (TweetX) запускается 18.09.2023
  • 3 города в тесте, 10 контрольных, 21 день
  • MDE ~4–5%, бюджет €3,038
  • Результат: +11% подъём = +X дополнительных поездок = €Y чистой прибыли

Ключевые требования к данным

  • Минимум 25 дней исторических данных до теста (в 4–5 раз длиннее теста)
  • Минимум 10–20 географических единиц (города, регионы)
  • Ежедневные данные вместо еженедельных
  • Никаких пропусков в данных
  • Данные за 52 недели для учёта сезонности

Главный результат

ATT (Average Treatment Effect on Treated) — среднее влияние на обработанные города в день (например, +X поездок/день/город). Из этого считаются CPIC, ROI, чистая прибыль, MDE и интервалы неопределённости.

💡 Примечание: код Python для Geo-Lift в конце статьи.

За время своей карьеры я использовал квазиэкспериментальные планы с синтетическими контрольными группами для измерения влияния изменений в бизнесе. В Trustpilot мы изменили положение баннера на главной странице и ретроспективно увидели сигналы, указывающие на снижение нашего основного показателя спроса. Моделируя, как бы выглядела производительность без изменений, и сравнивая её с тем, что произошло, мы получили чёткое представление о дополнительном снижении. В Zensai мы решили обработать некоторые наши веб-формы и аналогичным образом подтвердили, оказывает ли изменение положительное влияние на лёгкость заполнения форм, о которой сообщают пользователи.

Этот подход работает везде, где вы можете разделить что-то на экспериментальные и контрольные группы: отдельных лиц, смартфоны, операционные системы, формы или целевые страницы. Вы обрабатываете некоторые из них. Остальные помогают вам смоделировать, что произошло бы без обработки. Затем вы сравниваете.

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

Есть три практических подхода для выделения дополнительного воздействия:

  1. Рандомизированные контролируемые испытания (РКИ), такие как тесты на конверсию или бренд, привлекательны, когда вы можете использовать их в больших рекламных платформах. Они автоматизируют назначение пользователей случайным образом и могут давать статистически надёжные ответы в среде платформы. Однако, если вы не используете API конверсии, их возможности ограничены метриками и механизмами платформы.

  2. Geo-RCT (рандомизированные географические эксперименты) используют географию в качестве единицы анализа с рандомизированным назначением в экспериментальную и контрольную группы. Нет необходимости в отслеживании на индивидуальном уровне, но вам нужно достаточное количество географических единиц для достижения статистической мощности и уверенных результатов. Поскольку назначение рандомизировано, вы не создаёте синтетический контроль, как в следующем типе эксперимента.

  3. Квазигеоэксперимент подходит к тому же вопросу, используя географические единицы анализа, без необходимости отслеживания на индивидуальном уровне. В отличие от Geo-RCT, которые требуют рандомизации и большего количества географических единиц, этот квазиэкспериментальный подход предлагает три ключевых преимущества без необходимости рандомизации:

    • а) хорошо работает с меньшим количеством географических единиц (не нужно много географических единиц, как в Geo-RCT);
    • b) обеспечивает стратегический выбор рынка (прямой контроль над тем, где и когда применяется обработка, на основе бизнес-приоритетов);
    • c) размещает ретроспективный анализ и поэтапное развёртывание (если ваша кампания уже запущена или должна быть запущена поэтапно по операционным причинам, вы всё равно можете измерить дополнительное воздействие после).

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

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

Пример квазигеоэксперимента

Рис. 2: Пример квазиэксперимента (источник: собственное производство)

Рассмотрим компанию по заказу поездок, такую как Bolt, оценивающую новый канал в Польше. Бизнес некоторое время держал новый канал на радаре и теперь хочет его протестировать. Необходимо понять, как потенциально новая кампания по этому новому каналу под названием TweetX влияет на поездки, и какой минимальный бюджет требуется для обнаружения воздействия. Доступный набор данных — это ежедневная панель поездок, охватывающая 13 польских городов, начиная с 2022 года. Предлагаемая дата начала — 2023–09–18, и активация может быть национальной или городской. Практические ограничения: пользователи не могут быть включены в отдельные экспериментальные и контрольные группы, поскольку кампания по новому каналу нацелена только на новых пользователей. Это исключает A/B-тестирование на уровне пользователей. Кроме того, условия конфиденциальности не позволяют полагаться на отслеживание атрибуции.

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

Для проведения теста Geo-Lift с использованием дизайна синтетической контрольной группы на нашем примере мы будем использовать пакет GeoLift в R, разработанный VK. Набор данных, который я буду использовать, структурирован как ежедневные подсчёты поездок по 13 городам Польши.

Рис. 3: Набор данных для квазигеоэксперимента (источник: собственное производство)

Лучшие практики для ваших данных при использовании квазигеоэксперимента.

  • Используйте ежедневные данные вместо еженедельных, когда это возможно.
  • Используйте наиболее подробные данные о местоположении (например, почтовые индексы, города).
  • Имейте как минимум в 4–5 раз больше продолжительности теста в стабильных, докампанейных исторических данных (без серьёзных изменений или сбоев — подробнее об этом позже в главе об операционализации!).
  • Имейте как минимум 25 докампанейных периодов с минимум 10, но в идеале 20+ географических единиц.
  • В идеале собирайте данные за 52 недели, чтобы учесть сезонные закономерности и другие факторы.
  • Тест должен длиться не менее одного цикла покупки для продукта.
  • Проводите исследование не менее 15 дней (ежедневные данные) или 4–6 недель (еженедельные данные).
  • Панельные данные (ковариаты) полезны, но не обязательны.
  • Для каждой комбинации времени и местоположения включайте дату, местоположение и KPI (без пропущенных значений). Дополнительные ковариаты можно добавить, если они также соответствуют этому правилу.

Планирование вашего квазигеоэксперимента

Рис. 4: Планирование квазигеоэксперимента (источник: собственное производство)

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

Для запуска любого нового канала или кампании следует подходить поэтапно. Вот моя ABCDE структура, которая может вам в этом помочь:

(A) ОЦЕНКА

  • Установите, как будет измеряться дополнительность, и какой метод будет использоваться.

(B) БЮДЖЕТ

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

(C) КОНСТРУИРОВАНИЕ

  • Укажите, какие города будут обработаны, как будут сформированы контрольные группы, как долго продлится кампания и какие операционные ограничения необходимы.

(D) ДОСТАВКА

  • Преобразуйте статистические результаты в метрики и представьте результаты в виде отчётности.

(E) ОЦЕНКА

  • Используйте результаты для принятия более широких решений путём обновления MMM и MTA. Сосредоточьтесь на калибровке, стресс-тестировании, репликации и локализации для развёртывания.

(A) ОЦЕНКА маркетинговой переменной триагулирования

Рис. 5: Маркетинговая триагулированная структура и разбивка дополнительности (источник: собственное производство)

1. Маркетинговое триагулирование как отправная точка.

Начните с оценки того, какой частью маркетинговой триагулированной структуры вам нужно будет разбить. В нашем случае это будет дополнительность. Для других проектов аналогичным образом разбейте MTA и MMM. Например, MTA раскрывает эвристические методы вроде последнего клика, первого клика, первого или последнего касания с затуханием, (перевёрнутой) U-образной формы или W-образной формы, но также и данные, основанные на подходах вроде цепи Маркова. MMM может быть пользовательским, сторонним, Robyn или Meridian и включает дополнительные шаги вроде насыщения, адстока и перераспределения бюджета. Не забудьте настроить метрики измерения.

2. Дополнительностть операционализируется через тест Geo-Lift.

Тест Geo-Lift — это практическое выражение фреймворка, поскольку он считывает результат в тех же единицах, которыми управляет бизнес, таких как поездки (или продажи, конверсии, лиды) в день на город. Он создаёт экспериментальные и контрольные группы так же, как это сделал бы классический рандомизированный эксперимент, но делает это на географическом уровне.

Рис. 6: Тест Geo-Lift против пользовательского RCT конверсионного теста (источник: собственное производство)

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

3. Признание двух экспериментальных семейств теста Geo-Lift: РКИ и квазиэксперименты.

Там, где существуют рандомизированные контролируемые испытания на платформе (например, конверсионные или брендовые тесты подъёма), они остаются стандартом и могут быть использованы. Когда индивидуальная рандомизация невозможна, тест Geo-Lift проводится как квазиэксперимент.

4. Идентификация основана на методе синтетического контроля.

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

5. Калибровка и валидация — явные шаги, а не запоздалые мысли.

Экспериментальная оценка дополнительности используется для проверки того, что сигналы атрибуции указывают в правильном направлении, и для калибровки MMM эластичности и адстока (через калибровочный множитель), чтобы перекрёстное распределение бюджета основывалось на причинной истине.

Рис. 7: Как откалибровать ваш MTA и MMM. Используйте результаты квазигеоэксперимента для калибровки вашего MTA/MMM с помощью калибровочного множителя (источник: собственное производство)

Другие калибровочные моменты, о которых следует помнить:

  • а) Рассматривайте каждый эксперимент как распределение и используйте полный интервал для подъёма, ROI или CPA, чтобы сохранить неопределённость. Если вы проигнорируете интервал, вы потеряете многое из того, за что заплатили, и рискуете принять неправильное решение.
  • б) Результаты привязаны ко времени проведения теста, поэтому уделяйте меньше внимания по мере удаления от окна тестирования. Ваша уверенность должна уменьшаться по мере удаления от окна, потому что платформы и рынки меняются.
  • в) Маркетинговая эффективность меняется со временем. Изменения макросреды меняют и результаты вашей маркетинговой эффективности, что вполне нормально и не является красным флагом. Это важно для калибровки, потому что старая фиксированная подъёмность, заложенная в модель, которую вы используете сегодня, может выйти из синхронизации с реальностью (в основном из-за аукционов, аудитории, качества креатива и макро). Парадоксально, но вы можете даже выиграть от удаления калибратора из модели.

6. Измерьте воздействие в бизнес-терминах.

На этапе планирования основной статистикой является средний эффект воздействия на обработанных (ATT), выраженный в единицах результата в день (например, поездки на город в день). Эта оценка переводится в общее количество дополнительных поездок за тестовое окно, а затем в стоимость за дополнительную конверсию (CPIC) путём деления расходов на общее количество дополнительных поездок. Минимальный обнаруживаемый эффект (MDE) сообщается, чтобы сделать чувствительность дизайна явной и отделить действенные результаты от неубедительных. Наконец, чистая прибыль рассчитывается путём объединения исторической прибыли от поездок с дополнительными результатами и CPIC.

Общее количество дополнительных лидов можно умножить на смешанную историческую конверсию от лида к клиенту, чтобы оценить, сколько новых клиентов может генерировать кампания. Эта цифра затем умножается на среднюю прибыль на клиента в долларах. Таким образом, даже когда выручка реализуется ниже стадии лида, эксперимент всё равно даёт прозрачную оценку дополнительного финансового воздействия и чёткое правило принятия решения о масштабировании канала. Все остальные метрики, такие как ATE, общее количество дополнительных лидов, стоимость за дополнительный лид и MDE, будут рассчитываться аналогичным образом.


(B) БЮДЖЕТ для вашего квазиэксперимента.

Рис. 8: Оценка бюджета для квазигеоэксперимента (источник: собственное производство)

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

На практике дисперсия оценивается по историческим поездкам (или продажам, конверсиям или лидам в других отраслях). Количество обработанных городов и продолжительность определяют чувствительность. Например, как вы увидите позже, обработка трёх городов в течение 21 дня при удержании 10 в качестве контрольных обеспечивает достаточную мощность для обнаружения подъёмов примерно на 4–5%. Обнаружение меньших, но статистически значимых эффектов потребует больше времени, больше рынков или больше расходов.

Пакет Geo-Lift моделирует эти анализы мощности и затем выводит диаграмму моделирования бюджета, эффекта и мощности для любого идентификатора эксперимента.

Бюджет согласован с экономикой единицы. В случае с Bolt отраслевые данные предполагают стоимость поездки в размере €6–€12 и прибыль на поездку в размере €6. При таких предположениях минимальный расход для достижения MDE примерно в 5% составляет €3 038 за 3 недели или €48,23 на обработанный город в день. Это укладывается в ориентировочный бюджет в €5 000, но, что более важно, делает явным, какой эффект размера тест может обнаружить, а какой — нет.

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


(C) КОНСТРУИРОВАНИЕ вашего квазиэкспериментального дизайна.

Рис. 9: Выбор лечения и контрольных географических единиц в квазигеоэксперименте (источник: собственное производство)

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

Geo-Lift будет моделировать и группировать идеальные города-кандидаты для вашей обработки.

Контрольные группы — это не просто «как есть».

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

Операционные ограничения имеют решающее значение для защиты качества сигнала.

Рис. 10: Планирование и дизайн квазигеоэксперимента (источник: собственное производство)

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

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

Разработка теста означает выбор правильного баланса.

Рис. 11: Моделирование и ранжирование групп квазигеоэксперимента (источник: собственное производство)

Пакет Geo-Lift сделает за вас всю тяжёлую работу, моделируя и выстраивая все оптимальные эксперименты.

От вашего анализа мощности и функции выбора рынка код, выбор правильного экспериментального макета — это баланс между:

  • количеством городов;
  • продолжительностью;
  • расходами;
  • желаемым дополнительным подъёмом;
  • прибылью;
  • статистической значимостью;
  • соотношением теста и контроля;
  • наименьшим обнаруживаемым подъёмом;
  • другим бизнес-контекстом.

Конфигурация из трёх обработанных городов в течение 21-дневного периода, как в примере с Bolt, обеспечивает достаточную мощность для обнаружения подъёмов на уровне ~4–5%, сохраняя при этом тестовое окно достаточно коротким, чтобы минимизировать загрязнение. На основе предыдущих экспериментов мы знаем, что такой уровень мощности достаточен. Кроме того, нам нужно оставаться в рамках бюджета в €5 000 в месяц, и ожидаемые инвестиции в размере €3 038,16 за три недели хорошо вписываются в эти ограничения.


(D) ДОСТАВКА постэкспериментального отчёта.

Рис. 12: Результаты квазигеоэксперимента (источник: собственное производство)

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

В основе лежит средний эффект воздействия на обработанных (ATT), выраженный в единицах результата в день, таких как поездки, продажи или лиды. Из этого анализа рассчитывается общее количество дополнительных результатов за тестовое окно и выводится стоимость за дополнительную конверсию (CPIC) путём деления расходов на эти результаты. Минимальный обнаруживаемый эффект (MDE) сообщается вместе с результатами, чтобы сделать чувствительность теста прозрачной, отделяя действенные подъёмы от неубедительного шума. Наконец, анализ преобразует результаты в чистую прибыль путём объединения дополнительных конверсий со стоимостью единицы.

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

Будьте осторожны при интерпретации результатов для заинтересованных сторон. Статистический анализ со значением p предоставляет доказательства, а не абсолютные доказательства, поэтому формулировка имеет значение. GeoLift использует синтетический контроль/усовершенствованный синтетический контроль с частотным выводом.


(E) ОЦЕНКА вашего квазигеоэксперимента с более широкой точки зрения.

Рис. 13: Постэкспериментальная оценка и дальнейшие шаги (источник: собственное производство)

Не забывайте смотреть в целом и «видеть лес, а не только деревья».

Результаты должны быть включены в маркетинговую триагулированную структуру путём валидации атрибуции ROAS и калибровки маркетинговых микс-моделей с помощью причинного множителя.

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

Стресс-тестирование с помощью плацебо-тестов (в пространстве или во времени) также укрепит уверенность в ваших выводах.

Рис. 14: Пять случайных плацебо-тестов во времени (источник: собственное производство)

Ниже приведены результаты одного плацебо-теста во времени: +1,3% подъём от плацебо не является статистически сильным, чтобы отвергнуть отсутствие различий между экспериментальной и контрольной группами = H0 (как и ожидалось для плацебо):

Рис. 15: Результаты плацебо-теста во времени (источник: собственное производство)

Включение впечатлений от канала и расходов в перекрёстные взаимодействия в MMM помогает учесть взаимодействия с другими каналами в вашем медиамиксе.

Если кампания не обеспечивает ожидаемого подъёма, несмотря на то, что планирование предполагает, что она должна, важно оценить факторы, не отражённые в количественных результатах: послание или креативная реализация. Часто дефицит может быть объяснён тем, как кампания (не) находит отклик у целевой аудитории, а не недостатками в экспериментальном дизайне.

Что это даёт вам?

Квазигеоэксперимент позволяет вам доказать, действительно ли кампания сдвигает иглу без отслеживания на уровне пользователей или больших рандомизированных тестов. Вы выбираете несколько рынков, создаёте синтетический контроль из остальных и считываете дополнительное воздействие непосредственно в бизнес-единицах (поездки, продажи, лиды). План ABCDE делает это практичным:

  • Оцените маркетинговую триагулированную структуру и то, как вы будете измерять,
  • бюджетируйте до чёткого MDE,
  • сконструируйте экспериментальные и контрольные группы и операционные ограничения,
  • доставьте ATT → CPIC → прибыль, затем
  • оцените путём калибровки MMM/MTA, стресс-тестирования с помощью плацебо и рассмотрения вашего бизнес-контекста с более широкой точки зрения.

Конечный результат? Быстрые, дешёвые, обоснованные ответы, на которые можно действовать.

Полный код:

import pandas as pd
import numpy as np
from datetime import datetime, timedelta
import matplotlib.pyplot as plt

# Загрузка данных
long_data = pd.read_csv("/Users/tomasjancovic/Downloads/long_data.csv")

# Преобразование даты
long_data['date'] = pd.to_datetime(long_data['date'])

# Выбор рынка (анализ мощности)
GeoLift_PreTest = long_data.copy()

# Фильтрация данных до 2023-09-18
cutoff_date = pd.to_datetime('2023-09-18')
GeoTestData_PreTest = GeoLift_PreTest[GeoLift_PreTest['date'] < cutoff_date].copy()

# Добавление временного индекса
GeoTestData_PreTest['time'] = (GeoTestData_PreTest['date'] - GeoTestData_PreTest['date'].min()).dt.days

# Обзорный график
plt.figure(figsize=(14, 6))
for location in GeoTestData_PreTest['location'].unique():
    data = GeoTestData_PreTest[GeoTestData_PreTest['location'] == location]
    plt.plot(data['date'], data['Y'], label=location, alpha=0.7)
plt.xlabel('Date')
plt.ylabel('Y')
plt.legend()
plt.title('GeoLift Pre-Test Data')
plt.show()

# Анализ мощности и выбор рынка (симулированный вывод)
treatment_periods = [14, 21, 28, 35, 42]
N_values = [1, 2, 3, 4, 5]
effect_sizes = np.arange(0, 0.27, 0.02)
cpic = 6
budget = 5000
alpha = 0.05

print("Market Selection Analysis (simulated)")
print("=" * 80)
for period in treatment_periods:
    for n in N_values:
        mde = budget / (n * period * cpic)
        print(f"Period: {period} days | N cities: {n} | MDE: {mde:.2%}")

# ============================================================================
# СИМУЛЯЦИЯ: расширение временного ряда
# ============================================================================

def extend_time_series(data, extend_days):
    """Расширяет временной ряд на extend_days дней"""
    extended_data = []
    
    for city in data['location'].unique():
        city_data = data[data['location'] == city].sort_values('date').reset_index(drop=True)
        
        # Базовое значение (среднее последних 30 дней)
        baseline_value = city_data['Y'].tail(30).mean()
        
        # Эффекты дня недели (последние 60 дней)
        recent_data = city_data.tail(60).copy()
        recent_data['dow'] = recent_data['date'].dt.dayofweek
        dow_effects = recent_data.groupby('dow')['Y'].mean() / recent_data['Y'].mean()
        
        # Генерация новых дат
        last_date = city_data['date'].max()
        new_dates = [last_date + timedelta(days=i+1) for i in range(extend_days)]
        
        # Генерация новых значений
        np.random.seed(123)
        new_values = []
        for date in new_dates:
            dow = date.weekday()
            multiplier = dow_effects.get(dow, 1.0)
            value = baseline_value * multiplier + np.random.normal(0, city_data['Y'].std() * 0.1)
            new_values.append(max(0, round(value)))
        
        # Добавление в результат
        for date, value in zip(new_dates, new_values):
            extended_data.append({'date': date, 'location': city, 'Y': value})
    
    return pd.DataFrame(extended_data)

# Параметры симуляции
treatment_cities = ["Zabrze", "Szczecin", "Czestochowa"]
lift_magnitude = 0.11
treatment_start_date = pd.to_datetime('2023-09-18')
treatment_duration = 21
treatment_end_date = treatment_start_date + timedelta(days=treatment_duration - 1)

# Расширение временного ряда
original_end_date = long_data['date'].max()
days_to_extend = (treatment_end_date - original_end_date).days

extended_data = extend_time_series(long_data, days_to_extend)

# Объединение исходных и расширенных данных
full_data = pd.concat([
    long_data[['date', 'location', 'Y']],
    extended_data
], ignore_index=True).sort_values(['date', 'location']).reset_index(drop=True)

# Применение эффекта обработки
simulated_data = full_data.copy()
simulated_data['Y_original'] = simulated_data['Y']

mask = (
    (simulated_data['location'].isin(treatment_cities)) &
    (simulated_data['date'] >= treatment_start_date) &
    (simulated_data['date'] <= treatment_end_date)
)

simulated_data.loc[mask, 'Y'] = simulated_data.loc[mask, 'Y'] * (1 + lift_magnitude)

# Проверка обработки
verification = simulated_data[
    (simulated_data['location'].isin(treatment_cities)) &
    (simulated_data['date'] >= treatment_start_date) &
    (simulated_data['date'] <= treatment_end_date)
].copy()

verification['actual_lift'] = (verification['Y'] / verification['Y_original']) - 1

verification_summary = verification.groupby('location')[['actual_lift']].mean()
print("\n" + "=" * 80)
print("Treatment Effect Verification")
print("=" * 80)
print(verification_summary)

# Подготовка GeoLift ввода
GeoTestData_Full = simulated_data[['date', 'location', 'Y']].copy()
GeoTestData_Full['time'] = (GeoTestData_Full['date'] - GeoTestData_Full['date'].min()).dt.days

print("\n" + "=" * 80)
print("Final Dataset Shape:", GeoTestData_Full.shape)
print("Date Range:", GeoTestData_Full['date'].min(), "to", GeoTestData_Full['date'].max())
print("Locations:", GeoTestData_Full['location'].nunique())
print("=" * 80)
print(GeoTestData_Full.head(10))