权重计算(1)——客观赋权法

本文首先分类介绍主客观赋权法,然后简述四种客观赋权法的算法步骤,分别给出python代码。

1.1 赋权方法的分类

在用户建模的过程中,常常需要从用户的各项行为指标 ( x 1 , x 2 , . . . , x n ) (x_{1}, x_{2}, … , x_{n})(x 1 ​,x 2 ​,…,x n ​),以加权求和的方式计算用户的总体活跃度,形如: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 =a 1 ​x 1 ​+a 2 ​x 2 ​+…+a n ​x n ​

其中 a 1 , a 2 , . . . , a n a_{1}, a_{2}, … , a_{n}a 1 ​,a 2 ​,…,a n ​ 分别为 x 1 , x 2 , . . . , x n x_{1}, x_{2}, … , x_{n}x 1 ​,x 2 ​,…,x n ​ 的权重。通过对 x i ( i = 1 , 2 , . . . , n ) x_{i} ~ (i=1,2,…,n)x i ​(i =1 ,2 ,…,n ) 的 “重要性” 的设置,加权求和,计算用户的总得分。

对于如何确定 a 1 , a 2 , . . . , a n a_{1}, a_{2}, … , a_{n}a 1 ​,a 2 ​,…,a n ​ 的值,主要有八种方法,可分为以下四类:

  • 第1类(主观赋权法):AHP层次法和优序图法。利用数字的相对大小信息计算权重;
  • 第2类(根据信息量):熵值法(熵权法)。利用数据熵值信息即信息量大小计算权重;
  • 第3类(根据数据波动):CRITIC、独立性权重和信息量权重。利用数据的波动性或者数据之间的相关关系计算权重;
  • 第4类(信息浓缩思想):因子分析和主成分法。根据数据的信息浓缩原理,利用方差解释率计算权重。

名称数据波动性数据间相关关系数字大小信息适用性AHP层次法无无有适用于多个层次指标计算权重,专家打分赋权有一定的主观性优序图法无无有计算较简便,较多指标时使用得到的权重结果更可靠熵值法无无无适用于指标较多的、底层方案层指标计算权重,但对样本的依赖性较大,随着样本数据变化,权重会有一定的波动CRITIC权重法有有无综合考虑数据波动情况和指标间的相关性,适合指标自身带有一定相关性和波动性的数据信息量权重法有无无适用于将数据差异性视作一种信息,用数据波动程度来衡量指标权重独立性权重法无有无适用于指标本身带有一些相关性、属于同一系统下的指标计算权重因子分析法无有无指标较多时降维得到具有可解释性的因子权重,也可单独得到各指标权重,需要大量样本数据主成分分析法无有无适用于指标较多时降维得到主成分权重,也可单独得到各项指标权重,需要大量样本数据

注意:

  • 一般来说,计算权重时,可使用四种客观赋权法(熵权法、CRITIC权重法、信息量权重法、独立性权重法)分别计算各指标的权重,然后计算四种方法所得结果的均值,从而得到最终的权重。
  • 如果只想使用专家的意见,可以使用主观赋权法。
  • 因子分析法、主成分分析法主要用于降维并计算权重, 只能得到各个因子的权重,无法得到具体每个分析项的权重
  • 如果想要将主客观的权重结合起来,可以使用组合赋权法(集成赋权法)。

1.2 数据处理函数

这里把后面需要用到的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)

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'])

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)

2.1 熵权法

1、基本思想

利用信息量的多少,即数据携带的信息量大小(物理学上的熵值原理)进行权重计算。

2、适用范围

各信息(数据指标)之间存在差异。主要用于解决评价类问题(例如:选择哪种方案最好、哪位运动员或员工表现的更优秀)。

