Поиск и анализ аномалий в сырых данных веб-аналитики с помощью Python

Аномалии в трафике, конверсиях, поведении пользователей на сайте могут рассказать многое о здоровье веб-сайта. И если научиться их своевременно выявлять, то можно сэкономить множество сил, нервов, времени и денег. Простой пример – аномально высокая конверсия по одной из целей может быть следствием “наплыва” ботов на сайт и если это вовремя не обнаружить и не остановить рекламные кампании, то эти боты просто “съедят” рекламный бюджет.

Причины возникновения аномалий в трафике и конверсий веб-сайтов

Выбросы и аномалии в данных веб-аналитики могут возникать по разным причинам. Вот несколько основных:

  • Технические ошибки: Проблемы с кодом отслеживания, сбои в работе серверов или ошибки в настройке аналитических инструментов могут приводить к появлению в логах некорректных данных;
  • Боты и спам: Автоматизированные программы (боты) могут генерировать ложные данные, имитируя пользовательскую активность. Это может искажать статистику посещений и поведения пользователей;
  • Сезонные изменения: Временные изменения в поведении пользователей, связанные с сезонными факторами (например, рост активности перед праздниками), могут выглядеть как аномалии;
  • Маркетинговые кампании: Запуск рекламных кампаний или промо-акций может привести к резкому увеличению трафика и активности на сайте, что также может выглядеть как аномалия;
  • Изменения в пользовательском поведении: Внезапные изменения в поведении пользователей, вызванные внешними событиями (например, пандемия, паника на бирже), могут привести к аномалиям в данных;
  • Ошибки в данных: Человеческие ошибки при вводе данных или некорректная интеграция различных источников данных также могут приводить к возникновению выбросов и аномалий в данных.

Почему важно вовремя отслеживать выбросы и аномалии?

  1. Точность анализа: Выбросы и аномалии в статистике трафика и конверсий веб-сайта могут искажать общую картину и приводить к неправильным выводам;
  2. Оптимизация маркетинга: Понимание причин аномалий помогает оптимизировать маркетинговые стратегии. Например, если рост трафика связан с успешной рекламной кампанией, это может быть полезно для будущих маркетинговых решений;
  3. Улучшение пользовательского опыта: Аномалии могут указывать на проблемы с сайтом или приложением, которые негативно влияют на пользовательский опыт. Своевременное обнаружение таких проблем позволяет быстро их исправить;
  4. Защита от мошенничества: Выбросы могут быть признаком мошеннической активности, такой как спам или атаки ботов. Своевременное обнаружение и блокировка таких активностей помогает защитить сайт и данные пользователей;
  5. Управление ресурсами: Понимание причин аномалий помогает эффективно распределять ресурсы. Например, если рост трафика связан с сезонными факторами, можно заранее подготовиться к увеличению нагрузки на серверы.

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

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

Подготовка данных и импорт библиотек

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

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
from scipy import stats
from sklearn.ensemble import IsolationForest
from sklearn.preprocessing import StandardScaler
from datetime import datetime, timedelta

# Настройка стиля графиков
plt.style.use('seaborn')
sns.set_palette("deep")

Теперь давайте загрузим наши данные. В этом примере мы будем использовать датасет в формате csv, полученный в результате выгрузки сырых данных Яндекс Метрики.

# Загрузка данных
df = pd.read_csv('web_analytics_data.csv', parse_dates=['HitDateTime', 'VisitDateTime'])

# Преобразование столбцов с массивами
array_columns = ['PageGoals', 'PageGoalsTime', 'GoalsID', 'GoalsDateTime']
for col in array_columns:
    df[col] = df[col].apply(eval)

# Вывод информации о датасете
print(df.info())
print("\nПервые несколько строк датасета:")
print(df.head())

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

Предварительный анализ данных

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

Читайте также:  RFM-анализ с помощью Python

Анализ пропущенных значений

Первым шагом в нашем анализе будет проверка наличия пропущенных значений:

missing_values = df.isnull().sum()
print("Пропущенные значения:")
print(missing_values[missing_values > 0])

Если в наших данных есть пропущенные значения, нам нужно решить, как с ними поступить. В зависимости от контекста и количества пропусков, мы можем либо удалить строки с пропущенными значениями, либо заполнить их каким-либо способом (например, средним значением или методом интерполяции).

Анализ распределения числовых переменных

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

numeric_columns = df.select_dtypes(include=[np.number]).columns

fig, axes = plt.subplots(len(numeric_columns), 2, figsize=(15, 5*len(numeric_columns)))
fig.suptitle("Распределение числовых переменных", fontsize=16)

for i, col in enumerate(numeric_columns):
    sns.histplot(df[col], kde=True, ax=axes[i, 0])
    axes[i, 0].set_title(f"Гистограмма: {col}")
    
    sns.boxplot(x=df[col], ax=axes[i, 1])
    axes[i, 1].set_title(f"Box plot: {col}")

plt.tight_layout()
plt.show()

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

Анализ временных рядов

Поскольку наши данные содержат временные метки, имеет смысл проанализировать временные ряды некоторых ключевых метрик:

df['Date'] = df['HitDateTime'].dt.date

daily_stats = df.groupby('Date').agg({
    'WatchID': 'count',
    'VisitID': 'nunique',
    'ClientID': 'nunique',
    'Pageviews': 'sum'
}).reset_index()

fig, axes = plt.subplots(2, 2, figsize=(20, 15))
fig.suptitle("Ежедневная статистика", fontsize=16)

sns.lineplot(x='Date', y='WatchID', data=daily_stats, ax=axes[0, 0])
axes[0, 0].set_title("Количество просмотров страниц")

sns.lineplot(x='Date', y='VisitID', data=daily_stats, ax=axes[0, 1])
axes[0, 1].set_title("Количество уникальных сессий")

sns.lineplot(x='Date', y='ClientID', data=daily_stats, ax=axes[1, 0])
axes[1, 0].set_title("Количество уникальных пользователей")

sns.lineplot(x='Date', y='Pageviews', data=daily_stats, ax=axes[1, 1])
axes[1, 1].set_title("Общее количество просмотров страниц")

plt.tight_layout()
plt.show()

Этот график поможет нам выявить любые необычные паттерны или выбросы во временных рядах наших ключевых метрик.

Методы обнаружения аномалий

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

Статистический подход: Z-score

Один из простейших методов обнаружения аномалий – использование Z-score. Этот метод предполагает, что наши данные имеют нормальное распределение, и считает аномалиями те значения, которые отклоняются от среднего более чем на определенное количество стандартных отклонений.

def detect_anomalies_zscore(data, threshold=3):
    mean = np.mean(data)
    std = np.std(data)
    z_scores = [(y - mean) / std for y in data]
    return [abs(z_score) > threshold for z_score in z_scores]

# Применим метод к длительности визитов
visit_duration_anomalies = detect_anomalies_zscore(df['VisitDuration'])
df['VisitDurationAnomaly'] = visit_duration_anomalies

print(f"Количество аномалий в длительности визитов: {sum(visit_duration_anomalies)}")

# Визуализация результатов
plt.figure(figsize=(12, 6))
plt.scatter(df.index, df['VisitDuration'], c=df['VisitDurationAnomaly'], cmap='viridis')
plt.title('Аномалии в длительности визитов (Z-score)')
plt.xlabel('Индекс')
plt.ylabel('Длительность визита')
plt.colorbar(label='Аномалия')
plt.show()

Этот метод прост в реализации и интерпретации, но он имеет ограничения. Он предполагает нормальное распределение данных и не очень хорошо работает с мультимодальными распределениями.

Метод межквартильного размаха (IQR)

Метод межквартильного размаха (IQR) – это еще один статистический метод обнаружения аномалий, который менее чувствителен к экстремальным выбросам, чем Z-score.

def detect_anomalies_iqr(data, factor=1.5):
    Q1 = np.percentile(data, 25)
    Q3 = np.percentile(data, 75)
    IQR = Q3 - Q1
    lower_bound = Q1 - (factor * IQR)
    upper_bound = Q3 + (factor * IQR)
    return [(y < lower_bound) | (y > upper_bound) for y in data]

# Применим метод к количеству просмотров страниц
pageviews_anomalies = detect_anomalies_iqr(df['Pageviews'])
df['PageviewsAnomaly'] = pageviews_anomalies

print(f"Количество аномалий в просмотрах страниц: {sum(pageviews_anomalies)}")

# Визуализация результатов
plt.figure(figsize=(12, 6))
plt.scatter(df.index, df['Pageviews'], c=df['PageviewsAnomaly'], cmap='viridis')
plt.title('Аномалии в количестве просмотров страниц (IQR)')
plt.xlabel('Индекс')
plt.ylabel('Количество просмотров страниц')
plt.colorbar(label='Аномалия')
plt.show()

Метод IQR более устойчив к выбросам, чем Z-score, и не предполагает нормального распределения данных. Однако он может быть менее чувствительным к аномалиям в некоторых случаях.

Машинное обучение: Isolation Forest

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

# Выберем числовые признаки для анализа
features = ['VisitDuration', 'Pageviews']

# Нормализация данных
scaler = StandardScaler()
X = scaler.fit_transform(df[features])

# Применение Isolation Forest
clf = IsolationForest(contamination=0.1, random_state=42)
df['AnomalyScore'] = clf.fit_predict(X)

# -1 означает аномалию, 1 - нормальное наблюдение
df['IsAnomaly'] = df['AnomalyScore'].apply(lambda x: 'Anomaly' if x == -1 else 'Normal')

print(f"Количество обнаруженных аномалий: {sum(df['IsAnomaly'] == 'Anomaly')}")

# Визуализация результатов
plt.figure(figsize=(12, 8))
sns.scatterplot(data=df, x='VisitDuration', y='Pageviews', hue='IsAnomaly', palette='viridis')
plt.title('Аномалии, обнаруженные с помощью Isolation Forest')
plt.show()

Isolation Forest может обнаруживать аномалии в многомерном пространстве признаков, что делает его более мощным инструментом по сравнению с одномерными статистическими методами.

Читайте также:  Методы предиктивной аналитики и машинного обучения для оптимизации конверсии веб-сайтов

Анализ конкретных типов аномалий в веб-аналитике

Теперь, когда мы рассмотрели общие методы обнаружения аномалий, давайте применим их к конкретным сценариям, характерным для данных веб-аналитики.

Аномалии в поведении пользователей

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

# Расчет средних значений для каждого пользователя
user_avg = df.groupby('ClientID').agg({
    'VisitDuration': 'mean',
    'Pageviews': 'mean'
}).reset_index()

# Применение Isolation Forest к средним значениям пользователей
X_user = scaler.fit_transform(user_avg[['VisitDuration', 'Pageviews']])
user_avg['IsAnomaly'] = clf.fit_predict(X_user)

# Визуализация результатов
plt.figure(figsize=(12, 8))
sns.scatterplot(data=user_avg, x='VisitDuration', y='Pageviews', hue='IsAnomaly', palette='viridis')
plt.title('Аномалии в поведении пользователей')
plt.xlabel('Средняя длительность визита')
plt.ylabel('Среднее количество просмотров страниц')
plt.show()

# Анализ аномальных пользователей
anomalous_users = user_avg[user_avg['IsAnomaly'] == -1]
print("Примеры аномальных пользователей:")
print(anomalous_users.head())

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

Аномалии в источниках трафика

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

