协同过滤算法
协同过滤算法是一种基于用户或者物品的相似度来推荐相关商品的方法,它可以有效地解决商城系统中的信息过载问题。协同过滤算法的实践主要包括以下几个步骤:
- 数据收集和预处理。这一步需要从商城系统中获取用户的行为数据,如浏览、购买、评价等,然后进行一些必要的清洗和转换,以便后续的分析和计算。
- 相似度计算。这一步需要根据用户或者物品的特征或者行为,采用合适的相似度度量方法,如余弦相似度、皮尔逊相关系数、Jaccard 指数等,来计算用户之间或者物品之间的相似度矩阵。
- 推荐生成。这一步需要根据相似度矩阵和用户的历史行为,采用合适的推荐策略,如基于邻域的方法、基于模型的方法、基于矩阵分解的方法等,来生成针对每个用户的个性化推荐列表。
- 推荐评估和优化。这一步需要根据一些评价指标,如准确率、召回率、覆盖率、多样性等,来评估推荐系统的效果,并根据反馈信息和业务需求,进行一些参数调整和算法优化,以提高推荐系统的性能和用户满意度。
余弦相似度算法
余弦相似度,又称为余弦相似性,是通过计算两个向量的夹角余弦值来评估他们的相似度。余弦相似度将向量根据坐标值,绘制到向量空间中,如最常见的二维空间。
余弦相似度衡量的是 2 个向量间的夹角大小,通过夹角的余弦值表示结果,因此 2 个向量的余弦相似度为:
分子为向量 A 与向量 B 的点乘,分母为二者各自的 L2 相乘,即将所有维度值的平方相加后开方。
余弦相似度的取值为[-1,1],值越大表示越相似。
其中 A 与 B 表达向量(x1,y1)(x1,y1)与向量(x2,y2)(x2,y2)。
分子为 A 与 B 的点乘,分母为二者各自的 L2 相乘,即将所有维度值的平方相加后开方。
/**
* 计算向量之间的余弦相似度
*
* @param xs
* @param xs
* @return double
*/
private static double cosineSimilarity(List<Integer> xs, List<Integer> ys) {
double dotProduct = 0;
double norm1 = 0;
double norm2 = 0;
for (int i = 0; i < xs.size(); i++) {
Integer x = xs.get(i);
Integer y = ys.get(i);
dotProduct += x * y;
norm1 += Math.pow(x, 2);
norm2 += Math.pow(y, 2);
}
return dotProduct / (Math.sqrt(norm1) * Math.sqrt(norm2));
}
皮尔逊相关系数
皮尔森相关系数也称皮尔森积矩相关系数(Pearson product-moment correlation coefficient) ,是一种线性相关系数,是最常用的一种相关系数。记为 r,用来反映两个变量 X 和 Y 的线性相关程度,r 值介于-1 到 1 之间,绝对值越大表明相关性越强。
https://www.cnblogs.com/aspiration2016/p/15365882.html
public static double pearsonRelate(List<Integer> xs, List<Integer> ys) {
int n = xs.size();
double Ex = xs.stream().mapToDouble(x -> x).sum();
double Ey = ys.stream().mapToDouble(y -> y).sum();
double Ex2 = xs.stream().mapToDouble(x -> Math.pow(x, 2)).sum();
double Ey2 = ys.stream().mapToDouble(y -> Math.pow(y, 2)).sum();
double Exy = IntStream.range(0, n).mapToDouble(i -> xs.get(i) * ys.get(i)).sum();
double numerator = Exy - Ex * Ey / n;
double denominator = Math.sqrt((-Math.pow(Ex, 2) / n) * (Ey2 - Math.pow(Ey, 2) / n));
if (denominator == 0 || Double.isNaN(numerator) || Double.isNaN(denominator)) {
return 0.0;
}
return numerator / denominator;
}