Analyse du comportement des utilisateurs avec Pandas en pratique
L'analyse du comportement des utilisateurs est une base importante pour l'optimisation des produits. Ce cas démontre comment analyser les données d'accès, de rétention, de conversion et d'autres données comportementales des utilisateurs.
Préparation des données
Simuler des données de comportement utilisateur
Exemple
import pandas as pd
import numpy as np
np.random.seed(42)
n_users = 500
n_events = 5000
# Informations de base de l'utilisateur
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", "Parrainage", "Social"], n_users),
"Appareil": np.random.choice(["PC", "Mobile", "Tablette"], n_users, p=[0.3, 0.6, 0.1])
})
# Événements de comportement utilisateur
events = pd.DataFrame({
"ID d'événement": range(1, n_events + 1),
"ID utilisateur": np.random.randint(1, n_users + 1, n_events),
"Type d'événement": np.random.choice(
["Vue", "Clic", "Favori", "Ajouter au panier", "Commande", "Commentaire"],
n_events,
p=[0.4, 0.25, 0.1, 0.1, 0.1, 0.05]
),
"Heure de l'événement": pd.date_range("2024-01-15", periods=n_events, freq="10min")
})
# Fusionner les données
events = events.merge(users[["User ID", "Channel", "Device"]], on="User ID")
print("Données utilisateur :")
print(users.head())
print(f"\nNombre d'utilisateurs : {len(users)}")
print("\n"Données d'événements :")
print(events.head())
print(f"\nNombre d'événements : {len(events)}")
import numpy as np
np.random.seed(42)
n_users = 500
n_events = 5000
# Informations de base de l'utilisateur
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", "Parrainage", "Social"], n_users),
"Appareil": np.random.choice(["PC", "Mobile", "Tablette"], n_users, p=[0.3, 0.6, 0.1])
})
# Événements de comportement utilisateur
events = pd.DataFrame({
"ID d'événement": range(1, n_events + 1),
"ID utilisateur": np.random.randint(1, n_users + 1, n_events),
"Type d'événement": np.random.choice(
["Vue", "Clic", "Favori", "Ajouter au panier", "Commande", "Commentaire"],
n_events,
p=[0.4, 0.25, 0.1, 0.1, 0.1, 0.05]
),
"Heure de l'événement": pd.date_range("2024-01-15", periods=n_events, freq="10min")
})
# Fusionner les données
events = events.merge(users[["User ID", "Channel", "Device"]], on="User ID")
print("Données utilisateur :")
print(users.head())
print(f"\nNombre d'utilisateurs : {len(users)}")
print("\n"Données d'événements :")
print(events.head())
print(f"\nNombre d'événements : {len(events)}")
Analyse de l'activité des utilisateurs
Répartition des types d'événements
Exemple
# Statistiques des types d'événements
event_dist = events["Event Type"].value_counts()
event_pct = events["Event Type"].value_counts(normalize=True) * 100
print("=== Répartition des types d'événements ==="\n")
event_analysis = pd.DataFrame({
"Nombre": event_dist,
"Pourcentage": event_pct.round(2)
})
print(event_analysis)
print()
# Nombre d'utilisateurs par type d'événement
event_users = events.groupby("Event Type")["User ID"].nunique()
print("Nombre d'utilisateurs participant à chaque type d'événement :")
print(event_users)
event_dist = events["Event Type"].value_counts()
event_pct = events["Event Type"].value_counts(normalize=True) * 100
print("=== Répartition des types d'événements ==="\n")
event_analysis = pd.DataFrame({
"Nombre": event_dist,
"Pourcentage": event_pct.round(2)
})
print(event_analysis)
print()
# Nombre d'utilisateurs par type d'événement
event_users = events.groupby("Event Type")["User ID"].nunique()
print("Nombre d'utilisateurs participant à chaque type d'événement :")
print(event_users)
Engagement des utilisateurs
Exemple
# Événements des utilisateurs
user_events = ."Event ID"(agg).agg({
"Event ID": count,
"Event Type": lambda x: x.nunique()
}).rename(columns={
"Event ID": "Total Events",
"Event Type": "Number of Event Types"
})
print("=== Engagement des utilisateurs ==="\n")
print(f"Moyenne des événements par utilisateur : {user_events['Total Events'].mean():.1f}")
print(f"Médiane : {user_events['Total Events'].median():.0f}")
print(f"Max : {user_events['Total Events'].max()}")
print()
# Segmentation des utilisateurs
user_events["Activity Level"] = .cut(
user_events["Total des événements"],
bins=[0, 3, 10, 20, float("inf")],
labels=["Faible activité", "Normale", "Active", "Activité élevée"]
)
print("Distribution des niveaux d'activité des utilisateurs :")
print(user_events["Niveau d'activité"].value_counts())
user_events = ."Event ID"(agg).agg({
"Event ID": count,
"Event Type": lambda x: x.nunique()
}).rename(columns={
"Event ID": "Total Events",
"Event Type": "Number of Event Types"
})
print("=== Engagement des utilisateurs ==="\n")
print(f"Moyenne des événements par utilisateur : {user_events['Total Events'].mean():.1f}")
print(f"Médiane : {user_events['Total Events'].median():.0f}")
print(f"Max : {user_events['Total Events'].max()}")
print()
# Segmentation des utilisateurs
user_events["Activity Level"] = .cut(
user_events["Total des événements"],
bins=[0, 3, 10, 20, float("inf")],
labels=["Faible activité", "Normale", "Active", "Activité élevée"]
)
print("Distribution des niveaux d'activité des utilisateurs :")
print(user_events["Niveau d'activité"].value_counts())
Analyse du tunnel de conversion
Parcours de conversion
Exemple
# Compter les utilisateurs par type d'événement
funnel = events.groupby("Type d'événement")["ID utilisateur"].nunique()
funnel = funnel.reindex(["Vue", "Clic", "Favori", "Ajouter au panier", "Commande", "Commentaire"])
# Calculer les taux de conversion
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("=== Entonnoir de conversion ==="\n")
print(funnel_df)
print()
# Visualiser les données de l'entonnoir
print("Données de l'entonnoir :")
for step, row in funnel_df.iterrows():
print(f"{step}: {row['Users']} utilisateurs ({row['Absolute Conversion Rate']:.1f}%)")
funnel = events.groupby("Type d'événement")["ID utilisateur"].nunique()
funnel = funnel.reindex(["Vue", "Clic", "Favori", "Ajouter au panier", "Commande", "Commentaire"])
# Calculer les taux de conversion
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("=== Entonnoir de conversion ==="\n")
print(funnel_df)
print()
# Visualiser les données de l'entonnoir
print("Données de l'entonnoir :")
for step, row in funnel_df.iterrows():
print(f"{step}: {row['Users']} utilisateurs ({row['Absolute Conversion Rate']:.1f}%)")
Analyse des canaux
Performance par canal
Exemple
# Analyse des utilisateurs par canal
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("=== Analyse des canaux ==="\n")
print(channel_analysis)
print()
# Comparaison de conversion des canaux
channel_funnel = events[events["Event Type"].isin(["View", "Order"])].groupby(
["Channel", "Event Type"]
)["User ID"].nunique().unstack()
channel_funnel["Conversion Rate"] = (
channel_funnel["Order"] / channel_funnel["View"] * 100
).round(2)
print("Taux de conversion par canal :")
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("=== Analyse des canaux ==="\n")
print(channel_analysis)
print()
# Comparaison de conversion des canaux
channel_funnel = events[events["Event Type"].isin(["View", "Order"])].groupby(
["Channel", "Event Type"]
)["User ID"].nunique().unstack()
channel_funnel["Conversion Rate"] = (
channel_funnel["Order"] / channel_funnel["View"] * 100
).round(2)
print("Taux de conversion par canal :")
print(channel_funnel)
Analyse des appareils
Exemple
# Analyse des appareils
device_analysis = events.groupby("Device").agg({
"User ID": "nunique",
"Event ID": count
}).rename(columns={
"User ID": "Users",
"Event ID": "Events"
})
device_analysis["Events per User"] = (
device_analysis["Events"] / device_analysis["Users"]
).round(2)
print("=== Répartition des appareils ==="\n")
print(device_analysis)
print()
# Taux de conversion par appareil
device_funnel = events[events["Event Type"].isin(["View", "Order"])].groupby(
["Device", "Event Type"]
)["User ID"].nunique().unstack()
device_funnel["Conversion Rate"] = (
device_funnel["Order"] / device_funnel["View"] * 100
).round(2)
print("Taux de conversion par appareil :")
print(device_funnel)
device_analysis = events.groupby("Device").agg({
"User ID": "nunique",
"Event ID": count
}).rename(columns={
"User ID": "Users",
"Event ID": "Events"
})
device_analysis["Events per User"] = (
device_analysis["Events"] / device_analysis["Users"]
).round(2)
print("=== Répartition des appareils ==="\n")
print(device_analysis)
print()
# Taux de conversion par appareil
device_funnel = events[events["Event Type"].isin(["View", "Order"])].groupby(
["Device", "Event Type"]
)["User ID"].nunique().unstack()
device_funnel["Conversion Rate"] = (
device_funnel["Order"] / device_funnel["View"] * 100
).round(2)
print("Taux de conversion par appareil :")
print(device_funnel)
Analyse de rétention
Exemple
# Analyse de rétention simplifiée
# Supposons qu'être actif dans les 7 jours suivant l'inscription soit considéré comme une rétention
users_with_events = events.groupby("User ID")["Event Time"].agg(["min", "max"])
users_with_events.columns = ["First Active", "Last Active"]
# Fusionner les informations d'inscription
users_analysis = users.merge(users_with_events, left_on="User ID", right_index=True, how="left")
# Calculer les jours actifs
users_analysis["Active Days"] = (
users_analysis["Last Active"] - users_analysis["First Active"]
).dt.days + 1
print("=== Analyse de rétention des utilisateurs ==="\n")
print(f"Utilisateurs avec comportement : {len(users_with_events)}")
print(f"Nombre moyen de jours actifs : {users_analysis['Active Days'].mean():.1f} jours")
print()
# Rétention à J+1 (simplifiée)
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"Taux de rétention à J+1 : {retention_1d:.1f}%")
print(f"Taux de rétention à 3 jours : {retention_3d:.1f}%")
# Supposons qu'être actif dans les 7 jours suivant l'inscription soit considéré comme une rétention
users_with_events = events.groupby("User ID")["Event Time"].agg(["min", "max"])
users_with_events.columns = ["First Active", "Last Active"]
# Fusionner les informations d'inscription
users_analysis = users.merge(users_with_events, left_on="User ID", right_index=True, how="left")
# Calculer les jours actifs
users_analysis["Active Days"] = (
users_analysis["Last Active"] - users_analysis["First Active"]
).dt.days + 1
print("=== Analyse de rétention des utilisateurs ==="\n")
print(f"Utilisateurs avec comportement : {len(users_with_events)}")
print(f"Nombre moyen de jours actifs : {users_analysis['Active Days'].mean():.1f} jours")
print()
# Rétention à J+1 (simplifiée)
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"Taux de rétention à J+1 : {retention_1d:.1f}%")
print(f"Taux de rétention à 3 jours : {retention_3d:.1f}%")
Résumé de l'analyse
Exemple
print("""
=== Résumé de l'analyse du comportement des utilisateurs ===
1. Engagement des utilisateurs
- Les types d'événements sont dominés par les vues, suivis des clics
- Le nombre moyen d'événements par utilisateur est faible ; la fidélisation des utilisateurs doit être améliorée
2. Tunnel de conversion
- Il y a un abandon important ; l'expérience utilisateur doit être optimisée
- Le taux de conversion de la vue à la commande est relativement faible
3. Efficacité des canaux
- Il est recommandé de se concentrer sur l'optimisation du parcours de conversion des canaux à fort trafic
- Les performances varient selon les canaux ; des opérations affinées sont nécessaires
4. Performance des appareils
- Le mobile est l'appareil principal ; l'expérience mobile doit être optimisée
5. Suggestions d'optimisation
- 1) Optimiser l'affichage des produits pour améliorer la conversion de la vue au clic
- 2) Simplifier le processus d'achat pour réduire les abandons de commande
- 3) Optimiser la vitesse de chargement des pages sur mobile
- 4) Mettre en place un système d'opérations par niveaux d'utilisateurs
""")
=== Résumé de l'analyse du comportement des utilisateurs ===
1. Engagement des utilisateurs
- Les types d'événements sont dominés par les vues, suivis des clics
- Le nombre moyen d'événements par utilisateur est faible ; la fidélisation des utilisateurs doit être améliorée
2. Tunnel de conversion
- Il y a un abandon important ; l'expérience utilisateur doit être optimisée
- Le taux de conversion de la vue à la commande est relativement faible
3. Efficacité des canaux
- Il est recommandé de se concentrer sur l'optimisation du parcours de conversion des canaux à fort trafic
- Les performances varient selon les canaux ; des opérations affinées sont nécessaires
4. Performance des appareils
- Le mobile est l'appareil principal ; l'expérience mobile doit être optimisée
5. Suggestions d'optimisation
- 1) Optimiser l'affichage des produits pour améliorer la conversion de la vue au clic
- 2) Simplifier le processus d'achat pour réduire les abandons de commande
- 3) Optimiser la vitesse de chargement des pages sur mobile
- 4) Mettre en place un système d'opérations par niveaux d'utilisateurs
""")