在自然科学领域中,皮尔逊相关系数广泛用于度量两个变量之间的相关程度,其值介于-1与1之间。它是由卡尔·皮尔逊从弗朗西斯·高尔顿在19世纪80年代提出的一个相似却又稍有不同的想法演变而来的。这个相关系数也称作“皮尔逊积矩相关系数”。
图1中,几组 的点集,以及各个点集中 和 之间的相关系数。我们可以发现相关系数反映的是变量之间的线性关系和相关性的方向(第一排),而不是相关性的斜率(中间),也不是各种非线性关系(第三排)。请注意:中间的图中斜率为0,但相关系数是没有意义的,因为此时变量 是0。
其中E是数学期望,cov表示协方差,N表示变量取值的个数。
相关系数的值介于–1与+1之间,即–1≤r≤+1。其性质如下:
- 当r>0时,表示两变量正相关,r<0时,两变量为负相关。 当|r|=1时,表示两变量为完全线性相关,即为函数关系。
- 当r=0时,表示两变量间无线性相关关系。
- 当0<|r|<1时,表示两变量存在一定程度的线性相关。且|r|越接近1,两变量间线性关系越密切;|r|越接近于0,表示两变量的线性相关越弱。
- 一般可按三级划分:|r|<0.4为低度线性相关;0.4≤|r|<0.7为显著性相关;0.7≤|r|<1为高度线性相关。
当两个变量的标准差都不为零时,相关系数才有定义,皮尔逊相关系数适用于:
- 两个变量之间是线性关系,都是连续数据。
- 两个变量的总体是正态分布,或接近正态的单峰分布。
- 两个变量的观测值是成对的,每对观测值之间相互独立。
公式二:代码实现
/**
* 皮尔逊相关度系数计算
* @param ratingOne
* @param ratingTwo
* @return
*/
public Double getPearsonBydim(List<Double> ratingOne, List<Double> ratingTwo) {
try {
if(ratingOne.size() != ratingTwo.size()) {//两个变量的观测值是成对的,每对观测值之间相互独立。
if(ratingOne.size() > ratingTwo.size()) {//保留小的处理大
List<Double> temp = ratingOne;
ratingOne = new ArrayList<>();
for(int i=0;i<ratingTwo.size();i++) {
ratingOne.add(temp.get(i));
}
}else {
List<Double> temp = ratingTwo;
ratingTwo = new ArrayList<>();
for(int i=0;i<ratingOne.size();i++) {
ratingTwo.add(temp.get(i));
}
}
}
double sim = 0D;//最后的皮尔逊相关度系数
double commonItemsLen = ratingOne.size();//操作数的个数
double oneSum = 0D;//第一个相关数的和
double twoSum = 0D;//第二个相关数的和
double oneSqSum = 0D;//第一个相关数的平方和
double twoSqSum = 0D;//第二个相关数的平方和
double oneTwoSum = 0D;//两个相关数的乘积和
for(int i=0;i<ratingOne.size();i++) {//计算
double oneTemp = ratingOne.get(i);
double twoTemp = ratingTwo.get(i);
//求和
oneSum += oneTemp;
twoSum += twoTemp;
oneSqSum += Math.pow(oneTemp, 2);
twoSqSum += Math.pow(twoTemp, 2);
oneTwoSum += oneTemp*twoTemp;
}
double num = (commonItemsLen*oneTwoSum) - (oneSum*twoSum);
double den = Math.sqrt((commonItemsLen * oneSqSum - Math.pow(oneSum, 2)) * (commonItemsLen * twoSqSum - Math.pow(twoSum, 2)));
sim = (den == 0) ? 1 : num / den;
return sim;
} catch (Exception e) {
return null;
}
}
公式三:代码实现
public static Double getPearsonBydim2(List<Double> ratingOne, List<Double> ratingTwo) {
if(ratingOne.size() != ratingTwo.size()) {//两个变量的观测值是成对的,每对观测值之间相互独立。
return null;
}
double sim = 0D;//最后的皮尔逊相关度系数
double commonItemsLen = ratingOne.size();//操作数的个数
double oneSum = 0D;//第一个相关数的和
double twoSum = 0D;//第二个相关数的和
for(int i=0; i<commonItemsLen; i++) {
oneSum += ratingOne.get(i);
twoSum += ratingTwo.get(i);
}
double oneAvg = oneSum/commonItemsLen;//第一个相关数的平均值
double twoAvg = twoSum/commonItemsLen;//第二个相关数的平均值
double sonSum = 0D;
double tempOne = 0D;
double tempTwo = 0D;
for(int i=0; i<commonItemsLen; i++) {
sonSum += (ratingOne.get(i)-oneAvg)*(ratingTwo.get(i)-twoAvg);
tempOne += Math.pow((ratingOne.get(i)-oneAvg), 2);
tempTwo += Math.pow((ratingTwo.get(i)-twoAvg), 2);
}
double fatherSum = Math.sqrt(tempOne * tempTwo);
sim = (fatherSum == 0) ? 1 : sonSum / fatherSum;
return sim;
}
公式四:代码实现
public static Double getPearsonBydim3(List<Double> ratingOne, List<Double> ratingTwo) {
if(ratingOne.size() != ratingTwo.size()) {//两个变量的观测值是成对的,每对观测值之间相互独立。
return null;
}
double sim = 0D;//最后的皮尔逊相关度系数
double commonItemsLen = ratingOne.size();//操作数的个数
double oneSum = 0D;//第一个相关数的和
double twoSum = 0D;//第二个相关数的和
double onePSum = 0D;//第一个相关数平方的和
double twoPSum = 0D;//第二个相关数平方的和
double oneTwoSum = 0D;
for(int i=0; i<commonItemsLen; i++) {
oneSum += ratingOne.get(i);
twoSum += ratingTwo.get(i);
oneTwoSum += ratingOne.get(i) * ratingTwo.get(i);
onePSum += Math.pow(ratingOne.get(i), 2);
twoPSum += Math.pow(ratingTwo.get(i), 2);
}
double sonSum = oneTwoSum-((oneSum*twoSum)/commonItemsLen);
double fatherSum = Math.sqrt((onePSum-(Math.pow(oneSum, 2)/commonItemsLen))*(twoPSum-(Math.pow(twoSum, 2)/commonItemsLen)));
sim = (fatherSum == 0) ? 1 : sonSum / fatherSum;
return sim;
}
感谢博主:幽灵工作室参考
http://blog.csdn.net/u010670689/article/details/41895105