赞
踩
本文首先分类介绍主客观赋权法,然后简述四种客观赋权法的算法步骤,分别给出python代码。
在用户建模的过程中,常常需要从用户的各项行为指标 ( x 1 , x 2 , . . . , x n ) (x_{1}, x_{2}, ... , x_{n}) (x1,x2,...,xn),以加权求和的方式计算用户的总体活跃度,形如: S = a 1 x 1 + a 2 x 2 + . . . + a n x n S = a_{1} x_{1} + a_{2} x_{2} + ... + a_{n} x_{n} S=a1x1+a2x2+...+anxn
其中 a 1 , a 2 , . . . , a n a_{1}, a_{2}, ... , a_{n} a1,a2,...,an 分别为 x 1 , x 2 , . . . , x n x_{1}, x_{2}, ... , x_{n} x1,x2,...,xn 的权重。通过对 x i ( i = 1 , 2 , . . . , n ) x_{i} ~ (i=1,2,...,n) xi (i=1,2,...,n) 的 “重要性” 的设置,加权求和,计算用户的总得分。
对于如何确定 a 1 , a 2 , . . . , a n a_{1}, a_{2}, ... , a_{n} a1,a2,...,an 的值,主要有八种方法,可分为以下四类:
名称 | 数据波动性 | 数据间相关关系 | 数字大小信息 | 适用性 |
---|---|---|---|---|
AHP层次法 | 无 | 无 | 有 | 适用于多个层次指标计算权重,专家打分赋权有一定的主观性 |
优序图法 | 无 | 无 | 有 | 计算较简便,较多指标时使用得到的权重结果更可靠 |
熵值法 | 无 | 无 | 无 | 适用于指标较多的、底层方案层指标计算权重,但对样本的依赖性较大,随着样本数据变化,权重会有一定的波动 |
CRITIC权重法 | 有 | 有 | 无 | 综合考虑数据波动情况和指标间的相关性,适合指标自身带有一定相关性和波动性的数据 |
信息量权重法 | 有 | 无 | 无 | 适用于将数据差异性视作一种信息,用数据波动程度来衡量指标权重 |
独立性权重法 | 无 | 有 | 无 | 适用于指标本身带有一些相关性、属于同一系统下的指标计算权重 |
因子分析法 | 无 | 有 | 无 | 指标较多时降维得到具有可解释性的因子权重,也可单独得到各指标权重,需要大量样本数据 |
主成分分析法 | 无 | 有 | 无 | 适用于指标较多时降维得到主成分权重,也可单独得到各项指标权重,需要大量样本数据 |
注意:
- 一般来说,计算权重时,可使用四种客观赋权法(熵权法、CRITIC权重法、信息量权重法、独立性权重法)分别计算各指标的权重,然后计算四种方法所得结果的均值,从而得到最终的权重。
- 如果只想使用专家的意见,可以使用主观赋权法。
- 因子分析法、主成分分析法主要用于降维并计算权重,只能得到各个因子的权重,无法得到具体每个分析项的权重。
- 如果想要将主客观的权重结合起来,可以使用组合赋权法(集成赋权法)。
这里把后面需要用到的MinMax归一化、标准化、均值、标准差、方差、相关系数等函数都一起给出,后面的代码将仅给出算法,不再包含这些函数。
import pandas as pd import numpy as np import math from sklearn.preprocessing import StandardScaler, MinMaxScaler # 标准化 def normalize_Standard(df): scaler = StandardScaler() return pd.DataFrame(scaler.fit_transform(df), columns=df.columns.values) # MinMax归一化(0-1 归一化) def normalize_MinMax(df): scaler = MinMaxScaler(feature_range=(0,1)) return pd.DataFrame(scaler.fit_transform(df), columns=df.columns.values) # 均值 def compute_mat_mean(df): return pd.DataFrame(df.mean(), columns=['mean_value']) ## 标准差(使用df.std) def compute_mat_std(df): return pd.DataFrame(df.std(), columns=['std_value']) # 方差(标准差的平方) def compute_mat_var(df): df_std = pd.DataFrame(df.std(), columns=['std_value']) df_std['var_value'] = df_std['std_value'].apply(lambda x: x ** 2) return pd.DataFrame(df_std['var_value'], columns=['var_value']) # 相关矩阵(相关系数矩阵) def compute_mat_corr(df): return pd.DataFrame(df.corr(), columns=df.columns.values)
1、基本思想
利用信息量的多少,即数据携带的信息量大小(物理学上的熵值原理)进行权重计算。
2、适用范围
各信息(数据指标)之间存在差异。主要用于解决评价类问题(例如:选择哪种方案最好、哪位运动员或员工表现的更优秀)。
3、算法步骤
4、python代码
# 计算指标的熵值 (输入:标准化df; 输出:熵值df; ) def compute_entropy(df): col_names = df.columns.values df_mid = df[col_names] new_col_names = [] for cc in col_names: new_cc = '{}_1'.format(cc) new_col_names.append(new_cc) num_cc = df_mid[cc].count() sum_cc = df_mid[cc].sum() df_mid.loc[df_mid[cc] > 0, new_cc] = df_mid.loc[df_mid[cc] > 0, cc]\ .apply(lambda x: 0 - (x/sum_cc * math.log(x/sum_cc)) / math.log(num_cc)) df_mid.loc[df_mid[cc] == 0, new_cc] = 0 df_mid = df_mid[new_col_names] df_mid.columns = col_names return pd.DataFrame(df_mid.sum(), columns=['etp_value']) # 根据熵值计算权重 (输入:熵值df; 输出:权重df;) def compute_entropy_weight(df): df_mid = df[df.columns.values] num_cc = df_mid.count() sum_cc = df_mid.sum() df_mid['w_value'] = df_mid['etp_value'].apply(lambda x: (1 - x)/(num_cc - sum_cc)) df_mid['p_name'] = df_mid.index.values return df_mid[['p_name','w_value']] # 熵权法主函数 (输入:指标df; 输出:权重df;) def weight_entropy(df): df_mid = normalize_MinMax(df) return compute_entropy_weight(compute_entropy(df_mid))
1、基本思想
基于 指标的对比强度(标准差) 和 指标之间的冲突性(相关系数) 来综合衡量指标的客观权重。
2、适用范围
数据稳定性可视作一种信息,并且分析的指标或因素之间有着一定的关联关系。
3、算法步骤
4、python代码
# CRITIC权重法 主函数 def weight_critic(df): df_scale = normalize_MinMax(df) # 标准差 df_std = compute_mat_std(df_scale) df_std['p_name'] = df_std.index.values # 相关系数矩阵 df_corr = compute_mat_corr(df_scale) col_names = df_corr.columns.values # 求相关系数和 df_mid = df_corr[col_names] new_col_names = [] for cc in col_names: new_cc = '{}_1'.format(cc) new_col_names.append(new_cc) df_mid[new_cc] = df_mid[cc].apply(lambda x: 1-x) df_mid = df_mid[new_col_names] df_mid = pd.DataFrame(df_mid.sum(), columns=['r_value']) df_mid['p_name'] = col_names # 标准差与相关系数相乘 df_mix = pd.merge(df_std, df_mid, on='p_name') df_mix['pp_value'] = df_mix.apply(lambda x: x['std_value'] * x['r_value'], axis=1) # 最后计算权重值 sum_pp = df_mix['pp_value'].sum() df_mix['weight_value'] = df_mix['pp_value'].apply(lambda x: x/sum_pp) return df_mix[['p_name','weight_value']]
1、基本思想
基于指标数据所包含的信息量来确定指标权重,利用数据的变异系数进行权重赋值,变异系数越大,所赋的权重也越大。
2、适用范围
专家打分、或者面试官进行面试打分时对评价对象(面试者)进行综合评价。
3、算法步骤
4、python代码
# 信息量权重法 主函数 def weight_information(df): df_scale = normalize_MinMax(df) df_mid = df_scale[df_scale.columns.values] # 计算标准差 和 均值 df_std = compute_mat_std(df_mid) df_std['p_name'] = df_std.index.values df_mean = compute_mat_mean(df_mid) df_mean['p_name'] = df_mean.index.values # 合并两个df df_mix = pd.merge(df_std, df_mean, on='p_name') # 计算变异系数,再计算权重 df_mix['cof_value'] = df_mix.apply(lambda x: x['std_value'] / x['mean_value'], axis=1) sum_cof = df_mix['cof_value'].sum() df_mix['weight_value'] = df_mix['cof_value'].apply(lambda x: x / sum_cof) return df_mix[['p_name','weight_value']]
1、基本思想
利用指标之间的共线性强弱(复相关系数)来确定权重,仅仅只考虑了数据之间相关性;
2、适用范围
数据指标之间具有相关性;
3、算法步骤
复相关系数 R R R 的计算:
- 对指标 x i x_{i} xi,用余下 ( n − 1 ) (n-1) (n−1) 个指标线性表示,得到: x i ^ = a 1 x 1 + . . . + a n − 1 x n − 1 \hat{x_{i}} = a_{1}x_{1} + ... + a_{n-1}x_{n-1} xi^=a1x1+...+an−1xn−1
- 计算复相关系数 R R R,即计算 x i ^ \hat{x_{i}} xi^ 与 X 1 , X 2 , . . . , X n − 1 X_{1},X_{2},...,X_{n-1} X1,X2,...,Xn−1 之间的简单相关系数: R = ∑ ( x − x ˉ ) ( x ^ − x ˉ ) ∑ ( x − x ˉ ) 2 ( x ^ − x ˉ ) 2 R = \frac{\sum(x - \bar{x})(\hat{x} - \bar{x})}{\sqrt{\sum (x - \bar{x})^{2} (\hat{x} - \bar{x})^{2}}} R=∑(x−xˉ)2(x^−xˉ)2 ∑(x−xˉ)(x^−xˉ)
4、python代码
# 独立性权重法 from sklearn.linear_model import LinearRegression # 回归计算单元 使用sklearn.linear_model.LinearRegression def linear_regression(train_X, train_y): lrm = LinearRegression().fit(train_X, train_y) return lrm.predict(train_X) # 指标的回归计算 调度流程 def quota_regression(df): col_names = df.columns.values df_mid = df[col_names] new_col_names = [] for cc in col_names: new_cc = '{}_1'.format(cc) new_col_names.append(new_cc) train_cols = list(col_names) train_cols.remove(cc) df_mid[new_cc] = linear_regression(df_mid[train_cols], df_mid[cc]) return df_mid # 计算每个特征的简单相关系数 def get_corr_coef(df, col_names): df_mid = df[df.columns.values] new_col_names = [] for cc in col_names: new_cc = '{}_1'.format(cc) new_cc_corr = '{}_2'.format(cc) new_col_names.append(new_cc_corr) mean_cc = df_mid[cc].mean() cov_cc = df_mid.apply(lambda x: ((x[cc] - mean_cc) ** 2) * ((x[new_cc] - mean_cc) ** 2), axis=1).sum() #print('col_name: {}, mean: {}, cov: {} '.format(cc,mean_cc,cov_cc)) df_mid[new_cc_corr] = df_mid.apply(lambda x: (x[cc] - mean_cc) * (x[new_cc] - mean_cc) / math.sqrt(cov_cc), axis=1) df_out = pd.DataFrame(df_mid[new_col_names].sum(), columns=['coef_values']) df_out['p_name'] = col_names df_out.index = list(range(len(df_out))) df_out = df_out[['p_name','coef_values']] return df_out # 独立性权重法主函数 def weight_independ(df): column_names = df.columns.values df_scale = normalize_MinMax(df) df_mid = df_scale[column_names] df_coef = get_corr_coef(quota_regression(df_mid),column_names) df_coef['bw_coef'] = df_coef['coef_values'].apply(lambda x: 1/x) sum_bw = df_coef['bw_coef'].sum() df_coef['weight_value'] = df_coef['bw_coef'].apply(lambda x: x/sum_bw) return df_coef[['p_name','weight_value']]
赞
踩
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。