推薦系統之余弦相似度的Spark實現


推薦系統之余弦相似度的Spark實現

(1)原理分析

   余弦相似度度量是相似度度量中最常用的度量關系,從程序分析中,

  • 第一步是數據的輸入,
  • 其次是使用相似性度量公式
  • 最后是對不同用戶的遞歸計算。

   本例子是基於歐幾里得舉例的相似度計算。

(2)源代碼

 1 package com.bigdata.demo
 2 
 3 import org.apache.spark.{SparkContext, SparkConf}
 4 
 5 /**
 6   * Created by SimonsZhao on 3/29/2017.
 7   */
 8 object CollaborativeFilteringSpark {
 9   //1.設置環境變量
10   val conf=new SparkConf().setMaster("local").setAppName("CollaborativeFilteringSpark")
11   //2.實例化環境
12   val sc=new SparkContext(conf)
13   //3.設置用戶
14   val users=sc.parallelize(Array("aaa","bbb","ccc","ddd","eee"))
15   //4.設置電影名
16   sc.parallelize(Array("smzdm","ylxb","znb","nhsc","fcwr"))
17   //5.使用一個source嵌套map作為姓名電影名和分值的存儲
18   var source=Map[String,Map[String,Int]]()
19   //6.設置一個用以存放電影分的map
20   val filmSource =Map[String,Int]()
21   //7.設置電影評分
22   def getSource():Map[String,Map[String,Int]]={
23     val user1FilmSource=Map("smzdm"->2,"ylxb"->3,"znb"->1,"nhsc"->0,"fcwr"->1)
24     val user2FilmSource=Map("smzdm"->1,"ylxb"->2,"znb"->2,"nhsc"->1,"fcwr"->4)
25     val user3FilmSource=Map("smzdm"->2,"ylxb"->1,"znb"->0,"nhsc"->1,"fcwr"->4)
26     val user4FilmSource=Map("smzdm"->3,"ylxb"->2,"znb"->0,"nhsc"->5,"fcwr"->3)
27     val user5FilmSource=Map("smzdm"->5,"ylxb"->3,"znb"->1,"nhsc"->1,"fcwr"->2)
28     //存儲人的名字
29     source += ("aaa" -> user1FilmSource)
30     //存儲人的名字
31     source += ("bbb" -> user2FilmSource)
32     //存儲人的名字
33     source += ("ccc" -> user3FilmSource)
34     //存儲人的名字
35     source += ("ddd" -> user4FilmSource)
36     //存儲人的名字
37     source += ("eee" -> user5FilmSource)
38     //返回嵌套的map
39     source
40   }
41   //采用余弦相似度兩兩計算分值
42   def getCollaborateSource(user1:String,user2:String):Double={
43     //獲得第一個用戶的評分
44       val user1FilmSource =source.get(user1).get.values.toVector
45     //獲得第二個用戶的評分
46       val user2FileSource=source.get(user2).get.values.toVector
47     //對公示分子部分進行計算
48       val member=user1FilmSource.zip(user2FileSource).map(d => d._1 *d._2).reduce(_+_).toDouble
49     //求解分母的第一個變量
50       val temp1=math.sqrt(user1FilmSource.map(num=>{math.pow(num,2)}).reduce(_+_))
51     //求解分母第二個變量
52       val temp2=math.sqrt(user2FileSource.map(num=>{math.pow(num,2)}).reduce(_+_))
53     //求出分母
54       val denominator=temp1*temp2
55     //求出分式的值
56       member/denominator
57   }
58   def main(args: Array[String]) {
59     //初始化分數
60     getSource()
61     //設定目標對象
62     val name="bbb"
63     //進行迭代計算
64     users.foreach(user=>{
65       println(name+" 相對於"+user+"的相似性分數是:"+getCollaborateSource(name,user))
66     })
67   }
68 }

點擊可復制代碼

 1 package com.bigdata.demo
 2 
 3 import org.apache.spark.{SparkContext, SparkConf}
 4 
 5 /**
 6   * Created by SimonsZhao on 3/29/2017.
 7   */
 8 object CollaborativeFilteringSpark {
 9   //1.設置環境變量
10   val conf=new SparkConf().setMaster("local").setAppName("CollaborativeFilteringSpark")
11   //2.實例化環境
12   val sc=new SparkContext(conf)
13   //3.設置用戶
14   val users=sc.parallelize(Array("aaa","bbb","ccc","ddd","eee"))
15   //4.設置電影名
16   sc.parallelize(Array("smzdm","ylxb","znb","nhsc","fcwr"))
17   //5.使用一個source嵌套map作為姓名電影名和分值的存儲
18   var source=Map[String,Map[String,Int]]()
19   //6.設置一個用以存放電影分的map
20   val filmSource =Map[String,Int]()
21   //7.設置電影評分
22   def getSource():Map[String,Map[String,Int]]={
23     val user1FilmSource=Map("smzdm"->2,"ylxb"->3,"znb"->1,"nhsc"->0,"fcwr"->1)
24     val user2FilmSource=Map("smzdm"->1,"ylxb"->2,"znb"->2,"nhsc"->1,"fcwr"->4)
25     val user3FilmSource=Map("smzdm"->2,"ylxb"->1,"znb"->0,"nhsc"->1,"fcwr"->4)
26     val user4FilmSource=Map("smzdm"->3,"ylxb"->2,"znb"->0,"nhsc"->5,"fcwr"->3)
27     val user5FilmSource=Map("smzdm"->5,"ylxb"->3,"znb"->1,"nhsc"->1,"fcwr"->2)
28     //存儲人的名字
29     source += ("aaa" -> user1FilmSource)
30     //存儲人的名字
31     source += ("bbb" -> user2FilmSource)
32     //存儲人的名字
33     source += ("ccc" -> user3FilmSource)
34     //存儲人的名字
35     source += ("ddd" -> user4FilmSource)
36     //存儲人的名字
37     source += ("eee" -> user5FilmSource)
38     //返回嵌套的map
39     source
40   }
41   //采用余弦相似度兩兩計算分值
42   def getCollaborateSource(user1:String,user2:String):Double={
43     //獲得第一個用戶的評分
44       val user1FilmSource =source.get(user1).get.values.toVector
45     //獲得第二個用戶的評分
46       val user2FileSource=source.get(user2).get.values.toVector
47     //對公示分子部分進行計算
48       val member=user1FilmSource.zip(user2FileSource).map(d => d._1 *d._2).reduce(_+_).toDouble
49     //求解分母的第一個變量
50       val temp1=math.sqrt(user1FilmSource.map(num=>{math.pow(num,2)}).reduce(_+_))
51     //求解分母第二個變量
52       val temp2=math.sqrt(user2FileSource.map(num=>{math.pow(num,2)}).reduce(_+_))
53     //求出分母
54       val denominator=temp1*temp2
55     //求出分式的值
56       member/denominator
57   }
58   def main(args: Array[String]) {
59     //初始化分數
60     getSource()
61     //設定目標對象
62     val name="bbb"
63     //進行迭代計算
64     users.foreach(user=>{
65       println(name+" 相對於"+user+"的相似性分數是:"+getCollaborateSource(name,user))
66     })
67   }
68 }
點擊+可復制代碼

(3)結果分析

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM