Анализ поведения пользователей в Pandas на практике

Анализ поведения пользователей — важная основа оптимизации продукта. В этом примере показано, как анализировать данные о доступе пользователей, удержании, конверсии и другие поведенческие данные.


Подготовка данных

Смоделировать данные о поведении пользователей

Пример

import pandas as pd
import numpy as np

np.random.seed(42)
n_users = 500
n_events = 5000

# Базовая информация о пользователе
users = pd.DataFrame({
    "User ID": range(1, n_users + 1),
    "Registration Date": pd.date_range("2024-01-01", periods=n_users, freq="D")[:n_users],
    "Channel": np.random.choice(["Organic Search", "Advertising", "Реферал", "Соцсети"], n_users),
    "Устройство": np.random.choice(["ПК", "Мобильный", "Планшет"], n_users, p=[0.3, 0.6, 0.1])
})

# События поведения пользователей
events = pd.DataFrame({
    "ID события": range(1, n_events + 1),
    "ID пользователя": np.random.randint(1, n_users + 1, n_events),
    "Тип события": np.random.choice(
        ["Просмотр", "Клик", "Избранное", "Добавить в корзину", "Заказ", "Комментарий"],
        n_events,
        p=[0.4, 0.25, 0.1, 0.1, 0.1, 0.05]
    ),
    "Время события": pd.date_range("2024-01-15", periods=n_events, freq="10min")
})

# Объединить данные
events = events.merge(users[["User ID", "Channel", "Device"]], on="User ID")

