权重生成与评价模型——学习

本章主要涉及到的知识点有:

  • 层次分析法
  • 熵权法
  • TOPSIS分析法
  • 模糊评价法
  • CRITIC方法
  • 主成分分析法
  • 因子分析法
  • 数据包络法

1.1 层次分析法

1.1.1 层次分析法的原理

层次分析法(AHP)是一种结构化的决策工具,用于解决多准则决策问题。它通过以下五个步骤来简化和系统化决策过程:

  1. 构建层次模型:确定决策目标(目标层),影响目标的因素(准则层),以及可能的解决方案(方案层)。

  2. 构建比较矩阵:在相邻层次之间,通过成对比较来评估各因素或方案的相对重要性。

  3. 一致性检验:计算比较矩阵的一致性比率(CR),确保评价的合理性。CR值小于0.1表示矩阵通过检验,否则需要调整。

  4. 计算权重:求出每个比较矩阵的最大特征值及其对应的特征向量,并将特征向量归一化以得到权重。

  5. 综合评分和决策:根据权重和各方案在准则下的得分,计算出每个方案的总得分,然后选择得分最高的方案作为最终决策。

      

两个相邻的层次之间是需要构建成对比较矩阵的。比方说在上图,我们在目标层和准则层之间就需要构建第一层比较矩阵,这个矩阵的大小是行列均为4。矩阵的每一项表示因素i和因素j的相对重要程度。由于对角线上元素都是自己和自己做比较,所以对角线上元素为1。另外,还有一条重要性质:

                                                         

关于这个矩阵的每一项取值多少,若因素i比因素j重要,为了描述重要程度,我们用1~9中间的整数描述,如表5.2所示。

在层次分析法中,比较矩阵的构建基于1至9的标度,用于评估因素i与因素j的相对重要性。如果因素i更重要,我们选择一个数值;反之,使用该数值的倒数来表示。这种评估具有一定的主观性,但通过一致性检验可以确保其有效性。通常,我们优先使用奇数来表示明确的相对重要性,而偶数则用于表示不确定性或介于两个奇数值之间的情况。对于准则层和方案层,我们需要构建m个(n,n)大小的比较矩阵,并通过特征值分解来计算最大特征值和特征向量,进而得到一致性指标(CI),以检验矩阵的一致性。

                                                       

这里n取4的话很容易计算出CI值为0.0145。而除了CI,还有一个RI值(随机一致性指标),在不同的n的取值下RI值也不同。这个值是通过大量随机实验得到的统计规律,数值可以查表获得,将RI表列在下表中。

                               

得到RI和CI后,计算CI和RI的比值也就是CR。查表计算可以得到这个矩阵的CR值为0.0161。通常来说,当CR值超过0.1时,就可以认为这个矩阵是不合理的,需要被修改、被调整。这里由于没有超过这个阈值,所以可以认为这个比较矩阵通过了一致性检验。于是,剩下的过程便可以如法炮制,计算出准则层到方案层的4个矩阵了。

得到一致性检验结果后,还需要对最大特征值对应的特征向量进行归一化得到权重向量。归一化的方法为将特征向量除以该向量所有元素之和:

                                                 

以上原理可能不太理解的透彻,下边来举个案例

1.1.2 层次分析法的案例

 某日从三条河流的基站处抽检水样,得到了水质的四项检测指标如表5.1所示。请根据提供数据对三条河流的水质进行评价。其中,DO代表水中溶解氧含量,越大越好;CODMn表示水中高锰酸盐指数,NH3-N表示氨氮含量,这两项指标越小越好;pH值没有量纲,在6~9区间内较为合适。

                      

首先,我们需要对上面的数据分析:该评价问题一共有三个样本,四个评价指标。不同的评价指标还不太一样,有的越大越好有的越小越好。这里既然他们给出来了评价指标,就不再另外查找文献了。我们构建层次模型图:

      

接下来的操作就是对目标层到准则层构建一个大小为4的方阵,准则层到方案层构建4个大小为3的方阵。我们先来计算一下这个目标层到准则层,至于准则层到方案层的矩阵都是如法炮制的过程。例如,创建了这么一个矩阵:

                                         

对这个矩阵做特征值分解的代码如下:

import numpy as np 

# 构建矩阵
A=np.array([[1,1/5,1/3,1],
            [5,1,3,5],
            [3,1/3,1,3],
            [1,1/5,1/3,1]])

#获得指标个数
m=len(A)
n=len(A[0])
RI=[0,0,0.58,0.90,1.12,1.24,1.32,1.41,1.45,1.49,1.51]
#求判断矩阵的特征值和特征向量,V为特征值,D为特征向量
V,D=np.linalg.eig(A)
list1=list(V)
#求矩阵的最大特征值
B=np.max(list1)
index=list1.index(B)
C=d[:,index]

很容易地,我们定位到了最大的特征值与特征向量。进而我们计算CI和CR:

CI=(B-n)/(n-1)
CR=CI/RI[n]
if CR<0.10:
    print("CI=",CI)
    print("CR=",CR)
    print("对比矩阵A通过一致性检验,各向量权重向量Q为:")
    C_sum=np.sum(C)
    Q=C/C_sum
    print(Q)
else:
    print("对比矩阵A未通过一致性检验,需对对比矩阵A重新构造")

看见很多数值不要害怕它是随机的,是人设定的。

4个权重向量的排布

                    

将准则层到方案层得到的7个成对比较矩阵对应的权重向量排列为一个矩阵,矩阵的每一行表示对应的方案,矩阵的每一列代表评价准则。将这一方案权重矩阵与目标层到准则层的权重向量进行数量积,得到的分数就是最终的评分。最终得到的一个结论是:在评价过程中水中溶解氧含量与钴金属含量占评价体系比重最大,而四川攀枝花龙洞的水质虽然含钴元素比另外两个更高,但由于溶解氧更多,NH3-N的含量更小,水体不显富营养化。就整体而言,四川攀枝花龙洞得分高于重庆朱沱和湖北宜昌南津关。

