基于内容的推荐(Content-Based Recommendation)通过分析物品的内容特征(文本、标签、属性等),找到与用户历史偏好相似的物品进行推荐。核心思想:推荐与你过去喜欢的物品内容相似的东西。
| 类型 | 方法 | 示例 |
|---|---|---|
| 文本 | TF-IDF/BERT | 商品描述、新闻正文 |
| 标签 | 多热编码 | 商品类别、品牌 |
| 属性 | 数值/类别编码 | 价格区间、颜色 |
| 图像 | CNN特征 | 商品图片、视频封面 |
TF(t,d) = 词t在文档d中的出现次数 / 文档d的总词数
IDF(t) = log((N+1)/(df(t)+1)) + 1
TF-IDF(t,d) = TF(t,d) × IDF(t)
cos(a,b) = (a·b) / (||a||·||b||)
profile(u) = (1/|I_u|) Σ tfidf(i), i∈I_u
或加权平均:profile(u) = Σ r_ui·tfidf(i) / Σ r_ui
import numpy as np
from collections import defaultdict
import math
np.random.seed(42)
print("="*60+"\n基于内容的推荐系统\n"+"="*60)
# 模拟物品内容特征
n_items=20;n_tags=10
tags=[f"标签{j}"for j in range(n_tags)]
items=[f"物品{i}"for i in range(n_items)]
# 物品-标签矩阵
item_tags=np.random.random((n_items,n_tags))>0.7
item_tags=item_tags.astype(float)
print(f"物品数:{n_items} 标签数:{n_tags}")
print(f"平均每物品标签数:{item_tags.sum(axis=1).mean():.1f}")
# TF-IDF计算
def compute_tfidf(matrix):
n_docs,n_terms=matrix.shape
tf=matrix.copy()
# 归一化TF
row_sums=tf.sum(axis=1,keepdims=True)
row_sums[row_sums==0]=1
tf=tf/row_sums
# IDF
df=np.sum(matrix>0,axis=0)
idf=np.log((n_docs+1)/(df+1))+1
return tf*idf
tfidf=compute_tfidf(item_tags)
print("\nTF-IDF矩阵形状:",tfidf.shape)
print("物品0的TF-IDF:",[f"{v:.3f}"for v in tfidf[0]if v>0])
# 内容相似度(余弦)
def cosine_sim_matrix(M):
norm=np.linalg.norm(M,axis=1,keepdims=True)
norm[norm==0]=1
M_norm=M/norm
return M_norm@M_norm.T
content_sim=cosine_sim_matrix(tfidf)
print(f"\n内容相似度矩阵形状:{content_sim.shape}")
# 找最相似物品
target=0
sim_scores=content_sim[target]
sim_scores[target]=-1
top_sim=np.argsort(sim_scores)[-5:][::-1]
print(f"\n与物品0最相似的5个物品:")
for i in top_sim:
common_tags=np.where((item_tags[target]>0)&(item_tags[i]>0))[0]
print(f" 物品{i}:相似度={sim_scores[i]:.4f} 共同标签={[tags[j]for j in common_tags]}")
# 用户画像
n_users=15
user_profiles={}
for u in range(n_users):
n_liked=np.random.randint(2,6)
liked=np.random.choice(n_items,size=n_liked,replace=False)
profile=tfidf[liked].mean(axis=0)
user_profiles[u]=profile
# 基于内容推荐
def content_recommend(user_id,user_profiles,tfidf,top_k=5):
profile=user_profiles[user_id]
scores=tfidf@profile
# 排除已交互物品
liked_items=set(np.where(item_tags@profile>0)[0])
scored=[(i,s)for i,s in enumerate(scores)if i not in liked_items]
return sorted(scored,key=lambda x:-x[1])[:top_k]
print("\n基于内容推荐:")
for u in range(5):
rec=content_recommend(u,user_profiles,tfidf)
print(f" 用户{u}推荐:{[(f'物品{i}',f'{s:.3f}')for i,s in rec]}")
# 评估
def eval_content(user_profiles,tfidf,n_users):
precisions=[]
for u in range(n_users):
profile=user_profiles[u]
scores=tfidf@profile
# 随机隐藏1个交互
liked=np.where(item_tags@profile>0)[0]
if len(liked)<2:continue
hidden=np.random.choice(liked)
train_liked=[i for i in liked if i!=hidden]
profile_train=tfidf[train_liked].mean(axis=0)
scores_train=tfidf@profile_train
rec=np.argsort(scores_train)[-5:]
if hidden in rec:precisions.append(1)
else:precisions.append(0)
return np.mean(precisions)
prec=eval_content(user_profiles,tfidf,n_users)
print(f"\nHitRate@5:{prec:.4f}")
# 词汇覆盖率
tag_coverage=np.mean(np.any(tfidf>0,axis=0))
print(f"标签覆盖率:{tag_coverage:.2%}")
# 内容多样性
diversities=[]
for u in range(n_users):
rec=content_recommend(u,user_profiles,tfidf,top_k=5)
if len(rec)<2:continue
rec_items=[i for i,_ in rec]
sim_pairs=[]
for i in range(len(rec_items)):
for j in range(i+1,len(rec_items)):
sim_pairs.append(content_sim[rec_items[i],rec_items[j]])
diversities.append(1-np.mean(sim_pairs))
print(f"推荐列表多样性(1-平均相似度):{np.mean(diversities):.4f}")
✅ 验证通过
本课代码涵盖了从数据生成、模型训练到效果评估的完整流程。以下是关键步骤的详细解读:
代码设计原则:简洁可读、关键步骤有注释、结果可复现(固定随机种子)。
| 组件 | 版本 | 说明 |
|---|---|---|
| Python | 3.8+ | 推荐3.10版本 |
| NumPy | 1.21+ | 核心数值计算库 |
| SciPy | 1.7+ | 统计检验(部分课程) |
本课是第6课:基于内容的推荐,属于基础方法阶段。我们系统学习了本课的核心概念、数学原理和代码实现,并通过实机运行验证了算法的正确性。
练习1:实现Word2Vec替换TF-IDF构建物品表示
练习2:加入标签权重(不同标签对用户的重要性不同)
练习3:实现基于内容的冷启动推荐(新用户注册时选择兴趣标签)
练习4:对比TF-IDF和BERT特征的推荐效果
| 公司 | 场景 | 核心技术 |
|---|---|---|
| 字节跳动 | 抖音/TikTok | 多目标排序+实时特征+双塔召回 |
| 阿里巴巴 | 淘宝推荐 | DIN/DIEN序列模型+MIND多兴趣 |
| 腾讯 | 微信看一看 | DeepFM+图神经网络召回 |
| 美团 | 本地生活推荐 | 多场景多目标+时空特征 |
| Netflix | 视频推荐 | 矩阵分解+深度学习混合 |
✅ 理解基于内容推荐的核心流程
✅ 掌握TF-IDF和内容画像的构建
✅ 实现基于内容的推荐并评估
✅ 理解内容推荐的优势与局限