目前网上使用Python实现灰色关联分析的程序,都只是实现两个列之间的关联度计算,但是很多时候我们需要做出需要像Pandas中的矩阵可视化效果。于是我写了一个,具体效果请见以下实现:
灰色关联分析法
首先来讲一讲为什么使用灰色关联分析法。对于两个系统之间的因素,其随时间或不同对象而变化的关联性大小的量度,称为关联度。在系统发展过程中,若两个因素变化的趋势具有一致性,即同步变化程度较高,即可谓二者关联程度较高;反之,则较低。因此,灰色关联分析方法,是根据因素之间发展趋势的相似或相异程度,亦即“灰色关联度”,作为衡量因素间关联程度的一种方法。
简介
灰色系统理论提出了对各子系统进行灰色关联度分析的概念,意图透过一定的方法,去寻求系统中各子系统(或因素)之间的数值关系。因此,灰色关联度分析对于一个系统发展变化态势提供了量化的度量,非常适合动态历程分析。
计算步骤
确实参考数列与比较数列
对参考数列与比较数列进行无量纲化处理
计算关联系数,求关联度
此处我给出的是第三步的实现方式,无量纲化有一个参考方法,但是最好自己视具体情况处理。此处数据使用的是UCI的红酒质量数据集。
代码实现
源代码可以前往 github下载
(https://github.com/FontTian/DS-Exhibitio)
下载数据
import pandas as pd
import numpy as np
from numpy import *
import matplotlib.pyplot as plt
%matplotlib inline
# 从硬盘读取数据进入内存
wine = pd.read_csv("G:/Data/dataset/wine/wine.csv")
wine.head()
实现灰色关联分析
灰色关联分析一共分为了三个部分,这样比较容易大家随意摘取部分内容使用,第一个方法是无量纲化,我这里选择的是(x-mean)/(max-min),你也可以替换成其他方法。
(据我个人了解,一般而言标准化不行)
第二个部分是计算一个dataframe中单独某一列灰色关联分析度的方法,m代表参考列,可以任意选择。2010-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(data_wine_gra)
mask[np.triu_indices_from(mask)] = True
with sns.axes_style("white"):
sns.heatmap(DataFrame,
cmap="YlGnBu",
annot=True,
mask=mask,
)
plt.show()
ShowGRAHeatMap(data_wine_gra)
新图效果
全图效果