Browse Source

协同推荐算法java版本测试。
2019年5月15日11:30:44

herryhaixiao 6 years ago
parent
commit
af63d8257e

+ 12 - 0
elab-db/src/test/java/com.db.service/ITrainItemService.java

@@ -0,0 +1,12 @@
+package com.db.service;
+
+import com.db.service.model.TrainItem;
+import com.elab.core.services.ICommonService;
+
+/**
+ * @author liuhx
+ * @create 2019/04/02 10:15
+ * @email liuhx@elab-plus.com
+ **/
+public interface ITrainItemService extends ICommonService<TrainItem> {
+}

+ 14 - 0
elab-db/src/test/java/com.db.service/ITrainUserService.java

@@ -0,0 +1,14 @@
+package com.db.service;
+
+import com.db.service.model.TrainUser;
+import com.elab.core.services.ICommonService;
+
+/**
+ * @author liuhx
+ * @create 2019/04/02 10:14
+ * @email liuhx@elab-plus.com
+ **/
+public interface ITrainUserService extends ICommonService<TrainUser> {
+
+
+}

+ 14 - 0
elab-db/src/test/java/com.db.service/dao/ITrainItemDao.java

@@ -0,0 +1,14 @@
+package com.db.service.dao;
+
+import com.db.service.model.TrainItem;
+import com.elab.core.aop.annotations.XmlGroupName;
+import com.elab.core.dao.IBaseDaoSupport;
+
+/**
+ * @author liuhx
+ * @create 2019/04/02 10:36
+ * @email liuhx@elab-plus.com
+ **/
+@XmlGroupName("trainItem")
+public interface ITrainItemDao extends IBaseDaoSupport<TrainItem> {
+}

+ 14 - 0
elab-db/src/test/java/com.db.service/dao/ITrainUserDao.java

@@ -0,0 +1,14 @@
+package com.db.service.dao;
+
+import com.db.service.model.TrainUser;
+import com.elab.core.aop.annotations.XmlGroupName;
+import com.elab.core.dao.IBaseDaoSupport;
+
+/**
+ * @author liuhx
+ * @create 2019/04/02 10:24
+ * @email liuhx@elab-plus.com
+ **/
+@XmlGroupName("TrainUser")
+public interface ITrainUserDao extends IBaseDaoSupport<TrainUser> {
+}

+ 26 - 0
elab-db/src/test/java/com.db.service/impl/TrainItemServiceImpl.java

@@ -0,0 +1,26 @@
+package com.db.service.impl;
+
+import com.db.service.ITrainItemService;
+import com.db.service.dao.ITrainItemDao;
+import com.db.service.model.TrainItem;
+import com.elab.core.dao.IBaseDaoSupport;
+import com.elab.core.services.impl.CommonServiceAdaptor;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+/**
+ * @author liuhx
+ * @create 2019/04/02 10:35
+ * @email liuhx@elab-plus.com
+ **/
+@Service
+public class TrainItemServiceImpl extends CommonServiceAdaptor<TrainItem> implements ITrainItemService {
+
+    @Autowired
+    private ITrainItemDao trainItemDao;
+
+    @Override
+    protected IBaseDaoSupport<TrainItem> getBaseDaoSupport() {
+        return trainItemDao;
+    }
+}

+ 26 - 0
elab-db/src/test/java/com.db.service/impl/TrainUserServiceImpl.java

@@ -0,0 +1,26 @@
+package com.db.service.impl;
+
+import com.db.service.ITrainUserService;
+import com.db.service.dao.ITrainUserDao;
+import com.db.service.model.TTest;
+import com.db.service.model.TrainUser;
+import com.elab.core.dao.IBaseDaoSupport;
+import com.elab.core.services.impl.CommonServiceAdaptor;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+/**
+ * @author liuhx
+ * @create 2019/04/02 10:23
+ * @email liuhx@elab-plus.com
+ **/
+@Service
+public class TrainUserServiceImpl extends CommonServiceAdaptor<TrainUser> implements ITrainUserService {
+
+    @Autowired
+    private ITrainUserDao trainUserDao;
+    @Override
+    protected IBaseDaoSupport<TrainUser> getBaseDaoSupport() {
+        return trainUserDao;
+    }
+}