将一个成对比较矩阵的AHP过程封装为函数,完整函数如下。

def AHP(A):
    m=len(A)                                     #获取指标个数
    n=len(A[0])
    RI=[0, 0, 0.58, 0.90, 1.12, 1.24, 1.32, 1.41, 1.45, 1.49, 1.51]
    R= np.linalg.matrix_rank(A)                 #求判断矩阵的秩
    V,D=np.linalg.eig(A)                     #求判断矩阵的特征值和特征向量,V特征值,D特征向量;
    list1 = list(V)
    B= np.max(list1)                            #最大特征值
    index = list1.index(B)
    C = D[:, index]                             #对应特征向量
    CI=(B-n)/(n-1)                             #计算一致性检验指标CI
    CR=CI/RI[n]
    if CR<0.10:
        print("CI=", CI.real)
        print("CR=", CR.real)
        print('对比矩阵A通过一致性检验,各向量权重向量Q为:')
        sum=np.sum(C)
        Q=C/sum                                #特征向量标准化
        print(Q.real)                                #    输出权重向量
        return Q.real
    else:
        print("对比矩阵A未通过一致性检验,需对对比矩阵A重新构造")
        return 0

1.2 熵权分析法

熵权法是一种客观赋权方法,基于信息论的理论基础,根据各指标的数据的分散程度,利用信息熵计算并修正得到各指标的熵权,较为客观。相对而言这种数据驱动的方法就回避了上面主观性因素造成的重复修正的影响。

1.2.1 熵权分析法的原理

在多指标决策分析中,不同指标可能具有不同的衡量标准和方向性,这就需要对原始数据进行预处理,以确保它们在同一标准下进行比较。这个过程被称为指标正向化。以下是对您提供内容的概括和解释:

  1. 指标正向化:将所有指标转换为“越大越好”的形式,以便于统一处理和比较。

    • 对于极大型指标(越大越好),通常不需要正向化,直接进行归一化处理。
    • 对于极小型指标(越小越好),可以通过取相反数或倒数进行正向化。
    • 对于区间型指标,使用特定的函数将其转换到 [0, 1] 区间内,以反映其在特定范围内的适宜性。
    • 对于中值型指标,通过计算与最优值的偏差来进行正向化。
  2. 归一化处理:消除不同指标间的量纲影响,使它们具有可比性。常用的方法包括 min-max 归一化和 Z-score 归一化。

  3. 熵权法:一种客观确定指标权重的方法,基于信息熵的概念。计算步骤如下:

    • 构建判断矩阵 𝑅R。
    • 对判断矩阵进行归一化处理,得到归一化判断矩阵 𝐵B。
    • 利用信息熵计算各指标的权重。信息熵越小,表示指标的离散程度越大,对综合评价的贡献越大。
    • 计算权重系数 𝑤𝑗wj​,它反映了指标 j 在综合评价中的相对重要性。
  4. 熵权法的注意点

    • 熵权法依赖于数据量,需要有足够的数据支持。
    • 在应用熵权法之前,必须对数据进行正向化处理。

熵权法的主要优势在于它能够自动地根据数据的离散程度来分配权重,避免了主观赋权的偏差。这种方法特别适用于缺乏专家知识或难以量化指标重要性的情况,能够为多指标评价提供一种客观的权重确定方法。

1.2.2 熵权分析法的案例

首先,读取数据并对指标进行正向化。首先,pH这一列虽然是区间型指标,但是可以用pH=7作为最优值将其看作中间值型指标处理,与7的偏差越大则得分越小。DO和鱼类密度是极大型指标,剩下三个是极小型指标,所以用倒数的方法正向化。

import pandas as pd

newdata=pd.read_excel("test.xlsx",sheet_name='Sheet5')

newdata['pH*']=1-abs(newdata['pH*']-7)

newdata['CODMn']=1/newdata['CODMn']

newdata['NH3-N']=1/newdata['NH3-N']

newdata['垃圾密度']=1/newdata['垃圾密度']

newdata=newdata.set_index('地点名称').dropna()

将熵权法的代码复现如下所示:

def entropyWeight(data):
  data = np.array(data)
  # 归一化
  P = data / data.sum(axis=0)
  # 计算熵值
  E = np.nansum(-P * np.log(P) / np.log(len(data)), axis=0)
  # 计算权系数
  return (1 - E) / (1 - E).sum()

通过调用函数,可以得到权重分别为

[0.15547967, 0.01030048, 0.13105116, 0.50152061, 0.09189262,0.10975546]

1.3 TOPSIS分析法

TOPSIS评价法是有限方案多目标决策分析中常用的一种科学方法,其基本思想为,对原始决策方案进行归一化,然后找出最优方案和最劣方案,对每一个决策计算其到最优方案和最劣方案的欧几里得距离,然后再计算相似度。若方案与最优方案相似度越高则越优先。

TOPSIS方法的基本步骤:

  1. 数据标准化

    将原始数据进行正向化处理,确保所有指标都是“越大越好”。对正向化后的数据进行归一化处理,消除量纲的影响,得到归一化决策矩阵 𝑍Z。
  2. 确定理想解和负理想解

       

  1. 计算各方案与理想解和负理想解的距离

    • 计算每个方案 𝑖i 与理想解 𝑍∗Z∗ 的距离 𝐷𝑖∗​。
    • 计算每个方案 𝑖i 与负理想解 𝑍−Z− 的距离 𝐷𝑖−​。

    使用欧几里得距离公式: 

            

  1. 计算相对贴近度

    • 相对贴近度 𝐶𝑖Ci​ 表示方案 𝑖i 与理想解的接近程度,计算公式为:              
  2. 方案排序

    • 根据贴近度 Ci​ 对所有方案进行排序,贴近度越大的方案越接近理想解,因此越优。

改进的TOPSIS分析法:

在改进的TOPSIS方法中,考虑到不同指标的重要性可能不同,因此在计算距离时会为每个指标赋予不同的权重。

  1. 确定权重

    • 使用熵权法或层次分析法确定各指标的权重 𝑤𝑗wj​。
  2. 加权距离计算

  3. 相似度计算

    • 根据加权距离重新计算相对贴近度。
  4. 方案排序和选择

    • 根据改进的贴近度对方案进行排序和选择。

