相关分析是一种统计分析方法,用于研究两个或多个变量之间的关系和相互影响程度。它帮助我们了解变量之间的线性关系、趋势和相关程度。
在相关分析中,常用的指标是相关系数,用于衡量两个变量之间的相关程度。最常见的相关系数是皮尔逊相关系数(Pearson correlation coefficient),它衡量了两个变量之间的线性关系强度和方向。皮尔逊相关系数的取值范围在-1到1之间,接近1表示正相关,接近-1表示负相关,接近0表示无相关关系。
在Python中,可以使用pandas
和numpy
库进行相关分析。
# 设置绘图环境的字体大小
sns.set_context(font_scale=1.5)
# 读取数据集
df = pd.read_csv("../data/HR.csv")
# 提取数值类型的列
numeric_cols = df.select_dtypes(include=[np.number]).columns
# 计算相关系数矩阵并绘制热图
sns.heatmap(df[numeric_cols].corr(), vmin=-1, vmax=1, cmap=sns.color_palette("RdBu", n_colors=128))
# 显示图形
plt.show()
上述代码的注释解释如下:
pandas
用于数据处理,matplotlib.pyplot
用于绘图,seaborn
用于美化绘图风格,scipy.stats
用于计算相关系数,numpy
用于数据类型操作。pd.read_csv()
读取数据集,文件路径为"../data/HR.csv"。select_dtypes()
方法结合np.number
选择数据框中的数值类型的列,将其存储在numeric_cols
变量中。df[numeric_cols].corr()
计算数值列之间的相关系数矩阵。sns.heatmap()
绘制热图,其中vmin
和vmax
指定了颜色映射的取值范围,cmap
指定了使用的颜色映射方案。plt.show()
显示图形。分析结果图为:
如图,蓝色是接近于1,红色接近于-1。泛红的区域接近于负相关,泛蓝的区域接近于正相关。
相关分析中的熵、条件熵和互信息是信息论中的概念,用于衡量随机变量之间的关联性。
(1)熵(Entropy):熵是表示随机变量的不确定性的度量。对于一个离散随机变量,其熵的定义为所有可能取值的信息量的期望值的负数。熵越大,随机变量的不确定性越高。在相关分析中,熵可以用于衡量单个随机变量的不确定性。
公式: 值越接近于0,说明其不确定性越小。
(2)条件熵(Conditional Entropy):条件熵是在给定另一个随机变量的条件下,某个随机变量的不确定性。对于两个随机变量X和Y,给定Y的条件下,X的条件熵定义为在已知Y的取值情况下,X的熵的期望值。条件熵越大,表示X和Y之间的关联性越弱。
公式:
(3)熵增益(互信息(Mutual Information)):互信息衡量的是两个随机变量之间的相关性或依赖关系。对于两个随机变量X和Y,互信息定义为X和Y的联合分布与它们各自的边缘分布之间的差异。互信息可以看作是两个随机变量之间的共享信息量,互信息越大,表示两个随机变量之间的关联性越强。
在相关分析中,这些概念可以用于量化随机变量之间的关联程度,从而帮助理解和分析数据中的相互作用和依赖关系。
公式:
(4)熵增益率:熵增益率是一种用于特征选择的指标,常用于决策树算法中。它衡量了在给定某个特征的条件下,对目标变量的不确定性减少程度。熵增益率越高,意味着使用该特征进行划分可以获得更多的信息增益。计算熵增益率涉及两个概念:信息增益和分裂信息。信息增益是目标变量熵减少的量,分裂信息是指划分特征的熵。熵增益率通过将信息增益除以分裂信息来进行归一化,以解决特征取值数目不同带来的偏好问题。
公式:
(5)相关性:相关性是指两个变量之间的关联程度。相关性通常用于衡量两个变量之间的线性关系。相关性的取值范围在-1到1之间,其中-1表示完全负相关,0表示无相关性,1表示完全正相关。相关性可以帮助我们了解变量之间的趋势、依赖关系和相互影响程度。在数据分析中,可以通过计算相关系数(如皮尔逊相关系数)来衡量变量之间的相关性。
X | Y |
X1 | Y1 |
X1 | Y1 |
X2 | Y1 |
X2 | Y2 |
X2 | Y2 |
X2 | Y2 |
import pandas as pd
import seaborn as sns
import numpy as np
sns.set_context(font_scale=1.5)
df=pd.read_csv("../data/HR.csv")
s1=pd.Series(["X1","X1","X2","X2","X2","X2"])
s2=pd.Series(["Y1","Y1","Y1","Y2","Y2","Y2"])
def getEntropy(s):
if not isinstance(s,pd.core.series.Series):
s=pd.Series(s)
# 如果输入不是 pandas Series,则将其转换为 Series 类型
if not isinstance(s, pd.core.series.Series):
s = pd.Series(s)
# 计算每个值的出现频率并得到概率数组
prt_ary = pd.value_counts(s).values / float(len(s))
# 计算熵值,即对每个概率取负对数后乘以概率并求和
entropy = -(np.log2(prt_ary) * prt_ary).sum()
return entropy
print("熵值:", getEntropy(s2)) # Out:Entropy: 1.0
该代码定义了一个名为 getEntropy
的函数,用于计算序列 s
的熵值。函数首先检查输入 s
是否为 pandas Series 类型,如果不是,则将其转换为 Series 类型。然后,使用 pandas 的 value_counts
函数统计序列中每个值的出现次数,并计算出对应的概率。最后,根据熵值的计算公式,对每个概率取负对数并乘以概率,然后对所有结果求和,得到最终的熵值。函数返回计算得到的熵值。示例用法展示了如何使用 getEntropy
函数来计算特定序列 s2
的熵值,并打印结果。
# 求取条件熵
def getCondEntropy(s1, s2):
# 检查输入的序列长度是否相等
assert len(s1) == len(s2)
# 创建一个空字典
d = dict()
# 构建字典,键为 s1 的值,值为对应的 s2 值的列表
for i in range(len(s1)):
d[s1[i]] = d.get(s1[i], []) + [s2[i]]
# 计算条件熵,对每个键值对应的列表计算熵值,并加权求和
cond_entropy = sum([getEntropy(d[k]) * len(d[k]) / float(len(s1)) for k in d])
return cond_entropy
print("CondEntropy", getCondEntropy(s1,s2)) #Out: CondEntropy 0.5408520829727552
print("CondEntropy", getCondEntropy(s2,s1)) #Out:CondEntropy 0.4591479170272448
该代码定义了一个计算条件熵的函数 getCondEntropy
。首先,通过断言语句检查输入的序列 s1
和 s2
的长度是否相等。然后,创建一个空字典 d
。接下来,使用循环遍历序列 s1
和 s2
,将 s1
的值作为字典的键,s2
的对应值作为字典的值,将值添加到字典中。然后,通过列表推导式计算每个键值对应的列表的熵值,并乘以列表长度和总长度的比例,最后加权求和得到条件熵。最后,我们调用 getCondEntropy
函数,传入示例序列 s1
和 s2
,并打印计算得到的条件熵结果。
从结果可知,s1,s2与s2,s1的条件熵是不对应的。
# 熵增益(互信息)
def getEntropyGain(s1,s2):
return getEntropy(s2)-getCondEntropy(s1,s2)
print("EntropyGain",getEntropyGain(s1,s2)) #Out:EntropyGain 0.4591479170272448
# 熵增益率
def getEntropyGainRatio(s1,s2):
return getEntropyGain(s1,s2)/getEntropy(s2)
print("EntropyGainRatio",getEntropyGainRatio(s1,s2)) #Out:ntropyGainRatio 0.4591479170272448
#相关度
def getDiscreteRelation(a1, a2):
return getEntropyGain(a1, a2) / math.sqrt(getEntropy(a1) * getEntropy(a2))
print("DiscreteRelation",getDiscreteRelation(s1,s2)) #Out:DiscreteRelation 0.4791387674918639
# Gini
def getGini(a1, a2):
assert (len(a1) == len(a2))
d = dict()
for i in list(range(len(a1))):
d[a1[i]] = d.get(a1[i], []) + [a2[i]]
return 1 - sum([getProbSS(d[k]) * len(d[k]) / float(len(a1)) for k in d])
# 可能性平方和
def getProbSS(s):
if not isinstance(s, pd.core.series.Series):
s = pd.Series(s)
prt_ary = np.array(s.groupby(s).count().values / float(len(s)))
return sum(prt_ary ** 2)
print("Gini", getGini(s1, s2)) #Out: Gini 0.25
print("Gini", getGini(s2, s1)) #Out: Gini 0.2222222222222222
这段代码计算了两个变量之间的基尼系数(Gini coefficient)。getGini
函数接受两个数组作为输入,假设这两个数组的长度相等。它首先根据第一个数组 a1
中的元素将第二个数组 a2
中的元素分组,然后计算每个组的可能性平方和,最后将所有组的可能性平方和加权求和,并与1相减,得到基尼系数。
getProbSS
函数计算了给定序列 s
的可能性平方和。它首先将序列转换为 Pandas 的 Series 对象(如果尚未是),然后使用 groupby
方法按照元素进行分组,并计算每个元素的计数。接下来,它计算每个元素计数的可能性,将其转换为数组,并计算可能性平方和。
最后,通过调用 getGini
函数来计算两个示例数据集 s1
和 s2
之间的基尼系数,并打印结果。