SparkMLlib---基于余弦相似度的用户相似计算

本文介绍了一个基于Spark的用户相似性计算方法,通过余弦相似性评估不同用户对一系列电影评分的相似度。此方法适用于推荐系统中寻找目标用户的兴趣相似者。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

package mllib

import org.apache.log4j.{Level, Logger}
import org.apache.spark.{SparkContext, SparkConf}
import scala.collection.mutable.Map
/**
  * Created by 汪本成 on 2016/8/4.
  */
object UserSimilar {

  //屏蔽不必要的日志显示在终端上
  Logger.getLogger("org.apache.spark").setLevel(Level.WARN)
  Logger.getLogger("org.apache.eclipse.jetty.server").setLevel(Level.OFF)

  //程序入口
  val conf = new SparkConf().setMaster("local[1]").setAppName(this.getClass().getSimpleName().filter(!_.equals('$')))
  println(this.getClass().getSimpleName().filter(!_.equals('$')))

  val sc = new SparkContext(conf)

  //设置用户名
  val users = sc.parallelize(Array("张三", "李四", "王五", "赵六", "阿七"))
  //设置电影名
  val films = sc.parallelize(Array("逆战", "人间", "鬼屋", "西游记", "雪豹"))

  //使用一个source嵌套map作为姓名电影名和分值的存储
  val source = Map[String, Map[String, Int]]()

  //设置一个用以存放电影分的map
  val filmSource = Map[String, Int]()


  def getSource(): Map[String, Map[String, Int]] = {
    //设置电影评分
    val user1FilmSource = Map("逆战" -> 2, "人间" -> 3, "鬼屋" -> 1, "西游记" -> 0, "雪豹" -> 1)
    val user2FilmSource = Map("逆战" -> 1, "人间" -> 2, "鬼屋" -> 2, "西游记" -> 1, "雪豹" -> 4)
    val user3FilmSource = Map("逆战" -> 2, "人间" -> 1, "鬼屋" -> 0, "西游记" -> 1, "雪豹" -> 4)
    val user4FilmSource = Map("逆战" -> 3, "人间" -> 2, "鬼屋" -> 0, "西游记" -> 5, "雪豹" -> 3)
    val user5FilmSource = Map("逆战" -> 5, "人间" -> 3, "鬼屋" -> 1, "西游记" -> 1, "雪豹" -> 2)

    //对人名进行储存
    source += ("张三" -> user1FilmSource)
    source += ("李四" -> user2FilmSource)
    source += ("王五" -> user3FilmSource)
    source += ("赵六" -> user4FilmSource)
    source += ("阿七" -> user5FilmSource)

    //返回嵌套map
    source
  }

  //两两计算分值,采用余弦相似性
  def getCollaborateSource(user1: String, user2: String): Double = {
    //获得12两个用户的评分
    val user1FilmSource = source.get(user1).get.values.toVector
    val user2FilmSource = source.get(user2).get.values.toVector

    //对公式部分分子进行计算
    val member = user1FilmSource.zip(user2FilmSource).map(d => d._1 * d._2).reduce(_ + _).toDouble
    //求出分母第一个变量值
    val temp1 = math.sqrt(user1FilmSource.map(num => {math.pow(num, 2)}).reduce(_ + _))
    //求出分母第二个变量值
    val temp2 = math.sqrt(user2FilmSource.map(num => {math.pow(num, 2)}).reduce(_ + _))
    //求出分母
    val denominator = temp1 * temp2
    //进行计算
    member / denominator
  }

  def main(args: Array[String]) {
    //初始化分数
    getSource()

    val name1 = "张三"
    val name2 = "李四"
    val name3 = "王五"
    val name4 = "赵六"
    val name5 = "阿七"

    users.foreach(user => {
      println(name1 + " 相对于 " + user + " 的相似性分数是 " + getCollaborateSource(name1, user) )
    })

    println("--------------------------------------------------------------------------")

    users.foreach(user => {
      println(name2 + " 相对于 " + user + " 的相似性分数是 " + getCollaborateSource(name2, user) )
    })

    println("--------------------------------------------------------------------------")

    users.foreach(user => {
      println(name3 + " 相对于 " + user + " 的相似性分数是 " + getCollaborateSource(name3, user) )
    })

    println("--------------------------------------------------------------------------")

    users.foreach(user => {
      println(name4 + " 相对于 " + user + " 的相似性分数是 " + getCollaborateSource(name4, user) )
    })

    println("--------------------------------------------------------------------------")

    users.foreach(user => {
      println(name5 + " 相对于 " + user + " 的相似性分数是 " + getCollaborateSource(name5, user) )
    })

  }

}