距离计算方法:

  • 欧几里得距离:最常用的距离度量方式,反映方案与理想解在多维空间中的直线距离。
  • 曼哈顿距离:反映方案与理想解在网格化空间中的移动距离,适用于指标间的独立性较强时。
  • 余弦相似度:衡量方案与理想解在向量空间中的夹角,适用于考虑方案与理想解方向的一致性。

1.3.3 TOPSIS分析法的案例

import numpy as np

import pandas as pd



#TOPSIS方法函数

def TOPSIS(A1,w):

    Z=np.array(A1)

    #计算正、负理想解

    Zmax=np.ones([1,A1.shape[1]],float)

    Zmin=np.ones([1,A1.shape[1]],float)

    for j in range(A1.shape[1]):

        if j==1:

          Zmax[0,j]=min(Z[:,j])

          Zmin[0,j]=max(Z[:,j])

        else:

          Zmax[0,j]=max(Z[:,j])

          Zmin[0,j]=min(Z[:,j])

  #计算各个方案的相对贴近度C

    C=[]

    for i in range(A1.shape[0]):

          Smax=np.sqrt(np.sum(w*np.square(Z[i,:]-Zmax[0,:])))

          Smin=np.sqrt(np.sum(w*np.square(Z[i,:]-Zmin[0,:])))

          C.append(Smin/(Smax+Smin))

    C=pd.DataFrame(C)

    return C

输入归一化后的数据和权重系数就可以获得评价结果。利用上一节里面讲到的归一化方法进行数据处理并通过熵权法获得权重,调用代码可以得到最终结果。得分最高的是江苏南京林山,为0.657;得分最低的是湖北宜昌南津关,得分仅0.232。

可以看到,TOPSIS方法与层次分析法和熵权法都不同,它不是一个构造权重的方法,而是根据权重去进行得分折算的方法。这为我们分析评价类模型提供了一个新思路。

1.4 CRITIC分析法

1.4.1 CRITIC分析法的原理

CRITIC权重法是一种基于数据波动性的客观赋权法。其思想在于两项指标,分别是波动性(对比强度)和 冲突性(相关性)指标。对比强度使用标准差进行表示,如果数据标准差越大说明波动越大,权重会越高; 冲突性使用相关系数进行表示,如果指标之间的相关系数值越大,说明冲突性越小,那么其权重也就越低。权重计算时,对比强度与冲突性指标相乘,并且进行归一化处理,即得到最终的权重。CRITIC权重法适用于数据稳定性可视作一种信息,并且分析的指标或因素之间有着一定的关联关系的数据。

CRITIC法是一种数据驱动的多指标综合评价方法,它通过综合考虑指标的对比强度和变异程度来为每个指标赋予客观权重。这种方法的优势在于不仅考量了指标间的相对重要性,也考量了指标自身的波动性,从而提高了权重的客观性和准确性。CRITIC法特别适用于数据量充足且需要客观权重的情况。

CRITIC法的操作步骤可以概括为:

  1. 数据预处理:对原始数据进行无量纲化和正向化处理,确保所有指标在同一标准下比较,并且转换为“越大越好”或“越小越好”的形式。

  2. 计算指标变异性:通过计算每个指标的标准差来衡量其在样本中的变异程度,标准差越大,指标的区分度和信息强度越高。

  3. 计算指标冲突性:利用指标间的相关系数来衡量冲突性。如果两个指标高度相关,它们的信息存在重复,冲突性低;反之,相关性低,冲突性高。

  4. 获取信息量:将指标的变异性与冲突性相乘,得到每个指标的信息量,这反映了指标在评价体系中的综合重要性。

  5. 权重归一化:通过归一化信息量来确定每个指标的权重,然后使用这些权重对归一化后的数据矩阵进行加权,得到每个对象的评分。

  6. 评价与排序:根据对象的评分进行评价和排序,评分越高的对象越优。

CRITIC法的优点:

  • 综合考虑了指标的变异性和冲突性,能够更全面地反映指标的重要性。
  • 通过考虑指标间的相关性,避免了信息的重复,提高了权重的准确性。

1.4.2 CRITIC分析法的案例

以上边的数据为例展示CRITIC方法。上面的计算方法是非常纯粹的,封装为函数:

def CRITIC(df):
  std_d=np.std(df,axis=1)
  mean_d=np.mean(df,axis=1)
  cor_d=np.corrcoef(df)
  # 也可以使用df.corr()
  w_j=(1-cor_d).sum(0) *std_d
  print(w_j)
  w=(mean_d/(1-mean_d)*w_j)/sum(mean_d/(1-mean_d)*w_j)
  print(w)
##############################
经过计算,结果为:

pH*   0.180598

DO    0.199151

CODMn  0.185891

NH3-N  0.097907

鱼类密度   0.248081

垃圾密度   0.088372

1.5 模糊综合评价法

1.5.1 模糊综合分析法的原理

模糊综合评价法是一种在处理不确定性和模糊性方面具有显著优势的决策分析方法。它源自模糊数学理论,专门用于解决那些难以用传统精确数值评估的问题,如人类感知和判断中的模糊概念,例如“轻”、“重”、“热”、“冷”等。这些问题通常涉及个人感受和主观评价,无法用绝对明确的标准来衡量。

模糊综合评价法的核心在于使用隶属度来表达对象属于某个等级的程度,这种方法将定性评价转化为定量分析。它首先要求确定评价因素集合和评价等级集合。评价因素是评价对象的属性或特征,而评价等级则是评价结果的分类。接着,为每个因素分配权重,这些权重反映了因素在评价体系中的相对重要性。权重的确定可以基于专家意见、统计分析或已有文献。

隶属度的确定是模糊综合评价法的关键,它通过专家咨询、德尔菲法或文献分析获得,也可以根据具体指标通过类似TOPSIS中的正向化方法来确定。隶属度表示一个对象属于某个评价等级的概率或程度,是一个介于0到1之间的数值。一旦得到隶属度,就可以构建隶属度矩阵,这个矩阵反映了评价对象在各个因素下属于各个等级的隶属度。

