IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 人工智能 -> 大数据实战电商推荐系统(6)- 基于物品的协同过滤相似推荐(Item-CF算法) -> 正文阅读

[人工智能]大数据实战电商推荐系统(6)- 基于物品的协同过滤相似推荐(Item-CF算法)

数据获取和处理以及环境的配置详见上一篇文章: https://blog.csdn.net/qq_42754919/article/details/119679441

基于物品的协同过滤(Item-CF),只需收集用户的常规行为数据(比如点击、收藏、购买)就可以得到商品间的相似度,在实际项目中应用很广。

1. 基于物品的协同过滤(Item-CF)

基于物品的协同过滤(Item-CF)主要思想:对于同一个用户购买的不同商品内部应该存在某种相关性。因此可以用现存的行为数据判断两个物品的相似程度,分析商品受众的相似程度,进而得出商品间的相似度。当一个新的用户购买某个商品后,可以用商品相似度推荐给当前用户其他某种类型的商品,未必和之前购买的商品统一类型。我们把这种方法定义为物品的“同现相似度”,公式如下:我们把这种方法定义为物品的“同现相似度”,公式如下:
在这里插入图片描述
其中,Ni 是购买商品 i的数量,Nj 是购买商品 j 的数量,分子表示同一个用户同时购买两个商品的数量。

2. 代码

主要思路:

  1. 首先统计每个商品出现的频次,然后按用户ID进行内连接
  2. 使用sparkSQL获取每个商品出现的次数和用户的数量
  3. 带入公式计算出同现相似度,并过滤出相同两个商品

spark.sql()代码解析:从joined表中获取数据,按照 productId1,productId2进行分类。因此就可能存在多个userId,统计userId个数就是购买过两个商品的次数,并且count1和count2都是相同的,只需要获取第一个即可。最终count(userId) as cocount作为公式的分子,count1和count2作为公式的分母。
在这里插入图片描述

package com.root.itemcf

import org.apache.spark.SparkConf
import org.apache.spark.sql.SparkSession

case class ProductRating(UserId:Int, ProductId:Int, Score:Double, Time:Int)
//MongoDB的连接配置
case class MongoConfig(uri:String, db:String)
//定义推荐标准对象
case class Recommenderdation(productId:Int, score:Double)
//定义商品相似度列表
case class ProductRecs(productId:Int,recs:Seq[Recommenderdation])
object ItemCFRecommender {
  val MongoDB_Rating="Rating"
  val ItemCF_PRODUCT_RECS = "ItemCFProductRecs"
  val USER_MAX_RECOMMENDATION = 10
  def main(args: Array[String]): Unit = {
    val config = Map(
      "spark.cores" -> "local[*]",
      "mongo.uri" -> "mongodb://localhost:27017/recommender",
      "mongo.db" -> "recommender"
    )
    val sparkConf = new SparkConf().setMaster("local[*]").setAppName("ItemCFRecommender")
    val spark = SparkSession.builder().config(sparkConf).getOrCreate()
    import spark.implicits._
    implicit val mongoConfig = MongoConfig(config("mongo.uri"), config("mongo.db"))
    //加载数据,转换数据格式为DF处理
    val ratingDF = spark.read
      .option("uri", mongoConfig.uri)
      .option("collection", MongoDB_Rating)
      .format("com.mongodb.spark.sql")
      .load()
      .as[ProductRating]
      .map(x => (x.ProductId, x.UserId))
      .toDF("userId", "productId")
      .cache()
    //TODO:核心算法,计算同现相似度,得到商品的相似列表
    //统计每个商品的评分个数,按照productId做group by
    val productRatingCountDF = ratingDF.groupBy("productId").count()
    //在原有的评分表上rating添加count,将count添加到每次product出现的后面
    val ratingWithCountDF = ratingDF.join(productRatingCountDF, "productId")
    //将评分按照用户id两两配对,统计两个商品被同一个用户评分过的次数
    val joinedDF = ratingWithCountDF.join(ratingWithCountDF, "userId")
      .toDF("userId", "productId1", "count1", "productId2", "count2")
    joinedDF.show()
    joinedDF.createOrReplaceTempView("joined")
    //按照productId1,productId2做group by,统计userId的数量,就是对两个商品同时评分的人数
    val cooccurrenceDF = spark.sql(
      """
        |select productId1,productId2,
        |count(userId) as cocount,
        |first(count1) as count1,
        |first(count2) as count2
        |from joined
        |group by productId1,productId2
        |""".stripMargin).cache()
    cooccurrenceDF.show()
    //提取需要的数据,包装成(productId1,(productId1,score))
    val simDF = cooccurrenceDF.map {
      row =>
        val coocSim = cooccurrenceSim(row.getAs[Long]("cocount"), row.getAs[Long]("count1"), row.getAs[Long]("count1"))
        (row.getInt(0), (row.getInt(1), coocSim))
    }
      .rdd
      .groupByKey()
      .map { case (productId, recs) =>
        ProductRecs(productId, recs.toList
          .filter(x => x._1 != productId)
          .sortWith(_._2 > _._2).take(USER_MAX_RECOMMENDATION)
          .map(x => Recommenderdation(x._1, x._2)))
      } //转化成UserRecs表,数组集合的形式
      .toDF()

     simDF.write
      .option("uri",mongoConfig.uri)
      .option("collection",ItemCF_PRODUCT_RECS)
      .mode("overwrite")
      .format("com.mongodb.spark.sql")
      .save()
    spark.stop()
  }
  
    def cooccurrenceSim(coCount: Long, count1: Long, count2: Long): Double = {
      coCount / math.sqrt(count1 * count2)
    }
}

3. 结果展示

在这里插入图片描述

  人工智能 最新文章
2022吴恩达机器学习课程——第二课(神经网
第十五章 规则学习
FixMatch: Simplifying Semi-Supervised Le
数据挖掘Java——Kmeans算法的实现
大脑皮层的分割方法
【翻译】GPT-3是如何工作的
论文笔记:TEACHTEXT: CrossModal Generaliz
python从零学(六)
详解Python 3.x 导入(import)
【答读者问27】backtrader不支持最新版本的
上一篇文章      下一篇文章      查看所有文章
加:2021-08-15 15:32:20  更:2021-08-15 15:34:59 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/27 20:36:49-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码