博客
关于我
使用Python进行同期群分析(Cohort Analysis)
阅读量:516 次
发布时间:2019-03-07

本文共 6054 字,大约阅读时间需要 20 分钟。

同期群分析

同期群分析概念

同期群(Cohort)意为具有共同特点或举止类同的一群人,如不同性别或不同年龄的群体。在《精益数据分析》中的第二章《创业的记分牌》中,介绍了三种分析方法(市场细分、同期群分析以及A/B测试)。同期群分析可帮助我们快速了解其应用场景。

同期群分析定义

Comparing Cohort: It compares similar groups over time.

产品随着开发和测试的不断迭代,用户的体验会不断变化。刚在发布第一周加入的用户与隔几个月才加入的用户,可能会有不同的上手体验。例如,每个用户都会经历一个生命周期:从免费试用,到付费使用,最后停止使用。此外,你还会不停地对商业模式进行调整。第一周刚发布的用户可能会因为调试过程中的一些设置问题而感到不适,而是在4个月后才加入的用户则或许能更顺利地开始使用。那么,对于用户流失率,同期群分析可以为此提供答案。

同期群分析的核心目标

每一组用户构成一个同期群,参与整个试验过程。通过比较不同的同期群,你可以了解关键指标(如留存率、营收等)的表现是否随着时间的推移而发生了变化。

在用户分析层面,比如不同月份获取的用户、不同渠道的新增用户,以及具备不同特征的用户(如微信中每天至少和10个以上朋友交叉的用户)等,都可以应用同期群分析。通过分析不同特征的用户在时间维度下的行为差异,我们可以发现潜在的问题并为产品优化提供参考。

同期群分析的主要应用场景

