代码编织梦想

在这里插入图片描述

| 图源

  皮尔逊相关是计算两个变量之间线性相关关系,或者两个向量共线程度的常用指标,应返回衡量相关程度的r值,和相关显著程度的p值。我们熟知的工具包,如pandas,numpy和scipy等,只能计算单个变量x与变量y之间的相关值,或者多个变量两两相关的相关矩阵。当我们想要分别计算多个变量X与y之间的相关关系时,就需要自己手撕代码。如果觉得手撕代码太费头发,或者对代码不怎么精通,那么就往下看吧。笔者废了好大一把头发,基于numpy和scipy撕三个函数方法,帮你快速实现多个变量与y之间的相关关系,并同时返回r和p值。

copyright© 意疏:https://blog.csdn.net/sinat_35907936/article/details/123805702


单个变量与y的皮尔逊相关


  简单描述一下我们常用的求皮尔逊相关方法的使用。如果目标是求两个变量之间相关关系,并且需要返回p值,用scipy。如果是求多个变量两两相关的相关矩阵,用numpy和pandas,具体用什么,取决于输入是DataFrame还是numpy数组。

  假设我们有以下数据,变量x和变量y都具有100个观测值。

import numpy as np

np.random.seed(3)
x= 2 + np.random.random(100)
y = 1 + np.random.random(100)

  输入x,y,都是一维向量,其返回向量x与向量y的r和p值。对上述模拟数据求相关,如下。

import numpy as np
from scipy.stats import pearsonr

np.random.seed(3)
x= 2 + np.random.randn(100)
y = 1 + np.random.randn(100)
r, p = pearsonr(x, y)

print(r, p)
#-0.25690193664486277 0.009874914626309943

  输入就是DataFrame本身,函数计算表格中任意两列两两之间的相关值(注意一个变量的所有观测值放一列),最后返回一个相关矩阵,不包含p值。注意到该函数不包含y,要求x与y的相关关系,需要把x和y拼接在一起,再调用该方法。对上述模拟数据求相关,如下。

import numpy as np
import pandas as pd

np.random.seed(3)
x= 2 + np.random.randn(100)
y = 1 + np.random.randn(100)

# 拼接
xy = np.vstack((x, y)).T
pd_xy = pd.DataFrame(xy)

r_mat = pd_xy.corr()
print(r_mat)
#          0         1
# 0  1.000000 -0.256902
# 1 -0.256902  1.000000

r = np.array(r_mat.iloc[0,1].squeeze())
print(r)
# -0.25690193664486294

  该方法自由度比较高,输入X可以是向量或矩阵,输入y也可以是向量或者矩阵且不是必要参数,返回一个相关矩阵,不包含p值。当输入只有x时,效果与上述pandas相同(注意一个变量的所有观测值默认放一行,设置rowvar=False,一个变量的所有观测值将放一列),当x与y都存在时,函数会自动拼接x和y,形成xy,再求相关矩阵,相当于省去了pandas里拼接的步骤。对上述模拟数据求相关,如下。

import numpy as np

np.random.seed(3)
x= 2 + np.random.randn(100)
y = 1 + np.random.randn(100)

# 自动拼接
r_mat = np.corrcoef(x,y, rowvar=False)
print(r_mat)
# [[ 1.         -0.25690194]
# [-0.25690194  1.        ]]

r = r_mat[0,1].squeeze()
print(r)

#-0.2569019366448628

copyright© 意疏:https://blog.csdn.net/sinat_35907936/article/details/123805702


多个变量与y的皮尔逊相关


  假设我们有以下数据,X包含10个变量,每个变量1000个观测值,变量y包含1000个观测值。现在需要求X中每一个变量与y的皮尔逊相关,然后分别返回r和p。

import numpy as np

np.random.seed(3)

X = 2 + np.random.randn(1000,10)
y = 1 + np.random.randn(1000)
  • 循环单变量法——不推荐

  循环遍历所有的变量,这是最容易想到,最简单,却非常低效的方法。在变量很多的时候,这种方法的效率将远远低于后面两种方法。

# -*- coding: utf-8 -*-
"""
@author: CSDN 意疏
"""
import time
import numpy as np
from scipy.stats import pearsonr