3、算法步骤

  • 对数据样本进行MinMax归一化处理,成为一个m × n m \times n m ×n 的矩阵,m m m 为指标个数,n n n 为样本个数;
  • 计算每个指标数据项的比值:p i j = x i j ∑ i = 1 n x i j p_{ij} = \frac{x_{ij}}{\sum_{i=1}^{n} x_{ij}}p i j ​=∑i =1 n ​x i j ​x i j ​​
  • 计算每个指标的熵值:e j = − 1 ln ⁡ n ∑ i = 1 n ( p i j ln ⁡ p i j ) e_{j} = \frac{-1}{\ln n} \sum_{i=1}^{n} ( p_{ij} \ln p_{ij} )e j ​=ln n −1 ​i =1 ∑n ​(p i j ​ln p i j ​)
  • 计算指标的熵权:w j = 1 − e j n − ∑ e j w_{j} = \frac{1-e_{j}}{n – \sum e_{j}}w j ​=n −∑e j ​1 −e j ​​

4、python代码


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'])

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']]

def weight_entropy(df):
    df_mid = normalize_MinMax(df)
    return compute_entropy_weight(compute_entropy(df_mid))

3.1 CRITIC权重法

1、基本思想

基于 指标的对比强度(标准差) 和 指标之间的冲突性(相关系数) 来综合衡量指标的客观权重。

2、适用范围

数据稳定性可视作一种信息,并且分析的指标或因素之间有着一定的关联关系。

3、算法步骤

  • 对数据进行标准化处理,设有n n n 条记录,m m m 个指标;
  • 计算每个指标的标准差σ j \sigma_{j}σj ​ 和 相关矩阵R R R;
  • 计算每个指标包含的信息量:C j = σ j ∑ i = 1 n ( 1 − r i j ) C_{j} = \sigma_{j} \sum_{i=1}^{n} (1 – r_{ij})C j ​=σj ​i =1 ∑n ​(1 −r i j ​)
  • 计算指标的权重:w j = C j ∑ j = 1 m C j w_{j} = \frac{C_{j}}{\sum_{j=1}^{m} C_{j}}w j ​=∑j =1 m ​C j ​C j ​​

4、python代码


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']]

3.2 信息量权重法(变异系数法)

1、基本思想

基于指标数据所包含的信息量来确定指标权重,利用数据的变异系数进行权重赋值,变异系数越大,所赋的权重也越大。

2、适用范围

专家打分、或者面试官进行面试打分时对评价对象(面试者)进行综合评价。

3、算法步骤

  • 对数据进行标准化处理;
  • 计算每个指标的均值μ i \mu_{i}μi ​ 和标准差σ i \sigma_{i}σi ​;
  • 计算变异系数:C V i = σ i μ i CV_{i} = \frac{\sigma_{i}}{\mu_{i}}C V i ​=μi ​σi ​​
  • 计算权重:w i = C V i ∑ i = 1 m C V i w_{i} = \frac{CV_{i}}{\sum_{i=1}^{m} CV_{i}}w i ​=∑i =1 m ​C V i ​C V i ​​

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_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']]

3.3 独立性权重法

1、基本思想

利用指标之间的共线性强弱(复相关系数)来确定权重,仅仅只考虑了数据之间相关性;

2、适用范围

数据指标之间具有相关性;

3、算法步骤

  • 对数据进行MinMax归一化处理;
  • 计算各指标的复相关系数R R R 及其倒数C = 1 / R C = 1/R C =1 /R ;
  • 计算各指标的权重:w i = C i ∑ i = 1 m C i w_{i} = \frac{C_{i}}{\sum_{i=1}^{m} C_{i}}w i ​=∑i =1 m ​C i ​C i ​​

复相关系数 R R R 的计算:

  • 对指标x i x_{i}x i ​,用余下( 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}x i ​^​=a 1 ​x 1 ​+…+a n −1 ​x n −1 ​
  • 计算复相关系数R R R,即计算x i ^ \hat{x_{i}}x i ​^​ 与X 1 , X 2 , . . . , X n − 1 X_{1},X_{2},…,X_{n-1}X 1 ​,X 2 ​,…,X n −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

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()

        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']]

Original: https://blog.csdn.net/ii719481781/article/details/123253057
Author: 陌简宁
Title: 权重计算(1)——客观赋权法

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/613956/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球