协同过滤I2I的简单实现

基于物品的协同过滤是目前业界应用最多的算法。
可以通过下面公式定义物品的相似度:
w i , j = ∣ N ( i ) ∩ N ( j ) ∣ ∣ N ( i ) ∣ ∣ N ( j ) ∣ w_{i,j}=\frac{|N(i) \cap N(j)|}{\sqrt{|N(i)||N(j)|}} wi,j=N(i)N(j) N(i)N(j)
这里,分母 ∣ N ( i ) ∩ N ( j ) ∣ |N(i) \cap N(j)| N(i)N(j)是同时喜欢物品i和物品j的的用户数。为了减轻热门物品的影响,除以 ∣ N ( i ) ∣ ∣ N ( j ) ∣ \sqrt{|N(i)||N(j)|} N(i)N(j) ,惩罚了被很多用户喜欢的热门商品。

笛卡尔乘积

同时喜欢物品i和物品j的用户数,可以使用笛卡尔乘积来实现。
笛卡尔乘积是指在数学中,两个集合 X X X Y Y Y的笛卡尔积(Cartesian product),又称直积,表示为 X × Y X×Y X×Y,第一个对象是 X X X的成员而第二个对象是 Y Y Y的所有可能有序对的其中一个成员。
假设集合A={a, b},集合B={0, 1, 2},则两个集合的笛卡尔积为{(a, 0), (a, 1), (a, 2), (b, 0), (b, 1), (b, 2)}。
笛卡尔乘积在SQL中通过JOIN来实现。

Jaccard距离

是衡量两个集合相似度的算法,用两个集合的交集元素的个数占并集元素个数的比例来表示。
J ( X , Y ) = ∣ X ∩ Y ∣ ∣ X ∪ Y ∣ J(X,Y)=\frac{|X \cap Y|}{|X \cup Y|} J(X,Y)=XYXY
集合可以用布尔向量表示,所以当向量为布尔值时,计算向量相似度可以使用Jaccard距离。

大概在3年前我有一段时间一直在思考频繁项集挖掘和CF的本质区别是什么,包括还在一个会上问过周涛,他当时给我的说法是频繁项集挖掘算法复杂度太高了,一般实际中很少应用,效果可能会稍好。现在让我来看没有本质区别,因为本质都是挖掘item的co-occurence,包括各种proximity的计算方式,全集的二跳节点是相同的(而二跳节点有几万个),不同的是top-k。swing和其他传统方法最大的区别就是除了co-occurence,它考虑了网络本身的外延结构。频繁项集挖掘除了Apriori,还有PFP-growth,但是计算量仍然庞大,数据集小可以尝试。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
协同过滤算法是一种常见的推荐算法,其中最流行的是基于用户的协同过滤和基于物品的协同过滤。以下是一个简单的基于用户的协同过滤算法的Java实现: ```java import java.util.*; public class UserBasedCF { // 用户数 private int userNum; // 物品数 private int itemNum; // 用户评分矩阵 private int[][] userItemMatrix; // 相似度矩阵 private double[][] similarityMatrix; // 构造函数 public UserBasedCF(int userNum, int itemNum, int[][] userItemMatrix) { this.userNum = userNum; this.itemNum = itemNum; this.userItemMatrix = userItemMatrix; similarityMatrix = new double[userNum][userNum]; } // 计算用户相似度 public void computeSimilarity() { for (int i = 0; i < userNum; i++) { for (int j = i + 1; j < userNum; j++) { double similarity = computeUserSimilarity(i, j); similarityMatrix[i][j] = similarity; similarityMatrix[j][i] = similarity; } } } // 计算用户之间的相似度 private double computeUserSimilarity(int user1, int user2) { int commonNum = 0; int sum1 = 0, sum2 = 0; int sumSq1 = 0, sumSq2 = 0; for (int i = 0; i < itemNum; i++) { if (userItemMatrix[user1][i] > 0 && userItemMatrix[user2][i] > 0) { commonNum++; int rating1 = userItemMatrix[user1][i]; int rating2 = userItemMatrix[user2][i]; sum1 += rating1; sum2 += rating2; sumSq1 += rating1 * rating1; sumSq2 += rating2 * rating2; } } if (commonNum == 0) { return 0; } double numerator = commonNum * (sum1 * sum2) - (sum1 * sum2); double denominator = Math.sqrt((commonNum * sumSq1 - sum1 * sum1) * (commonNum * sumSq2 - sum2 * sum2)); if (denominator == 0) { return 0; } return numerator / denominator; } // 预测用户对物品的评分 public double predictRating(int user, int item) { double numerator = 0; double denominator = 0; for (int i = 0; i < userNum; i++) { if (i != user && userItemMatrix[i][item] > 0) { double similarity = similarityMatrix[user][i]; numerator += similarity * userItemMatrix[i][item]; denominator += similarity; } } if (denominator == 0) { return 0; } return numerator / denominator; } } ``` 以上是一个简单的基于用户的协同过滤算法的Java实现。您可以根据您的需求进行修改和扩展。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值