原创

Mahout实现推荐系统示例-基于7.2万用户对1万部电影的百万级评价和10万个标签数据

温馨提示:
本文最后更新于 2020年05月08日,已超过 1,445 天没有更新。若文章内的图片失效(无法正常加载),请留言反馈或直接联系我

Mahout简介

地址:https://mahout.apache.org/

用于创建可扩展的高性能机器学习应用程序。

其实就是封装了机器学习的一些算法,供我们使用和扩展。

推荐示例:7.2万用户对1万部电影的百万级评价和10万个标签数据

数据下载地址:https://grouplens.org/datasets/movielens/10m/

数据说明:
ratings.dat:

所有评级都包含在文件中ratings.dat。该文件的每一行代表一个用户对一部电影的评级,其格式如下:

UserID::MovieID::Rating::Timestamp

该文件中的各行首先按UserID排序,然后在用户中按MovieID排序。

评分等级为5星级,以半星级为增量。

时间戳表示自1970年1月1日午夜协调世界时(UTC)起的秒数。

tags.dat:

所有标签都包含在文件中tags.dat。此文件的每一行代表一个用户将一个标签应用于一部电影,并具有以下格式:

UserID::MovieID::Tag::Timestamp

该文件中的各行首先按UserID排序,然后在用户中按MovieID排序。

标签是用户生成的有关电影的元数据。每个标签通常是一个单词或简短短语。特定标签的含义,价值和目的由每个用户确定。

时间戳表示自1970年1月1日午夜协调世界时(UTC)起的秒数。

movies.dat:

电影信息包含在文件中movies.dat。该文件的每一行代表一部电影,并具有以下格式:

MovieID::Title::Genres

MovieID是真实的MovieLens ID。

根据政策,电影标题的输入应与IMDB中的相同,包括发行年份。但是,它们是手动输入的,因此可能存在错误和不一致之处。

流派是用管道分隔的列表,并从以下列表中选择:

行动
冒险
动画
儿童的
喜剧
犯罪
记录
戏剧
幻想
黑色电影
恐怖
音乐
神秘
浪漫
科幻
惊悚片
战争
西

引入依赖:

    <dependencies>
        <!-- 示例mahout-examples包已经包含了以下的这些包,但是,还是正式开发肯定不是加这个包 -->
        <dependency>
            <groupId>org.apache.mahout</groupId>
            <artifactId>mahout-examples</artifactId>
            <version>${mahout.version}</version>
        </dependency>

        <!-- 需要引入mahout的包 -->
        <dependency>
            <groupId>org.apache.mahout</groupId>
            <artifactId>mahout-hdfs</artifactId>
            <version>${mahout.version}</version>
        </dependency>
        <dependency>
            <groupId>org.apache.mahout</groupId>
            <artifactId>mahout-mr</artifactId>
            <version>${mahout.version}</version>
        </dependency>
        <dependency>
            <groupId>org.apache.mahout</groupId>
            <artifactId>mahout-hdfs</artifactId>
            <version>${mahout.version}</version>
            <type>test-jar</type>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.apache.mahout</groupId>
            <artifactId>mahout-math</artifactId>
            <version>${mahout.version}</version>
        </dependency>
        <dependency>
            <groupId>org.apache.mahout</groupId>
            <artifactId>mahout-integration</artifactId>
            <version>${mahout.version}</version>
        </dependency>
        <!-- //需要引入mahout的包 -->
    </dependencies>

基于物品的推荐

package com.lzhpo.ma1.test2.movie;

import org.apache.mahout.cf.taste.impl.recommender.GenericItemBasedRecommender;
import org.apache.mahout.cf.taste.impl.similarity.PearsonCorrelationSimilarity;
import org.apache.mahout.cf.taste.model.DataModel;
import org.apache.mahout.cf.taste.recommender.RecommendedItem;
import org.apache.mahout.cf.taste.similarity.ItemSimilarity;
import org.apache.mahout.cf.taste.similarity.precompute.example.GroupLensDataModel;

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

/**
 * 基于物品的推荐
 * <p>
 * 数据类别:7.2万用户对1万部电影的百万级评价和10万个标签数据。
 * 数据模型下载地址:https://grouplens.org/datasets/movielens/10m/
 * </p>
 *
 * @author lzhpo
 */
