在日常业务中,产品运营需要综合多个指标进行判断,如果没有目标变量进行监督训练的话,很难人为地判断哪个指标更好,综合起来哪个类别更优秀。
这里介绍一种基于熵权法的指标权重计算,熵权法是一种依据各指标值所包含的信息量的多少确定指标权重的客观赋权法,某个指标的熵越小,说明该指标值的变异程度越大,提供的信息量也就越多,在综合评价中起的作用越大,则该指标的权重也应越大。本文参考自熵值法原理及应用。
案例背景:通过几个业务指标评价小初高的表现
import numpy as np
import pandas as pd
# 构造数据
cars={
'小学':[3000,2.8,68,0.02,25],
'初中':[1000,1.2,45,0.08,5],
'高中':[2500,1.6,70,0.1,70],
}
df=pd.DataFrame(cars).T
df.columns=['活跃用户数','人均练习数','老师数','搜索无结果率','投诉用户数']
df
活跃用户数 | 人均练习数 | 老师数 | 搜索无结果率 | 投诉用户数 | |
---|---|---|---|---|---|
小学 | 3000.0 | 2.8 | 68.0 | 0.02 | 25.0 |
初中 | 1000.0 | 1.2 | 45.0 | 0.08 | 5.0 |
高中 | 2500.0 | 1.6 | 70.0 | 0.10 | 70.0 |
# 数据标准化 避免存在log0,增加0.01
def std_df(df, neg_cols):
'''
df:数据框
neg_cols:负面指标
return:标准化后的数据框
'''
df=df.copy()
for x in df.columns:
if x not in neg_cols: # 非负面指标
df[x]=df[[x]].apply(lambda x:(x-np.min(x))/(np.max(x)-np.min(x)))+0.01
else : # 负面指标
df[x]=df[[x]].apply(lambda x:(np.max(x)-x)/(np.max(x)-np.min(x)))+0.01
return df
# 指标权重计算
def solve_weight(df):
'''
df:数据框
return:指标权重
'''
df=df.copy()
# 计算p
for x in df.columns:
df[x]=df[[x]].apply(lambda x:x/np.sum(x))
# 计算lnp
df_lp=df.applymap(lambda x: np.log(x))
# 计算p*lnp
df_plnp=df.mul(df_lp)
# 计算e
e=-1/np.log(df.shape[0])*df_plnp.sum()
# 计算g
g=1-e
# 计算w
w=g/sum(g)
return w
# 计算加权得分
def solve_score(df, w):
'''
df:数据框
w:指标权重
return:带有分数值的df
'''
df=df.copy()
df['score']=df_std.dot(w)
return df
# 数据标准化
cols=df.columns
neg_cols=['搜索无结果率','投诉用户数'] # 负向指标
df_std=std_df(df, neg_cols)
# 计算权重
w = solve_weight(df_std)
# 输出指标权重
print('{:*^60}'.format('指标权重'))
print(w)
# 输出分值
solve_score(df_std, w).sort_values(by='score', ascending=False)
****************************指标权重****************************
活跃用户数 0.170761
人均练习数 0.244200
老师数 0.167703
搜索无结果率 0.244200
投诉用户数 0.173135
dtype: float64
活跃用户数 | 人均练习数 | 老师数 | 搜索无结果率 | 投诉用户数 | score | |
---|---|---|---|---|---|---|
小学 | 1.01 | 1.01 | 0.93 | 1.01 | 0.702308 | 0.943311 |
高中 | 0.76 | 0.26 | 1.01 | 0.01 | 0.010000 | 0.366824 |
初中 | 0.01 | 0.01 | 0.01 | 0.26 | 1.010000 | 0.244185 |
共勉~