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

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

协同过滤算法之基于计算物品之间相似度

方法:

//余弦相似度
ItemSimilarity itemSimilarity = new UncenteredCosineSimilarity(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>

推荐程序中,我们使用余弦相似度计算物品相似度


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.GenericItemBasedRecommender;
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.model.DataModel;
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.ItemSimilarity;
import org.apache.mahout.cf.taste.similarity.UserSimilarity;


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


/**
 * 推荐思路
 * 1、读取用户-物品-评分数据,转换成推荐数据模型
 * 2、定义物品相似度(余弦相似度、皮尔森相似度等)
 * 3、预测评分
 * 4、使用推荐引擎推荐物品
 */

public class BasedItemRecommendationTest {

    public static void main(String[] args) {
        //用户-物品-评分数据文件
        String filePath = "E:\\data\\alice.txt";
        
        //数据模型
        DataModel dataModel = null;

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

            /**
             * 物品相似度定义
             */

            //余弦相似度
            ItemSimilarity itemSimilarity = new UncenteredCosineSimilarity(dataModel);
            //欧几里得相似度
            //ItemSimilarity itemSimilarity= new EuclideanDistanceSimilarity(dataModel);
            //皮尔森相似度
            //ItemSimilarity itemSimilarity = new PearsonCorrelationSimilarity(dataModel);

            //定义推荐引擎
            Recommender recommender =new GenericItemBasedRecommender(dataModel, itemSimilarity);

            //获取物品迭代器
            LongPrimitiveIterator itemIDIterator = dataModel.getItemIDs();

            //遍历所有物品
            while(itemIDIterator.hasNext()){
                System.out.println("==================================================");
                Long itermID=itemIDIterator.next();
                LongPrimitiveIterator otherItemIDIterator=dataModel.getItemIDs();
                //打印物品相似度
                while (otherItemIDIterator.hasNext()){
                    Long otherItermID=otherItemIDIterator.next();
                    System.out.println("物品 "+itermID+" 与物品 "+otherItermID+" 的相似度为: "+itemSimilarity.itemSimilarity(itermID,otherItermID));
                }
            }

            //获取用户迭代器
            LongPrimitiveIterator userIDIterator =dataModel.getUserIDs();

            //遍历用户
            while(userIDIterator.hasNext()){
                //获取用户
                Long userID=userIDIterator.next();
                //获取用户userID的推荐列表
                List<RecommendedItem> itemList= recommender.recommend(userID,2);
                if(itemList.size()>0){
                    for(RecommendedItem item:itemList){
                        System.out.println("用户 "+userID+" 推荐物品 "+item.getItemID()+",物品评分 "+item.getValue());
                    }
                }else {
                    System.out.println("用户 "+userID+" 无任何物品推荐");
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

输出结果如下:

==================================================

物品 101 与物品 101 的相似度为: 0.9999999999999999

物品 101 与物品 102 的相似度为: 0.7802595923450996

物品 101 与物品 103 的相似度为: 0.8197822947299412

物品 101 与物品 104 的相似度为: 0.9433700705169152

物品 101 与物品 105 的相似度为: 0.9941002434954168

==================================================

物品 102 与物品 101 的相似度为: 0.7802595923450996

物品 102 与物品 102 的相似度为: 1.0

物品 102 与物品 103 的相似度为: 0.9420196895802699

物品 102 与物品 104 的相似度为: 0.8479844150302361

物品 102 与物品 105 的相似度为: 0.7388505791113108

==================================================

物品 103 与物品 101 的相似度为: 0.8197822947299412

物品 103 与物品 102 的相似度为: 0.9420196895802699

物品 103 与物品 103 的相似度为: 1.0

物品 103 与物品 104 的相似度为: 0.7840250892042882

物品 103 与物品 105 的相似度为: 0.7226101216384172

==================================================

物品 104 与物品 101 的相似度为: 0.9433700705169152

物品 104 与物品 102 的相似度为: 0.8479844150302361

物品 104 与物品 103 的相似度为: 0.7840250892042882

物品 104 与物品 104 的相似度为: 0.9999999999999999

物品 104 与物品 105 的相似度为: 0.9395584757365169

==================================================

物品 105 与物品 101 的相似度为: 0.9941002434954168

物品 105 与物品 102 的相似度为: 0.7388505791113108

物品 105 与物品 103 的相似度为: 0.7226101216384172

物品 105 与物品 104 的相似度为: 0.9395584757365169

物品 105 与物品 105 的相似度为: 0.9999999999999999

用户 1 推荐物品 105,物品评分 4.0751815

用户 2 无任何物品推荐

用户 3 无任何物品推荐

用户 4 无任何物品推荐

用户 5 无任何物品推荐
 

猜你喜欢

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