推荐模型创建加载

创建推荐模型上传hdfs

package cn.tedu.alsmovie

import org.apache.spark.SparkConf
import org.apache.spark.SparkContext
import org.apache.spark.mllib.recommendation.Rating
import org.apache.spark.mllib.recommendation.ALS

/**

  • 处理u.data 建立推荐系统模型,为编号为789号的用户推荐10部电影
    */
    object Driver {

def main(args: Array[String]): Unit = {

val conf=new SparkConf().setMaster("local").setAppName("alsmovie")
val sc=new SparkContext(conf)
val data=sc.textFile("c://data/ml/u.data", 4)
//--读取电影信息文件
val movieData=sc.textFile("c://data/ml/u.item",4)
//--RDD[String:line]->RDD[(movieId(key),movieName(value))]->collectAsMap->Map
val movieMap=movieData.map { line =>
    val info=line.split("\\|")
    val movieId=info(0).toInt
    val movieName=info(1)
    (movieId,movieName)
}.collectAsMap

val ratings=data.map { line =>
    val info=line.split("\t")
    val userId=info(0).toInt
    val movieId=info(1).toInt
    val score=info(2).toDouble
    
    Rating(userId,movieId,score)
  
}
//--隐藏因子数K,建议在10~50 不易过大。k越大,底层的计算代价越大
val model=ALS.train(ratings, 50, 10, 0.01)
//--为789号用户推荐10个电影
val u789Result=model.recommendProducts(789, 10)
                    .map { rat =>
                      //--获取用户id
                      val userId=rat.user
                      //--获取商品id
                      val movieid=rat.product
                      //--是通过movieMap 的key获取对应的value(电影名)
                      val movieName=movieMap(movieid)
                      //--获取评分
                      val score=rat.rating
                      //--返回结果
                      (userId,movieName,score)
                
}

//--检验模型推荐的准确性。本案例使用直观检验法
//--实现思路:①获取789号用户看过的所有电影
//--②根据789号用户对电影的打分,做降序排序,然后取出前10部(表示这是此用户最喜爱的前10部电影)
//--③用推荐的结果和他喜爱的电影比对,看是否有类似的

//--keyBy函数,会根据指定的匿名函数规则作为属性key来查找
//--下面表示以用户id属性为key来查找
//--lookup()指定具体的key数据
val u789Movies=ratings.keyBy { rat => rat.user}.lookup(789)


val u789Top10=u789Movies.sortBy{rat=> -rat.rating}.take(10)
                        .map { rat =>movieMap(rat.product)}

                        
//--模型存储,路径可以是本地文件系统,也可以是hdfs
//--模型存储后,以后在使用时,不需要重新迭代训练,直接加载即可以使用

model.save(sc,"hdfs://hadoop01:9000/rec-result")

}
}

加载推荐模型

package cn.tedu.alsmovie

import org.apache.spark.SparkConf
import org.apache.spark.SparkContext
import org.apache.spark.mllib.recommendation.MatrixFactorizationModel

/**

  • 加载推荐系统模型
    */
    object LoadDriver {

def cosArray(a1:Array[Double],a2:Array[Double])={

val a1a2=a1 zip a2
val a1a2Fenzi=a1a2.map{x=>x._1*x._2}.sum
val a1Fenmu=Math.sqrt(a1.map { x => x*x }.sum)
val a2Fenmu=Math.sqrt(a2.map { x => x*x }.sum)
//--返回两个向量之间夹角余弦
a1a2Fenzi/(a1Fenmu*a2Fenmu)

}

def main(args: Array[String]): Unit = {

val conf=new SparkConf().setMaster("local").setAppName("load")

val sc=new SparkContext(conf)

//--加载模型
val model=MatrixFactorizationModel.load(sc,"hdfs://hadoop01:9000/rec-result")

val u789Result=model.recommendProducts(789, 10)

//--Spark的ALS模型,只提供了基于用户的推荐(计算用户和用户之间的相似度,然后做推荐)
//--但是没有提供基于物品推荐的方法(计算物品和物品之间的相似度,然后做推荐),需要自己实现
//--场景:某个用户看了 123号电影。要求系统推荐10部电影
//--实现思路:核心是计算出其他电影和123号电影之间的相似度
//--①获取模型的物品因子矩阵
//--②获取123号电影的因子数组
//--③分别计算其他电影和123号电影的相似度(使用向量之间的夹角余弦来计算)
//--④根据相似度降序排序,取出前10部

//--获取用户的因子矩阵,本案例不需要
val userFeatures=model.userFeatures

//--获取物品因子矩阵,可以通过此因子矩阵计算出 电影-电影之间的相似度
//--RDD[(电影id,电影的因子数组)]
val movieFeatures=model.productFeatures

//--以电影id属性为key,具体找123号电影的数据
val movie123Features=movieFeatures.keyBy{x=>x._1}.lookup(123).head._2

val result=movieFeatures.map{case(movieId,feature)=>
  //--计算当前电影和123号电影之间的相似度
  val cos=cosArray(movie123Features, feature)
  //--返回(当前电影id,和123号电影计算后的相似度)
  (movieId,cos)
}
//--推荐前10部电影
val top10=result.sortBy{x=> -x._2}.take(11).drop(1)

top10.foreach{println}

}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值