+ 108 - 0
elab-db/src/test/java/com.db.service/main/HxCase.java

@@ -0,0 +1,108 @@
+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.concurrent.atomic.AtomicInteger;
+import java.util.stream.Collectors;
+
+/**
+ * @author liuhx
+ * @create 2019/04/02 16:22
+ * @email liuhx@elab-plus.com
+ **/
+@RunWith(SpringJUnit4ClassRunner.class)  //使用junit4进行测试
+@ContextConfiguration
+        ({"classpath:applicationContext-*.xml",})
+public class HxCase {
+    @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;
+    }
+
+    @Test
+    public void getUserItemSize() throws Exception {
+        List<TrainUser> resultList = findByUserList();
+        //建立物品到用户的倒排表 eg: a A B
+        Map<Integer, List<TrainUser>> itemList = resultList.stream()
+                .filter(trainUser -> ObjectUtils.isNotEmpty(trainUser.getItemId()))
+                .collect(Collectors.groupingBy(TrainUser::getItemId));
+
+        Map<Integer, List<TrainUser>> userList = resultList.stream()
+                .filter(trainUser -> ObjectUtils.isNotEmpty(trainUser.getUserId()))
+                .collect(Collectors.groupingBy(TrainUser::getUserId));
+
+
+        System.out.println(itemList.size());
+        int userSize = userList.size();
+        /*建立用户稀疏矩阵,用于用户相似度计算【相似度矩阵】*/
+        int[][] sparseMatrix = new int[userSize][userSize];
+
+        Map<Integer, Integer> userItemLength = new HashMap<>();//存储每一个用户ID对应的不同物品总数
+        Map<Integer, Integer> userID = new HashMap<>();//辅助存储每一个用户的用户ID映射
+        Map<Integer, Integer> idUser = new HashMap<>();//辅助存储每一个ID对应的用户映射
+        Set<Integer> items = new HashSet<>();//辅助存储物品集合,这里对应存的是物品的id
+
+        AtomicInteger count = new AtomicInteger();
+        userList.entrySet().iterator().forEachRemaining(user->{
+            userItemLength.put(user.getKey(), user.getValue().size());
+            userID.put(user.getKey(), count.intValue());//用户ID与稀疏矩阵建立对应关系
+            idUser.put(count.intValue(), user.getKey());
+            count.addAndGet(1);
+        });
+        itemList.entrySet().iterator().forEachRemaining(item->{
+            items.add(item.getKey());
+        });
+
+        //计算相似度矩阵【稀疏】
+        Set<Map.Entry<Integer, List<TrainUser>>> entrySet = itemList.entrySet();
+        Iterator<Map.Entry<Integer, List<TrainUser>>> iterator = entrySet.iterator();
+        while(iterator.hasNext()) {
+            List<TrainUser> commonUsers = iterator.next().getValue();
+            for (TrainUser user_u : commonUsers) {
+                for (TrainUser user_v : commonUsers) {
+                    if(user_u.getUserId().equals(user_v.getUserId())){
+                        continue;
+                    }
+                    sparseMatrix[userID.get(user_u.getUserId())][userID.get(user_v.getUserId())] += 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){//遍历每一件物品
+            List<TrainUser> users = itemList.get(item);//得到购买当前物品的所有用户集合
+            List<Integer> integers = users.stream().filter(trainUser -> ObjectUtils.isNotEmpty(trainUser.getUserId())).map(TrainUser::getUserId).collect(Collectors.toList());
+            if(!integers.contains(recommendUser)){//如果被推荐用户没有购买当前物品,则进行推荐度计算
+                double itemRecommendDegree = 0.0;
+                for(TrainUser user: users){
+                    itemRecommendDegree += sparseMatrix[userID.get(recommendUser)][userID.get(user.getUserId())]/Math.sqrt(userItemLength.get(recommendUser)*userItemLength.get(user.getUserId()));//推荐度计算
+                }
+                System.out.println("The item "+item+" for "+recommendUser +"'s recommended degree:"+itemRecommendDegree);
+            }
+        }
+    }
+}

+ 143 - 0
elab-db/src/test/java/com.db.service/main/RecommandCase.java

@@ -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);
+            }
+        }
+    }
+}
+*/

