Apache Mahout之协同过滤原理与实践(基于用户)

摘自Apache Mahout之协同过滤原理与实践

协同过滤算法之基于计算用户之间相似度

三种方法实现:

  //余弦相似度
  UserSimilarity userSimilarity = new UncenteredCosineSimilarity(dataModel);
  //欧几里得相似度
  UserSimilarity userSimilarity1 = new EuclideanDistanceSimilarity(dataModel);
  //皮尔森相似度
  UserSimilarity userSimilarity2 = new PearsonCorrelationSimilarity(dataModel);

流程:

1、数据准备

alice.txt文件:用户ID,物品ID,用户对物品的评分

1,101,5
1,102,3
1,103,4
1,104,4
2,101,3
2,102,1
2,103,2
2,104,3
2,105,3
3,101,4
3,102,3
3,103,4
3,104,3
3,105,5
4,101,3
4,102,3
4,103,1
4,104,5
4,105,4
5,101,1
5,102,5
5,103,5
5,104,2
5,105,1

2、代码实现

pom.xml中导入Hadoop Mahout算法库

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">

    <modelVersion>4.0.0</modelVersion>
    <groupId>com.leboop</groupId>
    <artifactId>mahout</artifactId>
    <version>1.0-SNAPSHOT</version>

    <properties>
        <!-- mahout版本号 -->
        <mahout.version>0.13.0</mahout.version>
    </properties>

    <dependencies>
        <!-- mahout -->
        <dependency>
            <groupId>org.apache.mahout</groupId>
            <artifactId>mahout-integration</artifactId>
            <version>${mahout.version}</version>
        </dependency>
    </dependencies>

</project>

推荐程序中,我们使用皮尔森系数计算用户相似度

1、将文件数据转换成数据模型
dataModel = new FileDataModel(new File(filePath));

2、用户相似度定义
//余弦相似度
UserSimilarity userSimilarity = new UncenteredCosineSimilarity(dataModel);
//欧几里得相似度
UserSimilarity userSimilarity1 = new EuclideanDistanceSimilarity(dataModel);
//皮尔森相似度
UserSimilarity userSimilarity2 = new PearsonCorrelationSimilarity(dataModel);

3、定义用户的2最近邻
long[] userN = userNeighborhood.getUserNeighborhood(userID);

4、定义推荐引擎
Recommender recommender = new GenericUserBasedRecommender(dataModel,userNeighborhood,userSimilarity2);

5、可通过通过两个迭代器计算任何两个用户的相似度输出查看

6、获取userID的N-最近邻
long[] userN = userNeighborhood.getUserNeighborhood(userID);

7、获取推荐物品,指定获取个数
List<RecommendedItem> recommendedItems = recommender.recommend(userID,2);

8、可遍历输出物品
import org.apache.mahout.cf.taste.common.TasteException;
import org.apache.mahout.cf.taste.impl.common.LongPrimitiveIterator;
import org.apache.mahout.cf.taste.impl.model.file.FileDataModel;
import org.apache.mahout.cf.taste.impl.neighborhood.NearestNUserNeighborhood;
import org.apache.mahout.cf.taste.impl.recommender.GenericUserBasedRecommender;
import org.apache.mahout.cf.taste.impl.similarity.EuclideanDistanceSimilarity;
import org.apache.mahout.cf.taste.impl.similarity.PearsonCorrelationSimilarity;
import org.apache.mahout.cf.taste.impl.similarity.UncenteredCosineSimilarity;
import org.apache.mahout.cf.taste.neighborhood.UserNeighborhood;
import org.apache.mahout.cf.taste.recommender.RecommendedItem;
import org.apache.mahout.cf.taste.recommender.Recommender;
import org.apache.mahout.cf.taste.similarity.UserSimilarity;

import java.io.File;
import java.io.IOException;
import java.util.Arrays;
import java.util.List;

