本文共 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/