【机器学习入门】第29讲:推荐系统开发实战——从协同过滤到深度学习的个性化推荐

资源软件动作暨昝绳鹤锁多好 /494b36Tkwj😕
链接:https://pan.quark.cn/s/43159509c536
「微信被删好友检测工具」筷莱坌教狴犴狾夺郝 链接:https://pan.quark.cn/s/43159509c536
链接:https://pan.quark.cn/s/4598337f6b3e
「【美剧系列】」链接:https://pan.quark.cn/s/663e3ca79519

复制群口令 !0b7236TlXn!😕
将加入群聊免费医院分享

引言:如何让“千人千面”成为现实?

假设你正在为一家电商平台构建商品推荐引擎:

  • 目标:为每个用户实时推荐可能感兴趣的商品
  • 挑战
    • 用户行为稀疏(大多数用户仅浏览少量商品)
    • 需平衡推荐结果的准确性与多样性
    • 新商品/新用户的冷启动问题
  • 突破口:融合用户行为、商品内容与上下文信息,构建混合推荐系统

本文将深入推荐系统的核心技术,从经典算法到深度学习模型,揭秘个性化推荐的实现逻辑。


一、推荐系统基础架构

1.1 核心组件解析

模块功能关键技术
召回层从海量候选集中快速筛选千级候选协同过滤、Embedding检索
排序层对候选集精准排序深度学习模型(DeepFM、Wide&Deep)
重排层添加业务规则与多样性控制多样性抽样、上下文过滤

1.2 评估指标对比

指标定义适用场景
准确率(Precision@K)前K个推荐中用户喜欢的比例强调推荐准确性
召回率(Recall@K)用户喜欢的商品有多少被推荐出来关注覆盖率
NDCG@K考虑排序位置的加权得分综合评估排序质量
多样性(Intra-List Diversity)推荐列表内商品差异度避免推荐结果同质化

二、经典推荐算法实战

2.1 协同过滤(User-Based CF)

from surprise import Dataset, KNNBasic  

# 加载MovieLens数据集  
data = Dataset.load_builtin('ml-100k')  

# 构建用户协同过滤模型  
sim_options = {'user_based': True, 'name': 'cosine'}  
algo = KNNBasic(sim_options=sim_options)  
algo.fit(data.build_full_trainset())  

# 为用户ID=196推荐Top-5电影  
user_inner_id = algo.trainset.to_inner_uid('196')  
user_neighbors = algo.get_neighbors(user_inner_id, k=10)  
movie_ids = [algo.trainset.to_raw_iid(inner_id) for inner_id in user_neighbors]  

2.2 矩阵分解(SVD++)

from surprise import SVDpp  

# 训练SVD++模型  
algo = SVDpp(n_factors=20, n_epochs=10)  
algo.fit(data.build_full_trainset())  

# 预测用户对某商品的评分  
uid = str(196)  
iid = str(302)  
pred = algo.predict(uid, iid)  
print(f"预测评分:{pred.est:.2f}")  # 输出:4.23  

三、深度学习推荐模型

3.1 Wide&Deep模型架构

import tensorflow as tf  

# 定义双塔结构  
wide_input = tf.keras.layers.Input(shape=(num_wide_features,), name='wide_input')  
deep_input = tf.keras.layers.Input(shape=(num_deep_features,), name='deep_input')  

# Wide部分(记忆用户行为模式)  
wide_branch = tf.keras.layers.Dense(1, activation='sigmoid')(wide_input)  

# Deep部分(挖掘潜在特征交互)  
deep_branch = tf.keras.layers.Dense(128, activation='relu')(deep_input)  
deep_branch = tf.keras.layers.Dense(64, activation='relu')(deep_branch)  

# 合并输出  
combined = tf.keras.layers.concatenate([wide_branch, deep_branch])  
output = tf.keras.layers.Dense(1, activation='sigmoid')(combined)  

model = tf.keras.Model(inputs=[wide_input, deep_input], outputs=output)  

3.2 深度兴趣网络(DIN)

class DIN(tf.keras.Model):  
    def __init__(self, item_feature_dim):  
        super().__init__()  
        self.att_layer = tf.keras.layers.Dense(36, activation='sigmoid')  
        self.dense = tf.keras.layers.Dense(1, activation='sigmoid')  

    def call(self, user_embed, item_seq_embed, target_item_embed):  
        # 计算目标商品与历史序列的注意力权重  
        att_weights = self.att_layer(  
            tf.concat([item_seq_embed, tf.expand_dims(target_item_embed, 1)], axis=-1)  
        )  
        weighted_seq = tf.reduce_sum(item_seq_embed * att_weights, axis=1)  
        # 合并用户特征与加权序列  
        combined = tf.concat([user_embed, weighted_seq], axis=-1)  
        return self.dense(combined)  

四、实战案例:电商推荐系统开发

4.1 特征工程示例

特征类型示例处理方式
用户画像年龄、性别、购买力等级One-Hot编码
行为序列最近浏览的10个商品IDEmbedding + 平均池化
上下文特征访问时间、设备类型分桶编码

4.2 全流程代码(PySpark + TensorFlow)

# 步骤1:Spark处理用户行为日志  
from pyspark.sql import functions as F  

raw_log = spark.read.parquet("user_behavior/*.parquet")  
user_seq = raw_log.groupBy("user_id").agg(  
    F.collect_list("item_id").alias("item_seq"),  
    F.collect_list("timestamp").alias("time_seq")  
)  

# 步骤2:生成训练样本  
train_data = user_seq.join(item_features, "item_id").join(user_features, "user_id")  

# 步骤3:TensorFlow模型训练  
model = WideDeepModel()  
model.fit(  
    x={'wide_input': wide_data, 'deep_input': deep_data},  
    y=labels,  
    epochs=10,  
    batch_size=1024  
)  

五、冷启动与多样性优化

5.1 冷启动解决方案

场景策略实现方法
新用户基于人口统计特征推荐热门商品规则引擎 + 聚类分析
新商品内容相似推荐(文本/图像Embedding)ViT提取图像特征 + 余弦相似度
全冷启动知识图谱推理推荐Neo4j图数据库查询

5.2 多样性增强技术

def diversity_rerank(candidates, k=10, alpha=0.7):  
    """  
    多样性重排:平衡相关性得分与品类差异  
    """  
    scores = [(item.score, item) for item in candidates]  
    selected = []  
    categories = set()  
    for _ in range(k):  
        best = None  
        max_score = -np.inf  
        for i, (score, item) in enumerate(scores):  
            diversity = len(categories | {item.category}) / (len(categories) + 1)  
            combined = alpha * score + (1 - alpha) * diversity  
            if combined > max_score:  
                max_score = combined  
                best = i  
        selected.append(scores.pop(best)[1])  
        categories.add(selected[-1].category)  
    return selected  
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

凉亭下

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

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

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

打赏作者

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

抵扣说明:

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

余额充值