Python实现 灰色关联分析 与结果可视化

之前在比赛的时候需要用Python实现灰色关联分析,从网上搜了下只有实现两个列之间的,于是我把它改写成了直接像Pandas中的计算工具直接计算person系数那样的形式,可以对整个矩阵进行运算,并给出了可视化效果,效果请见实现

作者提醒:部分读者反应在某些情况下与MATLAB自带灰色关联分析结果有较大差距,目前作者尚未对此问题进行检验,请谨慎使用

灰色关联分析法

对于两个系统之间的因素,其随时间或不同对象而变化的关联性大小的量度,称为关联度。在系统发展过程中,若两个因素变化的趋势具有一致性,即同步变化程度较高,即可谓二者关联程度较高;反之,则较低。因此,灰色关联分析方法,是根据因素之间发展趋势的相似或相异程度,亦即“灰色关联度”,作为衡量因素间关联程度的一种方法。

简介

灰色系统理论提出了对各子系统进行灰色关联度分析的概念,意图透过一定的方法,去寻求系统中各子系统(或因素)之间的数值关系。因此,灰色关联度分析对于一个系统发展变化态势提供了量化的度量,非常适合动态历程分析。

计算步骤

  1. 确实参考数列与比较数列
  2. 对参考数列与比较数列进行无量纲化处理
  3. 计算关联系数,求关联度

此处我给出的是第三步的实现方式,无量纲化请自己处理.数据使用UCI的红酒质量数据集.

代码实现

源代码可以前往 github下载

下载数据

import pandas as p
import numpy as np
from numpy import *
import matplotlib.pyplot as plt
%matplotlib inline

# 从硬盘读取数据进入内存
wine = pd.read_csv("/home/fonttian/Data/dataset/wine/wine.csv")
wine.head()

展示数据

实现灰色关联分析

灰色关联分析一共分为了三个部分,这样比较容易大家随意摘取部分内容使用,
第一个方法是无量纲化,我这里选择的是(x-mean)/(max-min),你也可以替换成其他方法(据我个人了解,一般而言标准化不行)

第二个部分是计算一个dataframe中单独某一列灰色关联分析度的方法,m代表参考列,可以任意选择。2019-3-26在windows上,个人测试wine数据集上一次运算大概0.3s性能不高不低。不过由于部分代码是numpy写的性能确实也比纯pandas快很多,我这篇文章下边长期有一个灰色关联分析Matlab与python灰色关联分析,但是其为纯pandas写的,看起来很方便,不过运算时间约为本代码的一倍,所以假如你想要单独计算一列,个人还是更推荐我的代码。但是如果你想要更快的性能,肯定还是自己写numpy更好

第三部分,是借助前两个方法实现的计算矩阵,不过因为计算次数比较多,会比较慢,适合出图。

# 无量纲化
def dimensionlessProcessing(df):
    newDataFrame = pd.DataFrame(index=df.index)
    columns = df.columns.tolist()
    for c in columns:
        d = df[c]
        MAX = d.max()
        MIN = d.min()
        MEAN = d.mean()
        newDataFrame[c] = ((d - MEAN) / (MAX - MIN)).tolist()
    return newDataFrame

def GRA_ONE(gray, m=0):
    # 读取为df格式
    gray = dimensionlessProcessing(gray)
    # 标准化
    std = gray.iloc[:, m]  # 为标准要素
    gray.drop(str(m),axis=1,inplace=True)
    ce = gray.iloc[:, 0:]  # 为比较要素
    shape_n, shape_m = ce.shape[0], ce.shape[1]  # 计算行列

    # 与标准要素比较,相减
    a = zeros([shape_m, shape_n])
    for i in range(shape_m):
        for j in range(shape_n):
            a[i, j] = abs(ce.iloc[j, i] - std[j])

    # 取出矩阵中最大值与最小值
    c, d = amax(a), amin(a)

    # 计算值
    result = zeros([shape_m, shape_n])
    for i in range(shape_m):
        for j in range(shape_n):
            result[i, j] = (d + 0.5 * c) / (a[i, j] + 0.5 * c)

    # 求均值,得到灰色关联值,并返回
    result_list = [mean(result[i, :]) for i in range(shape_m)]
    result_list.insert(m,1)
    return pd.DataFrame(result_list)


def GRA(DataFrame):
    df = DataFrame.copy()
    list_columns = [
        str(s) for s in range(len(df.columns)) if s not in [None]
    ]
    df_local = pd.DataFrame(columns=list_columns)
    df.columns=list_columns
    for i in range(len(df.columns)):
        df_local.iloc[:, i] = GRA_ONE(df, m=i)[0]
    return df_local

在这里插入图片描述