def batch_pearsonr(X, y):
    
    X = np.array(X)
    y = np.array(y)
    cols = X.shape[1]

    p_list = []
    r_list = []
    
    for col in range(cols):
        r, p = pearsonr(X[:, col], y)
        p_list.append(p)
        r_list.append(r)
    
    return np.array(r_list), np.array(p_list)

if '__name == __main__':
    
    np.random.seed(3)
    
    X = 2 + np.random.randn(1000,100)
    y = 1 + np.random.randn(1000)
    
    st = time.time()
    r, p = batch_pearsonr(X, y)
    print(time.time()-st)
    print(r)
    print(p)
0.007961273193359375
[-0.0227441   0.00720729  0.01410081  ... -0.028843    0.05403485  0.00350507]
[0.47249521 0.81993201 0.65605162 ... 0.36221919 0.08766555 0.91185276]
  • 公式法——推荐

  由皮尔逊相关的公式,推出多个变量与y相关的公式,然后实现。都是矩阵乘法,加上numpy高效率,这种方法效率会远高于上述循环单变量法。
r = 1 N ∑ i = 1 N ( x i − x ‾ ) ( y i − y ‾ ) σ x σ y (1) \tag 1 r = \cfrac {\cfrac 1 N \sum^N_{i=1}(x_i - \overline x)(y_i- \overline y)} {\sigma_{\bold x} \sigma_{\bold y}} r=σxσyN1i=1N(xix)(yiy)(1)

= ( x − x ‾ ) T ( y − y ‾ ) N ∗ σ x σ y (2) \tag 2 = \cfrac {(\bold x- \overline x)^T( y - \overline y)} {N*\sigma_{\bold x} \sigma_{\bold y} } =Nσxσy(xx)T(yy)(2)

r = ( X − X ‾ ) T ( y − y ‾ ) N ∗ σ X σ y (3) \tag 3 \bold r= \cfrac {(\bold X- \overline X)^T(\bold y - \overline y)} {N*\sigma_{\bold X} \sigma_{\bold y} } r=NσXσy(XX)T(yy)(3)

  求p值参考了scipy源码,通过btdtr函数来实现。

# -*- coding: utf-8 -*-
"""
@author: CSDN 意疏
"""

import time
import numpy as np
from scipy.special import btdtr
    
def batch_pearsonr(X, y):
    
    X = np.array(X)
    y = np.array(y)
    N = X.shape[0]
    
    X_center = X - X.mean(axis=0)
    X_std = X.std(axis=0)
    y_center = y - y.mean()
    y_std = y.std()
    
    r = np.dot(y_center.T, X_center)/(N*X_std*y_std)
    r[r>1]=1
    r[r<-1]=-1
    
    ab = N/2 - 1
    p = 2*btdtr(ab, ab, 0.5*(1 - abs(np.float64(r))))
    
    return r, p

if '__name == __main__':
    
    np.random.seed(3)
    
    X = 2 + np.random.randn(1000,100)
    y = 1 + np.random.randn(1000)
    
    st = time.time()
    r, p = batch_pearsonr(X, y)
    print(time.time()-st)
    print(r)
    print(p)

  在只有100个变量的情况下,公式法比循环单变量法效率也要高近一个数量级。

0.000997304916381836
[-0.0227441   0.00720729  0.01410081 ... -0.028843    0.05403485  0.00350507]
[0.47249521 0.81993201 0.65605162 ... 0.36221919 0.08766555 0.91185276]
  • 相关矩阵法——在较少变量时推荐

  一个变量与其他所有变量的相关值,是包含在变量间两两相关得到的相关矩阵中的,就像上述基于numpy和pandas的单变量相关。那么只要把X和y拼接起来,形成Xy,就可以通过算相关矩阵的方式,得到y与X中每一个变量的相关值。由于y拼在X后面,所以相关矩阵最后一行就是y与Xy中每个变量的相关值,去掉最后一个自相关值,就可以得到y与X中每一个变量的相关值了。为了代码简洁性,此处用numpy而非pandas。

  numpy本身不返回p值,所以求p值参考了scipy源码,通过btdtr函数来实现。

# -*- coding: utf-8 -*-
"""
@author: CSDN 意疏
"""
import time
import numpy as np
from scipy.special import btdtr
    
def batch_pearsonr(X, y):
    
    N = X.shape[0]
    r_mat = np.corrcoef(X,y, rowvar=False)
    r = r_mat[-1,:-1].squeeze()
    ab = N/2 - 1
    p = 2*btdtr(ab, ab, 0.5*(1 - abs(np.float64(r))))
    return r, p

