PYTHON_SPARK 基于物品协通过滤推荐算法离线化实现

PYTHON_SPARK 基于物品协通过滤推荐算法离线化实现

本文主要内容

  1. 算法介绍
  2. spark介绍
  3. 算法实现的基本流程
  4. 代码分部详解
  5. 完整代码

1. 算法介绍

在这里插入图片描述
Wij表示标号i.j物品的相似度。
U(i,j)表示同时对i,j有评分的用户集合

2 . spark介绍

spark算子大致分为两类
1 Transformation 变换/转换算子,这种算子并不提交作业,完成作业过程中间转换处理。
Transformation操作是延迟计算的,也就是说从一个RDD生成转换生成另一个RDD转换操作不是马上执行,需要等到有action操作时才会真正触发运算。
2 Action 行动算子:这类算子会出发SparkContext提交Job 作业。
Action 算子会触发 Spark 提交作业(Job),并将数据输出 Spark系统。

本文中使用到的算子

Transformation 类算子:
(1) map
通过对这个RDD的每个元素应用一个人函数返回一个新的RDD
(2)flatmap
将结果扁平化,从而返回一个新的RDD
(3)reduceByKey
与groupByKey类似,却有不同。如(a,1), (a,2), (b,1), (b,2)。groupByKey产生中间结果为( (a,1), (a,2) ), ( (b,1), (b,2) )。而reduceByKey为(a,3), (b,3)。
reduceByKey 功能是聚合,groupByKey是分组

Action 类算子:
(1)groupByKey 将所有的数据划分入新的分区,在进行计算。若一个键对应的值太多,会导致内存溢出。

3 . 算法实现的基本流程

输入:user_id,item_id,rating
输出:item 对 item 的评分
(1)按商品分组,统计用户对商品的评分
(2)对评分进行归一化
(3)对所有的评分求和,得到item 对item的评分

4.代码分部详解

(1)对数据进行整理,用户对相同item评分的划分为一组

ResultRDD = rdd.map(lambda x:(x['item_id'],x['user_id'] + '+' + str(x['scope'])))
UserItem = ResultRDD.groupByKey().map(lambda x:(x[0],list(x[1])))

输出:
[(u’9428’,
[u’237472+5’,
u’199815+5’,
u’170943+5’,
…]),
(u’10299’,
[u’680727+3’,
u’2155030+2’,
u’436492+3’]))]

(2)对评分进行归一化处理,限制数据的取值范围,保证数据的准确性,可参考性

def guiyi(data):
        item = data[0]
           user_items = data[1]
        sum = 0.0
        user_score_list = []

 	 for user_item in  user_items:
                user,s = user_item.split("+")
                sum += pow(int(s), 2)
        sum = math.sqrt(sum)

        for user_item in  user_items:
                 user,s = user_item.split("+")
                 user_score_list.append((user, item + "+" + str(float(s) / sum)))
        return user_score_list

def fl(data):
        return data
        
UserItemGy = UserItem.map(guiyi).flatMap(fl).groupByKey().map(lambda x:(x[0],list(x[1])))

输出:关于user 对 item 评分的集合
[(u’1308915’,
[u’9939+0.3194382825’,
u’10016+0.157407137505’,
u’10122+0.3194382825’,
u’10157+0.143149583578’,
…]),
(u’480835’,
[u’10344+0.316227766017’,
u’9535+0.105245666994’,
u’9614+0.490290337845’,
…])]
(3) 得出物品对物品的评分,两两取对,相加得出分数

def pair(data):
        user = data [0]
        item_score_list = data[1]
        items = []
        for i in range(0, len(item_score_list) - 1):
                for j in range(i + 1, len(item_score_list)):
                        item_a, score_a = item_score_list[i].split("+")
                        item_b, score_b = item_score_list[j].split("+")
                        score = float(score_a) * float(score_b)
                        items.append((item_a + " + " + item_b , score))
                        items.append((item_b + " + " + item_a , score))
        return items
UserItemSum = UserItemGy.map(pair).flatMap(fl).reduceByKey(lambda a, b: a + b)

输出:物品对物品的评分
[(u’10242 + 10309’, 0.04500002249999824),
(u’9657 + 9523’, 0.09382332812997889),
(u’9756 + 10259’, 0.012972730388020742)]

5. 完整代码

def fl(data):
        return data
def guiyi(data):
        item = data[0]
        user_items = data[1]
        sum = 0.0
        user_score_list = []

        for user_item in  user_items:
                user,s = user_item.split("+")
                sum += pow(int(s), 2)
        sum = math.sqrt(sum)

        for user_item in  user_items:
                 user,s = user_item.split("+")
                 user_score_list.append((user, item + "+" + str(float(s) / sum)))
        return user_score_list

def pair(data):
        user = data [0]
        item_score_list = data[1]
        items = []
        for i in range(0, len(item_score_list) - 1):
                for j in range(i + 1, len(item_score_list)):
                        item_a, score_a = item_score_list[i].split("+")
                        item_b, score_b = item_score_list[j].split("+")
                        score = float(score_a) * float(score_b)
                        items.append((item_a + " + " + item_b , score))
                        items.append((item_b + " + " + item_a , score))
        return items


ResultRDD = rdd.map(lambda x:(x['item_id'],x['user_id'] + '+' + str(x['scope'])))

UserItem = ResultRDD.groupByKey().map(lambda x:(x[0],list(x[1])))

UserItemGy = UserItem.map(guiyi).flatMap(fl).groupByKey().map(lambda x:(x[0],list(x[1])))

UserItemSum = UserItemGy.map(pair).flatMap(fl).reduceByKey(lambda a, b: a + b)
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值