模糊综合评价法不依赖于多个对象间的比较,即使是单个对象也能使用。它本质上是一个矩阵乘法过程,其中权重向量、模糊隶属度矩阵和评语对应的分数是关键要素。通过将隶属度矩阵与权重矢量相乘,再根据不同隶属度给出的评分,得到对象的总体评分。

该方法的特点在于其灵活性和适应性,尤其适用于评价标准的确定性不强,存在模糊性的情况。它能够将主观评价转化为客观评分,使得即使是单个对象的评价也变得可行和有效。此外,模糊综合评价法还能够提供对评价过程的深入理解,因为它不仅给出了最终的评价结果,还展示了各因素对结果的贡献程度。

然而,模糊综合评价法也有其局限性。首先,隶属度的确定可能受到主观判断的影响,需要专业知识和经验。其次,评价结果的解释可能需要额外的工作,以确保所有利益相关者都能理解。最后,如果评价因素之间存在交互作用,这种方法可能需要进一步的调整和完善。

       

1.5.2 模糊综合分析法的案例

假设以企业组织和管理水平评价为例,用模糊综合评价方法给出定量评价。这是专家(或其他统计方式)对评价打分表投票表决结果统计数据,简单的说就是对需要评价的因素(指标)给出主管或客观的“优、良、一般、较差、非常差”评价。

# 准则重要性矩阵
    criteria = np.array([[1, 7, 5, 7, 5],
                         [1 / 7, 1, 2, 3, 3],
                         [1 / 5, 1 / 2, 1,  2,  3],
                         [1 / 7, 1 / 3, 1 / 2, 1, 3],
                         [1 / 5, 1 / 3, 1 / 3, 1 / 3, 1]])

    # 对每个准则,方案优劣排序
    b1 = np.array([[1, 5], [1 / 5, 1]])
    b2 = np.array([[1, 2, 5], [1 / 2, 1, 2], [1 / 5, 1 / 2, 1]])
    b3 = np.array([[1, 5, 6, 8], [1 / 5, 1 ,2, 7], [1 / 6, 1 / 2, 1 ,4],[1 / 8, 1 / 7, 1 / 4, 1]])
    b4 = np.array([[1, 3, 4], [1 / 3, 1, 1], [1 / 4, 1, 1]])
    b5 = np.array([[1, 4, 5, 5], [1 / 4, 1, 2, 4], [1 /5 , 1 / 2, 1, 2], [1 / 5,1 /4,1 / 2, 1]])
#模糊综合评价法(FCE),输入准则权重、因素权重
def fuzzy_eval(criteria, eigen):
    #量化评语(优秀、    良好、    一般、    较差、   非常差)
    score = [1,0.8,0.6,0.4,0.2]
    
    df = pd.read_excel('FCE.xlsx')
    print('单因素模糊综合评价:{}\n'.format(df))
    #把单因素评价数据,拆解到5个准则中
    v1 = df.iloc[0:2,:].values
    v2 = df.iloc[2:5,:].values
    v3 = df.iloc[5:9,:].values
    v4 = df.iloc[9:12,:].values
    v5 = df.iloc[12:16,:].values
   
    vv = [v1,v2,v3,v4,v5]
   
    val = []
    num = len(eigen)
    for i in range(num):
        v = np.dot(np.array(eigen[i]),vv[i])
        print('准则{} , 矩阵积为:{}'.format(i+1,v))
        val.append(v)
       
    # 目标层
    obj = np.dot(criteria, np.array(val))
    print('目标层模糊综合评价:{}\n'.format(obj))
    #综合评分
    eval = np.dot(np.array(obj),np.array(score).T)
    print('综合评价:{}'.format(eval*100))
criteria, eigen=weight()
fuzzy_eval(criteria, eigen)

这里weight()返回的是每个指标的最终权重,大家自己很容易实现。最后转化为百分制评分下的模糊综合评价分数为69.76。

1.6 秩和比分析法

秩和比法(RSR, Rank-sum ratio)是由中国统计学家田凤调教授于1988年提出的一种综合评价方法,它适用于不同类型的数据集,包括四格表资料、n行m列资料、计量资料和分类资料。RSR方法的核心在于使用秩次信息来减少数据的不确定性和异常值的影响,从而得到更为稳健的评价结果。

RSR法的步骤详细概括如下:

  1. 排序:对效益型指标进行从小到大的排序,而成本型指标则从大到小排序,确保每个指标的顺序与其类型相匹配。

  2. 计算秩次:根据排序结果,为每个指标分配一个秩次,相同数据赋予平均秩次。

  3. 计算RSR值:利用秩次和相应的权重,计算每个指标的秩和比(RSR),这是一个无量纲统计量,能够反映指标的综合表现。

  4. 统计分析:基于RSR值进行统计分析,研究其分布情况,为评价对象的排序或分档提供依据。

  5. 排序或分档:根据RSR值对评价对象进行直接排序或分档排序,评估其综合表现。

RSR法的本质:

  • 转换:在一个n行m列的数据表中,通过秩的转换获得无量纲统计量RSR。
  • 分析:运用参数统计分析的概念与方法研究RSR的分布。
  • 排序:以RSR值对评价对象的优劣进行分档排序。

优点:

  • 非参数统计分析,对指标的选择无特殊要求,适用于各种评价对象。
  • 使用秩次计算,可以消除异常值的干扰,提高评价的稳定性。
  • 结合了参数分析的方法,使得结果比单纯采用非参数法更为精确。
  • 提供了直接排序和分档排序两种方式,使用范围广泛。

缺点:

  • 排序主要依据原始数据的秩次,可能丢失原始数据的大小差别信息。
  • 当RSR值不满足正态分布时,分档归类的结果可能与实际情况有偏差。
  • 只能回答分级程度是否有差别,不能进一步回答具体的差别情况。