# Агрегация данных по источникам трафика и датам
traffic_source_daily = df.groupby(['Date', 'Source'])['VisitID'].count().unstack(fill_value=0).reset_index()

# Применение Z-score к каждому источнику трафика
for source in traffic_source_daily.columns[1:]:
traffic_source_daily[f'{source}_anomaly'] = detect_anomalies_zscore(traffic_source_daily[source])

# Визуализация результатов
fig, axes = plt.subplots(2, 2, figsize=(20, 15))
fig.suptitle("Аномалии в источниках трафика", fontsize=16)
for i, source in enumerate(traffic_source_daily.columns[1:5]):  
 
# Выберем первые 4 источника для примера
ax = axes[i // 2, i % 2]
sns.lineplot(x='Date', y=source, data=traffic_source_daily, ax=ax)
anomalies = traffic_source_daily[traffic_source_daily[f'{source}_anomaly']]
ax.scatter(anomalies['Date'], anomalies[source], color='red', s=50)
ax.set_title(f"Источник: {source}")
ax.set_xlabel("Дата")
ax.set_ylabel("Количество визитов")
plt.tight_layout()
plt.show()

Также мы можем вывести дни с наибольшим количеством аномалий:

anomaly_counts = traffic_source_daily.iloc[:, -4:].sum(axis=1)
top_anomaly_days = anomaly_counts.nlargest(5)
print("Дни с наибольшим количеством аномалий в источниках трафика:")
print(top_anomaly_days)

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

Аномалии в достижении целей (микро- и макро-конверсий)

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

# Подсчет количества достигнутых целей для каждого визита
df['GoalsAchieved'] = df['GoalsID'].apply(len)

# Агрегация данных по датам
daily_goals = df.groupby('Date')['GoalsAchieved'].agg(['sum', 'mean']).reset_index()

# Применение метода IQR к суммарному количеству достигнутых целей
daily_goals['SumGoalsAnomaly'] = detect_anomalies_iqr(daily_goals['sum'])

# Визуализация результатов
plt.figure(figsize=(15, 7))
sns.lineplot(x='Date', y='sum', data=daily_goals)
anomalies = daily_goals[daily_goals['SumGoalsAnomaly']]
plt.scatter(anomalies['Date'], anomalies['sum'], color='red', s=50)
plt.title('Аномалии в суммарном количестве достигнутых целей')
plt.xlabel('Дата')
plt.ylabel('Количество достигнутых целей')
plt.show()

# Анализ аномальных дней
print("Дни с аномальным количеством достигнутых целей:")
print(anomalies[['Date', 'sum', 'mean']])

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

Углубленный анализ аномалий с использованием машинного обучения

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

Кластеризация и обнаружение выбросов

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

from sklearn.cluster import KMeans
from sklearn.preprocessing import StandardScaler

# Выбор признаков для кластеризации
features = ['VisitDuration', 'Pageviews', 'GoalsAchieved']

# Нормализация данных
scaler = StandardScaler()
X = scaler.fit_transform(df[features])

# Применение K-means
kmeans = KMeans(n_clusters=5, random_state=42)
df['Cluster'] = kmeans.fit_predict(X)

# Расчет расстояний до центров кластеров
distances = kmeans.transform(X)
df['DistanceToCenter'] = distances.min(axis=1)

# Определение порога для аномалий (например, 95-й перцентиль расстояний)
threshold = np.percentile(df['DistanceToCenter'], 95)
df['IsAnomaly'] = df['DistanceToCenter'] > threshold

# Визуализация результатов
plt.figure(figsize=(12, 8))
scatter = plt.scatter(df['VisitDuration'], df['Pageviews'], c=df['Cluster'], 
                      s=50*df['IsAnomaly']+10, alpha=0.6, cmap='viridis')
plt.colorbar(scatter)
plt.title('Кластеризация визитов и выявление аномалий')
plt.xlabel('Длительность визита')
plt.ylabel('Количество просмотров страниц')
plt.show()

# Анализ аномальных визитов
anomalies = df[df['IsAnomaly']]
print("Примеры аномальных визитов:")
print(anomalies[features + ['DistanceToCenter']].head())

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

Читайте также:  Автоматизация процессов анализа данных с помощью Python

Анализ временных рядов и обнаружение аномалий

Другой важный аспект анализа данных веб-аналитики – это обнаружение аномалий во временных рядах. Мы можем использовать методы, специально разработанные для анализа временных рядов, такие как ARIMA (AutoRegressive Integrated Moving Average) или Prophet от Facebook.

Давайте рассмотрим пример использования библиотеки Prophet для обнаружения аномалий в ежедневном количестве визитов:

from fbprophet import Prophet
from fbprophet.plot import add_changepoints_to_plot

# Подготовка данных для Prophet
daily_visits = df.groupby('Date')['VisitID'].count().reset_index()
daily_visits.columns = ['ds', 'y']

# Создание и обучение модели
model = Prophet(changepoint_prior_scale=0.05)
model.fit(daily_visits)

# Прогнозирование
future = model.make_future_dataframe(periods=0)
forecast = model.predict(future)

# Визуализация результатов
fig = model.plot(forecast)
a = add_changepoints_to_plot(fig.gca(), model, forecast)
plt.title('Анализ временного ряда количества визитов')
plt.show()

# Выявление аномалий
anomalies = forecast[forecast['y'] > forecast['yhat_upper']]
print("Даты с аномально высоким количеством визитов:")
print(anomalies[['ds', 'y', 'yhat', 'yhat_upper']])

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

Интерпретация и действия на основе обнаруженных аномалий

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

  • Классификация аномалий: Разделите аномалии на категории, например, “позитивные аномалии” (необычно высокое количество конверсий) и “негативные аномалии” (необычно низкое время на сайте);
  • Контекстный анализ: Рассмотрите аномалии в контексте других данных. Например, если вы обнаружили аномально высокий трафик из определенного источника, проверьте, не было ли в этот день запущено новых рекламных кампаний;
  • Временной анализ: Обратите внимание на время возникновения аномалий. Есть ли какие-то повторяющиеся паттерны? Связаны ли аномалии с определенными днями недели или временем суток?
  • Сегментация: Проанализируйте, связаны ли аномалии с определенными сегментами пользователей, устройствами или географическими регионами;
  • Технический аудит: Если обнаружены негативные аномалии (например, резкое падение конверсий), проведите технический аудит сайта, чтобы убедиться, что нет проблем с функциональностью;
  • A/B тестирование: Если вы внесли изменения на сайт и обнаружили позитивные аномалии, рассмотрите возможность проведения A/B теста для подтверждения эффективности изменений;
  • Мониторинг и оповещения: Настройте систему мониторинга и оповещений на основе выявленных паттернов аномалий, чтобы быстро реагировать на необычные ситуации в будущем.

Заключение

В этой статье мы рассмотрели различные методы поиска и анализа аномалий в сырых данных веб-аналитики с использованием Python. Мы начали с базовых статистических методов, таких как Z-score и IQR, затем перешли к более сложным алгоритмам машинного обучения, включая Isolation Forest и кластеризацию. Мы также рассмотрели специфические для веб-аналитики сценарии, такие как анализ поведения пользователей, источников трафика и достижения целей.

Применение этих методов на практике позволит вам:

  1. Быстро выявлять и реагировать на технические проблемы на сайте;
  2. Обнаруживать подозрительную активность, такую как боты или попытки мошенничества;
  3. Идентифицировать успешные маркетинговые кампании и оптимизировать распределение рекламного бюджета;
  4. Улучшать пользовательский опыт, выявляя и устраняя проблемные места в пользовательских сценариях;
  5. Более точно прогнозировать тренды и планировать ресурсы.

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