欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

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

程序员文章站 2024-03-31 13:24:46
最近在看《》,相比其他机器学习的书籍,这本书有许多案例,更贴近实际,而且也很适合我们这种准备学习machinelearning的小白。 这本书我觉得不足之处在于,里面没有...

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

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

皮尔逊数学公式如下,来自*。

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

其中,e是数学期望,cov表示协方差,\sigma_x和\sigma_y是标准差。

化简后得:

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

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

皮尔逊相似度计算的算法还是很简单的,实现起来也不难。只要求变量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<string, map<string, double>> dataset = null;
	public pearsoncorrelationscore() {
		initdataset();
	}
	/**
* 初始化数据集
*/
	private void initdataset() {
		dataset = new hashmap<string, map<string, double>>();
		// 初始化lisa rose 数据集
		map<string, double> rosemap = new hashmap<string, double>();
		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<string, double> jackmap = new hashmap<string, double>();
		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<string, double> genemap = new hashmap<string, double>();
		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 dupree", 3.5);
		genemap.put("the night listener", 3.0);
		dataset.put("gene seymour", genemap);
	}
	public map<string, map<string, double>> getdataset() {
		return dataset;
	}
	/**
* @param person1
*      name
* @param person2
*      name
* @return 皮尔逊相关度值
*/
	public double sim_pearson(string person1, string person2) {
		// 找出双方都评论过的电影,(皮尔逊算法要求)
		list<string> list = new arraylist<string>();
		for (entry<string, double> p1 : dataset.get(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<string, double> p1map = dataset.get(person1);
			map<string, double> 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"));
	}
}

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

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

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

总结

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