大数据JAVA实现 基于皮尔逊相关系数的相似度

来源:互联网 发布:淘宝怎么开店充话费 编辑:程序博客网 时间:2024/05/16 16:57
皮尔逊相关系数理解有两个角度 
1. 按照高中数学水平来理解, 它很简单, 可以看做将两组数据首先做Z分数处理之后, 然后两组数据的乘积和除以样本数Z分数一般代表正态分布中, 数据偏离中心点的距离.等于变量减掉平均数再除以标准差.(就是高考的标准分类似的处理)标准差则等于变量减掉平均数的平方和,再除以样本数,最后再开方. 
所以, 根据这个最朴素的理解,我们可以将公式依次精简为: 

公式

2.按照大学的线性数学水平来理解, 它比较复杂一点,可以看做是两组数据的向量夹角的余弦.

皮尔逊相关的约束条件 
1. 两个变量间有线性关系 
2. 变量是连续变量 
3. 变量均符合正态分布,且二元分布也符合正态分布 
4. 两变量独立


皮尔逊相关系数的值域等级

0.8-1.0 极强相关 
0.6-0.8 强相关 
0.4-0.6 中等程度相关 
0.2-0.4 弱相关 
0.0-0.2 极弱相关或无相关

以上内容看起来太过晦涩,不如看个手算的示例让人更容易懂 
使用维基中的例子

例如,假设五个国家的国民生产总值分别是1、2、3、5、8(单位10亿美元),又假设这五个国家的贫困比例分别是11%、12%、13%、15%、18%。

那么需要被计算的两个数据样本分别是

x->(1,2,3,5,8) 
y->(0.11,0.12,0.13,0.15,0.18)

接下来计算两个数据样本的平均值

x的平均值为3.8 
y的平均值为0.138

接下来计算皮尔逊系数的分子

用大白话来写就是: 
(1-3.8)*(0.11-0.138)=0.0784 
(2-3.8)*(0.12-0.138)=0.0324 
(3-3.8)*(0.13-0.138)=0.0064 
(5-3.8)*(0.15-0.138)=0.0144 
(8-3.8)*(0.18-0.138)=0.1764 
0.0784+0.0324+0.0064+0.0144+0.1764=0.308

同理分号下面的分别是 
sum((x-mean(x))^2)=30.8 sum((y-mean(y))^2)= 0.00308

sum((x-mean(x))^2)=30.8 
(1-3.8)^2=7.84 #平方 
(2-3.8)^2=3.24 #平方 
(3-3.8)^2=0.64 #平方 
(5-3.8)^2=1.44 #平方 
(8-3.8)^2=17.64 #平方 
7.84+3.24+0.64+1.44+17.64=30.8

同理,求得:

sum((y-mean(y))^2)= 0.00308

然后再开平方根,分别是:

30.8^0.5=5.549775 0.00308^0.5=0.05549775

用分子除以分母,就计算出最终结果:

0.308/(5.549775*0.05549775)=1


最后附上Java代码

DataNode

package org.data.entity;import java.util.Arrays;public class DataNode {    double[] datas;    public double[] getDatas() {        return datas;    }    public void setDatas(double[] datas) {        this.datas = datas;    }    @Override    public String toString() {        return "DataNode [datas=" + Arrays.toString(datas) + "]";    }    public DataNode() {    }    public DataNode(double[] datas) {        super();        this.datas = datas;    }}

PearsonCorrelationScore

package org.data.util;import org.data.entity.DataNode;/** * 计算两个样本数据之间的皮尔逊系数 * @author Joe * */public class PearsonCorrelationScore {    private double[] xData;    private double[] yData;    private double xMeans;    private double yMeans;    /**     * 求解皮尔逊的分子     */    private double numerator;    /**     * 求解皮尔逊系数的分母     */    private double denominator;    /**     * 计算最后的皮尔逊系数     */    private double pearsonCorrelationScore;    public PearsonCorrelationScore(DataNode x, DataNode y) {        //先获取DataNode的数据        this.xData = x.getDatas();        this.yData = y.getDatas();        //拿到两个数据的平均值        this.xMeans = this.getMeans(xData);        this.yMeans = this.getMeans(yData);        //计算皮尔逊系数的分子
 this.numerator = this.generateNumerator();        //计算皮尔逊系数的分母        this.denominator = this.generateDenomiator();        //计算皮尔逊系数        this.pearsonCorrelationScore = this.numerator / this.denominator;    }    /**     * 生成分子     * @return 分子     */    private double generateNumerator() {        double sum = 0.0;        for (int i = 0; i < xData.length; i++) {            sum += (xData[i] - xMeans) * (yData[i] - yMeans);        }        return sum;    }    /**     * 生成分母     * @return 分母     */    private double generateDenomiator() {        double xSum = 0.0;        for (int i = 0; i < xData.length; i++) {            xSum += (xData[i] - xMeans) * (xData[i] - xMeans);        }        double ySum = 0.0;        for (int i = 0; i < yData.length; i++) {            ySum += (yData[i] - yMeans) * (yData[i] - yMeans);
  }        return Math.sqrt(xSum) * Math.sqrt(ySum);    }    /**     * 根据给定的数据集进行平均值计算     * @param datas 数据集     * @return 给定数据集的平均值     */    private double getMeans(double[] datas) {        double sum = 0.0;        for (int i = 0; i < datas.length; i++) {            sum += datas[i];        }        return sum / datas.length;    }    public double getPearsonCorrelationScore() {        return this.pearsonCorrelationScore;    }}

最后代码测试

package org.data.client;import org.data.entity.DataNode;import org.data.util.PearsonCorrelationScore;public class PearsonTest {    public static void main(String[] args) {        DataNode x = new DataNode(new double[] {1, 2, 3, 5, 8});        DataNode y = new DataNode(new double[] {0.11, 0.12, 0.13, 0.15, 0.18});        PearsonCorrelationScore score = new PearsonCorrelationScore(x, y);        System.out.println(score.getPearsonCorrelationScore());    }}

转载地址


原创粉丝点击