# UserCF **Repository Path**: zhangzhishun/UserCF ## Basic Information - **Project Name**: UserCF - **Description**: 基于用户的协同过滤算法 - **Primary Language**: Java - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 7 - **Forks**: 4 - **Created**: 2020-04-18 - **Last Updated**: 2023-03-05 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # 算法思路整理 ## 思想 ​ 当一个用户 A 需要个性化推荐时,可以先找到和他兴趣相似的用户群体 G,然后把 G购买过的、并且 A 没有听说过的物品推荐给 A ## 解决问题思路 ​ 我们最终要计算的是向用户A推荐```A的全部相似用户购买的全部车辆中用户A没有购买的```车辆的概率,所以我们需要计算以下几点: 1. 设A的相似用户购买的全部车辆,为集合N ​ 首先使用余弦相似度公式:(设 N(u) 为用户 u 喜欢的物品集合) ![在这里插入图片描述](https://img-blog.csdnimg.cn/20200328143848734.png) ​ 寻找相似用户集合G,然后即可获取到相似用户车辆集合N 2. 设N中A没有购买的车辆集合,为集合M,对集合M进行遍历计算推荐概率 ​ 针对集合N的车辆进行遍历,找到M,然后使用公式:(```S(u, k)```包含和用户u兴趣最接近的K个用户,```N(i)```是对物品i有购买的用户集合,```w_uv```是用户u和用户v的相似度,```r_vi ```表示用户 v 对 i 的喜欢程度,默认1) ![在这里插入图片描述](https://img-blog.csdnimg.cn/20200328143926195.png) ​ 计算推荐概率 ## 算法实现思路 在这里插入图片描述 1. 建立车辆-用户倒排表 1.1 过程描述 ​ 针对所有用户,遍历每一个用户的购买记录,以购买记录的车辆为key,以用户ID为value向```itemUserCollection```集合中插入数据 1.2 相似度矩阵核心代码: ```java // items:存储车辆集合 eg: a,b,c,d,e // length:某一用户的购买车辆数目 // itemUserCollection:存储车辆到用户的倒排表 eg: a A B for(int j = 0; j < length; j ++){ // 如果已经包含对应的车辆--用户映射,直接添加对应的用户 if(items.contains(user_item[j])){ itemUserCollection.get(user_item[j]).add(entry.getKey().toString()); }else{ // 否则创建对应车辆--用户集合映射 items.add(user_item[j]); // 创建车辆--用户倒排关系 itemUserCollection.put(user_item[j], new HashSet<>()); itemUserCollection.get(user_item[j]).add(entry.getKey().toString()); } } ``` 1.3 执行结果 ​ ```itemUserCollection```存储车辆用户的倒排表,用于计算所有用户之间的相似度 ![在这里插入图片描述](https://img-blog.csdnimg.cn/20200328143902380.png) 2. 计算相似度矩阵 2.1 过程描述 ​ 从存储车辆到用户的倒排表```itemUserCollection```遍历,使用两层循环遍历```itemUserCollection```的value 2.2 相似度矩阵核心代码: ```java // 计算用户u与用户v都有正反馈的车辆总数 // sparseMatrix:存储用户两两之间的相似度 // userID.get(user_u):根据用户名获取到的用户ID,例如要对矩阵中AB位置执行加1,必须知道AB在矩阵中对应位置为01和10 // userID.get(user_v):同上 sparseMatrix[userID.get(user_u)][userID.get(user_v)] += 1; ``` 2.3 执行结果 ​ 假设```itemUserCollection```集合内存在一条数据:```a:A B C ```那么对```AB AC BA BC CA CB```对应位置上的相似度矩阵执行加1 ![在这里插入图片描述](https://img-blog.csdnimg.cn/20200328143908353.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM2MjU0Njk5,size_16,color_FFFFFF,t_70) 3. 计算用户之间的相似度、所有相似用户ID、相似用户购买车辆集合 3.1 过程描述: ​ 直接遍历用于存储用户两两之间的相似度的矩阵```sparseMatrix```,计算目标用户和相似用户的相似度,如果相似度大于0,那么将该用户放入相似用户集合```similarUsers```,并将他喜欢的车辆全部放入相似用户喜欢车辆集合```similarUsersItems``` 3.2 公式: ![在这里插入图片描述](https://img-blog.csdnimg.cn/20200328143848734.png) 3.3 计算用户相似度核心代码: ```java // sparseMatrix:存储用户两两之间的相似度 // recommendUserId:根据用户获取存储的ID 比如被推送的用户是A,那么recommendUserId=0 // userItemLength.get(recommendUser):被推荐用户recommendUser喜欢的车辆数量 // userItemLength.get(idUser.get(j)):相似用户j喜欢的车辆的数量 double semblance = sparseMatrix[recommendUserId][j]/Math.sqrt(userItemLength.get(recommendUser)*userItemLength.get(idUser.get(j))); ``` 3.4 执行结果:```similarUsers```存储所有相似用户 ```similarUsersItems```存储所有相似用户购买的车辆 ![在这里插入图片描述](https://img-blog.csdnimg.cn/20200328143916951.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM2MjU0Njk5,size_16,color_FFFFFF,t_70) 4. 存储目标用户对车辆的偏好度按偏好度降序 ​ 4.1 过程描述 ​ 遍历所有车辆,如果被推荐用户没有购买该车辆,那么使用下面的公式计算推荐该车辆的概率。 ​ 4.2 计算某一车辆偏好度公式: ![在这里插入图片描述](https://img-blog.csdnimg.cn/20200328143926195.png) ​ 4.3 核心代码 ```java // sparseMatrix[userID.get(recommendUser)][userID.get(user)]:用户两两之间的相似度,用于分子 // Math.sqrt(userItemLength.get(recommendUser)*userItemLength.get(user)):两用户喜欢的车的数量的乘积再开方作为分母 itemRecommendDegree += sparseMatrix[userID.get(recommendUser)][userID.get(user)]/Math.sqrt(userItemLength.get(recommendUser)*userItemLength.get(user)); ``` 4.4 执行结果 ​ result存储目标用户对车辆的偏好度并按偏好度降序 ​ 最终推荐概率都保存到了result集合中,key为推荐的车辆,value为推荐概率