8  灰色关联分析

灰色关联分析源于几何直观,实质上是一种曲线间几何形状的比较:几何形状越接近,则发展变化趋势越接近,关联程度就越大。

8.1 灰色关联度

8.1.1 数据无量纲处理

对单位不一,初值不同的序列,应首先进行初值化,即将该序列的所有数据分别除以首项数据,将变量化为无单位的相对数值。负向数据需要做正向化,若用取倒数变换,可以和初值化一起做,即用首项数据除以该所有数据;

或者,

  • 做数据均值化,所有数据都除以均值
  • 做数据百分比化,所有数据都除以最大值
  • 做数据归一化

mathmodels 包提供了初值化、均值化、最大值化函数 rescale_initial(), rescale_mean(), rescale_extreme() 专用于灰色关联预处理。

8.1.2 计算关联系数

设参考序列为 \[ X_0=\left\{x_0(1),x_0(2),\cdots,x_0(m)\right\} \]

比较序列为 \[ X_i=\left\{x_i(1),x_i(2),\cdots,x_i(m)\right\},\quad i=1,\cdots,n \]

比较序列 \(X_i\) 对参考序列 \(X_0\)\(k\) 处的关联系数定义为: \[ \eta_i\left(k\right)=\frac{\min_s\min_t\left|x_0\left(t\right)-x_s\left(t\right)\right|+\rho\max_s\max_t\left|x_0\left(t\right)-x_s\left(t\right)\right|}{\left|x_0\left(k\right)-x_i\left(k\right)\right|+\rho\max_s\max_t\left|x_0\left(t\right)-x_s\left(t\right)\right|} \] 其中,\(\min_s\min_t\left|x_0(t)-x_s(t)\right|\)\(\max_s\max_t\left|x_0(t)-x_s(t)\right|\) 分别称为两级最小差、两级最大差;\(\rho\) 称为分辨系数,越大分辨率越大,一般采用 \(\rho=0.5\)

8.1.3 计算灰色关联度

关联系数只表示了各个位置参考序列和比较序列之间的关联程度,为了从总体上了解序列之间的关联程度,必须求出它们的平均值,即灰色关联度\[ r_i=\frac{1}{n}\sum_{k=1}^n\eta_i(k) \] 若各指标有不同的权重,可以对进行加权平均,得到灰色加权关联度

结果解读:

  • \(r \in [0, 0.35)\),称为弱关联
  • \(r \in (0.35, 0.65)\),称为中度关联
  • \(r \in [0.65, 1]\),称为强关联

加载包:

library(tidyverse)
library(mathmodels)

8.2 案例 1:运动员训练与成绩

对某健将级女子铅球运动员的跟踪调查,获得其 1982 年至 1986 年每年最好成绩及 16 项专项素质和身体素质的数据,做灰色关联分析,看哪些指标与铅球成绩关联度更高?

8.2.1 创建数据

sports = readxl::read_excel("data/sports.xlsx")
sports
# A tibble: 5 × 18
   年份  铅球 `4kg前抛` `4kg后抛` `4kg原地` 立定跳远  高翻  抓举  卧推 `3kg前抛`
  <dbl> <dbl>     <dbl>     <dbl>     <dbl>    <dbl> <dbl> <dbl> <dbl>     <dbl>
1  1982  13.6      11.5      13.8      12.4     2.48    85    55    65      12.8
2  1983  14.0      13        16.4      12.7     2.49    85    65    70      15.3
3  1984  14.5      15.2      16.9      14.0     2.56    90    75    75      16.2
4  1985  15.6      15.3      16.6      14.0     2.64   100    80    85      16.4
5  1986  15.7      15.0      17.3      13.5     2.59   105    80    90      17.0
# ℹ 8 more variables: `3kg后抛` <dbl>, `3kg原地` <dbl>, `3kg滑步` <dbl>,
#   三级跳 <dbl>, 全蹲 <dbl>, 挺举 <dbl>, `30米跑` <dbl>, `100米跑` <dbl>

8.2.2 无量纲化处理

sports = sports |> 
  mutate(across(2:16, rescale_initial),
         across(17:18, \(x) rescale_initial(x, "-")))
sports
# A tibble: 5 × 18
   年份  铅球 `4kg前抛` `4kg后抛` `4kg原地` 立定跳远  高翻  抓举  卧推 `3kg前抛`
  <dbl> <dbl>     <dbl>     <dbl>     <dbl>    <dbl> <dbl> <dbl> <dbl>     <dbl>