运行结果:

[plain]  view plain  copy
  1. "C:\Program Files\Java\jdk1.8.0_77\bin\java" -Didea.launcher.port=7534 "-Didea.launcher.bin.path=D:\Program Files (x86)\JetBrains\IntelliJ IDEA 15.0.5\bin" -Dfile.encoding=UTF-8 -classpath "C:\Program Files\Java\jdk1.8.0_77\jre\lib\charsets.jar;C:\Program Files\Java\jdk1.8.0_77\jre\lib\deploy.jar;C:\Program Files\Java\jdk1.8.0_77\jre\lib\ext\access-bridge-64.jar;C:\Program Files\Java\jdk1.8.0_77\jre\lib\ext\cldrdata.jar;C:\Program Files\Java\jdk1.8.0_77\jre\lib\ext\dnsns.jar;C:\Program Files\Java\jdk1.8.0_77\jre\lib\ext\jaccess.jar;C:\Program Files\Java\jdk1.8.0_77\jre\lib\ext\jfxrt.jar;C:\Program Files\Java\jdk1.8.0_77\jre\lib\ext\localedata.jar;C:\Program Files\Java\jdk1.8.0_77\jre\lib\ext\nashorn.jar;C:\Program Files\Java\jdk1.8.0_77\jre\lib\ext\sunec.jar;C:\Program Files\Java\jdk1.8.0_77\jre\lib\ext\sunjce_provider.jar;C:\Program Files\Java\jdk1.8.0_77\jre\lib\ext\sunmscapi.jar;C:\Program Files\Java\jdk1.8.0_77\jre\lib\ext\sunpkcs11.jar;C:\Program Files\Java\jdk1.8.0_77\jre\lib\ext\zipfs.jar;C:\Program Files\Java\jdk1.8.0_77\jre\lib\javaws.jar;C:\Program Files\Java\jdk1.8.0_77\jre\lib\jce.jar;C:\Program Files\Java\jdk1.8.0_77\jre\lib\jfr.jar;C:\Program Files\Java\jdk1.8.0_77\jre\lib\jfxswt.jar;C:\Program Files\Java\jdk1.8.0_77\jre\lib\jsse.jar;C:\Program Files\Java\jdk1.8.0_77\jre\lib\management-agent.jar;C:\Program Files\Java\jdk1.8.0_77\jre\lib\plugin.jar;C:\Program Files\Java\jdk1.8.0_77\jre\lib\resources.jar;C:\Program Files\Java\jdk1.8.0_77\jre\lib\rt.jar;G:\location\spark-mllib\out\production\spark-mllib;C:\Program Files (x86)\scala\lib\scala-actors-migration.jar;C:\Program Files (x86)\scala\lib\scala-actors.jar;C:\Program Files (x86)\scala\lib\scala-library.jar;C:\Program Files (x86)\scala\lib\scala-reflect.jar;C:\Program Files (x86)\scala\lib\scala-swing.jar;G:\home\download\spark-1.6.1-bin-hadoop2.6\lib\datanucleus-api-jdo-3.2.6.jar;G:\home\download\spark-1.6.1-bin-hadoop2.6\lib\datanucleus-core-3.2.10.jar;G:\home\download\spark-1.6.1-bin-hadoop2.6\lib\datanucleus-rdbms-3.2.9.jar;G:\home\download\spark-1.6.1-bin-hadoop2.6\lib\spark-1.6.1-yarn-shuffle.jar;G:\home\download\spark-1.6.1-bin-hadoop2.6\lib\spark-assembly-1.6.1-hadoop2.6.0.jar;G:\home\download\spark-1.6.1-bin-hadoop2.6\lib\spark-examples-1.6.1-hadoop2.6.0.jar;D:\Program Files (x86)\JetBrains\IntelliJ IDEA 15.0.5\lib\idea_rt.jar" com.intellij.rt.execution.application.AppMain mllib.CollaborativeFilteringSpark  
  2. CollaborativeFilteringSpark  
  3. Using Spark's default log4j profile: org/apache/spark/log4j-defaults.properties  
  4. SLF4J: Class path contains multiple SLF4J bindings.  
  5. SLF4J: Found binding in [jar:file:/G:/home/download/spark-1.6.1-bin-hadoop2.6/lib/spark-assembly-1.6.1-hadoop2.6.0.jar!/org/slf4j/impl/StaticLoggerBinder.class]  
  6. SLF4J: Found binding in [jar:file:/G:/home/download/spark-1.6.1-bin-hadoop2.6/lib/spark-examples-1.6.1-hadoop2.6.0.jar!/org/slf4j/impl/StaticLoggerBinder.class]  
  7. SLF4J: See http://www.slf4j.org/codes.html#multiple_bindings for an explanation.  
  8. SLF4J: Actual binding is of type [org.slf4j.impl.Log4jLoggerFactory]  
  9. 16/08/04 20:41:49 INFO Slf4jLogger: Slf4jLogger started  
  10. 16/08/04 20:41:49 INFO Remoting: Starting remoting  
  11. 16/08/04 20:41:49 INFO Remoting: Remoting started; listening on addresses :[akka.tcp://sparkDriverActorSystem@192.168.1.100:8380]  
  12. 张三 相对于 张三 的相似性分数是 0.9999999999999999  
  13. 张三 相对于 李四 的相似性分数是 0.7089175569585667  
  14. 张三 相对于 王五 的相似性分数是 0.6055300708194983  
  15. 张三 相对于 赵六 的相似性分数是 0.564932682866032  
  16. 张三 相对于 阿七 的相似性分数是 0.8981462390204985  
  17. --------------------------------------------------------------------------  
  18. 李四 相对于 张三 的相似性分数是 0.7089175569585667  
  19. 李四 相对于 李四 的相似性分数是 1.0000000000000002  
  20. 李四 相对于 王五 的相似性分数是 0.8780541105074453  
  21. 李四 相对于 赵六 的相似性分数是 0.6865554812287477  
  22. 李四 相对于 阿七 的相似性分数是 0.6821910402406466  
  23. --------------------------------------------------------------------------  
  24. 王五 相对于 张三 的相似性分数是 0.6055300708194983  
  25. 王五 相对于 李四 的相似性分数是 0.8780541105074453  
  26. 王五 相对于 王五 的相似性分数是 1.0  
  27. 王五 相对于 赵六 的相似性分数是 0.7774630169639036  
  28. 王五 相对于 阿七 的相似性分数是 0.7416198487095662  
  29. --------------------------------------------------------------------------  
  30. 赵六 相对于 张三 的相似性分数是 0.564932682866032  
  31. 赵六 相对于 李四 的相似性分数是 0.6865554812287477  
  32. 赵六 相对于 王五 的相似性分数是 0.7774630169639036  
  33. 赵六 相对于 赵六 的相似性分数是 1.0  
  34. 赵六 相对于 阿七 的相似性分数是 0.738024966423108  
  35. --------------------------------------------------------------------------  
  36. 阿七 相对于 张三 的相似性分数是 0.8981462390204985  
  37. 阿七 相对于 李四 的相似性分数是 0.6821910402406466  
  38. 阿七 相对于 王五 的相似性分数是 0.7416198487095662  
  39. 阿七 相对于 赵六 的相似性分数是 0.738024966423108  
  40. 阿七 相对于 阿七 的相似性分数是 0.9999999999999998  
  41. 16/08/04 20:41:51 INFO RemoteActorRefProvider$RemotingTerminator: Shutting down remote daemon.  
  42.   
  43. Process finished with exit code 0  
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值