JAVA实现基于皮尔逊相关系数的相似度详解

网友投稿 432 2023-03-11


JAVA实现基于皮尔逊相关系数的相似度详解

最近在看《集体智慧编程》,相比其他机器学习的书籍,这本书有许多案例,更贴近实际,而且也很适合我们这种准备学习machinelearning的小白。

这本书我觉得不足之处在于,里面没有对算法的公式作讲解,而是直接用代码去实现,所以给想具体了解该算法带来了不便,所以想写几篇文章来做具体的说明。以下是第一篇,对皮尔逊相关系数作讲解,并采用了自己比较熟悉的java语言做实现。

皮尔逊数学公式如下,来自维基百科。

其中,E是数学期望,cov表示协方差,\sigma_X和\sigma_Y是标准差。

化简后得:

皮尔逊相似度计算的算法还是很简单的,实现起来也不难。只要求变量X、Y、乘积XY,X的平方,Y的平方的和。我的代码所使用的数据测试集来自《集体智慧编程》一书。代码如下:

package pearsonCorrelationScore;

import java.util.ArrayList;

import java.util.HashMap;

import java.util.List;

import java.util.Map;

import java.util.Map.Entry;

/**

* @author shenchao

*

* 皮尔逊相关度评价

*

* 以《集体智慧编程》一书用户评价相似度数据集做测试

*/

public class PearsonCorrelationScore {

private Map> dataset = null;

public PearsonCorrelationScore() {

initDataSet();

}

/**

* 初始化数据集

*/

private void initDataSet() {

dataset = new HashMap>();

// 初始化Lisa Rose 数据集

Map roseMap = new HashMap();

roseMap.put("Lady in the water", 2.5);

roseMap.put("Snakes on a Plane", 3.5);

roseMap.put("Just My Luck", 3.0);

roseMap.put("Superman Returns", 3.5);

roseMap.put("You, Me and Dupree", 2.5);

roseMap.put("The Night Listener", 3.0);

dataset.put("Lisa Rose", roseMap);

// 初始化Jack Matthews 数据集

Map jackMap = new HashMap();

jackMap.put("Lady in the water", 3.0);

jackMap.put("Snakes on a Plane", 4.0);

jackMap.put("Superman Returns", 5.0);

jackMap.put("You, Me and Dupree", 3.5);

jackMap.put("The Night Listener", 3.0);

dataset.put("Jack Matthews", jackMap);

// 初始化Jack Matthews 数据集

Map geneMap = new HashMap();

geneMap.put("Lady in the water", 3.0);

geneMap.put("Snakes on a Plane", 3.5);

geneMap.put("Just My Luck", 1.5);

geneMap.put("Superman Returns", 5.0);

geneMap.put("You, Me and DupvojDZWree", 3.5);

geneMap.put("The Night Listener", 3.0);

dataset.put("Gene Seymour", geneMap);

}

public Map> getDataSet() {

return dataset;

}

/**

* @param person1

* name

* @param person2

* name

* @return 皮尔逊相关度值

*/

public double sim_pearson(String person1, String person2) {

// 找出双方都评论过的电影,(皮尔逊算法要求)

List list = new ArrayList();

for (Entry p1 : dataset.gethttp://(person1).entrySet()) {

if (dataset.get(person2).containsKey(p1.getKey())) {

list.add(p1.getKey());

}

}

double sumX = 0.0;

double sumY = 0.0;

double sumX_Sq = 0.0;

double sumY_Sq = 0.0;

double sumXY = 0.0;

int N = list.size();

for (String name : list) {

Map p1Map = dataset.get(person1);

Map p2Map = dataset.get(person2);

sumX += p1Map.get(name);

sumY += p2Map.get(name);

sumX_Sq += Math.pow(p1Map.get(name), 2);

sumY_Sq += Math.pow(p2Map.get(name), 2);

sumXY += p1Map.get(name) * p2Map.get(name);

}

double numerator = sumXY - sumX * sumY / N;

double denominator = Math.sqrt((sumX_Sq - sumX * sumX / N)

* (sumY_Sq - sumY * sumY / N));

// 分母不能为0

if (denominator == 0) {

return 0;

}

return numerator / denominator;

}

public static void main(String[] args) {

PearsonCorrelationScore pearsonCorrelationScore = new PearsonCorrelationScore();

System.out.println(pearsonCorrelationScore.sim_pearson("Lisa Rose",

"Jack Matthews"));

}

}

将各个测试集的数据反映到二维坐标面中,如下所示:

上述程序求得的值实际上就为该直线的斜率。其斜率的区间在[-1,1]之间,其绝对值的大小反映了两者相似度大小,斜率越大,相似度越大,当相似度为1时,该直线为一条对角线。

总结

以上就是本文关于JAVA实现基于皮尔逊相关系数的相似度详解的全部内容,希望对大家有所帮助。如有不足之处,欢迎留言指出。感谢朋友们对本站的支持!


版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:基于Vue框架vux组件库实现上拉刷新功能
下一篇:拼团接口测试用例设计(拼团功能测试点编写)
相关文章

 发表评论

暂时没有评论,来抢沙发吧~