同期群分析Skill CohortAnalysis

用于跟踪和分析用户群体随时间的行为变化,识别留存率、流失率和终身价值等关键指标,以优化产品和用户策略。

数据分析 0 次安装 6 次浏览 更新于 3/3/2026

name: 同期群分析 description: 跟踪和分析用户同期群随时间的变化,计算留存率,并识别客户生命周期和留存分析中的行为模式

同期群分析

概览

同期群分析跟踪具有共同特征的用户群体随时间的变化,揭示留存、参与度和终身价值的模式。

何时使用

  • 测量用户留存率并识别何时用户流失
  • 分析客户终身价值(LTV)和回报期
  • 比较不同用户获取渠道或活动的表现
  • 了解产品变化如何随时间影响不同用户群体
  • 跟踪参与模式并识别流失的早期预警信号
  • 评估改进用户引导或功能发布对长期影响

核心概念

  • 同期群: 共享特征的用户群体(注册日期、地区等)
  • 同期群大小: 初始群体大小
  • 留存率: 剩余活跃的百分比
  • 流失率: 离开的百分比
  • 留存曲线: 同期群随时间的降解情况

同期群类型

  • 获取日期: 按注册周期分组的用户
  • 行为: 按采取的行动分组的用户
  • 收入: 按购买价值分组的用户
  • 地理: 按位置分组的用户
  • 人口统计: 按特征分组的用户

使用Python实现

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns

# 创建样本用户生命周期数据
np.random.seed(42)

# 生成用户数据
n_users = 5000
users = []

for user_id in range(n_users):
    signup_month = np.random.choice(range(1, 13))
    lifetime_months = np.random.poisson(6) + 1

    for month in range(1, lifetime_months + 1):
        users.append({
            'user_id': user_id,
            'signup_month': signup_month,
            'month': month,
            'active': 1,
        })

df = pd.DataFrame(users)

# 添加派生列
df['cohort_month'] = df['signup_month']
df['cohort_age'] = df['month']  # 可以是天、周等。
df['date'] = pd.to_datetime('2023-01-01') + pd.to_timedelta(df['signup_month'] * 30, unit='D')

print("用户数据摘要:")
print(df.head(10))

# 1. 同期群表(留存矩阵)
cohort_data = df.groupby(['cohort_month', 'cohort_age']).agg({
    'user_id': 'nunique'
}).reset_index()
cohort_data.columns = ['cohort_month', 'cohort_age', 'unique_users']

# 创建透视表
cohort_pivot = cohort_data.pivot(index='cohort_month', columns='cohort_age', values='unique_users')

