mllib 协同过滤_使用spark mllib协同过滤进行图书推荐(Java版)

2023-11-16

0. 协同过滤算法简介

协同过滤(Collaborative Filtering),简单来说是利用某兴趣相投、拥有共同经验之群体的喜好来推荐用户感兴趣的信息。根据关注内容的不同,协同过滤算法分为三类:

以用户为基础(User-based)的协同过滤:用相似统计的方法得到具有相似爱好或者兴趣的相邻用户,使用与推荐用户相似用户的感兴趣的项目进行推荐。

以项目为基础(Item-based)的协同过滤:“能够引起用户兴趣的项目,必定与其之前评分高的项目相似”,透过计算项目之间的相似性来代替用户之间的相似性。

以模型为基础(Model-based)的协同过滤:用历史数据得到一个模型,再用此模型进行预测。

mllib中实现了以模型为基础的协同过滤,使用als算法训练模型。

1. 数据源

book-crossing dataset:

其中包含三个文件

评分数据文件:"User-ID";"ISBN";"Book-Rating"

图书数据文件:"ISBN";"Book-Title";"Book-Author";"Year-Of-Publication";"Publisher";"Image-URL-S";"Image-URL-M";"Image-URL-L"

用户数据文件:“User-ID”;"Location";"Age"

2. 数据预处理

MLlib的ALS算法实现有一个小缺点:它要求user和item的ID必须是数值型,并且是32位非负整数。评分文件中userid为int类型,而ISBN为string类型,需要将其先转换为 int类型。这里我们采用将BX-Books中的所有图书一一对应到从1开始的自增id,使用hashmap保存映射关系,而后将BX-Book-Ratings中的ISBN映射到自增id上。在对数据进行映射的过程中发现,评分集中有ISBN未在图书表中出现,将此类型条目删除构成新的评分文件。

public static void processing() throws IOException {

ArrayList books = new ArrayList<>();

ArrayList ratings = new ArrayList<>();

CsvReader reader = new CsvReader("data/BX-Books.csv",';');

reader.readHeaders();

while (reader.readRecord()) {

books.add(reader.getValues());

}

reader.close();

reader = new CsvReader("data/BX-Book-Ratings.csv",';');

reader.readHeaders();

while (reader.readRecord()) {

ratings.add(reader.getValues());

}

reader.close();

//将isbn与自增int进行映射

HashMap map = new HashMap<>();

for(int i = 0 ; i < books.size() ; i++) {

map.put(books.get(i)[0],i+1);

}

//将isbn映射到int

FileWriter fileWriter = new FileWriter("data/book-rating.txt");

for(String[] rating:ratings) {

//当ISBN存在时

if(map.containsKey(rating[1])) {

fileWriter.write(rating[0].replaceAll("\"","")+";");

fileWriter.write(map.get(rating[1])+";");

fileWriter.write(rating[2].replaceAll("\"","")+"\n");

}

}

fileWriter.close();

}

3. 模型训练及推荐结果获取

创建一个类读取评分文件,在数据集中随机选取80%数据作为训练集,20%数据作为测试集。设置模型参数如最大迭代次数,正则项及冷启动策略等。全部参数如下:

numBlocks is the number of blocks the users and items will be partitioned into in order to parallelize computation (defaults to 10).

rank is the number of latent factors in the model (defaults to 10).

maxIter is the maximum number of iterations to run (defaults to 10).

regParam specifies the regularization parameter in ALS (defaults to 1.0).

implicitPrefs specifies whether to use the explicit feedback ALS variant or one adapted for implicit feedback data (defaults to false which means using explicit feedback).

alpha is a parameter applicable to the implicit feedback variant of ALS that governs the baseline confidence in preference observations (defaults to 1.0).