print("Данные пользователя:")
print(users.head())
print(f"\nКоличество пользователей: {len(users)}")
print("\n"Данные событий:")
print(events.head())
print(f"\nКоличество событий: {len(events)}")

Анализ активности пользователей

Распределение типов событий

Пример

# Статистика по типам событий
event_dist = events["Event Type"].value_counts()
event_pct = events["Event Type"].value_counts(normalize=True) * 100

print("=== Распределение типов событий ==="\n")
event_analysis = pd.DataFrame({
    "Count": event_dist,
    "Percentage": event_pct.round(2)
})
print(event_analysis)
print()

# Количество пользователей по типу события
event_users = events.groupby("Event Type")["User ID"].nunique()
print("Число пользователей, участвующих в каждом типе событий:")
print(event_users)

Вовлечённость пользователей

Пример

# Статистика событий пользователя
user_events = events.groupby("User ID").agg({
    "Event ID": "count",
    "Event Type": lambda x: x.nunique()
}).rename(columns={
    "Event ID": "Total Events",
    "Event Type": "Number of Event Types"
})

print("=== Вовлечённость пользователей ==="\n")
print(f"Среднее число событий на пользователя: {user_events['Total Events'].mean():.1f}")
print(f"Медиана: {user_events['Total Events'].median():.0f}")
print(f"Максимум: {user_events['Total Events'].max()}")
print()

# Сегментация пользователей
user_events["Activity Level"] = pd.cut(
    user_events["Всего событий"],
    bins=[0, 3, 10, 20, float("inf")],
    labels=["Низкая активность", "Нормальная", "Активная", "Высокая активность"]
)

print("Распределение уровня активности пользователей:")
print(user_events["Activity Level"].value_counts())

Анализ конверсионной воронки

Путь конверсии

Пример

# Подсчет пользователей по типам событий
funnel = events.groupby("Event Type")["User ID"].nunique()
funnel = funnel.reindex(["View", "Click", "Favorite", "Add to Cart", "Order", "Comment"])

# Расчет коэффициентов конверсии
funnel_df = pd.DataFrame({
    "Users": funnel,
    "Absolute Conversion Rate": (funnel / funnel["View"] * 100).round(2),
    "Step Conversion Rate": (funnel / funnel.shift(1) * 100).round(2)
}).fillna(100)

print("=== Воронка конверсии ==="\n")
print(funnel_df)
print()

# Визуализация данных воронки
print("Данные воронки:")
for step, row in funnel_df.iterrows():
    print(f"{step}: {row['Users']} пользователей ({row['Absolute Conversion Rate']:.1f}%)")

Анализ каналов

Эффективность по каналам

Пример

# Анализ пользователей по каналам
channel_analysis = events.groupby("Channel").agg({
    "User ID": "nunique",
    "Event ID": "count"
}).rename(columns={
    "User ID": "Users",
    "Event ID": "Events"
})

channel_analysis["Events per User"] = (
    channel_analysis["Events"] / channel_analysis["Users"]
).round(2)

print("=== Анализ каналов ==="\n")
print(channel_analysis)
print()

# Сравнение конверсии по каналам
channel_funnel = events[events["Event Type"].isin(["View", "Order"])].groupby(
    ["Канал", "Тип события"]
)["ID пользователя"].nunique().unstack()

channel_funnel["Коэффициент конверсии"] = (
    channel_funnel["Заказ"] / channel_funnel["Просмотр"] * 100
).round(2)

print("Коэффициент конверсии по каналам:")
print(channel_funnel)

Анализ устройств

Пример

# Анализ устройств
device_analysis = events.groupby("Устройство").agg({
    "User ID": "nunique",
    "Event ID": "count"
}).rename(columns={
    "User ID": "Users",
    "Event ID": "Events"
})

device_analysis["События на пользователя"] = (
    device_analysis["События"] / device_analysis["Пользователи"]
).round(2)

print("=== Распределение устройств ==="\n")
print(device_analysis)
print()

# Конверсия по устройствам
device_funnel = events[events["Event Type"].isin(["View", "Order"])].groupby(
    ["Device", "Event Type"]
)["ID пользователя"].nunique().unstack()

device_funnel["Conversion Rate"] = (
    device_funnel["Order"] / device_funnel["View"] * 100
).round(2)

print("Конверсия по устройствам:")
print(device_funnel)

Анализ удержания

Пример

# Упрощённый анализ удержания
# Предполагается, что активность в течение 7 дней после регистрации считается удержанием
users_with_events = events.groupby("User ID")["Event Time"].agg(["min", "max"])
users_with_events.columns = ["First Active", "Last Active"]

# Объединить информацию о регистрации
users_analysis = users.merge(users_with_events, left_on="User ID", right_index=True, how="left")

# Вычислить активные дни
users_analysis["Active Days"] = (
    users_analysis["Last Active"] - users_analysis["First Active"]
).dt.days + 1

print("=== Анализ удержания пользователей ==="\n")
print(f"Пользователи с поведением: {len(users_with_events)}")
print(f"Среднее количество активных дней: {users_analysis['Active Days'].mean():.1f} days")
print()

# Удержание на следующий день (упрощённо)
retention_1d = len(users_analysis[users_analysis["Active Days"] >= 2]) / len(users_analysis) * 100
retention_3d = len(users_analysis[users_analysis["Active Days"] >= 3]) / len(users_analysis) * 100

print(f"Коэффициент удержания на следующий день: {retention_1d:.1f}%")
print(f"Коэффициент удержания за 3 дня: {retention_3d:.1f}%")

Сводка анализа

Пример

print("""
=== Сводка анализа поведения пользователей ===

1. Вовлечённость пользователей
- Среди типов событий преобладают просмотры, затем следуют клики
- Среднее количество событий на пользователя низкое; необходимо повысить вовлечённость пользователей

2. Воронка конверсии
- Наблюдается значительный отсев; необходимо оптимизировать пользовательский опыт
- Коэффициент конверсии из просмотра в заказ относительно низкий

3. Эффективность каналов
- Рекомендуется сосредоточиться на оптимизации пути конверсии каналов с высоким трафиком
- Показатели различаются по каналам; требуется более тонкая оптимизация работы

4. Эффективность устройств
- Мобильные устройства являются основными; необходимо оптимизировать мобильный опыт

5. Рекомендации по оптимизации
- 1) Оптимизируйте отображение товаров, чтобы повысить конверсию из просмотра в клик
- 2) Упростите процесс покупки, чтобы снизить отказы на этапе оформления заказа
- 3) Оптимизируйте скорость загрузки страниц для мобильных устройств
- 4) Создайте систему многоуровневой работы с пользователями
"""
)
Другие расширения