🕸️ 第10课:图神经网络推荐(LightGCN)

特征与模型 图神经网络

🎯 学习目标

🗂️ 课程定位

本课属于推荐系统进阶课程的特征与模型阶段。本阶段的学习目标是系统掌握该领域的核心算法与实践方法,为后续阶段打下坚实基础。

本阶段课程一览

📖 核心理论

图神经网络(GNN)将推荐系统建模为用户-物品二部图,通过消息传递在图上传播信息。LightGCN是2020年提出的轻量级GCN推荐模型,去掉了传统GCN中的非线性变换和权重矩阵,仅保留邻域聚合,效果却更好。

为什么图结构重要

NGCF → LightGCN

维度NGCFLightGCN
特征变换有(W₁)
非线性激活有(ReLU)
层组合拼接+权重简单平均
参数量仅embedding
效果更好

📐 数学公式

LightGCN传播

e_u^(k) = Σ_{i∈N(u)} (1/√|N(u)|·√|N(i)|) · e_i^(k-1)

每层只做邻域聚合,无权重矩阵

层组合

e_u = (1/(L+1)) Σ_{k=0}^{L} e_u^(k)

所有层的embedding取平均

预测

ŷ(u,i) = e_u^T · e_i

💻 代码实现

import numpy as np
np.random.seed(42)
print("="*60+"\n图神经网络推荐(LightGCN)\n"+"="*60)
n_users=30;n_items=20;n_nodes=n_users+n_items
# 构建用户-物品二部图
n_interactions=120
edges=[]
for _ in range(n_interactions):
    u=np.random.randint(n_users)
    i=np.random.randint(n_items)
    edges.append((u,n_users+i))
edges=list(set(edges))
print(f"用户:{n_users} 物品:{n_items} 边:{len(edges)}")
# 邻接矩阵
A=np.zeros((n_nodes,n_nodes))
for u,i in edges:A[u,i]=A[i,u]=1
# 度归一化
D=np.diag(A.sum(axis=1)**(-0.5))
D[np.isinf(D)]=0
A_norm=D@A@D
print(f"图密度:{len(edges)/(n_users*n_items):.4f}")
# 初始embedding
emb_size=16
E=np.random.randn(n_nodes,emb_size)*0.1
# LightGCN传播
def lightgcn_propagate(A_norm,E,n_layers=3):
    all_embs=[E]
    E_cur=E.copy()
    for l in range(n_layers):
        E_cur=A_norm@E_cur
        all_embs.append(E_cur)
    # 层组合(平均)
    final=np.mean(all_embs,axis=0)
    return final,all_embs
E_final,all_embs=lightgcn_propagate(A_norm,E)
print(f"\nLightGCN传播后embedding形状:{E_final.shape}")
# 推荐评分
user_embs=E_final[:n_users]
item_embs=E_final[n_users:]
scores=user_embs@item_embs.T
# 为用户0推荐
target=0;interacted=set(i for u,i in edges if u==target)
rec_scores=[(i,scores[target,i])for i in range(n_items)if i not in interacted]
rec_sorted=sorted(rec_scores,key=lambda x:-x[1])[:5]
print(f"\n用户0推荐Top-5:")
for i,s in rec_sorted:print(f"  物品{i}:分数={s:.4f}")
# 评估BPR
print("\n--- BPR训练LightGCN ---")
E_train=np.random.randn(n_nodes,emb_size)*0.01
lr=0.01;reg=0.001
for ep in range(50):
    for _ in range(200):
        u=np.random.randint(n_users)
        pos=[i-n_users for uu,i in edges if uu==u]
        neg=[i for i in range(n_items)if i not in pos]
        if not pos or not neg:continue
        i=np.random.choice(pos);j=np.random.choice(neg)
        E_f,_=lightgcn_propagate(A_norm,E_train)
        u_emb=E_f[u];i_emb=E_f[n_users+i];j_emb=E_f[n_users+j]
        x_uij=np.dot(u_emb,i_emb)-np.dot(u_emb,j_emb)
        grad=1/(1+np.exp(x_uij))
        # 简化梯度更新embedding
        E_train[u]-=lr*(-grad*(i_emb-j_emb)+reg*E_train[u])
        E_train[n_users+i]-=lr*(-grad*u_emb+reg*E_train[n_users+i])
        E_train[n_users+j]-=lr*(grad*u_emb+reg*E_train[n_users+j])
    if(ep+1)%10==0:
        E_f,_=lightgcn_propagate(A_norm,E_train)
        u_embs=E_f[:n_users];i_embs=E_f[n_users:]
        auc_vals=[]
        for u in range(min(15,n_users)):
            pos=[i-n_users for uu,i in edges if uu==u]
            neg=[i for i in range(n_items)if i not in pos]
            if not pos or not neg:continue
            sp=u_embs[u]@i_embs[pos].T
            sn=u_embs[u]@i_embs[neg].T
            auc_vals.append(np.mean(sp[:,None]>sn[None,:]))
        print(f"  Epoch{ep+1}:AUC={np.mean(auc_vals):.4f}")