秩和比分析法原理:

  • 整次秩和比法:通过排序和秩次计算得到秩矩阵,适用于数据量较大且分布均匀的情况。
  • 非整次秩和比法:采用线性插值方式编秩,改进了整次秩和比法的不足,保留了更多的定量信息。

确定RSR的分布:

  • 编制RSR频数分布表,列出各组频数并计算累计频数。
  • 确定各组RSR的秩次范围及平均秩次。
  • 计算累计频率并进行修正,换算为概率单位Probit。

计算回归方程:

  • 以累积频率对应的Probit为自变量,RSR值为因变量,计算直线回归方程。
  • 对回归方程进行检验,包括残差独立性、方差齐性、回归系数的有效性以及拟合优度。

校正RSR值并分档排序:

  • 根据回归方程推算所对应的RSR估计值。
  • 对评价对象进行分档排序,分档数由研究者根据实际情况决定。

RSR法通过将数据映射到正态分布曲线上,并结合正态分布的相关划分方法进行分档,提供了一种科学、系统的评价工具,适用于多种复杂的决策和评价场景。

1.6.2 秩和比分析法案例

import pandas as pd
import numpy as np
import statsmodels.api as sm
from scipy.stats import norm


def rsr(data, weight=None, threshold=None, full_rank=True):
  Result = pd.DataFrame()
  n, m = data.shape

  # 对原始数据编秩
  if full_rank:
    for i, X in enumerate(data.columns):
      Result[f'X{str(i + 1)}:{X}'] = data.iloc[:, i]
      Result[f'R{str(i + 1)}:{X}'] = data.iloc[:, i].rank(method="dense")
  else:
    for i, X in enumerate(data.columns):
      Result[f'X{str(i + 1)}:{X}'] = data.iloc[:, i]
      Result[f'R{str(i + 1)}:{X}'] = 1 + (n - 1) * (data.iloc[:, i].max() - data.iloc[:, i]) / (data.iloc[:, i].max() - data.iloc[:, i].min())

  # 计算秩和比
  weight = 1 / m if weight is None else np.array(weight) / sum(weight)
  Result['RSR'] = (Result.iloc[:, 1::2] * weight).sum(axis=1) / n
  Result['RSR_Rank'] = Result['RSR'].rank(ascending=False)

  # 绘制 RSR 分布表
  RSR = Result['RSR']
  RSR_RANK_DICT = dict(zip(RSR.values, RSR.rank().values))
  Distribution = pd.DataFrame(index=sorted(RSR.unique()))
  Distribution['f'] = RSR.value_counts().sort_index()
  Distribution['Σ f'] = Distribution['f'].cumsum()
  Distribution[r'\bar{R} f'] = [RSR_RANK_DICT[i] for i in Distribution.index]
  Distribution[r'\bar{R}/n*100%'] = Distribution[r'\bar{R} f'] / n
  Distribution.iat[-1, -1] = 1 - 1 / (4 * n)
  Distribution['Probit'] = 5 - norm.isf(Distribution.iloc[:, -1])

  # 计算回归方差并进行回归分析
  r0 = np.polyfit(Distribution['Probit'], Distribution.index, deg=1)
  print(sm.OLS(Distribution.index, sm.add_constant(Distribution['Probit'])).fit().summary())
  if r0[1] > 0:
    print(f"\n回归直线方程为:y = {r0[0]} Probit + {r0[1]}")
  else:
    print(f"\n回归直线方程为:y = {r0[0]} Probit - {abs(r0[1])}")

  # 代入回归方程并分档排序
  Result['Probit'] = Result['RSR'].apply(lambda item: Distribution.at[item, 'Probit'])
  Result['RSR Regression'] = np.polyval(r0, Result['Probit'])
  threshold = np.polyval(r0, [2, 4, 6, 8]) if threshold is None else np.polyval(r0, threshold)
  Result['Level'] = pd.cut(Result['RSR Regression'], threshold, labels=range(len(threshold) - 1, 0, -1))

  return Result, Distribution


def rsrAnalysis(data, file_name=None, **kwargs):
  Result, Distribution = rsr(data, **kwargs)
  file_name = 'RSR 分析结果报告.xlsx' if file_name is None else file_name + '.xlsx'
  Excel_Writer = pd.ExcelWriter(file_name)
  Result.to_excel(Excel_Writer, '综合评价结果')
  Result.sort_values(by='Level', ascending=False).to_excel(Excel_Writer, '分档排序结果')
  Distribution.to_excel(Excel_Writer, 'RSR分布表')
  Excel_Writer.save()

  return Result, Distribution

data = pd.DataFrame({'产前检查率': [99.54, 96.52, 99.36, 92.83, 91.71, 95.35, 96.09, 99.27, 94.76, 84.80],
                     '孕妇死亡率': [60.27, 59.67, 43.91, 58.99, 35.40, 44.71, 49.81, 31.69, 22.91, 81.49],
                     '围产儿死亡率': [16.15, 20.10, 15.60, 17.04, 15.01, 13.93, 17.43, 13.89, 19.87, 23.63]},
                    index=list('ABCDEFGHIJ'), columns=['产前检查率', '孕妇死亡率', '围产儿死亡率'])
data["孕妇死亡率"] = 1 / data["孕妇死亡率"]
data["围产儿死亡率"] = 1 / data["围产儿死亡率"]
rsr(data)

1.7 主成分分析法

1.7.1 主成分分析法的原理

主成分分析(PCA)是一种在统计学中广泛应用的降维技术,它的目的是在保留数据集中大部分变异性的同时,减少变量的数量。这种方法通过转换原始数据集中的相关变量到一组新的无关变量——主成分,来实现降维和数据的重新表达。

PCA的过程开始于数据的去中心化,即从每个属性中减去其均值,消除数据的平均水平影响。接着,计算去中心化数据的协方差矩阵,以衡量变量间的相关性。最关键的一步是协方差矩阵的特征值分解,这一步揭示了数据中的主要变异方向。然后,根据特征值的大小进行排序,选择前k个最大的特征值对应的特征向量,这些特征向量定义了主成分的方向。

