Python 数学建模——灰色关联度分析

文章目录

介绍

  灰色关联度分析,可以反映两个序列 X ( k ) X(k) X(k) 和 Y ( k ) Y(k) Y(k) 之间的联系,用 r r r 表征。然而, r r r 的绝对大小并没有过多的意义,它的意义只在不同的 r r r 进行比较 时体现。比如 X ( k ) , Y ( k ) X(k),Y(k) X(k),Y(k) 之间的灰色关联度为 r x y = 0.8 r_{xy}=0.8 rxy=0.8, X ( k ) , Z ( k ) X(k),Z(k) X(k),Z(k) 之间的灰色关联度为 r x z = 0.5 r_{xz}=0.5 rxz=0.5,根据 r x y > r x z r_{xy}>r_{xz} rxy>rxz 判断 X ( k ) , Y ( k ) X(k),Y(k) X(k),Y(k) 之间的关系相比于 X ( k ) , Z ( k ) X(k),Z(k) X(k),Z(k) 更为紧密。

在分析两个 序列的关联性时,灰色关联度分析用处不大,因为不存在"比较"。此时反倒是可以用 Spearman 或者 Pearson 相关系数去衡量关联性,效果更佳。相比于 Pearson/Spearman 相关系数,灰色关联度分析更像是从折线图的形状上,分析两个变量之间的关联程度。

  据此,灰色关联度分析往往规定一个母序列 Y ( k ) ( k = 1 , 2 , ⋯   , n ) Y(k)(k=1,2,\cdots,n) Y(k)(k=1,2,⋯,n),并且设置 m m m 个子序列 X i ( k ) ( k = 1 , 2 , ⋯   , n ; i = 1 , 2 , ⋯   , m ) {{X}_{i}}(k)(k=1,2,\cdots ,n;i=1,2,\cdots ,m) Xi(k)(k=1,2,⋯,n;i=1,2,⋯,m),并探讨每个子序列与母序列 关联的紧密程度,依据是每个子序列与母序列之间的灰色关联度。

  你可能会产生疑问,灰色关联度分析能做到的,Spearman 和 Pearson 相关系数都可以做到啊,只需将依据改为每个子序列与母序列之间的 Peason/Spearman 相关系数。然而实际情况是,Peason/Spearman 相关系数的区分性太弱了,我将以一个例子说明 Peason/Spearman 相关系数不合适的原因。


例 下表为某地区国内生产总值的统计数据(以百万元计),问该地区从 2000 2000 2000 年到 2005 2005 2005 年之间哪一种产业对 GDP 总量影响最大。

年份 GDP 总量 第一产业 第二产业 第三产业
2000 2000 2000 1988 1988 1988 386 386 386 839 839 839 763 763 763
2001 2001 2001 2061 2061 2061 408 408 408 846 846 846 808 808 808
2002 2002 2002 2335 2335 2335 422 422 422 960 960 960 953 953 953
2003 2003 2003 2750 2750 2750 482 482 482 1258 1258 1258 1010 1010 1010
2004 2004 2004 3356 3356 3356 511 511 511 1577 1577 1577 1268 1268 1268
2005 2005 2005 3806 3806 3806 561 561 561 1893 1893 1893 1352 1352 1352

点击下载路径,Ctrl+S下载上表所示灰色关联度.csv表单。

  我们可以很方便地画出折线图,先观察一下趋势,发现都是逐年增加的:

  视图计算 Peason/Spearman 相关系数,结果是:

  • 国内生产总值分别对三种产业的 Pearson 相关系数是:[0.98845683 0.99738217 0.98954068]
  • 国内生产总值分别对三种产业的 Spearman 相关系数是:[1. 1. 1. ]

  显然 Peason/Spearman 相关系数分辨能力太弱,所以不适合运用。