同期群分析主要用于以下两个方面:

  • 对比不同同期群群体在同一体验周期内的数据指标,验证产品迭代优化的效果
  • 对比同一同期群群体在不同体验周期(生命周期)中的数据指标,发现长期体验中的问题
  • 同期群分析的流程

    进行同期群分析时,我们可以大致划分为以下两个流程:确定同期群的分组逻辑和确定同期群分析的关键数据指标。

    分组逻辑

    在确定分组逻辑之前,需遵循以下两个准则:1.群体具有相似行为特征2.群体具有相同的时间周期

    常见的分组逻辑包括:

  • 按获客月份(可按周或天分组)
  • 按获客渠道
  • 按用户完成的特定行为(如访问次数或购买次数)
  • 关键数据指标

    关键数据指标需要基于时间维度,通常包括:

  • 留存率
  • 人均付款金额
  • 人均购买次数
  • 自传播系数等
  • 举例说明

    以下是以留存率为指标的案例分析:

    import pandas as pandasfrom pandas import DataFrame

    数据来源于一个电商平台的用户付费日志,日志中包含日期、付费金额以及用户id(已脱敏处理)。

    数据读取

    import pandas as pd# 读取数据data = pd.read_csv('日志.csv', encoding='gb18030')

    数据预处理

    由于我们是按照月份进行分组,因此需要将日期重采样为月份。

    # 将日期转换为月份data['购买月份'] = pd.to_datetime(data['日期']).dt.to_period('M')

    计算每个月的付费总额和首单购买月份

    # 根据用户id和购买月份分组计算月付费总额和月付费次数order = data.groupby(['uid', '购买月份'], as_index=False).agg(    月付费总额=('付费金额', 'sum'),    月付费次数=('uid', 'count'))

    计算首单月份

    # 确定每个用户的首单月份order['首单月份'] = order.groupby('uid')['购买月份'].transform('min')

    计算用户加入后的月份差异

    # 计算每一笔交易与首单交易月份差异,并添加标签order['标签'] = order[['购买月份', '首单月份']].apply(    lambda x: str(x[1] - x[0]) if x[0] == x[1] else f'+{abs(x[0] - x[1])}月')

    同期群分析

    我们可以使用Python的 pandas 库来整理数据,为不同同期群创建分析视图。

    在这里,我们以留存率为例展示同期群分析的具体步骤:

    # 生成留存率分析表cohort_number = order.pivot_table(    index='首单月份',    columns='标签',    values='uid',    aggfunc='count',    fill_value=0).rename_axis(columns='留存率')# 将“同期群人数”移动到第一列cohort_number.insert(0, '同期群人数', cohort_number.pop('同期群人数'))

    留存率计算

    # 计算不同阶段留存率cohort_number.iloc[:, 1:] = cohort_number.iloc[:, 1:].divide(    cohort_number['同期群人数'],    axis=0)out1 = (cohort_number.style        .format("{:.2%}", subset=cohort_number.columns[1:])        .bar(subset='同期群人数', color='green')        .background_gradient("Reds", subset=cohort_number.columns[1:], high=1, axis=None))

    人均付款金额分析

    cohort_amount = order.pivot_table(    index='首单月份',    columns='标签',    values='月付费总额',    aggfunc='sum',    fill_value=0).rename_axis(columns='人均付款金额')cohort_amount.insert(0, '首月人均付费', cohort_amount.pop('同期群人数'))cohort_amount.insert(0, '同期群人数', cohort_number['同期群人数'])cohort_amount.iloc[:, 1:] = cohort_amount.iloc[:, 1:].divide(    cohort_amount['同期群人数'],    axis=0)out2 = (cohort_amount.style        .format("{:.2f}", subset=cohort_amount.columns[1:])        .background_gradient("Reds", subset=cohort_amount.columns[1:], axis=None)        .bar(subset='同期群人数', color='green'))

    人均购买次数分析

    cohort_count = order.pivot_table(    index='首单月份',    columns='标签',    values='月付费次数',    aggfunc='sum',    fill_value=0).rename_axis(columns='人均购买次数')cohort_count.insert(0, '首月人均频次', cohort_count.pop('同期群人数'))cohort_count.insert(0, '同期群人数', cohort_number['同期群人数'])cohort_count.iloc[:, 1:] = cohort_count.iloc[:, 1:].divide(    cohort_count['同期群人数'],    axis=0)out3 = (cohort_count.style        .format("{:.2f}", subset=cohort_count.columns[1:])        .background_gradient("Reds", subset=cohair_count.columns[1:], axis=None)        .bar(subset='同期群人数', color='green'))

    总体付费情况

    通过对每个月的总体消费情况进行分析,可以更直观地了解用户行为趋势。

    结果展示

    将分析结果导出为网页或图像文件,以便更直观地展示数据。

    代码整体展示

    以下是完整的代码示例:

    import pandas as pdfrom dataframe_image import DataframeImage# 读取数据data = pd.read_csv('日志.csv', encoding='gb18030')# 日期转换为月份data['购买月份'] = pd.to_datetime(data['日期']).dt.to_period('M')# 分组计算月付费总额和月付费次数order = data.groupby(['uid', '购买月份'], as_index=False).agg(    月付费总额=('付费金额', 'sum'),    月付费次数=('uid', 'count'))# 确定首单月份order['首单月份'] = order.groupby('uid')['购买月份'].transform('min')# 添加标签order['标签'] = order[['购买月份', '首单月份']].apply(    lambda x: str(x[1] - x[0]) if x[0] == x[1] else f'+{abs(x[0] - x[1])}月')# 生成留存率视图cohort_number = order.pivot_table(    index='首单月份',    columns='标签',    values='uid',    aggfunc='count',    fill_value=0).rename_axis(columns='留存率')# 移动“同期群人数”到第一列cohort_number.insert(0, '同期群人数', cohort_number.pop('同期群人数'))cohort_number.iloc[:, 1:] = cohort_number.iloc[:, 1:].divide(cohort_number['同期群人数'], axis=0)# 生成留存率图表out1 = (cohort_number.style        .format("{:.2%}", subset=cohort_number.columns[1:])        .bar(subset='同期群人数', color='green')        .background_gradient("Reds", subset=cohort_number.columns[1:], high=1, axis=None))# 生成人均付款金额图表cohort_amount = order.pivot_table(    index='首单月份',    columns='标签',    values='月付费总额',    aggfunc='sum',    fill_value=0).rename_axis(columns='人均付款金额')cohort_amount.insert(0, '首月人均付费', cohort_amount.pop('同期群人数'))cohort_amount.insert(0, '同期群人数', cohort_number['同期群人数'])cohort_amount.iloc[:, 1:] = cohort_amount.iloc[:, 1:].divide(    cohort_amount['同期群人数'],    axis=0)out2 = (cohort_amount.style        .format("{:.2f}", subset=cohort_amount.columns[1:])        .background_gradient("Reds", subset=cohort_amount.columns[1:], axis=None)        .bar(subset='同期群人数', color='green'))# 生成人均购买次数图表cohort_count = order.pivot_table(    index='首单月份',    columns='标签',    values='月付费次数',    aggfunc='sum',    fill_value=0).rename_axis(columns='人均购买次数')cohort_count.insert(0, '首月人均频次', cohort_count.pop('同期群人数'))cohort_count.insert(0, '同期群人数', cohort_number['同期群人数'])cohort_count.iloc[:, 1:] = cohort_count.iloc[:, 1:].divide(    cohort_count['同期群人数'],    axis=0)out3 = (cohort_count.style        .format("{:.2f}", subset=cohaft_count.columns[1:])        .background_gradient("Reds", subset=cohaft_count.columns[1:], axis=None)        .bar(subset='同期群人数', color='green'))# 将所有图表导出为HTML文件with open('out.html', 'w') as f:    f.write(out1.render())    f.write(out2.render())    f.write(out3.render())# 将图表单独导出为图片dfi = DataframeImage()dfi.export(obj=out1, filename='留存率.jpg')dfi.export(obj=out2, filename='人均付款金额.jpg')dfi.export(obj=out3, filename='人均购买次数.jpg')

    转载地址:http://aasjz.baihongyu.com/

    你可能感兴趣的文章
    null可以转换成任意非基本类型(int/short/long/float/boolean/byte/double/char以外)
    查看>>
    Number Sequence(kmp算法)
    查看>>
    Numix Core 开源项目教程
    查看>>
    numpy
    查看>>
    Numpy 入门
    查看>>
    NumPy 库详细介绍-ChatGPT4o作答
    查看>>
    NumPy 或 Pandas:将数组类型保持为整数,同时具有 NaN 值
    查看>>
    numpy 或 scipy 有哪些可能的计算可以返回 NaN?
    查看>>
    numpy 数组 dtype 在 Windows 10 64 位机器中默认为 int32
    查看>>
    numpy 数组与矩阵的乘法理解
    查看>>
    NumPy 数组拼接方法-ChatGPT4o作答
    查看>>
    numpy 用法
    查看>>
    Numpy 科学计算库详解
    查看>>
    Numpy.fft.fft和numpy.fft.fftfreq有什么不同
    查看>>
    numpy.linalg.norm(求范数)
    查看>>
    Numpy.ndarray对象不可调用
    查看>>
    Numpy.VisibleDeproationWarning:从不整齐的嵌套序列创建ndarray
    查看>>
    Numpy:按多个条件过滤行?
    查看>>
    Numpy:条件总和
    查看>>
    numpy、cv2等操作图片基本操作
    查看>>