通过这些特征向量,PCA进行线性变换,将原始数据投影到新的空间中,每个主成分都是原始变量的加权线性组合。在这个新空间中,每个主成分都尽可能地保留了原始数据的变异性,并且彼此独立。最终,PCA不仅实现了数据的降维,还通过主成分提供了对数据结构的解释。

值得注意的是,在实际操作中,PCA的计算通常采用奇异值分解(SVD)方法,因为SVD在数值稳定性和计算效率上更有优势。然而,从概念上理解,特征值分解提供了一个直观的框架,使得PCA的步骤和原理更容易被理解。PCA在数据预处理、模式识别、图像处理等领域都有重要应用,是数据分析中不可或缺的工具。

1.7.2 主成分分析法的案例

主成分分析在数据处理和评价中有很大应用。首先,我们通过鸢尾花数据集的例子来看到它是如何减少数据列数的。鸢尾花数据集是一个在机器学习和统计学领域广泛使用的经典数据集。它包含了150个样本,每个样本有4个特征:萼片长度、萼片宽度、花瓣长度和花瓣宽度,这四个特征都是以厘米为单位。这些特征用于描述鸢尾花的外观。数据集中的样本分为三类,每类50个样本,分别代表山鸢尾、变色鸢尾和维吉尼亚鸢尾三种不同的鸢尾属植物。这个数据集在第9章会被再一次搬上舞台,这里主要是测试主成分分析法。

通过sklearn.datasets的接口导入数据,可以发现其中有四列自变量,再使用sklearn.decomposition提供的PCA函数进行主成分分析即可。代码形如:

import matplotlib.pyplot as plt
import sklearn.decomposition as dp
from sklearn.datasets import load_iris
x,y=load_iris(return_X_y=True) #加载数据,x表示数据集中的属性数据,y表示数据标签
pca=dp.PCA(n_components=0.99) #加载pca算法,设置降维后主成分数目为2
reduced_x=pca.fit_transform(x,y) #对原始数据进行降维,保存在reduced_x中
red_x,red_y=[],[]
blue_x,blue_y=[],[]
green_x,green_y=[],[]
for i in range(len(reduced_x)): #按鸢尾花的类别将降维后的数据点保存在不同的表表中
    if y[i]==0:
           red_x.append(reduced_x[i][0])
       	red_y.append(reduced_x[i][1])
      elif y[i]==1:
           blue_x.append(reduced_x[i][0])
        blue_y.append(reduced_x[i][1])
  else:
       green_x.append(reduced_x[i][0])
       green_y.append(reduced_x[i][1])
plt.scatter(red_x,red_y,c='r',marker='x')
plt.scatter(blue_x,blue_y,c='b',marker='D')
plt.scatter(green_x,green_y,c='g',marker='.')
plt.show()

这里参数中PCA的参数设置有两种方法:如果n_components为整数,说明希望取到几个主成分;如果为小数,则说明希望保留多少的信息量,也就是取前几个特征值它们的和能够超过参数给定的阈值。

主成分分析法如何应用于评价呢?其实非常简单,将所有的主成分乘上对应的权重就可以得到最终的评分了,也就是:

                                    

我们回到例7.3,如果想使用主成分分析法对数据进行综合评价,可以怎么做呢?首先,在经过数据的正向化和归一化以后,可以手动实现PCA如下:

def pca(X,n_components):
  X=np.array(X)
  X=X-np.mean(X)
  n=len(X)
  A=np.dot(X.T,X)/(n-1)
  V,D=np.linalg.eig(A)
  idx = (-V).argsort(axis=None)[:n_components]
  P=D[idx]
  F=np.dot(X,P.T)
  return V[idx]/sum(V),F

在使用同样的正向化和归一化手段以后,可以给出对应的主成分评分。值得注意的是,主成分评分可能会出现负数,但并不影响。得分越高则说明评价结果越好,越低甚至为负数则评价结果越差。

1.8 因子分析法

1.8.1 因子分析法的原理

因子分析法是一种在统计学中用于揭示数据潜在结构的分析方法,它与主成分分析(PCA)虽然在某些方面相似,但在原理和应用上存在明显差异。因子分析着重于识别和描述变量间的相关性,通过将原始变量分解为不可观测的潜在因子,旨在简化数据结构并提取数据的内在含义。

在进行因子分析之前,需要通过巴雷特检验或KMO检验来确定数据是否适合该分析。这些检验帮助我们了解变量间是否存在显著的相关性,从而决定是否可以进行因子分析。巴雷特检验通过比较变量方差与相关系数矩阵的行列式值,评估变量间的相关性;而KMO检验则通过比较简单相关系数和偏相关系数的平方和,评估数据的适合度。

因子分析的流程通常包括以下几个步骤:首先,选择一组相关性较强的变量进行分析;然后,计算这些变量的相关系数矩阵,为因子分析提供基础;接着,从变量中提取公共因子,并决定提取的因子数量,通常基于累计方差贡献率;之后,进行因子旋转以提高因子的可解释性,简化载荷矩阵的结构;最后,计算因子得分,这些得分可以用于后续的统计分析。

因子载荷矩阵是因子分析中的核心概念,它描述了变量与因子之间的关系,其元素的平方和表示了因子对变量方差的解释程度。因子载荷矩阵的逆可以用来将原始变量表示为公共因子和特殊因子的线性组合,这使得我们能够利用公共因子来解释原始数据的结构和模式。

因子旋转是提高因子分析可解释性的关键步骤,它通过正交变换简化载荷矩阵的结构,使得因子载荷的绝对值更接近于1或0,从而更清晰地识别出哪些变量与公共因子有强烈的关联。常见的旋转方法包括方差最大法等。

因子得分是因子分析的最终产物,它们不仅提供了对原始变量的抽象表示,而且有助于理解变量之间的关系,识别影响结果的关键因素。因子得分在人文社会科学问题中尤为重要,因为它们具有很好的可解释性,能够与社会科学理论紧密结合,并具有广阔的后续应用空间。

1.8.2 因子分析法的案例

