距离相关系数的原理及其实现(Numpy代码+第三方包的实现)

一、原理

最近在做特征选择的练习题时,要考量很多个特征的相关性,并且特征之间是非线性关系的,我们常见的皮尔逊相关系数无法准确使用,考虑使用距离相关系数来度量:

距离相关系数:研究两个变量之间的独立性,距离相关系数为0表示两个变量是独立的。克服了皮尔逊相关系数的弱点,皮尔逊相关系数为0并不一定表示两个变量之间是独立的,也有可能是非线性相关的。

利用 D i s t a n c e      C o r r e l a t i o n Distance\;\;Correlation DistanceCorrelation来研究两个变量 μ \mu μ v v v之间的独立性,记为 d c o r r ( μ    ,    v ) dcorr(\mu\;,\;v) dcorr(μ,v)

d c o r r ( μ    ,    v ) dcorr(\mu\;,\;v) dcorr(μ,v)=0时,说明两个变量 μ \mu μ v v v之间独立; d c o r r ( μ    ,    v ) dcorr(\mu\;,\;v) dcorr(μ,v)越大,说明 μ \mu μ v v v之间的相关性越强。

{ ( μ i    ,    v i )    ,    i = 1 , 2 , ⋯   , n } \{(\mu_i\;,\;v_i)\;,\;i=1,2,\cdots,n\} {(μi,vi),i=1,2,,n}是总体 ( μ    ,    v ) (\mu\;,\;v) (μ,v)的随机样本, S z e k e l y Szekely Szekely等定义两个随机变量 μ \mu μ v v v的DC样本估计值为:
d c o r r ( μ    ,    v ) = d c o v ( μ    ,    v ) d c o v ( μ    ,    μ ) d c o v ( v    ,    v ) dcorr(\mu\;,\;v)=\frac{dcov(\mu\;,\;v)}{\sqrt{dcov(\mu\;,\;\mu)dcov(v\;,\;v)}} dcorr(μ,v)=dcov(μ,μ)dcov(v,v) dcov(μ,v)

其中, d c o v 2 ( μ    ,    v ) = S 1 ^ + S 2 ^ − 2 S 3 ^ dcov^2(\mu\;,\;v)=\hat{S_1}+\hat{S_2}-2\hat{S_3} dcov2(μ,v)=S1^+S2^2S3^ S 1 ^    ,    S 2 ^    ,    S 3 ^ \hat{S_1}\;,\;\hat{S_2}\;,\;\hat{S_3} S1^,S2^,S3^分别为:

S 1 ^ = 1 n 2 ∑ i = 1 n ∑ j = 1 n ∣ ∣ μ i − μ j ∣ ∣ d μ ∣ ∣ v i − v j ∣ ∣ d v \hat{S_1}=\frac{1}{n^2}\sum_{i=1}^n\sum_{j=1}^n||\mu_i-\mu_j||_{d\mu}||v_i-v_j||_{dv} S1^=n21i=1nj=1n∣∣μiμjdμ∣∣vivjdv

S 2 ^ = 1 n 2 ∑ i = 1 n ∑ j = 1 n ∣ ∣ μ i − μ j ∣ ∣ d μ 1 n 2 ∑ i = 1 n ∑ j = 1 n ∣ ∣ v i − v j ∣ ∣ d v \hat{S_2}=\frac{1}{n^2}\sum_{i=1}^n\sum_{j=1}^n||\mu_i-\mu_j||_{d\mu}\frac{1}{n^2}\sum_{i=1}^n\sum_{j=1}^n||v_i-v_j||_{dv} S2^=n21i=1nj=1n∣∣μiμjdμn21i=1nj=1n∣∣vivjdv

S 3 ^ = 1 n 3 ∑ i = 1 n ∑ j = 1 n ∑ l = 1 n ∣ ∣ μ i − μ l ∣ ∣ d μ ∣ ∣ v j − v l ∣ ∣ d v \hat{S_3}=\frac{1}{n^3}\sum_{i=1}^n\sum_{j=1}^n\sum_{l=1}^n||\mu_i-\mu_l||_{d\mu}||v_j-v_l||_{dv} S3^=n31i=1nj=1nl=1n∣∣μiμldμ∣∣vjvldv