# 层数影响
print("\nGCN层数影响:")
for n_layers in [1,2,3,4]:
    E_f,_=lightgcn_propagate(A_norm,E_train,n_layers)
    u_e=E_f[:n_users];i_e=E_f[n_users:]
    auc_v=[]
    for u in range(min(15,n_users)):
        pos=[i-n_users for uu,i in edges if uu==u]
        neg=[i for i in range(n_items)if i not in pos]
        if not pos or not neg:continue
        sp=u_e[u]@i_e[pos].T;sn=u_e[u]@i_e[neg].T
        auc_v.append(np.mean(sp[:,None]>sn[None,:]))
    print(f"  layers={n_layers}:AUC={np.mean(auc_v):.4f}")

🔴 运行结果

============================================================ 图神经网络推荐(LightGCN) ============================================================ 用户:30 物品:20 边:106 图密度:0.1767 LightGCN传播后embedding形状:(50, 16) 用户0推荐Top-5: 物品4:分数=0.0144 物品8:分数=0.0110 物品0:分数=0.0109 物品18:分数=0.0108 物品16:分数=0.0096 --- BPR训练LightGCN --- Epoch10:AUC=0.9417 Epoch20:AUC=0.9539 Epoch30:AUC=0.9574 Epoch40:AUC=0.9565 Epoch50:AUC=0.9557 GCN层数影响: layers=1:AUC=0.9659 layers=2:AUC=0.9571 layers=3:AUC=0.9557 layers=4:AUC=0.9431

✅ 验证通过

🔍 代码解读

本课代码涵盖了从数据生成、模型训练到效果评估的完整流程。以下是关键步骤的详细解读:

  1. 数据准备:生成模拟数据,确保算法可在本地运行验证。工业场景中需替换为真实数据。
  2. 模型训练:实现核心算法的SGD/ALS等优化过程,关注学习率和正则化的选择。
  3. 推荐生成:基于训练好的模型为用户生成推荐列表,排除已交互物品。
  4. 效果评估:使用Precision/Recall/NDCG/AUC等指标评估推荐质量。
  5. 方法对比:多种方法横向对比,理解不同算法的优劣。

代码设计原则:简洁可读、关键步骤有注释、结果可复现(固定随机种子)。

代码运行环境

组件版本说明
Python3.8+推荐3.10版本
NumPy1.21+核心数值计算库
SciPy1.7+统计检验(部分课程)

代码扩展建议

💡 关键洞察

GCN推荐的优势

挑战与方向

📝 本章小结

本课是第10课:图神经网络推荐(LightGCN),属于特征与模型阶段。我们系统学习了本课的核心概念、数学原理和代码实现,并通过实机运行验证了算法的正确性。

核心要点回顾

  1. 理解图结构在推荐中的重要性
  2. 掌握LightGCN的核心设计
  3. 实现简化版GCN推荐
  4. 理解GCN推荐的优势与挑战

实践建议

常见误区

🧪 练习

练习1:实现NGCF(带特征变换)并与LightGCN对比

练习2:调整GCN层数1-4层,观察过平滑现象

练习3:实现mini-batch GraphSAGE采样训练

练习4:在LightGCN中加入社交关系图

📚 延伸阅读

推荐论文

推荐资源

💼 面试考点

高频面试题

  1. 请简述本课核心算法的原理、优缺点和适用场景。
  2. 如何评估推荐系统的效果?离线指标和在线效果为什么会有差异?
  3. 推荐系统面临的核心挑战有哪些?分别如何解决?
  4. 请描述推荐系统的完整架构,从数据到展示的全流程。
  5. 如何处理冷启动问题?有哪些具体方案?

答题技巧

🏭 工业案例

大厂推荐实践

公司场景核心技术
字节跳动抖音/TikTok多目标排序+实时特征+双塔召回
阿里巴巴淘宝推荐DIN/DIEN序列模型+MIND多兴趣
腾讯微信看一看DeepFM+图神经网络召回
美团本地生活推荐多场景多目标+时空特征
Netflix视频推荐矩阵分解+深度学习混合

工程要点

规模参考

🏆 本课成就

✅ 理解图结构在推荐中的重要性

✅ 掌握LightGCN的核心设计和传播公式

✅ 实现简化版GCN推荐模型

✅ 理解GCN推荐的挑战与改进方向

推荐系统进阶·第10/30课·Powered by OpenClaw