nonnegative specifies whether or not to use nonnegative constraints for least squares (defaults to false).public class Recommend {

public static class Rating implements Serializable {

private int userId;

private int bookId;

private float rating;

public Rating() {}

public Rating(int userId, int bookId, float rating) {

this.userId = userId;

this.bookId = bookId;

this.rating = rating;

}

public int getUserId() {

return userId;

}

public int getBookId() {

return bookId;

}

public float getRating() {

return rating;

}

public static Rating parseRating(String str) {

String[] fields = str.split(";");

if (fields.length != 3) {

throw new IllegalArgumentException("Each line must contain 3 fields");

}

int userId = Integer.parseInt(fields[0]);

int bookId = Integer.parseInt(fields[1]);

float rating = Float.parseFloat(fields[2]);

return new Rating(userId, bookId, rating);

}

}

public static void main(String[] args) {

SparkSession spark = SparkSession

.builder()

.appName("JavaALSExample")

.getOrCreate();

JavaRDD ratingsRDD = spark

.read().textFile("data/book-rating.txt").javaRDD()

.map(Rating::parseRating);

Dataset ratings = spark.createDataFrame(ratingsRDD, Rating.class);

Dataset[] splits = ratings.randomSplit(new double[]{0.8, 0.2});

Dataset training = splits[0];

Dataset test = splits[1];

ALS als = new ALS()

.setMaxIter(10)

.setRegParam(0.01)

.setUserCol("userId")

.setItemCol("bookId")

.setRatingCol("rating");

ALSModel model = als.fit(training);

// 冷启动策略

model.setColdStartStrategy("drop");

Dataset predictions = model.transform(test);

RegressionEvaluator evaluator = new RegressionEvaluator()

.setMetricName("rmse")

.setLabelCol("rating")

.setPredictionCol("prediction");

Double rmse = evaluator.evaluate(predictions);

System.out.println("Root-mean-square error = " + rmse);

// 全部用户推荐top10

Dataset userRecs = model.recommendForAllUsers(10);

// 全部图书推荐top10用户

Dataset bookRecs = model.recommendForAllItems(10);

// 部分用户推荐top10

Dataset users = ratings.select(als.getUserCol()).distinct().limit(3);

Dataset userSubsetRecs = model.recommendForUserSubset(users, 10);

// 部分图书推荐top10用户

Dataset books = ratings.select(als.getItemCol()).distinct().limit(3);

Dataset bookSubSetRecs = model.recommendForItemSubset(books, 10);

userRecs.show();

bookRecs.show();

userSubsetRecs.show(false); //不省略字符打印

bookSubSetRecs.show();

spark.stop();

}

}

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