因子分析分为探索型因子分析和验证型因子分析。探索性因子分析是从数据出发,寻找能获得最大解释性的因子数量;而验证型因子分析则是研究之前已经提出了理论假设,现在需要用实验数据佐证。Python可以使用factor_analyzer实现:

我们从国家统计局获取了自2005—2012年间各类学校的生师比(学生数量与教师数量的比值),数据如表5.9所示,试对数据进行因子分析并进行一定解释。

这是一个非常典型的社会科学问题。我们这里提出了假说:问题可以被分解为三个因子。但首先,我们需要对数据进行预处理:

import pandas as pd

import numpy as np

data=pd.read_csv("查询数据.csv",encoding='gbk')

data=data.interpolate('linear')

data=data.fillna(method='bfill')

newdata=data[['小学生师比(教师人数=1)', '初中生师比(教师人数=1)',

    '普通高中生师比(教师人数=1)', '职业高中生师比(教师人数=1)', '普通中专生师比(教师人数=1)',

    '普通高校生师比(教师人数=1)', '本科院校生师比(教师人数=1)', '专科院校生师比(教师人数=1)', '教育经费(万元)',

    '国家财政性教育经费(万元)', '国家财政预算内教育经费(万元)', '各类学校教育经费社会捐赠经费(万元)',

    '各类学校教育经费学杂费(万元)']]

通过插值与填充,我们对数据中的空缺进行了处理。下面对数据进行巴雷特球形检验和KMO检验:

from factor_analyzer import FactorAnalyzer

import pandas as pd

import seaborn as sns

from matplotlib import pyplot as plt

import numpy as np

import math

from scipy.stats import bartlett

plt.rcParams['font.sans-serif'] = ['SimHei']  #显示中文

plt.rcParams['axes.unicode_minus']=False #用来正常显示负号

plt.style.use("ggplot")

 

n_factors=3#因子数量

cols=['小学生师比(教师人数=1)', '初中生师比(教师人数=1)',

    '普通高中生师比(教师人数=1)', '职业高中生师比(教师人数=1)', '普通中专生师比(教师人数=1)',

    '普通高校生师比(教师人数=1)', '本科院校生师比(教师人数=1)', '专科院校生师比(教师人数=1)']

 

#用检验是否进行

df=newdata[cols]

corr=list(df.corr().to_numpy())

print(bartlett(*corr)) #巴雷特方法

def kmo(dataset_corr): #KMO方法

  corr_inv = np.linalg.inv(dataset_corr) #求逆

  nrow_inv_corr, ncol_inv_corr = dataset_corr.shape

  A = np.ones((nrow_inv_corr,ncol_inv_corr))

  for i in range(nrow_inv_corr):

        for j in range(i,ncol_inv_corr,1):

              A[i,j] = -(corr_inv[i,j])/(math.sqrt(corr_inv[i,i]*corr_inv[j,j]))

            A[j,i] = A[i,j]

  dataset_corr = np.asarray(dataset_corr)

  kmo_num = np.sum(np.square(dataset_corr)) - np.sum(np.square(np.diagonal(A)))

  kmo_denom = kmo_num + np.sum(np.square(A)) - np.sum(np.square(np.diagonal(A)))

  kmo_value = kmo_num / kmo_denom

  return kmo_value

print(kmo(newdata[cols].corr().to_numpy())) 

1.9 数据包络分析法

绩效评估是评估组织或个人如何以较少的资源获得较多的产出结果的多属性评估,也称之为成本效益分析。数据包络分析是 A.Charnes, W.W.Copper 和 E.Rhodes 在 1978 年提出的评价多指标输入输出,衡量系统有效性的方法。将属性划分为投入项、产出项(成本型、效益型指标),不预先设定权重,只关心总产出与总投入,以其比率作为相对效率。

1.9.1 CCR数据包络模型

数据包络分析(DEA)是一种评估生产效率的统计方法,它能够同时考虑多个投入和产出指标。DEA包括多种模型,其中CCR和BBC模型是最常用的两种。

CCR模型,由Charnes、Cooper和Rhodes于1978年提出,主要用于评价决策单元(DMU)的效率。该模型通过构建线性规划模型来寻找最优的权重向量,以最大化投入产出比。模型的目的是在一定的投入水平下,实现产出的最大化。在CCR模型中,通过分析λ的和可以判断规模报酬的性质,从而识别规模报酬递增、固定或递减的情况。

BBC模型是CCR模型的改进,由Banker、Bardhan和Chang提出。它从产出的角度出发,考虑在相同投入水平下的产出效率,称为“投入导向模式”。BBC模型得到的效率称为技术效率,当DEA等于1时,表示决策单元是技术有效的。BBC模型通过求解λ和θ来评估技术效率,其中θ表示产出的可扩展性。

DEA的核心在于评估决策单元的性价比,即在较少的投入下获得较多的产出。DEA不仅可以用来评估单个决策单元的效率,还可以比较不同单元之间的效率差异,为改进提供方向。尽管BBC模型在实际应用中较少,但CCR模型的掌握为理解和应用DEA提供了坚实的基础。通过DEA,可以识别效率低下的区域,为提高生产效率和资源配置的优化提供决策支持。

1.9.2 数据包络模型的实现

这里我们实现数据包络模型中的CCR方法,并以面向对象的方法进行封装:

import numpy as np

from scipy.optimize import fmin_slsqp

 

