|
@@ -0,0 +1,143 @@
|
|
|
+/*
|
|
|
+package com.db.service.main;
|
|
|
+
|
|
|
+import com.db.service.ITrainItemService;
|
|
|
+import com.db.service.ITrainUserService;
|
|
|
+import com.db.service.model.TrainItem;
|
|
|
+import com.db.service.model.TrainUser;
|
|
|
+import com.elab.core.utils.ObjectUtils;
|
|
|
+import org.junit.Test;
|
|
|
+import org.junit.runner.RunWith;
|
|
|
+import org.springframework.beans.factory.annotation.Autowired;
|
|
|
+import org.springframework.test.context.ContextConfiguration;
|
|
|
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
|
|
+
|
|
|
+import java.util.*;
|
|
|
+import java.util.stream.Collectors;
|
|
|
+
|
|
|
+*/
|
|
|
+/**
|
|
|
+ * @author liuhx
|
|
|
+ * @create 2019/04/02 10:09
|
|
|
+ * @email liuhx@elab-plus.com
|
|
|
+ **//*
|
|
|
+
|
|
|
+@RunWith(SpringJUnit4ClassRunner.class) //使用junit4进行测试
|
|
|
+@ContextConfiguration
|
|
|
+ ({"classpath:applicationContext-*.xml",})
|
|
|
+public class RecommandCase {
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ private ITrainUserService trainUserService;
|
|
|
+ @Autowired
|
|
|
+ private ITrainItemService trainItemService;
|
|
|
+
|
|
|
+ public List<TrainUser> findByUserList() throws Exception {
|
|
|
+ TrainUser user = new TrainUser();
|
|
|
+ List<TrainUser> list = trainUserService.selectByList(user);
|
|
|
+ return list;
|
|
|
+ }
|
|
|
+
|
|
|
+ public List<TrainItem> findByItemList() throws Exception {
|
|
|
+ TrainItem item = new TrainItem();
|
|
|
+ List<TrainItem> list = trainItemService.selectByList(item);
|
|
|
+ return list;
|
|
|
+ }
|
|
|
+
|
|
|
+ @Test
|
|
|
+ public void getUserItemSize() throws Exception {
|
|
|
+ List<TrainUser> userList = findByUserList();
|
|
|
+ Map<Integer, List<TrainUser>> resultList = userList.stream()
|
|
|
+ .filter(trainUser -> ObjectUtils.isNotEmpty(trainUser.getItemId()))
|
|
|
+ .collect(Collectors.groupingBy(TrainUser::getItemId));
|
|
|
+ System.out.println(resultList.size());
|
|
|
+ int userSize = resultList.size();
|
|
|
+ */
|
|
|
+/*建立用户稀疏矩阵,用于用户相似度计算【相似度矩阵】*//*
|
|
|
+
|
|
|
+ int[][] sparseMatrix = new int[userSize][userSize];
|
|
|
+ Map<Integer, Integer> userItemLength = new HashMap<>();//存储每一个用户对应的不同物品总数 eg: A 3
|
|
|
+ Map<Integer, Set<Integer>> itemUserCollection = new HashMap<>();//建立物品到用户的倒排表 eg: a A B
|
|
|
+ Set<Integer> items = new HashSet<>();//辅助存储物品集合
|
|
|
+ Map<Integer, Integer> userID = new HashMap<>();//辅助存储每一个用户的用户ID映射
|
|
|
+ Map<Integer, Integer> idUser = new HashMap<>();//辅助存储每一个ID对应的用户映射
|
|
|
+
|
|
|
+ for(int i = 0; i < userSize ; i++) { */
|
|
|
+/*依次处理userSize个用户 *//*
|
|
|
+
|
|
|
+ int userId = resultList.entrySet().stream().collect(Collectors.toList()).get(i).getKey();
|
|
|
+ Object[] objects = resultList.entrySet().stream().collect(Collectors.toList()).get(i).getValue().toArray();
|
|
|
+ int length = objects.length;
|
|
|
+ userItemLength.put(userId, length-1);//eg: A 3
|
|
|
+// String[] user_item = scanner.nextLine().split(" ");
|
|
|
+// int length = user_item.length;
|
|
|
+// userItemLength.put(user_item[0], length-1);//eg: A 3
|
|
|
+ userID.put(userId, i);//用户ID与稀疏矩阵建立对应关系
|
|
|
+ idUser.put(i, userId);
|
|
|
+// //建立物品--用户倒排表
|
|
|
+ for (int j = 1; j < length; j ++) {
|
|
|
+ int itemId = ((TrainUser)objects[j]).getItemId();
|
|
|
+ if(items.contains(itemId)){//如果已经包含对应的物品--用户映射,直接添加对应的用户
|
|
|
+ itemUserCollection.get(itemId).add(userId);
|
|
|
+ }else{//否则创建对应物品--用户集合映射
|
|
|
+ items.add(itemId);
|
|
|
+ itemUserCollection.put(itemId, new HashSet<Integer>());//创建物品--用户倒排关系
|
|
|
+ itemUserCollection.get(itemId).add(userId);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+// //计算指定用户recommendUser的物品推荐度
|
|
|
+// for(String item: items){//遍历每一件物品
|
|
|
+// Set<String> users = itemUserCollection.get(item);//得到购买当前物品的所有用户集合
|
|
|
+// if(!users.contains(recommendUser)){//如果被推荐用户没有购买当前物品,则进行推荐度计算
|
|
|
+// double itemRecommendDegree = 0.0;
|
|
|
+// for(String user: users){
|
|
|
+// itemRecommendDegree += sparseMatrix[userID.get(recommendUser)][userID.get(user)]/Math.sqrt(userItemLength.get(recommendUser)*userItemLength.get(user));//推荐度计算
|
|
|
+// }
|
|
|
+// System.out.println("The item "+item+" for "+recommendUser +"'s recommended degree:"+itemRecommendDegree);
|
|
|
+// }
|
|
|
+// }
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ //计算相似度矩阵【稀疏】
|
|
|
+ Set<Map.Entry<Integer, Set<Integer>>> entrySet = itemUserCollection.entrySet();
|
|
|
+ Iterator<Map.Entry<Integer, Set<Integer>>> iterator = entrySet.iterator();
|
|
|
+ while(iterator.hasNext()) {
|
|
|
+ Set<Integer> commonUsers = iterator.next().getValue();
|
|
|
+ for (Integer user_u : commonUsers) {
|
|
|
+ for (Integer user_v : commonUsers) {
|
|
|
+ if(user_u.equals(user_v)){
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ sparseMatrix[userID.get(user_u)][userID.get(user_v)] += 1;//计算用户u与用户v都有正反馈的物品总数
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ int recommendUser = 1;
|
|
|
+ //计算用户之间的相似度【余弦相似性】
|
|
|
+ int recommendUserId = userID.get(recommendUser);
|
|
|
+ for (int j = 0;j < sparseMatrix.length; j++) {
|
|
|
+ if(j != recommendUserId){
|
|
|
+ System.out.println(idUser.get(recommendUserId)+"--"+idUser.get(j)+"相似度:"+sparseMatrix[recommendUserId][j]/Math.sqrt(userItemLength.get(idUser.get(recommendUserId))*userItemLength.get(idUser.get(j))));
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ //计算指定用户recommendUser的物品推荐度
|
|
|
+ for(Integer item: items){//遍历每一件物品
|
|
|
+ Set<Integer> users = itemUserCollection.get(item);//得到购买当前物品的所有用户集合
|
|
|
+ if(!users.contains(recommendUser)){//如果被推荐用户没有购买当前物品,则进行推荐度计算
|
|
|
+ double itemRecommendDegree = 0.0;
|
|
|
+ for(Integer user: users){
|
|
|
+ itemRecommendDegree += sparseMatrix[userID.get(recommendUser)][userID.get(user)]/Math.sqrt(userItemLength.get(recommendUser)*userItemLength.get(user));//推荐度计算
|
|
|
+ }
|
|
|
+ System.out.println("The item "+item+" for "+recommendUser +"'s recommended degree:"+itemRecommendDegree);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+*/
|