Всем привет!
Это моя первая статья на Хабре, поэтому буду рад комментариям, советам, предложениям и любой реакции.
Я работаю в авиакомпании, занимаюсь анализом продаж, что сильно связано в том числе с планированием и прогнозированием. В условиях, когда российский рынок авиаперевозок сужается, авиакомпании стремятся оптимизировать свою маршрутную сеть, а если и развиваться — то только на направлениях с высоким пассажиропотоком. Дефицит самолетов в условиях санкций делает ошибки непростительными, поэтому своей целью я ставил разработку модели прогнозирования трафика между городами РФ.
Архитектура
В целом, направления делятся на несколько крупных подгрупп, для которых логично использовать разные паттерны в прогнозировании. Так, например, есть курортные направления из Москвы (Сочи, Крым и прочие), по которым спрос хоть и сезонен, но довольно стабилен. Есть курортные направления из регионов, где спрос сильно сезон — банально по той причине, что рейсы выполняются только летом. В целом, поток на курортных направлений сильно зависит от количества гостиниц — нельзя уместить миллион туристов в Сочи за раз, если койко-мест — всего 500 тысяч. Существует также отдельный пул вахтовых направлений — по ним спрос всесезонный, который зависит от экономики вахтового региона. Я счел целесообразным решить на первом этапе задачу кластеризации, где я по пулу факторов попробую разделить направления на кластеры, и только потом — задачу регрессии.
Соответственно, в качестве факторов, влияющих на пассажиропоток, я выбрал следующие:
-
Тип направления: курортное, вахтовое, деловое (между крупными деловыми центрами)
-
Средняя температура в городах и обеспеченность коллективными средствами размещения (для выделения курортных направлений)
-
Расстояние между городами
-
Сезонность
-
Средняя зарплата в городах, население городов, коэффициент мобильности населения и ВРП региона (для выделения вахтовых направлений)
-
Годовой пассажиропоток между городами
Глобально, алгоритм должен выглядеть следующим образом:
Кластеризация
Определим вводные данные для кластеризации:
Признак |
Описание |
RSC |
Круговой сегмент |
Var |
Месячный к-т вариации |
Dist |
Расстояние |
Temp* |
Среднегодовая температура |
Population* |
Население |
Total* |
Годовой пассажиропоток чз город |
Mobility* |
Коэффициент мобильности населения |
GRP* |
ВРП региона |
GRP_per_capita* |
ВРП на душу населения в регионе |
ZP* |
Средняя заработная плата в регионе |
* — парные факторы для города вылета и города прилета
Месячный коэффициент вариации рассчитал как отношение месячного среднего квадратического отклонения к среднемесячному пассажиропотоку — это позволит оценить, насколько в среднем поток нестабилен.
Все факторы, что со звездочкой, были взяты из Росстата, кроме коэффициента мобильности — его на нашел как отношение общего количества вылетевших из города пассажиров к населению города.
Отдельной задачей был расчет расстояния между городами, его я реализовал с помощью библиотеки geopy:
from geopy.geocoders import Nominatim from geopy.distance import geodesic as GD from math import radians, cos, sin, asin, sqrt app = Nominatim(user_agent='myencoder', timeout=5) cities_for_dist = tdf['Город'].unique() dist = pd.DataFrame(columns=['Dist'], index=cities_for_dist) def get_dist(city1='Москва', city2='Санкт-Петербург'): loc1 = app.geocode(city1).raw loc2 = app.geocode(city2).raw lat1 = float(loc1['lat']) lon1 = float(loc1['lon']) lat2 = float(loc2['lat']) lon2 = float(loc2['lon']) dest = distance_1(lat1, lat2, lon1, lon2) return dest def distance_1(La1, La2, Lo1, Lo2): Lo1 = radians(Lo1) Lo2 = radians(Lo2) La1 = radians(La1) La2 = radians(La2) # Формула Гаверсинуса D_Lo = Lo2 - Lo1 D_La = La2 - La1 P = sin(D_La / 2)**2 + cos(La1) * cos(La2) * sin(D_Lo / 2)**2 Q = 2 * asin(sqrt(P)) # Радиус земли для расчета расстояния R_km = 6371 # Итоговый результат return(Q * R_km)
Алгоритм выполнялся довольно долго — для 400 направлений ушло около 20 минут. Поэтому я сразу сохранил его в csv и в следующих итерациях читал csv-файл с расстояниями. Удивительно, что не возникло проблем с распознаванием таких специфических городов, как Игарка, Талакан и Купол.
Я планировал сформировать около 5-10 кластеров, чтобы выборки в каждом кластере были адекватного (не слишком маленького) размера.
Вводные данные выглядят следующим образом:
Далее я решил отобрать оптимальное число кластеров с помощью коэффициент Силуэта, а заодно подобрать гиперпараметр n_init. Ситуация сложилась следующим образом:
Видим, что лучшее число кластеров — 7 штук, при гиперпараметре в n_init равном 2. Хотя коэффициент Силуэта невысокий, этого достаточно, чтобы получить приемлемые результаты. А результаты кластеризации оказались очень интересными.
Видим, что кластеры разделились очень логично, а при детальном рассмотрении я практически не нашел выбросов в кластерах.
Регрессия
Теперь попробуем построить три модели регрессии: RandomForest, GradientBoosting, CatBoost.
В качестве вводных берем следующие факторы:
Признак |
Описание |
Total |
Пассажиропоток на направлении за год |
Var |
Месячный к-т вариации |
Dist |
Расстояние |
Temp* |
Среднегодовая температура |
Population* |
Население |
Total1* |
Годовой пассажиропоток чз город |
Mobility* |
Коэффициент мобильности населения |
GRP* |
ВРП региона |
GRP_per_capita* |
ВРП на душу населения в регионе |
ZP* |
Средняя заработная плата в регионе |
Вводные для регрессии выглядят так:
После отбора гиперпараметров, вышли следующие результаты:
Модель/ Метрика |
RandomForest Regressor |
GradientBoosting Regressor |
CatBoost Regressor |
R2 |
0,56 |
0,45 |
0,75 |
MAPE |
29,3% |
30,0% |
53,6% |
Видим, что для всех трех моделей и R2, и MAPE оказались не очень качественными, но для дальнейших исследований я оставлю RandomForest и GradientBoosting.
Вывод
Удалось с умеренной точностью прогнозировать пассажиропоток на московских рейсах с ошибкой менее 30%;
Решение задачи кластеризации позволило осуществить качественное разделение рейсов по подгруппам, что может быть использовано в авиакомпаниях для упрощения анализа и группировки данных.
Рекомендации для себя на будущее я оставил следующие:
-
Добавить фактор емкостей конкурентов для повышения точности модели
-
Включить фактор сезонных мероприятий или перевахтовок для крупных городов
-
Добавить в анализ перемещения между городами в том числе трансферными рейсами
Спасибо за уделенное внимание. Буду рад обратной связи.
ссылка на оригинал статьи https://habr.com/ru/post/713160/
Добавить комментарий