ALS 是 spark 的协同过滤算法,已集成到 Spark 的 mllib 库中
使用anaconda的jupyter开发,交互性好
数据集:
电影数据集 ml-100k.zip,下载地址:https://grouplens.org/datasets/movielens/
其中,u.dat是用户评分数据(包括用户id、电影id、评分、日期)
u.item是电影数据(包括电影id、电影名)
准备工作:
1. 启动hadoop cluster:start-all.sh
2. 上传测试文件:hadoop fs -put ml-100k /test
(ml-100k所在目录打开终端,上传到hdfs文件系统 /test)
3. jupyter启动pyspark
本地模式:
PYSPARK_DRIVER_PYTHON="jupyter" PYSPARK_DRIVER_PYTHON_OPTS="notebook" pyspark
yarn-client模式:
PYSPARK_DRIVER_PYTHON="jupyter" PYSPARK_DRIVER_PYTHON_OPTS="notebook" MASTER=yarn-client pyspark
4. 新建notebook,ALS.ipynb
完整代码:
# 文件路径
global Path
if sc.master[0:5]=="local":
Path = "file:/root/PycharmProjects/dataset/ml-100k/"
else:
Path = "hdfs://hadoop01:9000/test/ml-100k/"
#path
# 读取数据
rawUserData = sc.textFile(Path+"u.data")
#rawUserData.count()
#rawUserData.take(5)
# 分割、取前三列
rawRating = rawUserData.map(lambda line:line.split("\t")[:3])
#rawRating.take(5)
# 读取电影名称
itemRDD = sc.textFile(Path+"u.item")
# 分割,map转换为(电影id,电影名),转换为字典
movieTitle = itemRDD.map(lambda line:line.split("|"))\
.map(lambda item:(int(item[0]),item[1]))\
.collectAsMap()
#movieTitle
# 用户数量
#numUsers = rawRating.map(lambda x:x[0]).distinct().count()
#numUsers
# 电影数量
#numMovies = rawRating.map(lambda x:x[1]).distinct().count()
#numMovies
# 训练模型
from pyspark.mllib.recommendation import ALS
model = ALS.train(rawRating,10,10,0.01)
#model
# 使用模型进行推荐
#1. 针对用户推荐电影
#model.recommendProducts(100,5) # 针对id为100的用户推荐5部电影
#2 针对电影推荐用户
# model.recommendUsers(product=200,num=5) # 针对id为200的电影推荐5个用户
# 针对用户推荐电影
recommendP = model.recommendProducts(100,5)
for P in recommendP:
user=P[0] # 用户id
movie = movieTitle[P[1]] # 电影名
rating = P[2] # 推荐评分
print("对用户 "+str(user)+" 推荐电影 "+movie+" 推荐评分 "+str(rating))