mllib 协同过滤_使用spark mllib协同过滤进行图书推荐(Java版) 的相关文章

  • 最全的前端性能优化手段回答

    前端性能优化手段 参考答案 前端性能优化手段从以下几个方面入手 加载优化 执行优化 渲染优化 样式优化 脚本优化 1 加载优化 减少HTTP请求 缓存资源 压缩代码 无阻塞 首屏加载 按需加载 预加载 压缩图像 减少Cookie 避免重定向
  • 时序预测模型汇总

    时序预测模型 一 自回归 AR 在 AR 模型中 我们使用变量过去值的线性组合来预测感兴趣的变量 术语自回归表明它是变量对自身的回归 二 移动平均模型 MA 与在回归中使用预测变量的过去值的 AR 模型不同 MA 模型在类似回归的模型中关注
  • 三角函数的向量表示的原理计算

    在 电路 中 三相电源经常用复数或者是向量来表示 但是与我们初高中熟知的空间向量不同 这里的三相交流电是一种时间向量 由于采用的形式是正弦形式 使得其也可以用空间向量中的平行四边形原则来进行计算合成 下面将介绍一下正弦量可以用向量表示的原理
  • 生成tensorrt引擎错误记录-yolov5

    warning nvinfer1 Dims type is deprecated Wdeprecated declarations note TRT DEPRECATED DimensionType type MAX DIMS lt The
  • c++ virtual 关键字 override 关键字

    文章目录 1 什么是virtual 2 为什么需要 3 通常用在什么情形 4 延伸 虚函数 纯虚函数 override 关键字 9 问题汇总 9 1 非虚函数和虚函数都可以重写 那区别是啥 9 2 基类虚函数 纯虚函数 子类有没有 over
  • MS5543单通道、16位、串行通信、高速ADC转换芯片

    产品简述 MS5543 是一款单通道 16 位 串行输入 电压输出的数模 转换器 采用 2 7V 至 5 5V 单电源供电 输出范围为 0V 至 V REF 在输出范围内保证单调性 在温度范围为 40 C 至 85 C 能够提供 1LSB
  • linux设备驱动归纳总结(四):3.抢占和上下文切换

    xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx 上一节介绍了进程调度的一些基本概念 并简单介绍了在没有抢占的情况下
  • 生产环境使用HBase,你必须知道的最佳实践

    需要关注的一些最佳实践经验 Schema设计七大原则 1 每个region的大小应该控制在10G到50G之间 2 一个表最好保持在 50到100个 region的规模 3 每个cell最大不应该超过10MB 如果超过 应该有些考虑业务拆分
  • Java中存储金额用什么数据类型

    文章目录 1 抛砖引玉 2 加减乘除 3 大小比较 4 小数位数及四舍五入规则 1 抛砖引玉 在给自己做一个小的Java记账小程序的时候 对金额的处理时必不可少的 一开始选择的是float数据类型 在数据库中 存储金额的数据字段也是floa
  • 二进制转16进制字符串和16进制字符串转二进制的C和JAVA实现

    二进制转16进制字符串和16进制字符串转二进制的C语言实现 二进制转16进制字符串 长度会翻倍 void ByteToHexStr const unsigned char source char dest int sourceLen 16进
  • 《Kubernetes部署篇:Ubuntu20.04基于外部etcd+部署kubernetes1.24.17集群(多主多从)》

    一 部署架构图 1 架构图如下所示 2 部署流程图如下所示 二 环境信息 1 部署规划 主机名 K8S版本 系统版本 内核版本 IP地址 备注 k8s master 63 1 24 17 Ubuntu 20 04 5 LTS 5 15 0
  • 【QT】判断鼠标按键

    代表按键类型的枚举变量 enum Qt MouseButton Qt NoButton 0x00000000 Qt AllButtons 0x07ffffff Qt LeftButton 0x00000001 Qt RightButton
  • 12306验证码识别 --- 2017-12

    1 附件中包含12306查询验证码识别客户端和所需要测试的样本图片 2 模型正确率95 以上 3 操作方式 3 1 解压里面的Client zip 找到里面的user client exe可执行文件 3 2 点击里面的browse按钮进行选
  • unity基本知识点2

    一 把图片打包成图集 1 全选图片 把texture type改成sprite 2DandUI Packing Tag是打包标签 给想打包的图片写上统一的标签才可打包 2 edit project setting editor里inspec
  • 测试人:“躺平?不可能的“, 盘点测试人在职场的优势

    之前有这么一个段子 有人喜欢创造世界 他们做了程序员 有人喜欢拯救世界 他们做了测试员 近几年 测试工程师在企业究竟是怎么样的发展 随着企业对于用户体验的满意度越来越重视 更加推动了软件测试工程师这个岗位的需求度 接下来 我们从4个纬度来分
  • Envoy源码分析之ThreadLocal

    ThreadLocal机制 Envoy中的ThreadLocal机制其实就是我们经常说的线程本地存储简称TLS Thread Local Storage 顾名思义通过TLS定义的变量会在每一个线程专有的存储区域存储一份 访问TLS的时候 其
  • 后台管理系统布局以及跳转,点击菜单局部刷新,右侧显示对应界面

    完整版教程 https blog csdn net Lining s article details 117676170 1 整体布局如下 右侧菜单的html 代码 使用了Thymeleaf 模版 这是左测的菜单栏 左侧的所有菜单最外层是一
  • clang(llvm)命令调用android NDK 编译C应用

    在window下载的android NDK解压后 可以用如下命令 安装NDK独立编译工具 这样再用命令时不用带一把参数了 D Program Files python27 python make standalone toolchain p
  • 在asp中数据库的连接

    其中数据库bbs mdb有张friend 的表

随机推荐