Prophet – это библиотека с открытым исходным кодом, разработанная специально для прогнозирования временных рядов. Она основана на декомпозиционной модели, которая учитывает тренд, сезонность и праздничные эффекты. Prophet особенно хорошо подходит для задач прогнозирования с сильными сезонными паттернами и несколькими циклами в исторических данных.
Ключевые особенности Prophet:
- Простота использования: не требует глубоких знаний в области статистики или прогнозирования;
- Надежность: хорошо справляется с пропущенными данными и выбросами;
- Интерпретируемость: предоставляет понятные компоненты прогноза (тренд, сезонность, праздники);
- Гибкость: позволяет легко настраивать различные параметры модели.
Эти характеристики делают Prophet идеальным инструментом для прогнозирования трафика и конверсий сайта, где мы часто сталкиваемся с сезонными паттернами, нерегулярными событиями и шумными данными.
Подготовка данных для анализа
Прежде чем мы начнем работу с Prophet, необходимо подготовить наши данные. Для этого примера мы будем использовать данные, выгруженные со счетчика Яндекс.Метрики. Этот датасет содержит богатую информацию о посещениях сайта, включая временные метки, идентификаторы пользователей, URL-адреса, длительность сессий, количество просмотров страниц и информацию о конверсиях.
Давайте начнем с загрузки и предварительной обработки данных:
import pandas as pd
import numpy as np
from prophet import Prophet
import matplotlib.pyplot as plt
# Загрузка данных
df = pd.read_csv('website_data.csv')
# Преобразование столбцов даты и времени
date_columns = ['HitDateTime', 'VisitDateTime', 'PageGoalsTime', 'GoalsDateTime']
for col in date_columns:
df[col] = pd.to_datetime(df[col])
# Агрегация данных по дням
daily_data = df.groupby(df['HitDateTime'].dt.date).agg({
'WatchID': 'count',
'VisitID': 'nunique',
'ClientID': 'nunique',
'Pageviews': 'sum',
'GoalsID': lambda x: np.sum([len(i) for i in x if isinstance(i, list)])
}).reset_index()
# Переименование столбцов
daily_data.columns = ['ds', 'hits', 'visits', 'users', 'pageviews', 'conversions']
# Просмотр первых нескольких строк
print(daily_data.head())
В этом коде мы выполняем следующие шаги:
- Загружаем данные из CSV-файла;
- Преобразуем столбцы с датами и временем в формат datetime;
- Агрегируем данные по дням, подсчитывая количество хитов, уникальных посещений, уникальных пользователей, просмотров страниц и конверсий;
- Переименовываем столбцы для удобства работы с Prophet.
Теперь у нас есть подготовленный датафрейм daily_data, который мы будем использовать для прогнозирования.
Построение базовой модели Prophet
Теперь, когда наши данные готовы, давайте построим базовую модель Prophet для прогнозирования трафика сайта. Мы начнем с прогнозирования количества посещений (visits).
# Создаем модель Prophet
m = Prophet()
# Обучаем модель на наших данных
m.fit(daily_data[['ds', 'visits']])
# Создаем датафрейм с будущими датами для прогноза (например, на 30 дней вперед)
future = m.make_future_dataframe(periods=30)
# Делаем прогноз
forecast = m.predict(future)
# Визуализируем результаты
fig = m.plot(forecast)
plt.title('Прогноз посещений сайта на 30 дней')
plt.xlabel('Дата')
plt.ylabel('Количество посещений')
plt.show()
# Выводим компоненты прогноза
fig2 = m.plot_components(forecast)
plt.show()
В этом примере мы:
- Создаем экземпляр модели Prophet;
- Обучаем модель на наших исторических данных о посещениях;
- Создаем датафрейм с будущими датами для прогноза (в данном случае на 30 дней вперед);
- Делаем прогноз и визуализируем результаты;
- Отображаем компоненты прогноза (тренд, недельную и годовую сезонность).
Этот базовый прогноз уже дает нам представление о будущем трафике сайта, учитывая исторические тренды и сезонность. Однако мы можем значительно улучшить нашу модель, настроив ее параметры и добавив дополнительную информацию.
Настройка параметров модели
Prophet предоставляет множество параметров для тонкой настройки модели. Давайте рассмотрим некоторые из наиболее важных:
- changepoint_prior_scale: Контролирует гибкость тренда. Более высокие значения позволяют тренду быстрее меняться;
- seasonality_prior_scale: Контролирует силу сезонности. Более высокие значения позволяют сезонным эффектам быть более выраженными;
- holidays_prior_scale: Контролирует силу праздничных эффектов;
- seasonality_mode: Может быть “additive” или “multiplicative”. Определяет, как сезонные эффекты взаимодействуют с трендом.
Давайте попробуем настроить нашу модель:
# Создаем модель Prophet с настроенными параметрами
m = Prophet(
changepoint_prior_scale=0.05,
seasonality_prior_scale=10,
seasonality_mode='multiplicative',
daily_seasonality=True,
weekly_seasonality=True,
yearly_seasonality=True
)
# Добавляем праздники
russian_holidays = pd.DataFrame({
'holiday': 'russian_holidays',
'ds': pd.to_datetime(['2023-01-01', '2023-02-23', '2023-03-08', '2023-05-09', '2023-06-12', '2023-11-04']),
'lower_window': 0,
'upper_window': 1,
})
m.add_country_holidays(country_name='RU')
m.add_holidays(russian_holidays)
# Обучаем модель и делаем прогноз
m.fit(daily_data[['ds', 'visits']])
future = m.make_future_dataframe(periods=30)
forecast = m.predict(future)
# Визуализируем результаты
fig = m.plot(forecast)
plt.title('Улучшенный прогноз посещений сайта на 30 дней')
plt.xlabel('Дата')
plt.ylabel('Количество посещений')
plt.show()
# Выводим компоненты прогноза
fig2 = m.plot_components(forecast)
plt.show()
В этом примере мы:
- Настроили параметры модели для более гибкого тренда и сильной сезонности;
- Добавили ежедневную, еженедельную и годовую сезонность;
- Добавили российские праздники, которые могут влиять на трафик сайта.
Эти настройки позволяют модели лучше учитывать специфику нашего сайта и более точно прогнозировать будущий трафик.
Анализ компонентов прогноза
Одно из главных преимуществ Prophet – это возможность легко интерпретировать различные компоненты прогноза. Давайте подробнее рассмотрим каждый из них:
Тренд
Тренд показывает общее направление изменения трафика сайта во времени. Он может быть линейным или нелинейным, в зависимости от настроек модели и характера данных. Анализ тренда позволяет нам понять, растет ли популярность нашего сайта в долгосрочной перспективе или, наоборот, падает.
Недельная сезонность
Недельная сезонность отражает, как трафик сайта меняется в течение недели. Например, мы можем увидеть, что трафик выше в будние дни и ниже в выходные, или наоборот, в зависимости от специфики сайта.
Годовая сезонность
Годовая сезонность показывает, как трафик меняется в течение года. Это может быть связано с сезонными факторами, такими как праздники, отпускной сезон или учебный год.
Праздничные эффекты
Праздничные эффекты отражают, как различные праздники влияют на трафик сайта. Это особенно важно для сайтов электронной коммерции, где праздники часто приводят к значительным всплескам трафика и продаж.
Анализируя эти компоненты, мы можем получить ценные инсайты о поведении нашей аудитории и факторах, влияющих на трафик сайта. Например:
- Если мы видим сильный положительный тренд, это может указывать на успешность наших маркетинговых стратегий или растущий интерес к нашему продукту;
- Анализ недельной сезонности может помочь нам оптимизировать время публикации контента или запуска рекламных кампаний;
- Понимание годовой сезонности позволяет лучше планировать ресурсы и маркетинговые активности в течение года.
Зная влияние праздников на трафик, мы можем заранее подготовиться к пиковым нагрузкам и разработать специальные предложения для этих периодов.
Прогнозирование конверсий
До сих пор мы фокусировались на прогнозировании трафика сайта. Однако для многих бизнесов не менее важно прогнозировать конверсии. Давайте применим наш подход к прогнозированию конверсий:
# Создаем модель Prophet для прогнозирования конверсий
m_conv = Prophet(
changepoint_prior_scale=0.05,
seasonality_prior_scale=10,
seasonality_mode='multiplicative',
daily_seasonality=True,
weekly_seasonality=True,
yearly_seasonality=True
)
# Добавляем праздники
m_conv.add_country_holidays(country_name='RU')
m_conv.add_holidays(russian_holidays)
# Обучаем модель и делаем прогноз
m_conv.fit(daily_data[['ds', 'conversions']])
future_conv = m_conv.make_future_dataframe(periods=30)
forecast_conv = m_conv.predict(future_conv)
# Визуализируем результаты
fig = m_conv.plot(forecast_conv)
plt.title('Прогноз конверсий сайта на 30 дней')
plt.xlabel('Дата')
plt.ylabel('Количество конверсий')
plt.show()
# Выводим компоненты прогноза
fig2 = m_conv.plot_components(forecast_conv)
plt.show()
Этот код аналогичен тому, что мы использовали для прогнозирования трафика, но теперь мы фокусируемся на конверсиях. Анализируя прогноз конверсий, мы можем получить дополнительные инсайты:
- Сравнение сезонности трафика и конверсий может показать, совпадают ли периоды высокого трафика с периодами высокой конверсии;
- Анализ тренда конверсий может помочь оценить эффективность наших усилий по оптимизации сайта и маркетинговых кампаний;
- Понимание влияния праздников на конверсии может помочь в планировании специальных акций и предложений.
Прогнозирование качества трафика
Помимо количества посещений и конверсий, важно также анализировать качество трафика. Одним из показателей качества трафика может быть среднее количество просмотренных страниц за визит. Давайте создадим модель для прогнозирования этого показателя:
# Рассчитываем среднее количество просмотров страниц на визит
daily_data['pages_per_visit'] = daily_data['pageviews'] / daily_data['visits']
# Создаем модель Prophet для прогнозирования качества трафика
m_quality = Prophet(
changepoint_prior_scale=0.05,
seasonality_prior_scale=10,
seasonality_mode='additive',
daily_seasonality=True,
weekly_seasonality=True,
yearly_seasonality=True
)
# Добавляем праздники
m_quality.add_country_holidays(country_name='RU')
m_quality.add_holidays(russian_holidays)
# Обучаем модель и делаем прогноз
m_quality.fit(daily_data[['ds', 'pages_per_visit']])
future_quality = m_quality.make_future_dataframe(periods=30)
forecast_quality = m_quality.predict(future_quality)
# Визуализируем результаты
fig = m_quality.plot(forecast_quality)
plt.title('Прогноз среднего количества просмотров страниц на визит на 30 дней')
plt.xlabel('Дата')
plt.ylabel('Среднее количество просмотров страниц на визит')
plt.show()
# Выводим компоненты прогноза
fig2 = m_quality.plot_components(forecast_quality)
plt.show()
Этот код позволяет нам прогнозировать качество трафика, измеряемое средним количеством просмотров страниц на визит. Анализ этого показателя может дать нам ценные инсайты:
- Если мы видим растущий тренд, это может указывать на то, что наш контент становится более интересным для посетителей, или что навигация по сайту улучшается;
- Сезонные колебания могут показать, когда пользователи наиболее активно взаимодействуют с сайтом;
- Резкие изменения могут указывать на технические проблемы или изменения в поведении пользователей, требующие дополнительного исследования.
Комбинирование прогнозов и расчет дополнительных метрик
Теперь, когда у нас есть прогнозы для различных аспектов трафика и конверсий, мы можем объединить их для получения более полной картины и расчета дополнительных метрик. Например, мы можем рассчитать прогнозируемый коэффициент конверсии:
# Объединяем прогнозы
combined_forecast = pd.merge(forecast[['ds', 'yhat']],
forecast_conv[['ds', 'yhat']],
on='ds',
suffixes=('_visits', '_conversions'))
# Рассчитываем прогнозируемый коэффициент конверсии
combined_forecast['conversion_rate'] = combined_forecast['yhat_conversions'] / combined_forecast['yhat_visits']
# Визуализируем прогноз коэффициента конверсии
plt.figure(figsize=(12, 6))
plt.plot(combined_forecast['ds'], combined_forecast['conversion_rate'])
plt.title('Прогноз коэффициента конверсии на 30 дней')
plt.xlabel('Дата')
plt.ylabel('Коэффициент конверсии')
plt.show()
Этот код объединяет наши прогнозы посещений и конверсий, а затем рассчитывает прогнозируемый коэффициент конверсии. Анализ этого показателя может дать нам дополнительные инсайты:
- Мы можем увидеть, как изменяется эффективность нашего сайта в плане количества конверсий с течением времени;
- Сезонные колебания коэффициента конверсии могут помочь нам определить периоды, когда наши посетители наиболее склонны к совершению целевых действий;
- Сравнение прогнозируемого коэффициента конверсии с историческими данными может помочь нам оценить, улучшается ли эффективность нашего сайта или маркетинговых кампаний.
Учет внешних факторов
До сих пор мы основывали наши прогнозы исключительно на исторических данных трафика и конверсий. Однако в реальном мире на эти показатели могут влиять различные внешние факторы. Prophet позволяет нам учитывать такие факторы, добавляя дополнительные регрессоры в модель.
Например, предположим, что на трафик нашего сайта влияют погодные условия (что может быть актуально для сайтов, связанных с туризмом или продажей сезонных товаров). Мы можем добавить данные об уличной температуре в нашу модель:
# Предположим, у нас есть данные о средней дневной температуре
temperature_data = pd.read_csv('temperature_data.csv')
temperature_data['ds'] = pd.to_datetime(temperature_data['date'])
# Объединяем наши данные с данными о температуре
daily_data_with_temp = pd.merge(daily_data, temperature_data[['ds', 'temperature']], on='ds', how='left')
# Создаем модель Prophet с дополнительным регрессором
m_with_temp = Prophet(
changepoint_prior_scale=0.05,
seasonality_prior_scale=10,
seasonality_mode='multiplicative',
daily_seasonality=True,
weekly_seasonality=True,
yearly_seasonality=True
)
# Добавляем температуру как дополнительный регрессор
m_with_temp.add_regressor('temperature')
# Обучаем модель и делаем прогноз
m_with_temp.fit(daily_data_with_temp[['ds', 'visits', 'temperature']])
# Для прогноза нам нужно предоставить будущие значения температуры
future_with_temp = m_with_temp.make_future_dataframe(periods=30)
future_with_temp = pd.merge(future_with_temp, temperature_data[['ds', 'temperature']], on='ds', how='left')
forecast_with_temp = m_with_temp.predict(future_with_temp)
# Визуализируем результаты
fig = m_with_temp.plot(forecast_with_temp)
plt.title('Прогноз посещений сайта на 30 дней с учетом температуры')
plt.xlabel('Дата')
plt.ylabel('Количество посещений')
plt.show()
# Выводим компоненты прогноза, включая влияние температуры
fig2 = m_with_temp.plot_components(forecast_with_temp)
plt.show()
Помимо учета температуры, давайте рассмотрим еще один пример – учет курса Биткоина в наших прогнозах. Это может быть полезно для сайтов, связанных с криптовалютами или финансовыми технологиями.
Для этого мы будем использовать библиотеку yfinance для загрузки данных о курсе Биткоина с Yahoo Finance:
import yfinance as yf
from prophet import Prophet
import pandas as pd
import matplotlib.pyplot as plt
# Загружаем данные о курсе Биткоина
btc_data = yf.download('BTC-USD', start='2020-01-01', end='2023-09-21')
btc_data = btc_data.reset_index()
btc_data = btc_data[['Date', 'Close']]
btc_data.columns = ['ds', 'btc_price']
# Объединяем наши данные с данными о курсе Биткоина
daily_data_with_btc = pd.merge(daily_data, btc_data, on='ds', how='left')
# Создаем модель Prophet с дополнительным регрессором
m_with_btc = Prophet(
changepoint_prior_scale=0.05,
seasonality_prior_scale=10,
seasonality_mode='multiplicative',
daily_seasonality=True,
weekly_seasonality=True,
yearly_seasonality=True
)
# Добавляем курс Биткоина как дополнительный регрессор
m_with_btc.add_regressor('btc_price')
# Обучаем модель и делаем прогноз
m_with_btc.fit(daily_data_with_btc[['ds', 'visits', 'btc_price']])
# Для прогноза нам нужно предоставить будущие значения курса Биткоина
# В данном примере мы просто повторим последнее известное значение
future_with_btc = m_with_btc.make_future_dataframe(periods=30)
last_btc_price = btc_data['btc_price'].iloc[-1]
future_with_btc['btc_price'] = last_btc_price
forecast_with_btc = m_with_btc.predict(future_with_btc)
# Визуализируем результаты
fig = m_with_btc.plot(forecast_with_btc)
plt.title('Прогноз посещений сайта на 30 дней с учетом курса Биткоина')
plt.xlabel('Дата')
plt.ylabel('Количество посещений')
plt.show()
# Выводим компоненты прогноза, включая влияние курса Биткоина
fig2 = m_with_btc.plot_components(forecast_with_btc)
plt.show()
В этом примере мы загружаем исторические данные о курсе Биткоина, объединяем их с нашими данными о посещениях сайта, и используем курс Биткоина как дополнительный регрессор в модели Prophet. Обратите внимание, что для простоты мы предполагаем, что курс Биткоина в будущем останется неизменным (равным последнему известному значению). В реальном сценарии вы могли бы использовать отдельную модель для прогнозирования курса Биткоина или использовать фьючерсные цены.
Итак, мы рассмотрели 2 примера введения дополнительных переменных в прогнозы показателей сайтов: уличной температуры и курса Биткоина. Этот подход позволяет нам учитывать влияние внешних факторов на трафик и конверсии сайта. Мы можем использовать различные внешние факторы в зависимости от специфики нашего бизнеса:
- Для сайтов электронной коммерции это могут быть экономические показатели, такие как индекс потребительских цен или уровень безработицы;
- Для новостных сайтов можно учитывать количество значимых событий или индекс новостной активности;
- Для B2B сайтов можно включить данные о деловой активности в соответствующей отрасли.
Учет внешних факторов может значительно повысить точность наших прогнозов и помочь лучше понять динамику трафика и конверсий нашего сайта.
Оценка точности прогнозов
После создания моделей и получения прогнозов важно оценить их точность. Prophet предоставляет несколько инструментов для измерения точности. Давайте рассмотрим каждый из этих методов:
Кросс-валидация
Prophet позволяет легко выполнить кросс-валидацию для оценки производительности модели:
from prophet.diagnostics import cross_validation, performance_metrics
# Выполняем кросс-валидацию
df_cv = cross_validation(m, initial='365 days', period='30 days', horizon = '30 days')
# Рассчитываем метрики производительности
df_p = performance_metrics(df_cv)
print(df_p)
Этот код выполняет кросс-валидацию, используя последний год данных как начальный тренировочный набор, затем прогнозирует следующие 30 дней, сдвигается на 30 дней вперед и повторяет процесс. Это дает нам представление о том, насколько хорошо наша модель работает на различных периодах данных.
Метрики производительности
Prophet предоставляет несколько метрик для оценки производительности модели:
- Mean Absolute Error (MAE);
- Mean Squared Error (MSE);
- Root Mean Squared Error (RMSE);
- Mean Absolute Percentage Error (MAPE)
Вот как можно посчитать их значения для построенной прогнозной модели:
import numpy as np
from prophet.diagnostics import cross_validation, performance_metrics
# Выполняем кросс-валидацию
df_cv = cross_validation(m, initial='365 days', period='30 days', horizon='30 days')
# Рассчитываем стандартные метрики производительности
df_p = performance_metrics(df_cv)
print("Стандартные метрики Prophet:")
print(df_p)
# Теперь рассчитаем метрики вручную для демонстрации
y_true = df_cv['y']
y_pred = df_cv['yhat']
# Mean Absolute Error (MAE)
mae = np.mean(np.abs(y_true - y_pred))
# Mean Squared Error (MSE)
mse = np.mean((y_true - y_pred)**2)
# Root Mean Squared Error (RMSE)
rmse = np.sqrt(mse)
# Mean Absolute Percentage Error (MAPE)
mape = np.mean(np.abs((y_true - y_pred) / y_true)) * 100
print("\nМетрики, рассчитанные вручную:")
print(f"MAE: {mae}")
print(f"MSE: {mse}")
print(f"RMSE: {rmse}")
print(f"MAPE: {mape}%")
Эти метрики помогают нам понять, насколько в среднем наши прогнозы отклоняются от фактических значений. Например, MAPE удобен для интерпретации, так как выражается в процентах, но может быть проблематичным, если в данных есть нулевые значения. RMSE более чувствителен к выбросам, чем MAE, что может быть полезно или нежелательно в зависимости от конкретной задачи.
Выбор наиболее подходящей метрики зависит от специфики вашей задачи и характера данных. Часто полезно рассматривать несколько метрик одновременно для получения более полной картины производительности модели.
Диагностические графики
Библиотека Prophet также имеет встроенные диагностические графики для оценки точности прогнозов временных рядов:
from prophet.plot import plot_cross_validation_metric
# Строим график метрики производительности
fig = plot_cross_validation_metric(df_cv, metric='mape')
plt.title('Mean Absolute Percentage Error для различных горизонтов прогнозирования')
plt.show()
Этот график показывает, как изменяется ошибка прогноза (в данном случае MAPE) при увеличении горизонта прогнозирования. Это помогает нам понять, насколько далеко в будущее мы можем прогнозировать с приемлемой точностью.
Интерпретация результатов и принятие решений
Теперь, когда у нас есть прогнозы трафика, конверсий и других метрик, а также оценка точности этих прогнозов, мы можем использовать эту информацию для принятия обоснованных бизнес-решений. Вот несколько примеров того, как мы можем интерпретировать результаты и использовать их на практике:
- Планирование ресурсов: Если мы прогнозируем значительный рост трафика, мы можем заранее увеличить мощности сервера или расширить команду поддержки;
- Оптимизация маркетинговых кампаний: Зная сезонные паттерны трафика и конверсий, мы можем планировать наши рекламные кампании на периоды, когда они будут наиболее эффективны;
- Постановка целей: Прогнозы могут служить основой для постановки реалистичных целей по трафику и конверсиям на следующий период;
- Выявление аномалий: Если фактические показатели значительно отклоняются от прогнозируемых, это может сигнализировать о проблемах на сайте или изменениях в поведении пользователей, требующих внимания;
- Оценка эффективности изменений: Сравнивая фактические показатели с прогнозами, мы можем оценить эффект от внесенных изменений на сайте или в маркетинговой стратегии;
- Бюджетирование: Прогнозы конверсий могут помочь в планировании бюджета на рекламу и другие маркетинговые активности;
- Оптимизация контент-стратегии: Анализ сезонности и качества трафика может помочь в планировании публикации контента для максимизации вовлеченности аудитории.
Таким образом, прогнозирование трафика и конверсий сайта с помощью Prophet – это мощная техника для принятия обоснованных решений в области цифрового маркетинга и развития веб-ресурсов. Тем не менее, важно помнить, что прогнозирование – это не точная наука, и даже самые лучшие модели могут ошибаться. Поэтому всегда следует сочетать результаты прогнозирования с экспертными знаниями о вашем бизнесе и рынке.