1  1982  1         1         1         1        1     1     1     1         1   
2  1983  1.03      1.13      1.19      1.02     1.00  1     1.18  1.08      1.20
3  1984  1.07      1.32      1.23      1.12     1.03  1.06  1.36  1.15      1.27
4  1985  1.15      1.33      1.20      1.13     1.06  1.18  1.45  1.31      1.28
5  1986  1.15      1.31      1.26      1.08     1.04  1.24  1.45  1.38      1.33
# ℹ 8 more variables: `3kg后抛` <dbl>, `3kg原地` <dbl>, `3kg滑步` <dbl>,
#   三级跳 <dbl>, 全蹲 <dbl>, 挺举 <dbl>, `30米跑` <dbl>, `100米跑` <dbl>

8.2.3 计算灰色关联度

mathmodel 包提供了 grey_corr() 函数实现计算灰色关联度,基本语法:

grey_corr(ref, cmp, rho = 0.5, w = NULL)
  • ref 为参考序列
  • cmp 为比较序列
  • rho 为分辨系数
  • w 为指标权重向量

采用默认分辨系数,不提供指标权重:

res = grey_corr(sports[[2]], sports[,3:18])
  • 将结果转化为数据框,并排序:
enframe(res, value = "灰色关联度") |> 
  arrange(-灰色关联度)
# A tibble: 16 × 2
   name     灰色关联度
   <chr>         <dbl>
 1 全蹲          0.933
 2 3kg滑步       0.895
 3 高翻          0.855
 4 4kg原地       0.854
 5 挺举          0.847
 6 立定跳远      0.776
 7 30米跑        0.745
 8 100米跑       0.726
 9 3kg原地       0.708
10 三级跳        0.705
11 3kg后抛       0.683
12 4kg后抛       0.663
13 卧推          0.659
14 4kg前抛       0.588
15 3kg前抛       0.582
16 抓举          0.502

8.3 案例 2:投资产出优势分析

灰色关联分析的参考序列只有 \(1\) 个,当参考序列不止 \(1\) 个时,让比较序列和各个参考序列都做一遍灰色关联分析,得到灰色关联度矩阵,叫作优势分析

设有 \(m\) 个参考序列,\(l\) 个比较序列,则这 \(l\) 个比较序列对每一个参考序列都有 \(1\) 个关联度,记 \(r_ij\) 表示第 \(j\) 个比较序列对第 \(i\) 个参考序列的关联度,可得到关联度矩阵 \(R = (r_{ij})_m \times l\)

根据矩阵 \(R\) 的各元素的大小,可分析判断出哪些因素起主要影响(优势因素),哪些因素起次要影响。

8.3.1 创建数据

invest = read_csv("data/invest.csv")
invest
# A tibble: 5 × 12
   year    x1    x2    x3    x4    x5    y1    y2    y3    y4    y5    y6
  <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
1  1979  309.  195.  24.6  20    19.0  170   57.6  88.6  11.2  4.03  13.7
2  1980  310   190.  21    25.6  19    174   70.7  70    13.3  4.26  15.6
3  1981  295   187.  12.2  23.3  22.3  197   76.8  85.4  16.8  4.34  13.8
4  1982  346   205   15.1  29.2  23.5  216.  80.7  99.8  18.9  5.06  12.0
5  1983  367   223.  14.6  30    27.7  236.  89.8 103.   22.8  5.78  14.0

8.3.2 无量纲化处理

invest = invest |> 
  mutate(across(-1, rescale_initial))
invest
# A tibble: 5 × 12
   year    x1    x2    x3    x4    x5    y1    y2    y3    y4    y5    y6
  <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
1  1979 1     1     1      1     1     1     1    1      1     1    1    
2  1980 1.00  0.972 0.854  1.28  1.00  1.02  1.23 0.790  1.19  1.06 1.14 
3  1981 0.956 0.958 0.496  1.16  1.17  1.16  1.33 0.964  1.50  1.08 1.01 
4  1982 1.12  1.05  0.614  1.46  1.24  1.27  1.40 1.13   1.69  1.26 0.874
5  1983 1.19  1.14  0.592  1.5   1.46  1.39  1.56 1.17   2.04  1.43 1.02 

8.3.3 优势分析:批量计算灰色关联度

map_dfc(invest[7:12], \(x) grey_corr(x, invest[2:6])) |> 
  mutate(`投资/产出` = names(invest)[2:6], .before = 1)
