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_的指正

已标记关键词 清除标记
相关推荐
©️2020 CSDN 皮肤主题: 编程工作室 设计师:CSDN官方博客 返回首页