Как мы определяем, что цена выгодная
Дешёвая цена и выгодная цена — разные вещи. Тур в Абхазию за 30 000 ₽ дешевле тура на Мальдивы за 200 000 ₽, но это не значит, что первый выгодный, а второй нет. Выгода видна только в сравнении: сколько похожие туры — то же направление, тот же город вылета, столько же ночей — стоили последние 45 дней. Этим мы и занимаемся.
Ниже описан расчёт для пакетных туров — это основной продукт проекта. Авиабилеты мы тоже наблюдаем, но считаем по отдельной норме, которая с туровской не смешивается; про них есть свой раздел с собственным списком признаков и собственным списком того, чего мы не видим.
Мы копим историю цен
Разово посмотреть на цену бесполезно: не с чем сравнивать. Поэтому мы несколько раз в сутки снимаем цены по одним и тем же наборам параметров и складываем их в базу. Через какое-то время по каждому набору набирается ряд наблюдений — и вот у него уже есть середина, верх и низ.
Из этого ряда и получается норма: обычная цена похожих туров в это время года при такой глубине покупки. Норма не задаётся вручную и не берётся из головы, она пересчитывается из накопленных наблюдений.
Берём не весь архив подряд, а скользящее окно последних 45 дней: цены на туры двигаются вместе с сезоном, курсом и полётной программой, и прошлогоднее наблюдение о сегодняшней норме не говорит ничего. Старые наблюдения из окна выпадают, новые добавляются, норма пересчитывается заново.
Норма — это медиана, а не среднее
Среднее арифметическое для цен не годится, и вот почему. Возьмём девять предложений примерно по 60 000 ₽ и одно за 600 000 ₽ — какой-нибудь люксовый номер, случайно попавший в ту же выборку. Среднее подскочит примерно до 114 000 ₽, хотя ни одно реальное предложение столько не стоит. Медиана в этом же ряду останется около 60 000 ₽, потому что ей всё равно, насколько далеко улетело крайнее значение, — важно только, что оно одно.
Это свойство называется устойчивостью к выбросам, и оно тут решающее. Данные о ценах всегда грязноваты: попадаются опечатки источника, цены за номер вместо цены за человека, случайно затесавшиеся другие продукты. Среднее такие значения утаскивают за собой, медиана их переживает.
Кроме середины мы храним нижнюю и верхнюю части ряда — чтобы понимать не только «сколько обычно», но и «насколько широко разбросаны цены». Там, где разброс велик, поймать выгодное предложение реально; там, где все цены стоят плечом к плечу, охотиться не за чем.
По каким признакам сравниваем
Норма считается не «по Турции вообще», а по набору совпадающих признаков. Иначе получится сравнение несравнимого, и любая цифра будет враньём. В набор входят:
- Направление. Очевидное: Турция и Мальдивы — разные рынки.
- Город вылета. Один и тот же отель из Москвы и из Красноярска стоит по-разному, потому что перелёт разный. Мешать города — значит объявлять выгодной обычную московскую цену для жителя Сибири.
- Длительность. Неделя и две недели — разные товары. Тур на 14 ночей всегда «дешевле нормы», если норма посчитана вперемешку с семидневками, и это не выгода, а ошибка расчёта.
- Глубина бронирования — за сколько дней до вылета покупают тур. Цена за три дня до вылета и за три месяца живёт по разным законам. Мы разбиваем глубину на несколько диапазонов и сравниваем внутри диапазона: горящий тур меряется с горящими, ранний с ранними.
- Питание. «Всё включено» и «только завтраки» отличаются на десятки процентов цены.
- Звёздность отеля. По той же причине.
И сразу о границе этого набора: конкретный отель в него не входит. Мы сравниваем не тот же самый тур с ним же прежним, а предложение с недавними ценами на похожие туры — совпадающие по перечисленным выше признакам. Пятизвёздочный отель на первой линии и пятизвёздочный в километре от моря попадают в один ряд, и разницу между ними наша норма не различает. Поэтому отклонение от нормы — оценка по доступным признакам, а не приговор конкретному отелю.
Плата за такую строгость — дробление данных. Каждый добавленный признак делит выборку на части, и вместо одного ряда из сорока наблюдений можно получить шесть рядов по семь, где считать уже нечего. Поэтому у нас есть нижняя граница: если наблюдений в наборе меньше порога, норма не считается и сигнала не будет вовсе. Лучше промолчать, чем посчитать по трём точкам.
Авиабилеты считаются отдельно от туров
Кроме пакетных туров мы наблюдаем цены на авиабилеты. Это другой товар, и считается он по той же механике, но в собственном ряду: цены на билеты никогда не попадают в одну выборку с ценами на туры.
Причина арифметическая, а не идейная. Тур стоит десятки тысяч рублей, билет — единицы или первые десятки. Сложить их в один ряд — значит получить норму, которая не описывает ни то, ни другое: для билета она завышена в разы, для тура занижена. На такой норме обычный билет выглядит скидкой в 70 %, а настоящая скидка на тур упирается в наш же предохранитель от абсурдных значений и отбрасывается как ошибка данных. Поэтому источник данных входит в набор признаков сравнения наравне с направлением и городом вылета, и разделение происходит само.
По каким признакам сравниваются билеты
У билета нет ни ночей, ни питания, ни звёздности — этих признаков просто не существует для перелёта. Остаётся то, что осмысленно и что мы действительно знаем:
- Направление. Для билетов это страна прилёта целиком, а не конкретный аэропорт. Мы спрашиваем цены по стране, поэтому в одном ряду оказываются рейсы в разные города одной страны.
- Город вылета. Как и у туров. Для городов с несколькими аэропортами берётся город целиком: рейсы из всех его аэропортов попадают в один ряд.
- Глубина бронирования. За сколько дней до вылета видна цена. Тот же набор диапазонов, что и у туров: билет за неделю до вылета сравнивается с билетами за неделю до вылета, а не с купленными за полгода.
- Источник данных. Он и отделяет билеты от туров, о чём написано выше.
Всё. Набор признаков у билетов беднее туровского, и это стоит понимать буквально: ряд, в котором мы ищем отклонение, у билетов шире и разнороднее.
Чего мы не знаем про билеты
Список отдельный от туровского ниже, потому что не совпадает с ним.
- Пересадки. Прямой рейс и рейс с двумя стыковками — разные товары по удобству и часто по цене. Число пересадок источник сообщает, но в расчёт нормы оно у нас не входит: в одном ряду оказываются и прямые, и стыковочные. Значительная часть разброса цен внутри нормы объясняется именно этим, и дешёвый билет вполне может оказаться билетом с долгой стыковкой.
- Багаж. Входит ли он в тариф или доплачивается отдельно, мы не видим вовсе. Разница здесь — тысячи рублей, то есть сопоставима с самим отклонением, которое мы измеряем.
- Авиакомпания и тариф. Невозвратный билет лоукостера и гибкий тариф обычного перевозчика лежат в одном ряду. Условия возврата, обмена и выбора места в наших данных отсутствуют.
- Обратная дата. Мы отслеживаем дату вылета. Продолжительность поездки в ключ сравнения не входит, поэтому билет туда-обратно на выходные и на три недели попадают в одну выборку.
- Класс обслуживания и наличие мест. Мы смотрим на экономкласс, но не знаем, сколько мест по этой цене осталось: цена, найденная кем-то пару часов назад, могла быть последней.
Отсюда та же оговорка, что и для туров, только сильнее: отклонение от нормы у билета — повод посмотреть, а не описание перелёта. Пересадки, багаж и условия тарифа придётся проверить на странице продавца.
Сигнал — это попадание в нижнюю часть распределения
Мы не выдаём сигнал просто потому, что цена низкая. Низкая цена сама по себе может означать что угодно: несезон, неудобный вылет, отель, который всегда столько стоит. Сигнал возникает, когда предложение попадает в нижнюю часть распределения своего набора — то есть дешевле почти всего, что мы видели по этому же направлению, городу, длительности и глубине покупки.
Дополнительно мы требуем, чтобы отрыв от середины был заметным. Отклонение на пару процентов — это шум, а не новость, о таком писать незачем. И сверху тоже стоит ограничитель: если цена вдруг оказалась ниже нормы в разы, это почти наверняка ошибка в данных источника, а не подарок. Такие предложения мы отбрасываем, а не публикуем.
Чего мы не учитываем
Это самая важная часть страницы, и обычно её не пишут. У источников, из которых мы берём цены, просто нет части данных — а значит, наша норма их не различает. Знать об этом нужно до того, как вы поедете сравнивать наш сигнал с реальным предложением туроператора.
- Конкретный отель. В ключ сравнения он не входит: в одном ряду оказываются разные отели, совпавшие по направлению, вылету, ночам, питанию и звёздности. Отсюда и берётся заметная часть разброса цен внутри нормы.
- Тип номера и вид из окна. Стандартный номер и номер с видом на море в одном и том же отеле различаются по цене, а в наших данных это чаще всего одна строка. Часть разброса внутри нормы объясняется именно этим.
- Состав туристов. Цена, как правило, приходит в расчёте на взрослого при двухместном размещении. Тур на двоих взрослых с ребёнком, одиночная поездка или третий человек в номере пересчитываются иначе, и наш процент отклонения к ним применим лишь приблизительно.
- Багаж. Входит ли в перелёт багаж или только ручная кладь — в данных обычно не указано, а разница составляет вполне ощутимую сумму при покупке на месте.
- Трансфер и страховка. Включён ли переезд из аэропорта в отель и какая страховка входит в пакет, мы не видим. Два тура с одинаковой ценой могут отличаться на эти услуги.
- Конкретный корпус, ремонт, отзывы. Мы работаем с ценой, а не с качеством отдыха. Дешевизна иногда объясняется тем, что отель плохой, — этого наша цифра не покажет.
Отсюда простое следствие: наш процент отклонения — это оценка по тем признакам, которые нам доступны, а не полное описание предложения. Он говорит, что цену стоит посмотреть. Проверить условия по этому списку всё равно придётся вам, уже на странице туроператора.