public class BaseItemRecommender {
    public static void main(String[] args) throws Exception {
        //准备数据 这里是电影评分数据
        File file = new File("E:\\JavaCode\\MyProject\\Algorithm-Java\\mahout\\ma_demo1\\src\\main\\resources\\testFile\\movieData\\ml-10M100K\\ratings.dat");
        //将数据加载到内存中,GroupLensDataModel是针对开放电影评论数据的
        DataModel dataModel = new GroupLensDataModel(file);
        //计算相似度,相似度算法有很多种,欧几里得、皮尔逊等等。
        ItemSimilarity itemSimilarity = new PearsonCorrelationSimilarity(dataModel);
        //构建推荐器,协同过滤推荐有两种,分别是基于用户的和基于物品的,这里使用基于物品的协同过滤推荐
        GenericItemBasedRecommender recommender = new GenericItemBasedRecommender(dataModel, itemSimilarity);
        //给用户ID等于5的用户推荐10个与2398相似的商品
        List<RecommendedItem> recommendedItemList = recommender.recommendedBecause(5, 2398, 10);
        //打印推荐的结果
        System.out.println("使用基于物品的协同过滤算法");
        System.out.println("根据用户5当前浏览的商品2398,推荐10个相似的商品");
        for (RecommendedItem recommendedItem : recommendedItemList) {
            System.out.println(recommendedItem);
        }
        long start = System.currentTimeMillis();
        recommendedItemList = recommender.recommendedBecause(5, 34, 10);
        //打印推荐的结果
        System.out.println("使用基于物品的协同过滤算法");
        System.out.println("根据用户5当前浏览的商品34,推荐10个相似的商品");
        for (RecommendedItem recommendedItem : recommendedItemList) {
            System.out.println(recommendedItem);
        }
        System.out.println(System.currentTimeMillis() - start);
    }
}

运行结果:

 使用基于物品的协同过滤算法
根据用户5当前浏览的商品2398,推荐10个相似的商品
RecommendedItem[item:326, value:6.8727612]
RecommendedItem[item:919, value:6.829988]
RecommendedItem[item:920, value:6.7896104]
RecommendedItem[item:527, value:6.227647]
RecommendedItem[item:926, value:6.2026863]
RecommendedItem[item:1235, value:6.1972055]
RecommendedItem[item:1096, value:6.1763406]
RecommendedItem[item:1104, value:6.1685]
RecommendedItem[item:538, value:6.1250587]
RecommendedItem[item:412, value:5.929688]
使用基于物品的协同过滤算法
根据用户5当前浏览的商品34,推荐10个相似的商品
RecommendedItem[item:919, value:6.6934185]
RecommendedItem[item:1225, value:6.2523694]
RecommendedItem[item:926, value:6.244406]
RecommendedItem[item:1104, value:6.2245407]
RecommendedItem[item:923, value:6.187429]
RecommendedItem[item:1219, value:6.1394296]
RecommendedItem[item:527, value:6.1108875]
RecommendedItem[item:920, value:6.078272]
RecommendedItem[item:608, value:6.0102806]
RecommendedItem[item:538, value:5.8557873]
14

基于用户的推荐

package com.lzhpo.ma1.test2.movie;

import org.apache.mahout.cf.taste.common.TasteException;
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.PearsonCorrelationSimilarity;
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.UserSimilarity;
import org.apache.mahout.cf.taste.similarity.precompute.example.GroupLensDataModel;

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

/**
 * 基于用户的推荐
 * <p>
 * 数据类别:7.2万用户对1万部电影的百万级评价和10万个标签数据。
 * 数据模型下载地址:https://grouplens.org/datasets/movielens/10m/
 * </p>
 *
 * @author lzhpo
 */
public class BaseUserRecommender {
    public static void main(String[] args) throws IOException, TasteException {
        System.out.println("==================================================================");
        System.out.println("------------------------使用基于用户的协同过滤算法---------------------");
        System.out.println("==================================================================");
        //准备数据 这里是电影评分数据
        File file = new File("E:\\JavaCode\\MyProject\\Algorithm-Java\\mahout\\ma_demo1\\src\\main\\resources\\testFile\\movieData\\ml-10M100K\\ratings.dat");
        //将数据加载到内存中,GroupLensDataModel是针对开放电影评论数据的
        DataModel dataModel = new GroupLensDataModel(file);

        //计算相似度,相似度算法有很多种,欧几里得、皮尔逊等等。
        UserSimilarity similarity = new PearsonCorrelationSimilarity(dataModel);
        //计算最近邻域,邻居有两种算法,基于固定数量的邻居和基于相似度的邻居,这里使用基于固定数量的邻居
        UserNeighborhood userNeighborhood = new NearestNUserNeighborhood(100, similarity, dataModel);
        //构建推荐器,协同过滤推荐有两种,分别是基于用户的和基于物品的,这里使用基于用户的协同过滤推荐
        Recommender recommender = new GenericUserBasedRecommender(dataModel, userNeighborhood, similarity);

        //给用户ID等于99的用户推荐6部电影
        List<RecommendedItem> recommendedItemList = recommender.recommend(99, 6);
        //打印推荐的结果
        System.out.println("开始为用户ID为99的用户推荐 " +recommendedItemList.size() +"部电影......");
        for (RecommendedItem recommendedItem : recommendedItemList) {
            System.out.println(recommendedItem);
        }
    }
}

运行结果:

==================================================================
------------------------使用基于用户的协同过滤算法---------------------
==================================================================
开始为用户ID为99的用户推荐 6部电影......
RecommendedItem[item:703, value:5.0]
RecommendedItem[item:88, value:5.0]
RecommendedItem[item:215, value:5.0]
RecommendedItem[item:61, value:5.0]
RecommendedItem[item:82, value:5.0]
RecommendedItem[item:102, value:5.0]
本文目录