【资源软件】 动作暨昝绳鹤锁多好 /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个商品ID | Embedding + 平均池化 |
上下文特征 | 访问时间、设备类型 | 分桶编码 |
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