使用Python進行同期群分析(Cohort?Analysis)
同期群分析
同期群分析概念
同期群(Cohort)的字面意思(有共同特點或舉止類同的)一群人,比如不同性別,不同年齡。
在《精益數(shù)據(jù)分析》中的第2章 創(chuàng)業(yè)的記分牌 中介紹了三種分析方法(市場細分、同期群分析以及A/B測試),其中關(guān)于同期群分析的討論可以幫助我們快速了解它的應用場景。
同期群分析:比較的是相似群體隨時間的變化。
產(chǎn)品會隨著你的開發(fā)和測試而不斷迭代,這就導致在產(chǎn)品發(fā)布第一周就加入的用戶和后來才加入的用戶有著不同的體驗。比如,每個用戶都會經(jīng)歷一個生命周期:從免費試用,到付費使用,最后停止使用。同時,在這期間里,你還在不停地對商業(yè)模式進行調(diào)整。于是,在產(chǎn)品上線第一個月就“吃螃蟹”的用戶勢必與四個月后才加入的用戶有著不同的上手體驗。這對用戶流失率會有什么影響?我們用同期群分析來尋找答案。
每一組用戶構(gòu)成一個同期群,參與整個試驗過程。通過比較不同的同期群,你可以獲知:從總體上看,關(guān)鍵指標的表現(xiàn)是否越來越好了。
結(jié)合到用戶分析層面,比如不同月份獲取的用戶,不同渠道新增用戶,具備不同特征的用戶(比如微信里每天至少和10個以上朋友微信的用戶)。
同期群分析(Cohort Analysis),將這些具有不同特征的人群進行對比分析,以發(fā)現(xiàn)他們在時間維度下的行為差異。
因此,同期群分析主要用于以下2點:
- 對比 不同 同期群群體同一體驗周期的數(shù)據(jù)指標,驗證產(chǎn)品迭代優(yōu)化的效果
- 對比 同一 同期群群體不同體驗周期(生命周期)的數(shù)據(jù)指標,發(fā)現(xiàn)長線體驗的問題
我們在進行同期群分析的時候,大致可以劃分為2個流程:確定同期群分組邏輯和確定同期群分析的關(guān)鍵數(shù)據(jù)指標。
- 具有相似行為特征的群體
- 具有相同時間周期的群體
例如:
- 按獲客月份(按周甚至按天分組)
- 按獲客渠道
- 按照用戶完成的特定行為,比如用戶訪問網(wǎng)站的次數(shù)或者購買次數(shù)來分類。
關(guān)于關(guān)鍵數(shù)據(jù)指標,需要是基于時間維度下的比如留存、營收、自傳播系數(shù)等等。
下面是以留存率作為指標的案例示例:
下面是某電商的運營數(shù)據(jù),我們將以該數(shù)據(jù)演示用python進行同期群分析。
同期群分析案例詳解:
數(shù)據(jù)是某電商用戶付費日志,日志字段包含日期、付費金額和用戶id,已脫敏處理。
數(shù)據(jù)讀取
import pandas as pd df = pd.read_csv('日志.csv', encoding="gb18030") df.head()
分析方向
分組邏輯:
這里只按照用戶的初始購買月份進行分組,如果日志包含的分類字段更多(比如 渠道、性別或者年齡等),可以考慮更多種分組邏輯。
關(guān)鍵數(shù)據(jù)指標:
針對此份數(shù)據(jù),至少有3個數(shù)據(jù)指標可以進行分析:
- 留存率
- 人均付款金額
- 人均購買次數(shù)
數(shù)據(jù)預處理
因為我們是按照月份進行分組,所以需要先將日期重采樣為月份:
df['購買月份'] = pd.to_datetime(df.日期).dt.to_period("M") df.head()
計算每個用戶在每個月的付費總額:
order = df.groupby(["uid", "購買月份"], as_index=False).agg( 月付費總額=("付費金額","sum"), 月付費次數(shù)=("uid","count"), ) order.head()
計算每個用戶的首單購買月份作為同期群分組,并將其對應到原始數(shù)據(jù)上:
order["首單月份"] = order.groupby("uid")['購買月份'].transform("min") order.head()
計算每條購買記錄的時間與首單購買時間的月份差,并重置月份差標簽:
order["標簽"] = (order.購買月份-order.首單月份).apply(lambda x:"同期群人數(shù)" if x.n==0 else f"+{x.n}月") order.head()
兩個月份均為時期類型,相減后得到object類型的列,而該列每個元素的類型是pandas._libs.tslibs.offsets.MonthEnd
MonthEnd類型具有屬性n能返回具體差值整數(shù)。
同期群分析
前面我們說了至少有3個數(shù)據(jù)指標可以進行分析:
- 留存率
- 人均付款金額
- 人均購買次數(shù)
從留存率角度進行同期群分析
通過數(shù)據(jù)透視表可以一次性計算所需的數(shù)據(jù):
cohort_number = order.pivot_table(index="首單月份", columns="標簽", values="uid", aggfunc="count", fill_value=0).rename_axis(columns="留存率") cohort_number
注意:rename_axis(columns=None)用于刪除列標簽的軸名稱。rename_axis(columns=“留存率”)則設(shè)置軸名稱為留存率。
將 本月新增 列移動到第一列:
cohort_number.insert(0, "同期群人數(shù)", cohort_number.pop("同期群人數(shù)")) cohort_number
具體過程是先通過pop刪除該列,然后插入到0位置,并命名為指定的列名。
在本次的分析中,留存率的具體計算方式為:+N月留存率=+N月付款用戶數(shù)/首月付款用戶數(shù)
cohort_number.iloc[:, 1:] = cohort_number.iloc[:, 1:].divide(cohort_number.本月新增, axis=0) cohort_number
以百分比形式顯示,并設(shè)置顏色:
out1 = (cohort_number.style .format("{:.2%}", subset=cohort_number.columns[1:]) .bar(subset="同期群人數(shù)", color="green") .background_gradient("Reds", subset=cohort_number.columns[1:], high=1, axis=None) ) out1
至此計算完畢。
從人均付款金額角度進行同期群分析
要從從人均付款金額角度考慮,需要考慮同期群基期這個整體。具體計算方式是先計算各月的付款總額,然后除以基期的總?cè)藬?shù):
cohort_amount = order.pivot_table(index="首單月份", columns="標簽", values="月付費總額", aggfunc="sum", fill_value=0).rename_axis(columns="人均付款金額") cohort_amount.insert(0, "首月人均付費", cohort_amount.pop("同期群人數(shù)")) cohort_amount.insert(0, "同期群人數(shù)", cohort_number.同期群人數(shù)) cohort_amount.iloc[:, 1:] = cohort_amount.iloc[:, 1:].divide(cohort_amount.同期群人數(shù), 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="同期群人數(shù)", color="green") ) out2
可以看到,12月份的同期群首月新用戶人均消費為703.43元,然后逐月遞減,到+4月后這些用戶人均消費僅11.41元。而隨著版本的迭代發(fā)展,新增用戶的首月消費并沒有較大提升,且接下來的消費趨勢反而不如12月份。由此可見產(chǎn)品的發(fā)展受到了一定的瓶頸,需要思考增長營收的出路了。
一般來說, 通過同期群分析可以比較好指導我們后續(xù)更深入細致的數(shù)據(jù)分析,為產(chǎn)品優(yōu)化提供參考。
從人均購買次數(shù)角度進行同期群分析
依然按照上面一樣的套路:
cohort_count = order.pivot_table(index="首單月份", columns="標簽", values="月付費次數(shù)", aggfunc="sum", fill_value=0).rename_axis(columns="人均購買次數(shù)") cohort_count.insert(0, "首月人均頻次", cohort_count.pop("同期群人數(shù)")) cohort_count.insert(0, "同期群人數(shù)", cohort_number.同期群人數(shù)) cohort_count.iloc[:, 1:] = cohort_count.iloc[:, 1:].divide(cohort_count.同期群人數(shù), axis=0) out3 = (cohort_count.style .format("{:.2f}", subset=cohort_count.columns[1:]) .background_gradient("Reds", subset=cohort_count.columns[1:], axis=None) .bar(subset="同期群人數(shù)", color="green") ) out3
可以得到類似上述一致的結(jié)論。
每月總體付費情況
下面我們看看每個月的總體消費情況:
order.groupby("購買月份").agg( 付費人數(shù)=("uid", "count"), 人均付款金額=("月付費總額", "mean"), 月付費總額=("月付費總額", "sum") )
可以看到總體付費人數(shù)和付費金額都在逐月下降。
將結(jié)果導出網(wǎng)頁或截圖
對于Styler類型,我們可以調(diào)用render方法轉(zhuǎn)化為網(wǎng)頁源代碼,通過以下方式即可將其導入到一個網(wǎng)頁文件中:
with open("out.html", "w") as f: f.write(out1.render()) f.write(out2.render()) f.write(out3.render())
如果你的電腦安裝了谷歌游覽器,還可以安裝dataframe_image,將這個表格導出為圖片。
安裝:pip install dataframe_image
import dataframe_image as dfi dfi.export(obj=out1, filename='留存率.jpg') dfi.export(obj=out2, filename='人均付款金額.jpg') dfi.export(obj=out3, filename='人均購買次數(shù).jpg')
dfi.export的參數(shù):
- obj : 被導出的Datafream對象
- filename : 文件保存位置
- fontsize : 字體大小
- max_rows : 最大行數(shù)
- max_cols : 最大列數(shù)
- table_conversion : 使用谷歌游覽器或原生’matplotlib’, 只要寫非’chrome’的值就會使用原生’matplotlib’
- chrome_path : 指定谷歌游覽器位置
整體完整代碼
import pandas as pd import dataframe_image as dfi df = pd.read_csv('日志.csv', encoding="gb18030") df['購買月份'] = pd.to_datetime(df.日期).dt.to_period("M") order = df.groupby(["uid", "購買月份"], as_index=False).agg( 月付費總額=("付費金額", "sum"), 月付費次數(shù)=("uid", "count"), ) order["首單月份"] = order.groupby("uid")['購買月份'].transform("min") order["標簽"] = ( order.購買月份-order.首單月份).apply(lambda x: "同期群人數(shù)" if x.n == 0 else f"+{x.n}月") cohort_number = order.pivot_table(index="首單月份", columns="標簽", values="uid", aggfunc="count", fill_value=0).rename_axis(columns="留存率") cohort_number.insert(0, "同期群人數(shù)", cohort_number.pop("同期群人數(shù)")) cohort_number.iloc[:, 1:] = cohort_number.iloc[:,1:].divide(cohort_number.同期群人數(shù), axis=0) out1 = (cohort_number.style .format("{:.2%}", subset=cohort_number.columns[1:]) .bar(subset="同期群人數(shù)", 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("同期群人數(shù)")) cohort_amount.insert(0, "同期群人數(shù)", cohort_number.同期群人數(shù)) cohort_amount.iloc[:, 1:] = cohort_amount.iloc[:, 1:].divide(cohort_amount.同期群人數(shù), 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="同期群人數(shù)", color="green") ) cohort_count = order.pivot_table(index="首單月份", columns="標簽", values="月付費次數(shù)", aggfunc="sum", fill_value=0).rename_axis(columns="人均購買次數(shù)") cohort_count.insert(0, "首月人均頻次", cohort_count.pop("同期群人數(shù)")) cohort_count.insert(0, "同期群人數(shù)", cohort_number.同期群人數(shù)) cohort_count.iloc[:, 1:] = cohort_count.iloc[:, 1:].divide(cohort_count.同期群人數(shù), axis=0) out3 = (cohort_count.style .format("{:.2f}", subset=cohort_count.columns[1:]) .background_gradient("Reds", subset=cohort_count.columns[1:], axis=None) .bar(subset="同期群人數(shù)", color="green") ) outs = [out1, out2, out3] with open("out.html", "w") as f: for out in outs: f.write(out.render()) display(out) dfi.export(obj=out1, filename='留存率.jpg') dfi.export(obj=out2, filename='人均付款金額.jpg') dfi.export(obj=out3, filename='人均購買次數(shù).jpg')
到此這篇關(guān)于使用Python進行同期群分析(Cohort Analysis)的文章就介紹到這了,更多相關(guān)Python同期群分析內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Python3實現(xiàn)抓取javascript動態(tài)生成的html網(wǎng)頁功能示例
這篇文章主要介紹了Python3實現(xiàn)抓取javascript動態(tài)生成的html網(wǎng)頁功能,結(jié)合實例形式分析了Python3使用selenium庫針對javascript動態(tài)生成的HTML網(wǎng)頁元素進行抓取的相關(guān)操作技巧,需要的朋友可以參考下2017-08-08Jupyter Lab設(shè)置切換虛擬環(huán)境的實現(xiàn)步驟
本文主要介紹了Jupyter Lab設(shè)置切換虛擬環(huán)境的實現(xiàn)步驟,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2023-02-02在Python中使用CasperJS獲取JS渲染生成的HTML內(nèi)容的教程
這篇文章主要介紹了在Python中使用CasperJS獲取JS渲染生成的HTML內(nèi)容的教程,需要先用JavaScript創(chuàng)建一個接口文件,需要的朋友可以參考下2015-04-04將Python中的數(shù)據(jù)存儲到系統(tǒng)本地的簡單方法
這篇文章主要介紹了將Python中的數(shù)據(jù)存儲到系統(tǒng)本地的簡單方法,主要使用了pickle模塊,需要的朋友可以參考下2015-04-04