print("
同期群大小(原始用户计数):")
print(cohort_pivot)

# 2. 同期群留存(作为同期群大小的百分比)
cohort_size = cohort_pivot.iloc[:, 0]
retention_table = cohort_pivot.divide(cohort_size, axis=0) * 100

print("
同期群留存率(%):")
print(retention_table.round(1))

# 3. 可视化留存矩阵
fig, axes = plt.subplots(2, 1, figsize=(14, 8))

# 原始计数的热图
sns.heatmap(cohort_pivot, annot=True, fmt='g', cmap='YlOrRd', ax=axes[0],
            cbar_kws={'label': '用户计数'})
axes[0].set_title('同期群大小 - 用户计数')
axes[0].set_xlabel('同期群年龄(月)')
axes[0].set_ylabel('同期群月份')

# 留存率的热图
sns.heatmap(retention_table, annot=True, fmt='.0f', cmap='RdYlGn', vmin=0, vmax=100,
            ax=axes[1], cbar_kws={'label': '留存%'})
axes[1].set_title('同期群留存率(%)')
axes[1].set_xlabel('同期群年龄(月)')
axes[1].set_ylabel('同期群月份')

plt.tight_layout()
plt.show()

# 4. 留存曲线
fig, ax = plt.subplots(figsize=(12, 6))

# 为每个同期群绘制留存曲线
for cohort_month in cohort_pivot.index[:8]:  # 前8个同期群
    cohort_retention = retention_table.loc[cohort_month]
    ax.plot(cohort_retention.index, cohort_retention.values, marker='o', label=f'同期群 {cohort_month}')

ax.set_xlabel('同期群年龄(月)')
ax.set_ylabel('留存率(%)')
ax.set_title('按同期群的留存曲线')
ax.legend(bbox_to_anchor=(1.05, 1), loc='upper left')
ax.grid(True, alpha=0.3)
ax.set_ylim([0, 105])

plt.tight_layout()
plt.show()

# 5. 平均留存曲线
fig, ax = plt.subplots(figsize=(10, 6))

# 计算每个年龄的平均留存
avg_retention = retention_table.mean()
ax.plot(avg_retention.index, avg_retention.values, marker='o', linewidth=2, markersize=8, color='navy')
ax.fill_between(avg_retention.index, avg_retention.values, alpha=0.3, color='navy')

# 添加置信区间
std_retention = retention_table.std()
ax.fill_between(std_retention.index,
                avg_retention - std_retention,
                avg_retention + std_retention,
                alpha=0.2, color='navy', label='±1 标准差')

ax.set_xlabel('同期群年龄(月)')
ax.set_ylabel('留存率(%)')
ax.set_title('平均留存曲线与置信带')
ax.legend()
ax.grid(True, alpha=0.3)
ax.set_ylim([0, 105])

plt.tight_layout()
plt.show()

# 6. 流失率
churn_rate = 100 - retention_table
print("
流失率(%):")
print(churn_rate.round(1).head())

# 7. 收入同期群分析
# 添加收入数据
np.random.seed(42)
df['revenue'] = np.random.exponential(50, len(df))

# 按同期群的收入
revenue_data = df.groupby(['cohort_month', 'cohort_age']).agg({
    'revenue': 'sum',
    'user_id': 'nunique'
}).reset_index()
revenue_data['revenue_per_user'] = revenue_data['revenue'] / revenue_data['user_id']

revenue_pivot = revenue_data.pivot(index='cohort_month', columns='cohort_age', values='revenue')
rpu_pivot = revenue_data.pivot(index='cohort_month', columns='cohort_age', values='revenue_per_user')

# 可视化收入
fig, axes = plt.subplots(2, 1, figsize=(14, 8))

sns.heatmap(revenue_pivot, annot=True, fmt='.0f', cmap='YlGnBu', ax=axes[0],
            cbar_kws={'label': '总收入($)'})
axes[0].set_title('按同期群的总收入')
axes[0].set_xlabel('同期群年龄(月)')
axes[0].set_ylabel('同期群月份')

sns.heatmap(rpu_pivot, annot=True, fmt='.2f', cmap='YlGnBu', ax=axes[1],
            cbar_kws={'label': '每位用户的收入($)'})
axes[1].set_title('按同期群的每位用户收入')
axes[1].set_xlabel('同期群年龄(月)')
axes[1].set_ylabel('同期群月份')

plt.tight_layout()
plt.show()

# 8. 终身价值计算
df['month_since_signup'] = df['cohort_age']
ltv_data = df.groupby('user_id').agg({
    'revenue': 'sum',
    'cohort_month': 'first',
    'month_since_signup': 'max',
}).reset_index()
ltv_data.columns = ['user_id', 'lifetime_value', 'cohort_month', 'lifetime_months']

# 按同期群的平均LTV
ltv_by_cohort = ltv_data.groupby('cohort_month')['lifetime_value'].agg(['mean', 'median', 'std'])

print("
同期群的终身价值:")
print(ltv_by_cohort.round(2))

fig, ax = plt.subplots(figsize=(10, 6))
ltv_by_cohort['mean'].plot(kind='bar', ax=ax, color='skyblue', edgecolor='black')
ax.set_title('按同期群的平均终身价值')
ax.set_xlabel('同期群月份')
ax.set_ylabel('终身价值($)')
ax.grid(True, alpha=0.3, axis='y')
plt.tight_layout()
plt.show()

# 9. 同期群随时间的构成
fig, ax = plt.subplots(figsize=(12, 6))

# 按同期群每月活跃用户
active_by_month = df.groupby(['date', 'cohort_month']).size().reset_index(name='active_users')
pivot_active = active_by_month.pivot(index='date', columns='cohort_month', values='active_users')

pivot_active.plot(ax=ax, marker='o')
ax.set_title('按同期群每月活跃用户')
ax.set_xlabel('月份')
ax.set_ylabel('活跃用户')
ax.legend(title='同期群月份', bbox_to_anchor=(1.05, 1))
ax.grid(True, alpha=0.3)

plt.tight_layout()
plt.show()

# 10. 同期群摘要指标
summary_metrics = pd.DataFrame({
    '同期群月份': cohort_size.index,
    '初始规模': cohort_size.values,
    '第1个月留存': retention_table.iloc[:, 0].values,
    '第3个月留存': retention_table.iloc[:, min(2, retention_table.shape[1]-1)].values,
    '平均LTV': ltv_by_cohort['mean'].values,
})

print("
同期群摘要指标:")
print(summary_metrics.round(2))

# 11. 可视化比较
fig, axes = plt.subplots(1, 3, figsize=(15, 4))

# 第1个月与第3个月留存
ax_plot = axes[0]
months = ['第1个月', '第3个月']
month_1_ret = retention_table.iloc[:, 0].mean()
month_3_ret = retention_table.iloc[:, min(2, retention_table.shape[1]-1)].mean()
ax_plot.bar(months, [month_1_ret, month_3_ret], color=['#1f77b4', '#ff7f0e'], edgecolor='black')
ax_plot.set_ylabel('留存率(%)')
ax_plot.set_title('按里程碑的平均留存')
ax_plot.set_ylim([0, 100])
for i, v in enumerate([month_1_ret, month_3_ret]):
    ax_plot.text(i, v + 2, f'{v:.1f}%', ha='center')

# 同期群规模趋势
axes[1].plot(cohort_size.index, cohort_size.values, marker='o', linewidth=2, markersize=8)
axes[1].set_xlabel('同期群月份')
axes[1].set_ylabel('同期群规模')
axes[1].set_title('随时间变化的同期群规模')
axes[1].grid(True, alpha=0.3)

# LTV趋势
axes[2].plot(ltv_by_cohort.index, ltv_by_cohort['mean'].values, marker='o', linewidth=2, markersize=8, color='green')
axes[2].set_xlabel('同期群月份')
axes[2].set_ylabel('平均终身价值($)')
axes[2].set_title('按同期群的LTV趋势')
axes[2].grid(True, alpha=0.3)

plt.tight_layout()
plt.show()

print("
同期群分析完成!")

关键指标

  • 留存率: 同期群活跃的百分比
  • 流失率: 同期群流失的百分比
  • 第1天/月留存: 早期参与度
  • 终身价值: 每位用户的总收入
  • 回报期: 回收CAC的时间

寻找的洞察

  • 早期留存预测器
  • 同期群之间的差异
  • 季节性模式
  • 参与度下降
  • 收入趋势

交付物

  • 同期群留存矩阵
  • 留存曲线可视化
  • 流失率分析
  • 终身价值计算
  • 每个同期群的收入
  • 带有洞察的执行摘要
  • 可操作的建议