# A tibble: 5 × 7
  `投资/产出`    y1    y2    y3    y4    y5    y6
  <chr>       <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
1 x1          0.802 0.689 0.891 0.678 0.811 0.743
2 x2          0.761 0.666 0.858 0.663 0.774 0.766
3 x3          0.557 0.529 0.579 0.568 0.565 0.562
4 x4          0.810 0.885 0.577 0.780 0.804 0.607
5 x5          0.935 0.800 0.675 0.731 0.921 0.632

8.4 灰色关联评价

灰色关联评价,类似于理想解法,算法步骤如下:

  • 对指标数据预处理:一致化、规范化后,得到规范矩阵;
  • 由于各个指标对综合评价的权重不同,需要根据指标权重对规范矩阵做加权,得到加权规范矩阵;
  • 构造参考样本,为“正理想样本”,即各个指标取最大值,构成的最佳样本;
  • 将每个样本(评价对象)看作是比较序列,将参考样本作为参考序列,代入灰色关联分析算法,计算灰色关联度。
  • 根据该灰色关联度,就可以排序或评价样本的优劣。

以评价河流水质为例。

8.4.1 数据预处理

  • 只将中间型、区间型指标做归一化:
df = water_quality |>
  mutate(PH = rescale_middle(PH, 7),
         nutrient = rescale_interval(nutrient, 10, 20))
df
# A tibble: 20 × 5
      ID    O2     PH  germ nutrient
   <dbl> <dbl>  <dbl> <dbl>    <dbl>
 1     1  4.69 0.717     51    1    
 2     2  2.03 0.407     19    0.694
 3     3  9.11 0.524     46    0.906
 4     4  8.61 0.966     46    0.444
 5     5  7.13 0.655     50    0.691
 6     6  2.39 0.841     38    0.601
 7     7  7.69 0.855     38    0.655
 8     8  9.3  0.869     27    0    
 9     9  5.45 0.572      5    1    
10    10  6.19 0.814     17    0.785
11    11  7.93 0.634      9    0.699
12    12  4.4  0.807     17    0.542
13    13  7.46 0.145     23    1    
14    14  2.01 0         47    0.455
15    15  2.04 0.586     23    1    
16    16  7.73 0.407     52    1    
17    17  6.35 0.6       25    0.182
18    18  8.29 0.0276    39    1    
19    19  3.54 0.814     54    0.409
20    20  7.44 0.490      8    0.273

8.4.2 指标权重:熵权法

已经归一化的指标,不必重复做归一化:

idx = c("+", NA, "-", NA)
res = entropy_weight(df[2:5], idx)  
res$w
       O2        PH      germ  nutrient 
0.3153202 0.1813149 0.3506929 0.1526721 

8.4.3 灰色关联评价

mathmodels 包提供了 grey_corr_topsis() 函数实现灰色关联 TOPSIS 法,基本语法:

grey_corr_topsis(X, w, index = NULL, rho = 0.5)
  • X 为决策矩阵
  • w 为指标权重
  • index 可以指定对哪些列做正向("+")、负向("-")、不做(NA)归一化,默认 index = NULL 表示,所有列都不做归一化。
  • rho 为分辨系数

执行灰色关联 TOPSIS 评价,已经归一化的指标,不必重复做归一化:

gcd = grey_corr_topsis(df[2:5], res$w, idx)

转化成 0-100 分数,增加排名列:

tibble(ID = df$ID, 灰色关联度 = gcd, 
       score = rescale(灰色关联度, b = 100),
       rank = min_rank(-score)) |>
  arrange(-score)
# A tibble: 20 × 4
      ID 灰色关联度 score  rank
   <dbl>      <dbl> <dbl> <int>
 1    11      0.613 100       1
 2     9      0.613  99.9     2
 3    10      0.592  91.9     3
 4     7      0.562  80.4     4
 5    20      0.560  79.6     5
 6     3      0.558  79.0     6
 7     8      0.557  78.6     7
 8    13      0.552  76.7     8
 9     4      0.552  76.5     9
10    12      0.545  73.9    10
11    18      0.520  64.2    11
12    16      0.511  60.9    12
13    15      0.506  58.8    13
14     5      0.503  57.6    14
15    17      0.502  57.3    15
16     1      0.501  56.9    16
17     6      0.472  45.8    17
18     2      0.469  44.8    18
19    19      0.430  29.8    19
20    14      0.353   0      20