离线用户基于内容召回集

3.5 离线用户基于内容召回集

学习目标

  • 目标
    • 知道离线内容召回的概念
    • 知道如何进行内容召回计算存储规则
  • 应用
    • 应用spark完成离线用户基于内容的协同过滤推荐

3.5.1 基于内容召回实现

  • 目的:实现定时离线更新用户的内容召回集合
  • 步骤:
    • 1、过滤用户点击的文章
    • 2、用户每次操作文章进行相似获取并进行推荐

过滤用户点击的文章

ur.spark.sql("use profile")
user_article_basic = ur.spark.sql("select * from user_article_basic")
user_article_basic = user_article_basic.filter('clicked=True')

用户每次操作文章进行相似获取并进行推荐

# 基于内容相似召回(画像召回)
ur.spark.sql("use profile")
user_article_basic = self.spark.sql("select * from user_article_basic")
user_article_basic = user_article_basic.filter("clicked=True")

def save_content_filter_history_to__recall(partition):
    """计算每个用户的每个操作文章的相似文章,过滤之后,写入content召回表当中(支持不同时间戳版本)
    """
    import happybase
    pool = happybase.ConnectionPool(size=10, host='hadoop-master')

    # 进行为相似文章获取
    with pool.connection() as conn:

        # key:   article_id,    column:  similar:article_id
        similar_table = conn.table('article_similar')
        # 循环partition
        for row in partition:
            # 获取相似文章结果表
            similar_article = similar_table.row(str(row.article_id).encode(),
                                                columns=[b'similar'])
            # 相似文章相似度排序过滤,召回不需要太大的数据, 百个,千
            _srt = sorted(similar_article.items(), key=lambda item: item[1], reverse=True)
            if _srt:
                # 每次行为推荐10篇文章
                reco_article = [int(i[0].split(b':')[1]) for i in _srt][:10]

                # 获取历史看过的该频道文章
                history_table = conn.table('history_recall')
                # 多个版本
                data = history_table.cells('reco:his:{}'.format(row.user_id).encode(),
                                           'channel:{}'.format(row.channel_id).encode())

                history = []
                if len(data) >= 2:
                    for l in data[:-1]:
                        history.extend(eval(l))
                else:
                    history = []

                # 过滤reco_article与history
                reco_res = list(set(reco_article) - set(history))

                # 进行推荐,放入基于内容的召回表当中以及历史看过的文章表当中
                if reco_res:
                    # content_table = conn.table('cb_content_recall')
                    content_table = conn.table('cb_recall')
                    content_table.put("recall:user:{}".format(row.user_id).encode(),
                                      {'content:{}'.format(row.channel_id).encode(): str(reco_res).encode()})

                    # 放入历史推荐过文章
                    history_table.put("reco:his:{}".format(row.user_id).encode(),
                                      {'channel:{}'.format(row.channel_id).encode(): str(reco_res).encode()})

        conn.close()

user_article_basic.foreachPartition(save_content_filter_history_to__recall)
  • 1、获取用户点击的某文章相似文章结果并排序过滤
    • 相似结果取出TOPK:根据实际场景选择大小,10或20
# 循环partition
for row in partition:
    # 获取相似文章结果表
    similar_article = similar_table.row(str(row.article_id).encode(),
                                        columns=[b'similar'])
    # 相似文章相似度排序过滤,召回不需要太大的数据, 百个,千
    _srt = sorted(similar_article.items(), key=lambda item: item[1], reverse=True)
    if _srt:
        # 每次行为推荐若干篇文章
        reco_article = [int(i[0].split(b':')[1]) for i in _srt][:10]
  • 2、过滤历史召回的所有文章(所有的召回类型)
# 获取历史看过的该频道文章
history_table = conn.table('history_recall')
# 多个版本
data = history_table.cells('reco:his:{}'.format(row.user_id).encode(),
                           'channel:{}'.format(row.channel_id).encode())

history = []
if len(data) >= 2:
    for l in data[:-1]:
        history.extend(eval(l))
else:
    history = []

# 过滤reco_article与history
reco_res = list(set(reco_article) - set(history))
  • 3、对结果进行存储,历史推荐存储
# 进行推荐,放入基于内容的召回表当中以及历史看过的文章表当中
if reco_res:
    # content_table = conn.table('cb_content_recall')
    content_table = conn.table('cb_recall')
    content_table.put("recall:user:{}".format(row.user_id).encode(),
                      {'content:{}'.format(row.channel_id).encode(): str(reco_res).encode()})

    # 放入历史推荐过文章
    history_table.put("reco:his:{}".format(row.user_id).encode(),
                      {'channel:{}'.format(row.channel_id).encode(): str(reco_res).encode()})
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Echo-Niu

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值