class DEA(object):

  def __init__(self, inputs, outputs):

    # supplied data

    self.inputs = inputs

    self.outputs = outputs

    # parameters

    self.n = inputs.shape[0]

    self.m = inputs.shape[1]

    self.r = outputs.shape[1]

    # iterators

    self.unit_ = range(self.n)

    self.input_ = range(self.m)

    self.output_ = range(self.r)

    # result arrays

    self.output_w = np.zeros((self.r, 1), dtype=np.float)  # output weights

    self.input_w = np.zeros((self.m, 1), dtype=np.float)  # input weights

    self.lambdas = np.zeros((self.n, 1), dtype=np.float)  # unit efficiencies

    self.efficiency = np.zeros_like(self.lambdas)  # thetas

  def __efficiency(self, unit):

    # compute efficiency

    denominator = np.dot(self.inputs, self.input_w)

    numerator = np.dot(self.outputs, self.output_w)

    return (numerator/denominator)[unit]

  def __target(self, x, unit):

    in_w, out_w, lambdas = x[:self.m], x[self.m:(self.m+self.r)], x[(self.m+self.r):]  # unroll the weights

    denominator = np.dot(self.inputs[unit], in_w)

    numerator = np.dot(self.outputs[unit], out_w)

    return numerator/denominator

  def __constraints(self, x, unit):

    in_w, out_w, lambdas = x[:self.m], x[self.m:(self.m+self.r)], x[(self.m+self.r):]  # unroll the weights

    constr = []  # init the constraint array

    # for each input, lambdas with inputs

    for input in self.input_:

      t = self.__target(x, unit)

      lhs = np.dot(self.inputs[:, input], lambdas)

      cons = t*self.inputs[unit, input] - lhs

      constr.append(cons)

    # for each output, lambdas with outputs

   for output in self.output_:

      lhs = np.dot(self.outputs[:, output], lambdas)

      cons = lhs - self.outputs[unit, output]

      constr.append(cons)

    # for each unit

    for u in self.unit_:

      constr.append(lambdas[u])

    return np.array(constr)

  def __optimize(self):

    d0 = self.m + self.r + self.n

    # iterate over units

    for unit in self.unit_:

      # weights

      x0 = np.random.rand(d0) - 0.5
      x0 = fmin_slsqp(self.__target, x0, f_ieqcons=self.__constraints, args=(unit,),disp=False)

      # unroll weights

      self.input_w, self.output_w, self.lambdas = x0[:self.m], x0[self.m:(self.m+self.r)], x0[(self.m+self.r):]

      self.efficiency[unit] = self.__efficiency(unit)

  def fit(self):

    self.__optimize()  # optimize

    return self.efficiency

在这里我们给出一系列测试用例,若第1到4列为投入指标,第5到11列为产出指标,测试每个对象的投入产出效率如下:

# 定义输入和输出数据  

data = np.array([[39414, 2823, 34877, 44562, 2036, 603, 322, 934936, 929914, 1492, 29811],  

       [54934, 1911, 52242, 35262, 3862, 908, 396, 1075563, 1030664, 1780, 29811],  

      [96442, 2743, 88737, 303221, 4307, 1596, 694, 1104835, 1010146, 1936, 32678],  

       [107079, 3036, 98513, 478883, 3956, 2530, 1089, 909220, 862077, 2160, 36063],  

      [124359, 3326, 116897, 378318, 4102, 2669, 1179, 1117851, 1123109, 2349, 38951],  

       [140167, 3900, 130355, 261203, 4180, 3538, 1991, 1116429, 1100510, 2446, 40324],  

       [161523, 3989, 153722, 444755, 4309, 3727, 1593, 878466, 880226, 2637, 43211],  

       [177681, 4669, 167161, 422267, 4630, 6629, 1867, 1048053, 1003952, 2904, 47116],  

       [124969, 4416, 111415, 286399, 3829, 5665, 2591, 1142395, 1112661, 3092, 49406]])

X=data[:,0:4]

y=data[:,5:11]

dea = DEA(X,y)

rs = dea.fit()

print(rs)

从结果上来看,这些样本中有多个样本的投入产出比能达到1,说明它们的效率是比较高的。而对于没有达到1的样本,则需要进一步分析它们的规模报酬是哪一种类型。

1.10 评价模型总结

1.10.1 指标体系的构建

评价类模型是一系列系统化和规范化的方法,它们能够同时对多个指标、因素、维度和个体进行综合评估。这些模型的关键在于构建一个科学的指标体系、准确的权重计算方法以及合理的评分规则。一个良好的指标体系是评估过程的基石,它要求我们首先明确评估的目标和目的,确保所选指标与评估目标紧密相连。接下来,收集相关数据和信息,确保数据的可靠性和完整性,为选择关键指标提供支持。

在选择指标时,我们需要关注它们的可操作性、关联性和可靠性,这些指标应易于测量和计算,并且在指标之间存在密切的相关性或因果关系。此外,稳定性和可重复性也是选择指标时的重要考量因素。一旦指标确定,就需要为它们分配权重和优先级,这通常基于不同因素的重要性和组织的战略目标。最后,评价模型的结果需要通过反馈和沟通进行阐述和分析,确保理论与实践相结合,并在实际应用中不断优化指标体系,以满足实际需求。

综合评价的过程不仅为决策者提供了定量化的总体判断,而且通过这一过程,我们能够更深入地理解问题,为复杂决策提供有力的支持。

1.10.2 两大核心:权重生成与得分评价

权重生成和得分评价构成了评价类模型的两大核心。权重的计算可以通过多种方法进行,包括基于熵值、相关系数与方差、成对比较矩阵等,这些方法能够反映出不同指标在评价体系中的重要性。而得分评价则涉及加权求和、计算距离、模糊隶属度等技术,用以将指标的表现量化为综合得分。

在选择评价类模型时,需要综合考虑问题类型、数据类型、数据量、分析需求、算法复杂度、可操作性、指标数量、权重分配,以及主观与客观因素的平衡。例如,层次分析法适合处理定性与定量相结合的问题,而模糊综合评价法则更适用于处理具有较强模糊性的问题。主成分分析和因子分析则擅长于高维度数据的降维。熵权法在大量数据集中准确计算权重方面表现出色,而因子分析可能在样本量较少的情况下同样有效。

算法的复杂度也是一个考量因素,一些模型如主成分分析需要较为复杂的数学推导,而熵权法则因简单易懂而在实际中广受欢迎。此外,当面临指标众多或权重分配复杂的情况时,选择能够妥善处理这些问题的模型至关重要。最后,评价类模型在选择时还必须考虑其处理主观与客观因素的能力,以确保评价结果的全面性和准确性。

  • 14
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值