+ 56 - 0
elab-db/src/test/java/com.db.service/model/TrainItem.java

@@ -0,0 +1,56 @@
+package com.db.service.model;
+
+import javax.persistence.Id;
+import javax.persistence.Table;
+
+/**
+ * @author liuhx
+ * @create 2019/04/01 18:48
+ * @email liuhx@elab-plus.com
+ **/
+@Table(name = "tianchi_fresh_comp_train_item_2w")
+public class TrainItem {
+    @Id
+    private Integer id;
+
+    @javax.persistence.Column(name="item_id")
+    private Integer itemId;
+
+    @javax.persistence.Column(name="item_geohash")
+    private String itemGeohash;
+
+    @javax.persistence.Column(name="item_category")
+    private String itemCategory;
+
+    public Integer getId() {
+        return id;
+    }
+
+    public void setId(Integer id) {
+        this.id = id;
+    }
+
+    public Integer getItemId() {
+        return itemId;
+    }
+
+    public void setItemId(Integer itemId) {
+        this.itemId = itemId;
+    }
+
+    public String getItemGeohash() {
+        return itemGeohash;
+    }
+
+    public void setItemGeohash(String itemGeohash) {
+        this.itemGeohash = itemGeohash;
+    }
+
+    public String getItemCategory() {
+        return itemCategory;
+    }
+
+    public void setItemCategory(String itemCategory) {
+        this.itemCategory = itemCategory;
+    }
+}

+ 91 - 0
elab-db/src/test/java/com.db.service/model/TrainUser.java

@@ -0,0 +1,91 @@
+package com.db.service.model;
+
+import javax.persistence.Id;
+import javax.persistence.Table;
+
+/**
+ * @author liuhx
+ * @create 2019/04/01 18:52
+ * @email liuhx@elab-plus.com
+ **/
+@Table(name = "tianchi_fresh_comp_train_user_2w")
+public class TrainUser {
+
+    @Id
+    private Integer id;
+
+    @javax.persistence.Column(name="user_id")
+    private Integer userId;
+
+    @javax.persistence.Column(name="item_id")
+    private Integer itemId;
+
+    @javax.persistence.Column(name="behavior_type")
+    private String behaviorType;
+
+    @javax.persistence.Column(name="user_geohash")
+    private String userGeohash;
+
+    @javax.persistence.Column(name="item_category")
+    private String itemCategory;
+
+    @javax.persistence.Column(name="time")
+    private String time;
+
+
+    public Integer getId() {
+        return id;
+    }
+
+    public void setId(Integer id) {
+        this.id = id;
+    }
+
+    public Integer getUserId() {
+        return userId;
+    }
+
+    public void setUserId(Integer userId) {
+        this.userId = userId;
+    }
+
+    public Integer getItemId() {
+        return itemId;
+    }
+
+    public void setItemId(Integer itemId) {
+        this.itemId = itemId;
+    }
+
+    public String getBehaviorType() {
+        return behaviorType;
+    }
+
+    public void setBehaviorType(String behaviorType) {
+        this.behaviorType = behaviorType;
+    }
+
+    public String getUserGeohash() {
+        return userGeohash;
+    }
+
+    public void setUserGeohash(String userGeohash) {
+        this.userGeohash = userGeohash;
+    }
+
+    public String getItemCategory() {
+        return itemCategory;
+    }
+
+    public void setItemCategory(String itemCategory) {
+        this.itemCategory = itemCategory;
+    }
+
+    public String getTime() {
+        return time;
+    }
+
+    public void setTime(String time) {
+        this.time = time;
+    }
+}