举个栗子:假设某电商的单量下滑,昨日单量100单,今日50单,想看看具体是哪个因素引起的?数据包含3个维度,一个是渠道(A1、A2、A3),一个是品类(B1、B3、B4、B5、B6),一个是活动(C1、C2、C3、C4)
在互联网的各类业务中,遇到关键指标的异动,譬如电商业务的GMV下降,游戏业务的收入下滑,一般分析师都会采用下钻维度的方法去看具体是哪个细分维度引起的下降。如果涉及维度较多,手动去归因必然会影响效率,因此可以用Adtributor算法自动化输出归因的维度。
简单的来说,Adtributor算法就是算出每个维度的枚举值的JS散度和解释度,再进行排序。
import pandas as pd
import numpy as np
'''
A: 渠道 1,2,3
B: 品类 1,2,3,4,5,6
C:维度 1,2,3,4,5
'''
lists = [['A','1', 83,37]
,['A','2', 6,3]
,['A','3', 11,10]
,['B','1', 20,15]
,['B','2', 20,4]
,['B','3', 10,1]
,['B','4', 20,19]
,['B','5', 20,9]
,['B','6', 10,1]
,['C','1', 2,1]
,['C','2', 22,39]
,['C','3', 48,7]
,['C','4', 28,4]
]
df = pd.DataFrame(lists, columns=['Attribute', 'Values', 'yesterday', 'today'])
dim_group= df.groupby('Attribute').sum()
dim_group =dim_group.rename(columns = {'yesterday':'yesterday_sum', 'today':'today_sum'})
df=pd.merge(df, dim_group, on = 'Attribute', how = 'left')
df['p']=df1['yesterday']/df1['yesterday_sum']
df['q']=df1['today']/df1['today_sum']
df['ep'] = ( df['today'] - df['yesterday'] )/ ( df['today_sum'] - df['yesterday_sum'] )
df['js'] = round(0.5*(df['p']*np.log(2*df['p']/(df['p']+df['q'])))+0.5*(df['q']*np.log(2*df['q']/(df['p']+df['q']))),6)
# 降序排列:js、ep
result = df.sort_values(by=['js', 'ep'],ascending=False).reset_index()
result[['Attribute','Values','ep','js']].head(5)
可以看出造成单量下降的原因主要是活动3、活动4单量下降造成的。EP为负,代表与异动方向相反,比如活动2相比昨日单量反倒是上涨的,虽然它的S很高,但是它并不是造成单量下滑的原因,换句话说,如果活动2和昨日一样,整体单量应该下滑得更大。
在做分析的时候,也可以把EP大于某个门槛值再做排序,更加方便一点。
附录:
# A
df[:3]['js'].sum() # 0.007918
# B
df[3:9]['js'].sum() # 0.062536
# C
df[-4:]['js'].sum() # 0.160186
CK:
https://mp.weixin.qq.com/s/SoA4p5EY4IKHyw7IKwTUyg