转自:https://blog.csdn.net/AlexMerer/article/details/74908435
https://blog.csdn.net/huangfei711/article/details/78456165
建议查看原文。
最早接触pearson相关系数时,是和同学一起搞数学建模,当时也是需要一种方法评价两组数据之间的相关性,于是找到了皮尔森(pearson)相关系数和斯皮尔曼(spearman)相关系数。其实,还有一种相关系数肯德尔(kendall)相关系数。在这三大相关系数中,spearman和kendall属于等级相关系数亦称为“秩相关系数”,是反映等级相关程度的统计分析指标。今天暂时用不到,所以现在只做pearson的相关研究。
首先放上公式:
公式定义为: 两个连续变量(X,Y)的pearson相关性系数(Px,y)等于它们之间的协方差cov(X,Y)除以它们各自标准差的乘积(σX,σY)。系数的取值总是在-1.0到1.0之间,接近0的变量被成为无相关性,接近1或者-1被称为具有强相关性。
皮尔森相关系数是衡量线性关联性的程度,p的一个几何解释是其代表两个变量的取值根据均值集中后构成的向量之间夹角的余弦。
根据以上公式,python3实现代码:
def pearson(vector1, vector2):
n = len(vector1)
#simple sums
sum1 = sum(float(vector1[i]) for i in range(n))
sum2 = sum(float(vector2[i]) for i in range(n))
#sum up the squares
sum1_pow = sum([pow(v, 2.0) for v in vector1])
sum2_pow = sum([pow(v, 2.0) for v in vector2])
#sum up the products
p_sum = sum([vector1[i]*vector2[i] for i in range(n)])
#分子num,分母den
num = p_sum - (sum1*sum2/n)
den = math.sqrt((sum1_pow-pow(sum1, 2)/n)*(sum2_pow-pow(sum2, 2)/n))
if den == 0:
return 0.0
return num/den
现在,用两个向量测试一下:
vector1 = [2,7,18,88,157,90,177,570]
vector2 = [3,5,15,90,180, 88,160,580]
运行结果为0.998,可见这两组数是高度正相关的。
现在用股票数据试下:
with open('hs300_399300.csv', 'r') as db01:
reader = csv.DictReader(db01)
column1 = [float(row['收盘价']) for row in reader]
# 再次读取全部文件需要将文件指针移到文件开始处
db01.seek(0)
reader = csv.DictReader(db01)
column2 = [float(row['最高价']) for row in reader]
# 取前30天的数据
list1 = column1[:30]
list2 = column2[:30]
print(pearson(list1, list2))
pearson系数为0.986,表明收盘价和最高价竟然高度正相关。分析原因:基数大(3600),数据变化小(变动不超过三位数)。
接下来用seaborn.jointplot()画图。jointplot是画两个变量或者单变量的图像,是对JointGrid类的实现。x,y为DataFrame中的列名或者是两组数据,data指向dataframe ,kind是你想要画图的类型,stat_func 用于计算统计量关系的函数,kind 的类型scatter,reg,resid,kde,hex.
# 之前一直遇到utf-8不能识别报错,后来的转换方法还是在国外论坛找到的,如下
import csv
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
stock = pd.read_csv("hs300_399300a.csv", index_col=0, encoding="gbk")
sns.jointplot(x="收盘价", y="最高价", data=stock, kind="reg")
plt.show()
只能这样上传图片,先凑合看看,先将csv文件截取了前30条数据,然后jointplot画图的类型从左到右分别为reg,kde,hex.图像更加直观,收盘价和最高价果然是高度正相关,原因基数太大,每日变化幅度太小。
=================================================================================
要理解 Pearson 相关系数,首先要理解协方差(Covariance)。协方差表示两个变量 X,Y 间相互关系的数字特征,其计算公式为:
COV(X,Y)=1n−1∑n1(Xi−X¯¯¯¯)(Yi−Y¯¯¯¯)COV(X,Y)=1n−1∑1n(Xi−X¯)(Yi−Y¯)
当 Y = X 时,即与方差相同。当变量 X,Y 的变化趋势一致时,如果某个 XiXi 大于 X¯¯¯¯X¯,相应的 YiYi 也大于 Y¯¯¯¯Y¯;如果某个 XiXi 小于 X¯¯¯¯X¯,相应的 YiYi 也小于 Y¯¯¯¯Y¯,那么 COV(X,Y)COV(X,Y) 就是正值,当变量 X,Y 的变化趋势相反时,那么 COV(X,Y)COV(X,Y) 就是负值。
Pearson 相关系数公式如下:
COR(X,Y)=∑n1(Xi−X¯¯¯¯¯)(Yi−Y¯¯¯¯)∑n1(Xi−X¯¯¯¯¯)2∑n1(Yi−Y¯¯¯¯)2√COR(X,Y)=∑1n(Xi−X¯)(Yi−Y¯)∑1n(Xi−X¯)2∑1n(Yi−Y¯)2
由公式可知,Pearson 相关系数是用协方差除以两个变量的标准差得到的,虽然协方差能反映两个随机变量的相关程度(协方差大于0的时候表示两者正相关,小于0的时候表示两者负相关),但其数值上受量纲的影响很大,不能简单地从协方差的数值大小给出变量相关程度的判断。为了消除这种量纲的影响,于是就有了相关系数的概念。
当两个变量的方差都不为零时,相关系数才有意义,相关系数的取值范围为[-1,1]。《数据挖掘导论》中给了一个很形象的图来说明相关度大小与相关系数之间的联系:
由上图可以总结,当相关系数为1时,成为完全正相关;当相关系数为-1时,成为完全负相关;相关系数的绝对值越大,相关性越强;相关系数越接近于0,相关度越弱。
关于皮尔逊相关系数的编程计算,MATLAB 中提供了现有的函数:
cor = corr(Matrix,'type','Pearson')
1
Matrix 参数即为需要计算的矩阵。
=================================================================================
matlab实现
function coeff = myPearson(X , Y)
% 本函数实现了皮尔逊相关系数的计算操作
%
% 输入:
% X:输入的数值序列
% Y:输入的数值序列
%
% 输出:
% coeff:两个输入数值序列X,Y的相关系数
%
if length(X) ~= length(Y)
error('两个数值数列的维数不相等');
return;
end
fenzi = sum(X .* Y) - (sum(X) * sum(Y)) / length(X);
fenmu = sqrt((sum(X .^2) - sum(X)^2 / length(X)) * (sum(Y .^2) - sum(Y)^2 / length(X)));
coeff = fenzi / fenmu;
end %函数myPearson结束
=================================================================================