public class test {
    public static void main(String[]args){

        //用户-物品-评分文件路径
        String filePath = "E:\\data\\alice.txt";

        //数据模型
        FileDataModel dataModel = null;

        try {
            //文件数据转换成数据模型
            dataModel = new FileDataModel(new File(filePath));

            /*
            用户相似度定义
             */

            //余弦相似度
            UserSimilarity userSimilarity = new UncenteredCosineSimilarity(dataModel);
            //欧几里得相似度
            UserSimilarity userSimilarity1 = new EuclideanDistanceSimilarity(dataModel);
            //皮尔森相似度
            UserSimilarity userSimilarity2 = new PearsonCorrelationSimilarity(dataModel);

            //定义用户的2最近邻
            UserNeighborhood userNeighborhood = new NearestNUserNeighborhood(2,userSimilarity2,dataModel);

            //定义推荐引擎
            Recommender recommender = new GenericUserBasedRecommender(dataModel,userNeighborhood,userSimilarity2);

            //从数据模型中获取所有用户的ID迭代器
            LongPrimitiveIterator usersIterator = dataModel.getUserIDs();

            //通过迭代器遍历所有用户ID
            while(usersIterator.hasNext()){
                System.out.println("=======================================");
                //用户ID
                long userID = usersIterator.nextLong();
                //用户ID迭代器
                LongPrimitiveIterator otherusersIterator = dataModel.getUserIDs();
                //相当于两个for循环,遍历用户ID,计算任何两个用户的相似度
                while(otherusersIterator.hasNext()){
                    Long otherUserID = otherusersIterator.nextLong();
                    System.out.println("用户 " + userID
                    + " 与用户 "+ otherUserID + " 的相似度为 "
                    + userSimilarity2.userSimilarity(userID,otherUserID));
                }

                //userID的N-最近邻
                long[] userN = userNeighborhood.getUserNeighborhood(userID);
                //用户userID的推荐物品,最多推荐两个
                List<RecommendedItem> recommendedItems = recommender.recommend(userID,2);
                System.out.println("用户 " + userID + " 的2-最近邻是 " + Arrays.toString(userN));
                if(recommendedItems.size()>0){
                    for (RecommendedItem item : recommendedItems){
                        System.out.println("推荐的物品 " + item.getItemID()
                        + "预测评分是 " + item.getValue());
                    }
                }
                else{
                    System.out.println("无任何物品推荐");
                }
            }


        } catch (IOException e) {
            e.printStackTrace();
        } catch (TasteException e) {
            e.printStackTrace();
        }
    }
}

输出如下: 

=======================================
用户 1 与用户 1 的相似度为 0.9999999999999998
用户 1 与用户 2 的相似度为 0.8528028654224417
用户 1 与用户 3 的相似度为 0.7071067811865475
用户 1 与用户 4 的相似度为 0.0
用户 1 与用户 5 的相似度为 -0.7921180343813393
用户 1 的2-最近邻是 [2, 3]
推荐的物品 105预测评分是 3.9065998
=======================================
用户 2 与用户 1 的相似度为 0.8528028654224417
用户 2 与用户 2 的相似度为 1.0
用户 2 与用户 3 的相似度为 0.4677071733467446
用户 2 与用户 4 的相似度为 0.4899559349388647
用户 2 与用户 5 的相似度为 -0.9001487972234673
用户 2 的2-最近邻是 [1, 4]
无任何物品推荐
=======================================
用户 3 与用户 1 的相似度为 0.7071067811865475
用户 3 与用户 2 的相似度为 0.4677071733467422
用户 3 与用户 3 的相似度为 1.0
用户 3 与用户 4 的相似度为 -0.16116459280507703
用户 3 与用户 5 的相似度为 -0.466569474815843
用户 3 的2-最近邻是 [1, 2]
无任何物品推荐
=======================================
用户 4 与用户 1 的相似度为 0.0
用户 4 与用户 2 的相似度为 0.489955934938866
用户 4 与用户 3 的相似度为 -0.16116459280507558
用户 4 与用户 4 的相似度为 1.0
用户 4 与用户 5 的相似度为 -0.6415029025857746
用户 4 的2-最近邻是 [2, 1]
无任何物品推荐
=======================================
用户 5 与用户 1 的相似度为 -0.7921180343813393
用户 5 与用户 2 的相似度为 -0.9001487972234682
用户 5 与用户 3 的相似度为 -0.466569474815843
用户 5 与用户 4 的相似度为 -0.6415029025857751
用户 5 与用户 5 的相似度为 1.0
用户 5 的2-最近邻是 [3, 4]
无任何物品推荐

猜你喜欢

转载自blog.csdn.net/qq_38262266/article/details/90199233