原理

  在使用灰色关联度重新解决上面这个问题之前,先介绍一下灰色关联度的计算方法 。在确定母序列 Y ( k ) ( k = 1 , 2 , ⋯   , n ) Y(k)(k=1,2,\cdots,n) Y(k)(k=1,2,⋯,n) 和子序列 X i ( k ) ( k = 1 , 2 , ⋯   , n ; i = 1 , 2 , ⋯   , m ) {{X}_{i}}(k)(k=1,2,\cdots ,n;i=1,2,\cdots ,m) Xi(k)(k=1,2,⋯,n;i=1,2,⋯,m) 后,还需要进行以下几步:

  1. 无量纲化处理 。从下面两种不同的方式中选择一种即可:
    • 初值化处理: x i ( k ) = x i ( k ) x i ( 1 ) ( k = 1 , 2 , ⋯   , n ; i = 1 , 2 , ⋯   , m ) {{x}{i}}(k)=\cfrac{{{x}{i}}(k)}{{{x}_{i}}(1)}\quad(k=1,2,\cdots ,n;i=1,2,\cdots ,m) xi(k)=xi(1)xi(k)(k=1,2,⋯,n;i=1,2,⋯,m)
    • 均值化处理: x i ( k ) = x i ( k ) x ‾ i ( k = 1 , 2 , ⋯   , n ; i = 1 , 2 , ⋯   , m ) {{x}{i}}(k)=\cfrac{{{x}{i}}(k)}{\overline{x}_i}\quad(k=1,2,\cdots ,n;i=1,2,\cdots ,m) xi(k)=xixi(k)(k=1,2,⋯,n;i=1,2,⋯,m)
  2. 计算关联系数 :
    ξ i ( k ) = min ⁡ i min ⁡ k ∣ y ( k ) − x i ( k ) ∣ + ρ max ⁡ i max ⁡ k ∣ y ( k ) − x i ( k ) ∣ ∣ y ( k ) − x i ( k ) ∣ + ρ max ⁡ i max ⁡ k ∣ y ( k ) − x i ( k ) ∣ {{ξ}{i}}(k)=\frac{{\min{i}{\min_{k}|}}y(k)-{{x}{i}}(k)|+\rho {\max{i}{\max_{k}|}}y(k)-{{x}{i}}(k)|}{|y(k)-{{x}{i}}(k)|+\rho {\max_{i}{\max_{k}|}}y(k)-{{x}_{i}}(k)|} ξi(k)=∣y(k)−xi(k)∣+ρmaximaxk∣y(k)−xi(k)∣minimink∣y(k)−xi(k)∣+ρmaximaxk∣y(k)−xi(k)∣其中分辨系数 ρ ∈ ( 0 , + ∞ ) \rho\in(0,+\infty) ρ∈(0,+∞),值越小分辨能力越大,一般在 ( 0 , 1 ) (0,1) (0,1) 内取值。当 ρ < 0.5463 \rho<0.5463 ρ<0.5463 时,分辨能力最好。一般取 ρ = 0.5 \rho=0.5 ρ=0.5。
  3. 计算关联度 。因为关联系数是比较数列与参考数列在各个时刻(即曲线中的各点)的关联程度值,所以它的数不止一个,而信息过于分散不便于进行整体性比较。因此有必要将各个时刻的关联系数集中为一个值,即求其平均值,作为比较数列与参考数列间关联程度的数量表示: r i = 1 n ∑ k = 1 n ξ i ( k ) i = 1 , 2 , ⋯   , m {{r}{i}}=\frac{1}{n}\sum{k=1}^{n}{{{ξ}_{i}}}(k)\quad i=1,2,\cdots ,m ri=n1k=1∑nξi(k)i=1,2,⋯,m
  4. 关联度排序 。根据 r i r_i ri 进行排序,就可以得到母序列和各个子序列的关联程度大小。

代码实例

  介绍完灰色关联度 r r r 的计算方法后,我们就用灰色关联度重新解决上面的例子,数据存储在灰色关联度.csv文件中。这里取 ρ = 0.5 \rho=0.5 ρ=0.5,并且无量纲化处理时使用均值化处理。

py 复制代码
import pandas as pd

x = pd.read_csv('灰色关联度.csv')
x = x.iloc[:, 1:].T

# 1、数据均值化处理
x_mean = x.mean(axis=1)
for i in range(x.index.size):
    x.iloc[i, :] = x.iloc[i, :] / x_mean[i]

# 2、提取参考队列和比较队列
ck = x.iloc[0, :]
cp = x.iloc[1:, :]

# 比较队列与参考队列相减
t = pd.DataFrame()
for j in range(cp.index.size):
    temp = pd.Series(cp.iloc[j, :] - ck)
    t = t.append(temp, ignore_index=True)

# 求最大差和最小差
mmax = t.abs().max().max()
mmin = t.abs().min().min()
rho = 0.5
# 3、求关联系数
ksi = ((mmin + rho * mmax) / (abs(t) + rho * mmax))

# 4、求关联度
r = ksi.sum(axis=1) / ksi.columns.size

# 5、关联度排序,得到结果r3>r2>r1
result = r.sort_values(ascending=False)

print(result)
"""
关联度
r3 = 0.757300 (第三季度)
r2 = 0.624296 (第二季度)
r1 = 0.508432 (第一季度)
"""

  尝试了 ρ ∈ ( 0 , 2 ) \rho\in(0,2) ρ∈(0,2) 的一些情况,结果都是第三季度的关联度最大,如左图。右图是无量纲化处理改为初值化处理的结果。

相关推荐
实名上网宋凯宣43 分钟前
Django
后端·python·django
如若1232 小时前
【论文复现】CoFailMed:从零复现医学图像分割的共享失败审计,含完整代码流程与科研绘图
人工智能·python
砚底藏山河3 小时前
python量化自定义周期 K 线合成
java·开发语言·数据库·python·金融
视觉小萌新3 小时前
AI Class 3 · Chapter 1:变量、字符串、list/dict、if/for(python学习-小白版-有经验可跳过)
python·学习·list
薛定谔的猫-菜鸟程序员4 小时前
软件架构设计师开发资料大全(从入门到精通)
后端·python·系统架构·flask·架构设计师
Ramble_Naylor6 小时前
Rust深度解读:Send 与 Sync 的本质与线程安全边界
python·算法·rust
Allen_LVyingbo6 小时前
NVIDIA CUDA Tile 在医疗计算中的算子形式化、算法重构与内核实现
大数据·python·算法·重构·知识图谱·健康医疗·数据库架构
云和数据.ChenGuang7 小时前
Python 闭包详解:从原理到实战
linux·开发语言·人工智能·python·kubernetes
我命由我123458 小时前
Python 实用操作 - 文件操作(打开与关闭文件、读取文件、文件写入)
java·开发语言·前端·javascript·数据库·python·java-ee
青少儿编程课堂8 小时前
蓝桥杯·全国青少年信息素养大赛·电子学会Python/C++考级:倍增法求最近公共祖先LCA解析
c++·python·算法·bfs·信息学竞赛