二、Numpy代码实现

from scipy.spatial.distance import pdist, squareform
import numpy as np
from numbapro import jit, float32
def distcorr(X, Y):
    """ Compute the distance correlation function
    >>> a = [1,2,3,4,5]
    >>> b = np.array([1,2,9,4,4])
    >>> distcorr(a, b)
    0.762676242417
    """
    X = np.atleast_1d(X)
    Y = np.atleast_1d(Y)
    if np.prod(X.shape) == len(X):
        X = X[:, None]
    if np.prod(Y.shape) == len(Y):
        Y = Y[:, None]
    X = np.atleast_2d(X)
    Y = np.atleast_2d(Y)
    n = X.shape[0]
    if Y.shape[0] != X.shape[0]:
        raise ValueError('Number of samples must match')
    a = squareform(pdist(X))
    b = squareform(pdist(Y))
    A = a - a.mean(axis=0)[None, :] - a.mean(axis=1)[:, None] + a.mean()
    B = b - b.mean(axis=0)[None, :] - b.mean(axis=1)[:, None] + b.mean()
    
    dcov2_xy = (A * B).sum()/float(n * n)
    dcov2_xx = (A * A).sum()/float(n * n)
    dcov2_yy = (B * B).sum()/float(n * n)
    dcor = np.sqrt(dcov2_xy)/np.sqrt(np.sqrt(dcov2_xx) * np.sqrt(dcov2_yy))
    return dcor

这篇代码来自国外一位大佬所写,原地址为:

https://gist.github.com/satra/aa3d19a12b74e9ab7941

三、第三方包 d c o r dcor dcor实现

3.1安装 d c o r dcor dcor包的正确方法

这个的难点在于安装 d c o r dcor dcor包的 c o n d a conda conda版本,我用pip install dcor总是报错,无法解决错误,也不是博客里提供的错误里类型。

经过一番探索,我确定了最终的安装方法:

conda install -c conda-forge dcor

这样能顺利安装成功!

 >>> a = [1,2,3,4,5]
 >>> b = np.array([1,2,9,4,4])
 >>> dcor.distance_correction(a, b)
    0.762676242417

具体的操作细节可以看官网:

https://dcor.readthedocs.io/en/latest/apilist.html

  • 11
    点赞
  • 41
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
在 C++ 中,Mat 是 OpenCV 库中表示图像和矩阵的数据结构,而 numpyPython 中表示矩阵和数组的数据结构。如果你需要将 C++ 中的 Mat 转换为 numpy 中的数组,可以使用以下代码: ```python import numpy as np import cv2 # 读取图像文件 img = cv2.imread("image.jpg") # 将 Mat 转换为 numpy 数组 img_array = np.array(img) # 输出数组的形状和数据类型 print("Array shape:", img_array.shape) print("Array data type:", img_array.dtype) ``` 在上面的代码中,我们首先使用 OpenCV 的 imread 函数读取图像文件,得到一个 Mat 对象。然后,使用 numpy 的 array 函数将该对象转换为 numpy 数组。最后,输出数组的形状和数据类型。 需要注意的是,这种方式会将图像中的所有通道(例如 RGB 通道)合并成一个数组。如果你希望将每个通道分别保存在不同的数组中,可以将 numpy 数组的最后一个维度拆分成多个维度,例如: ```python # 将 Mat 转换为 numpy 数组 img_array = np.array(img).transpose(2, 0, 1) # 输出数组的形状和数据类型 print("Array shape:", img_array.shape) print("Array data type:", img_array.dtype) # 分别输出每个通道的数组 for i, channel in enumerate(("B", "G", "R")): print(f"{channel} channel:") print(img_array[i]) ``` 在上面的代码中,我们使用 numpy 的 transpose 函数将 numpy 数组的最后一个维度拆分成三个维度,分别对应于 RGB 通道。然后,输出数组的形状和数据类型,并分别输出每个通道的数组。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

旅途中的宽~

你的鼓励将是我创作的最大动力

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

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

打赏作者

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

抵扣说明:

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

余额充值