if '__name == __main__':
    
    np.random.seed(3)
    
    X = 2 + np.random.randn(1000,100)
    y = 1 + np.random.randn(1000)
    
    st = time.time()
    r, p = batch_pearsonr(X, y)
    print(time.time()-st)
    print(r)
    print(p)

  从模拟数据结果上看,虽然相关矩阵大量值都是白算的,但是它的效率却比循环单变量法高很多,与公式法相当,但赢在代码量少。不过当变量数目非常多的时候,这种方法效率可能比循环单变量法还低,因为涉及大量的不必要计算。

0.0010364055633544922
[-0.0227441   0.00720729  0.01410081 ... -0.028843 0.05403485  0.00350507]
[0.47249521 0.81993201 0.65605162 ... 0.36221919 0.08766555 0.91185276]

copyright© 意疏:https://blog.csdn.net/sinat_35907936/article/details/123805702


参考


https://blog.csdn.net/sinat_35907936/article/details/115253078?spm=1001.2014.3001.5501
https://github.com/scipy/scipy/blob/v1.8.0/scipy/stats/_stats_py.py#L3900-L4117

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/sinat_35907936/article/details/123805702

python数据可视化seaborn(二)—— 分布数据可视化-爱代码爱编程

这篇文章是Python可视化seaborn系列的第二篇文章,本文将详解seaborn如何探索数据的分布。 import numpy as np import pandas as pd import matplotlib.p

python数据可视化——分布数据可视化_weixin_44099558的博客-爱代码爱编程_python 地理数据可视化