结果可视化

该部分添加了三角形显示的功能,注意如果你出现了图形显示不全(最后一行显示一半的问题,是Matplotlib 的一个版本的问题,升级一下即可)。如果你想要显示全部注释热图方法中的mask参数即可,不过由于本矩阵为全float计算,会带有舍入误差,数据量大的时候差异可能会比较大。所以两中方法各有利弊,请自行选择。

# 灰色关联结果矩阵可视化
# 灰色关联结果矩阵可视化
import seaborn as sns

def ShowGRAHeatMap(DataFrame):
    colormap = plt.cm.RdBu
    ylabels = DataFrame.columns.values.tolist()
    f, ax = plt.subplots(figsize=(14, 14))
    ax.set_title('GRA HeatMap')
    
    # 设置展示一半,如果不需要注释掉mask即可
    mask = np.zeros_like(DataFrame)
    mask[np.triu_indices_from(mask)] = True
    
    with sns.axes_style("white"):
        sns.heatmap(DataFrame,
                    cmap="YlGnBu",
                    annot=True,
                    mask=mask,
                   )
    plt.show()
    
data_wine_gra = GRA(wine)
ShowGRAHeatMap(data_wine_gra)

新图效果

在这里插入图片描述
全图效果
wine 的灰色关联分析热度图

一些资料

  1. 原文链接:Python实现 灰色关联分析 与结果可视化
  2. 参考文章:百度百科 灰色关联分析法
  3. 参考文章:简书 Python实现灰色关联
  4. 建议学习:Maximal Information Coefficient (MIC)最大互信息系数详解与实现

额外说明

本博客一开始也是我紧急写的,而第二部分是为了出图,因此整体代码采用了pandas为主,混了部分numpy,但是由于pandas本身有问题,很多情况下,直接用pandas的dataframe代替numpy矩阵进行矩阵性能会比循环低(测试版本ubuntu16.04,ubuntu18.04,测试数据0.5k-200k),而我当时也没什么时间写全numpy矢量运算,所以最后就成为了现在这种代码情况。而且该代码已经适合我个人目前的工作(大数据工程师)需要了,更大规模的数据我是用的spark或者pyspark,因此我短时间内没有更新numpy版本的需要,不过如果我更新了,也会第一时间发出来,并给出链接,这点请放心。

除此之外,感谢博友piaoyang_的指正

  • 106
    点赞
  • 680
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 143
    评论
以下是Python灰色关联度及其可视化的示例代码: ```python import numpy as np import matplotlib.pyplot as plt # 灰色关联度计算函数 def gray_relation(x, y): x_mean = np.mean(x) y_mean = np.mean(y) delta_x = np.abs(x - x_mean) delta_y = np.abs(y - y_mean) c = 0.5 gx = np.min(delta_x) / (np.max(delta_x) + c) gy = np.min(delta_y) / (np.max(delta_y) + c) return gx, gy # 数据准备 x = np.array([1, 2, 3, 4, 5, 6]) y1 = np.array([10, 8, 12, 14, 9, 10]) y2 = np.array([8, 6, 10, 12, 8, 7]) y3 = np.array([7, 9, 11, 13, 10, 12]) # 计算灰色关联度 gx1, gy1 = gray_relation(x, y1) gx2, gy2 = gray_relation(x, y2) gx3, gy3 = gray_relation(x, y3) # 可视化灰色关联度 plt.plot(x, y1, label='y1') plt.plot(x, y2, label='y2') plt.plot(x, y3, label='y3') plt.legend() plt.twinx() plt.plot(x, [gx1, gx2, gx3], 'ro-', label='gx') plt.plot(x, [gy1, gy2, gy3], 'bo-', label='gy') plt.legend() plt.show() ``` 代码说明: 首先定义了一个灰色关联度计算函数`gray_relation`,该函数接受两个数组参数`x`和`y`,计算出它们的灰色关联度`gx`和`gy`,并返回这两个值。 然后准备了三组数据`y1`、`y2`和`y3`,以及对应的自变量`x`。 接着,分别计算了这三组数据与自变量`x`的灰色关联度,并将结果保存在`gx1`、`gy1`、`gx2`、`gy2`、`gx3`和`gy3`中。 最后,使用Matplotlib库将三组数据分别绘制在同一个坐标系中,并将灰色关联度绘制在另一个坐标系中。在绘制灰色关联度时,使用`twinx()`函数创建一个新的y轴,使得灰色关联度可以与原始数据在同一个图中表示。绘图完成后使用`show()`函数显示图形。 运行上述代码,将得到一个包含三组数据和其对应灰色关联度的图形。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 143
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Font Tian

写的很好,请给我钱

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值