Задача
К нам приходит сеть фитнес-клубов с понятной болью: клиенты уходят, а понять, кто именно и когда – нельзя. В фитнесе это ощущается сильнее, чем в других подписках: человек не пишет заявление и не отменяет договор. Он просто перестаёт ходить. Формально абонемент ещё действует, фактически клиента уже нет.
Стандартная реакция – рассылка скидок по всей базе раз в квартал. Это дорого и бьёт мимо: большая часть получателей и так собиралась остаться, а те, кто уже принял решение уйти, на скидку не реагируют – у них другая причина.
Задача формулируется в два шага. Первый: найти тех, кто на грани, заранее. Второй, который обычно забывают: понять, что именно им предложить.
Почему общий список по базе не работает
Первое, что напрашивается – обучить модель, отсортировать всю базу по риску и обзванивать верхушку. Так я и сделал, и на этом обжёгся.
В верх общего рейтинга попадают почти одни клиенты с высоким базовым риском: те, кто купил месяц и сходил два раза. У них риск ухода 24% против 1% у клиента с годовым корпоративным контрактом. Общий список ими и забивается.
Проблема в том, что уходящие есть и в надёжных группах, и терять их обиднее: такой клиент платит вперёд, приносит доптраты, держится дольше. Но в общий топ он не попадёт никогда – его риск ниже, чем у любого «месячника».
И вторая, менее очевидная беда. Вероятность 40% значит разное для разных людей. Для клиента с годовым контрактом это ЧП: что-то случилось – травма, переезд, конфликт с тренером. Для купившего месяц – обычный вторник. Один порог для обоих бессмысленен.
Пять портретов вместо одного списка
Разделил базу на пять групп – по поведению и условиям, а не по демографии.
| портрет | доля базы | отток за 15 дней | чем отличается |
|---|---|---|---|
| Купил месяц и пропал | 30% | 24% | короткий абонемент, ходит редко, активность просела |
| Живёт далеко | 15% | 18% | клуб не по пути, знакомых в зале нет |
| Нет телефона в базе | 10% | 7% | средний по всему, но с ним нельзя связаться |
| Ходит часто | 19% | 4% | 2,8 раза в неделю, абонемент тоже короткий |
| Годовой от партнёра | 26% | 1% | оплачен работодателем, ходит на групповые |
Разрыв между крайними – в 24 раза. Работать с ними одинаково – всё равно что лечить перелом и насморк одной таблеткой.
Отдельно стоит посмотреть на два средних портрета. У «ходит часто» абонемент такой же короткий, как у самого рискового – 2,6 месяца против 2,0. А отток в шесть раз ниже. Решает не длина контракта, а привычка. Это ломает интуицию владельца, который считает, что спасение в годовых картах: карта не удерживает, удерживает регулярность посещений.
Как это работает
- Собираем данные. Минимум – кто и когда пришёл, что покупал и когда. Если клуб ведёт журнал посещений (турникеты, отметки на ресепшене, вход по QR в приложении) – точность заметно выше. Обязательно нужны ушедшие: модель учится на разнице между теми, кто остался, и теми, кто перестал ходить. По активной базе учиться не на чем – примеров ухода в ней нет.
- Режем историю снапшотами. Каждые две недели фиксируем состояние клиента на этот день и считаем признаки строго по данным до этой даты. Метка – ушёл ли он в следующие 15 дней. Это единственный способ учиться честно: если хоть один признак заглянет в будущее, модель покажет красивые цифры и развалится в проде.
- Обучаем градиентный бустинг. CatBoost, два десятка признаков, валидация строго по времени: учимся на раннем периоде, проверяем на позднем. Случайное разбиение здесь врёт – оно позволяет подглядеть будущее соседних снапшотов того же клиента.
- Ранжируем внутри портрета. Модель считает риск каждому, дальше берём верхние 25% в каждом портрете отдельно. Сам портрет в обучение не подаётся – это ярлык для работы с результатом. Модель получает только сырые признаки, из которых портрет и складывается: у реального клиента метки «портрет 3» в базе нет.
- Отдаём боту. Список с причиной по каждому уходит голосовому боту – он обзванивает и делает предложение. Разное для разных портретов.
Что предлагать: плюшка под портрет
Главное правило – не сваливаться в скидку. Из пяти портретов она уместна для одного, и то как апсейл.
Купил месяц и пропал. У него нет привычки, деньги ни при чём. Работает бесплатное занятие с тренером или запись на групповое: задача – привести в зал ещё раз.
Живёт далеко. Проблема в дороге. Скидка мимо: помогает другой клуб сети поближе к дому или работе, гостевой доступ во все точки. Если сеть одна – честно предложить заморозку вместо ухода.
Нет телефона. Это вообще не задача удержания, а задача данных. Такого клиента бот не наберёт – его выносим в отдельный список для администратора, контакт добираем при следующем визите.
Ходит часто. Он уже лоялен. Ему предлагаем годовой абонемент со скидкой: клиенту выгодно, клуб получает деньги вперёд и снижает риск в разы. По сути это апсейл под видом удержания.
Годовой от партнёра. Если у такого вырос риск – случилось что-то серьёзное. Здесь нужен личный звонок и выяснение причины, а не оффер.
Отдельная находка: доптраты в кафе и на массаж – признак вовлечённости. Кто тратит в клубе, уходит реже. Поэтому для средних портретов часто выгоднее бонус на доптраты, чем скидка на абонемент: клубу дешевле, а клиента втягивает глубже.
Результат
Подробный разбор с калькулятором потерь – на странице услуги.
Стек
Грабли, на которые наступил
Первая модель показала 0,96 и оказалась пустышкой. Признак «дней до конца абонемента» забрал 90% важности – модель просто считала дни до окончания контракта. Формально утечки не было, но история получалась бессмысленная: такое и без машинного обучения видно в календаре. Пришлось переделать генерацию данных так, чтобы поведенческий уход не совпадал с датой окончания абонемента – в жизни человек перестаёт ходить задолго до того, как кончится оплаченный период.
Горизонт 60 дней оказался бесполезен. Начинал с двух месяцев, как принято в подписочных сервисах. Для фитнеса это мимо: клиент с месячным абонементом весь живёт 30 дней, предупреждать за 60 – всё равно что предсказывать погоду на прошлой неделе. Сократил до 15 дней – и точность выросла, и список стал рабочим: «звонить сегодня», а не «когда-нибудь».
Средний срок жизни клиента – ловушка. Считал, что удержанный принесёт ещё столько же, сколько живёт средний клиент. Это неверно: средний срок считается по всем сразу, одни его давно прошли, другие не дойдут никогда. А удержанный – это тот, кто уже собирался уйти, он заведомо не средний. Сейчас считаю только тот месяц, который человек оплатил, всё сверх – не обещаю.
Телефон есть не у всех. В данных 10% клиентов без контакта. На отток это почти не влияет, но для обзвона критично: бот их не наберёт. Это признак не риска, а достижимости – и он требует отдельного процесса.
Вопросы и ответы
Данные настоящие?
Нет, и это важно проговорить. Модель обучена на модельном наборе, собранном по типовым показателям фитнес-рынка: месячный отток, доли портретов, частота посещений, длина абонементов. Реальную клиентскую базу для демонстрации мы не используем. Методика при этом настоящая – на данных клуба она воспроизводится один в один, меняются только цифры.
Сколько данных нужно?
Год истории. Обязательно вместе с ушедшими – без примеров ухода учиться не на чем. Персональные данные не нужны: имена и телефоны заменяются номерами.
А если клуб не ведёт учёт посещений?
Модель будет работать, но предупреждать позже. Платежи дают базовый сигнал – приближение конца абонемента, история продлений. Журнал визитов добавляет главное: спад активности, который начинается за недели до решения уйти.
Что с сетью из нескольких клубов?
Учим одну модель на всей сети, а решения принимаем по каждому клубу отдельно. Клуб на 2000 человек даёт слишком мало событий, чтобы обучать отдельную модель, но различия между точками модель учитывает как признак. А списки на обзвон формируются локально – бюджет и персонал у каждого клуба свои.
Как понять, что это вообще сработало?
Только контрольной группой. Часть рисковых клиентов намеренно не обзваниваем и сравниваем отток с теми, кого обработали. Без этого любые цифры – вера, а не измерение.
Сколько это занимает?
Модель на готовых данных – несколько дней. Основное время уходит не на обучение, а на данные: выгрузку, сверку, разметку оттока. Дальше пилот с контрольной группой – месяц-полтора, чтобы накопить статистику.