这篇文章是Python可视化seaborn系列的第二篇文章,本文将详解seaborn如何探索数据的分布。 import numpy as np import pandas as pd import matplotlib.pyplot as plt import seaborn as sns % matplotlib inline sns.set(c

《大话脑影像》之:趣谈散点图与相关系数-爱代码爱编程

 最近不少读者对高大上的机器学习,动态脑网络,曲面形态指标共变网络感到爱不起,针对于此,我们特别推出一些基本的做脑功能的概念讲解,希望大家一步一步来,年轻人,不要动不动想一步登天,识得唔识得啊?      那今天我们就谈谈这个相关系数……. 说起相关系数,从字面上的含义就可看出,就是两个信号之间的相关性。但是你真正理解内在的机理吗? 结论放在最前面:

数据分析学习总结笔记14:A/B Test及Python实现-爱代码爱编程

文章目录 1 引言2 A/B Test的必要性3 统计形式主义的必要性4 假设检验入门4.1 z检验评估平均花费时间4.2 z检验评估平均花费时间4.3 Z检验评估转化率5 总结 1 引言 A/B Test,又称为对比测试,指的是一种实验技术,以确定根据一个选定的指标,新的设计是否带来改进。 在Web分析和UI用户体验中,这个想法是通过随机

scipy.stats.pearsonr - 皮尔森相关系数-爱代码爱编程

函数:pearsonr(x,y) 功能: 计算特征与目标变量之间的相关度 参数说明: 1)输入:x为特征,y为目标变量. 2)输出:r: 相关系数 [-1,1]之间,p-value: p值。 注: p值越小,表示相关系数越显著,一般p值在500个样本以上时有较高的可靠性。 示例: 数据 样本数:1000特征数:3(3维数

2020研究生数据建模C题总结-脑电信号分析判别-爱代码爱编程

前言 2020年研究生数学建模大赛上月结束,最终的比赛成绩还没有公布,现在是2020年10月,在此总结一下建模大赛的选题与成果。记录过去,展望未来。 我们团队选择C题,题目内容如下: 脑电信号按其产生的方式可分为诱发脑电信号和自发脑电信号。诱发脑电信号是通过某种外界刺激使大脑产生电位变化从而形成的脑电活动;自发脑电信号是指在没有外界特殊刺激下,大

python做数据分析有哪些优势-全网最全数据分析师面试干货-python篇-爱代码爱编程

以下内容如有借鉴,均在文章末尾附上原文章链接。 介于Python不是我目前的重点,本篇暂时只列出基础问题。 1.什么是Python?使用Python有什么好处? Python是一种编程语言,它有对象、模块、线程、异常处理和自动内存管理。 它简洁、简单、方便、容易扩展,有许多自带的数据结构,而且它开源。 2.什么是PEP8? PEP8是一个编程规范,内容是一

皮尔森相关系数的python实现_深入理解皮尔逊相关系数&python代码-爱代码爱编程

1.常见理解误区 (1)计算出变量A和变量B的皮尔逊相关系数为0,不代表A和B之间没有相关性,只能说明A和B之间不存在线性相关关系。 例:温度和冰淇淋销量之间的散点图像如下,可以发现大致成二次函数图像,随着温度升高,销量也会增加,达到峰值后,随着温度升高,销量反而下降。也就是说,销量和温度之间是有关系的。 不过,计算温度和销量之间的皮尔逊相关系数

数学建模用python分析gdp_数学建模--相关性分析及Python实现-爱代码爱编程

写在前面: 笔记为自行整理,内容出自课程《数学建模学习交流》,主讲人:清风 相关系数只是用来衡量两个变量线性相关程度的指标,因此,使用相关系数衡量相关性前需要确认变量间是线性相关的。 相关系数 import pandas as pd import numpy as np import matplotlib.pyplot as plt %m

数据分析进阶 - 相关分析(皮尔逊相关系数)-爱代码爱编程

相关分析 相关分析是研究两个或两个以上处于同等地位的随机变量间的相关关系的统计分析方法。通过对不同特征或数据间的关系进行分析,发现其中关键影响及驱动因素。在实际的工作应用中,常常用于特征的发现与选择。针对不同数据类型的变量,需要选用不同的检验方法,具体如下表所示 变量个数变量类型检验方法两个均为连续变量皮尔逊相关系数、简单线性回归两个均为有序分类变量M

脑功能影像分析之多体素模式识别(MVPA)(一)-爱代码爱编程

来源于网站 carney institute for brain science脑功能影像分析之多体素模式识别 一 数据集介绍 数据集下载 此文件夹包含以下内容: raw data for the 8 runs (run#.nii) pre-processed data for the 8 runs (run#.preproc.nii) stimulu

脑科学磁共振成像(MRI)初学者必看——功能脑网络、小世界网络、FDR校正、脑电信号频率变换、模板、假设检验、广义线性模型、独立成分分析、影像组学、任务态和静息态方法汇总-爱代码爱编程

磁共振成像初学者必看 一、浅谈功能脑网络二、不同模态脑网络的构建功能脑网络结构脑网络白质纤维束脑网络加权网络二值网络三、趣谈散点图与相关系数四、脑电信号频域变换五、fMRI中的FDR校正六、模板(mask)1、模板(mask )往往是与ROI联系在一起的2、mask作用的原理3、常见的mask七、假设检验和效果量八、组水平标准化九、由 ALFF 说

变量之间的相关性研究-爱代码爱编程

目录 1 什么是相关性?协方差及协方差矩阵相关系数(1)简单相关分析(2)偏相关分析(3)复相关分析(4)典型相关分析2 对已有数据的预分析2.1 绘制变量相关的热力图2.2 对热力图进行分析3 具体研究的展开3.1 车速 km/h与最低电池值(电压)的研究3.2 SOC(电池剩余电量)与总电压V的研究3.3 总电压V与最高温度值的研究4 总结

Python让Excel飞起来—批量进行数据分析-爱代码爱编程

目录 案例01 批量升序排序一个工作簿中的所有工作表  举一反三 批量排序多个工作簿中的数据 案例02 筛选一个工作簿中的所有工作表数据 举一反三 在一个工作簿中筛选单一类别数据 案例03 对多个工作簿中的工作表分别进行分类汇总 举一反三 批量分类汇总多个工作簿中的指定工作表 举一反三 将多个工作簿数据分类汇总到一个工作簿 案例04 对一个

注意,这十种常见统计错误,撰写论文时不要犯-爱代码爱编程

关注“心仪脑”查看更多脑科学知识的分 关键词:干货分享、论文 为了让科学研究的结论更有说服力,本文整理了十种科学文献中出现的一些最常见的统计错误。这些错误源于无效的实验设计、不恰当的分析或有缺陷的推理。本文就作者、审稿人和读者如何识别和解决这些错误提供建议,并希望在未来能够避免这些错误。 1.缺乏足够的控制条件/控制组(Absence of an a