Анализ поведения пользователей в 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)}")
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)
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())
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}%)")
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)
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)
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}%")
# Предполагается, что активность в течение 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) Создайте систему многоуровневой работы с пользователями
""")
=== Сводка анализа поведения пользователей ===
1. Вовлечённость пользователей
- Среди типов событий преобладают просмотры, затем следуют клики
- Среднее количество событий на пользователя низкое; необходимо повысить вовлечённость пользователей
2. Воронка конверсии
- Наблюдается значительный отсев; необходимо оптимизировать пользовательский опыт
- Коэффициент конверсии из просмотра в заказ относительно низкий
3. Эффективность каналов
- Рекомендуется сосредоточиться на оптимизации пути конверсии каналов с высоким трафиком
- Показатели различаются по каналам; требуется более тонкая оптимизация работы
4. Эффективность устройств
- Мобильные устройства являются основными; необходимо оптимизировать мобильный опыт
5. Рекомендации по оптимизации
- 1) Оптимизируйте отображение товаров, чтобы повысить конверсию из просмотра в клик
- 2) Упростите процесс покупки, чтобы снизить отказы на этапе оформления заказа
- 3) Оптимизируйте скорость загрузки страниц для мобильных устройств
- 4) Создайте систему многоуровневой работы с пользователями
""")