个人学习记录,如有错漏请见谅!
GCN学习笔记:Graph Convolution Network(GCN)学习记录
Intro
GCN里的特征转换和非线性激活没用,移除之后甚至提高模型的准确性
因此LightGCN只包含了GCN里面最关键的部分:邻居聚合
user-item graph
该部分为此视频笔记
以及该Lecture 13的ppt
把用户和商品的交互建模成二部图:如下图所示
二部图的两个条件
1.节点有两类:分为用户和商品(节点类型更多的话就是异构图)
2.每条边连接的两个节点分别属于不同的类别(因此用户和用户之间没有关系,商品和商品之间也没有关系)
于是预测推荐结果的问题就转化为预测一个用户节点和一个商品节点之间有没有边link的问题--------link prediction
矩阵分解 Matrix Factorization
邻接矩阵A的维度:users+items,如下图所示
user-user和item-item矩阵:元素全为0,因为user-item graph作为二部图不允许同类型节点之间有联系
对矩阵R做矩阵分解,得到user embedding matrix和item embedding matrix,再点乘得到新矩阵作为推荐依据
为什么用图神经网络而不是矩阵分解
1.矩阵分解精度不够高
2.图神经网络可以解决特定的问题
图神经网络
why embedding:需要打分方程给每条用户和商品的边打分,推荐的时候,取前K个分数最高的商品推荐给用户(前提是未推荐过)
边的得分=用户和商品的embedding作为输入,经过打分方程后的输出
为什么loss function不用MSE或者交叉熵损失:
不能对评价指标recall@K使用梯度下降,MSE和cross entropy loss不便计算,就用surrogate loss function(代理损失函数:binary loss或BPR)
代理损失函数:
定义并使用了正负采样(E为positive edges,Eneg为negative edges)
加上sigmoid function
让正样本的分数高于负样本的分数
binary loss:如下图所示
但是binary loss有问题:如下图所示
例子:如下图所示
模型给每个用户-商品对都计算一个分数
边预测的结果是对的但是binary loss仍然会惩罚模型-------因为没有个性化
总结:所以代理损失函数需要“个性化”------要求每个用户正样本的分数高于负样本的分数而不是所有用户中正样本的分数高于负样本的分数--------使用BPR loss (Bayesian Personalized
Ranking)
步骤:
1.学习到user和item的embedding
2.设计损失函数,如下图所示------目的:使正样本的预测结果远大于负样本的预测结果(考虑user和item的映射关系)-------BPR优化中的正负样本(正样本是有过交互的用户-商品对,负样本是没有交互的用户-商品对)
在minibatch上使用BPR:如下图所示
minibatch在所有用户中采样Umini个用户
在Umini这个子集中,对每一个用户,采样他的一条正样本和一些负样本
计算minibatch上的loss(是minibatch上所有用户loss的加和,就是上面final BPR loss在minibatch上的应用)
该PPT后面有分析NGCF和LightGCN
课程视频
以下笔记为该视频的学习记录
因为每一次梯度下降都会遍历数据集,为了降低cost,使用SGD随机梯度下降
SGD与minibatch有关,不是在整个数据集上做梯度下降,而是在一小批数据点上做梯度下降
batch:minibatch中数据点的个数
iteration:在minibatch上做一次随机梯度下降 iteration=dataset size/batch size
epoch:处理多少个minibatch直到遍历完整个数据集
如下图所示
如何计算梯度:如下图所示
如果f是数,那么参数W是向量,因为向量相乘(点积)结果为数
如果f是向量,那么参数W是权重矩阵,因为矩阵相乘结果为矩阵
前向/反向传播:
先反向传播计算梯度,再前向传播计算输出结果
如下图所示
Random walk
该部分为视频学习笔记
loss function如下图所示
黄色框里的就是softmax
3.推荐系统预测全过程,如下图所示
(1)根据user-item graph 构建邻接矩阵A
(2)邻接矩阵输入模型中,得到模型预测的user和item的embedding(图中用颜色作为区分)
(3)user embedding matrix和itemembedding matrix做点乘,得到新的user-item矩阵,分数高的商品可以被推荐给用户
怎么衡量模型好坏
recall@ K2
Pu是计算出的新的user-item矩阵中的正样本
Ru是推荐的样本,因为有可能没有排除已经交互过的商品所以Ru在图中并不属于Pu
最后recall的结果是每个用户被推荐的未交互过的正样本加和再除以总的用户数量
如下图所示
论文创新点
1.表明GCN里的特征转换和非线性激活没正面作用,做了消融实验
2.提出LightGCN模型,只包含邻居聚合,简化模型设计
3.把LightGCN和NGCF比较
NGCF解释
用户和商品的embedding通过GCN得到,输入包括自己的信息和邻居的信息,这个公式就是GCN的公式
为什么非线性激活方程和特征变化在推荐系统中没有用
对比:
在GCN原论文中(半监督的节点分类),每个节点都有丰富的语义特征作为输入(比如节点的各种信息)
在协同过滤中,在用户-商品交互图中的节点只有ID作为输入(并没有实际语义)
因此非线性激活方程和特征变化不仅没有优化模型,反而增加了模型训练的难度
做消融实验得出的结论
(1) NGCF 和 NGCF-f对比,NGCF-n和NGCF-fn 对比:加入W1,W2这样的特征变换矩阵使模型效果变差
(2)NGCF 和NGCF-n:有特征变换时加入非线性激活方程,模型效果变化不明显;
NGCF-f和NGCF-fn:没有特征变换时加入非线性激活方程,模型效果变差
(3)NGCF和NGCF-fn:同时加入特征变换和非线性激活方程对模型产生负面影响
结论
从图像中看出:
是训练的困难度导致NGCF模型恶化而不是过拟合
(原因我觉得是从论文中的4幅图像中看出过拟合的图像不是这样的曲线?而额外useless的操作:feature transformation and nonlinear activation function导致训练模型更加困难)
提出模型LightGCN
Light Graph Convolution (LGC)
可以看到简化了GCN的公式
值得注意的是:LGC只聚合了相连的邻居的信息,并不聚合目标节点自己的信息
这样做的原因是:下面的The layer combination operation完成了和self-connections一样的效果
Layer Combination and Model Prediction.
这样LightGCN中可训练的模型参数只有一开始所有用户和商品的信息
怎样得到每个节点最后的表达:使用权重ak表达第k层embedding在最终表达中的重要性
设定ak=1/(K+1)
所以最终embedding=从0…(k-1)的embedding相加再除以(K+1)
(这样实现了self-connections一样的效果)
别的模型是聚合后直接得到final embedding,而LightGCN多做了ak这一步sum
补充:
编码器:把节点映射到向量
节点相似度方程:点积—cos余弦
(两向量正交—不相似-----点积小
两向量越相似------点积越大)
解码器:把向量变成相似度分数
为什么用layer combination to get final representations
(1)随着GCN层数越来越大,会导致节点的embedding过平滑问题(所有节点的embedding很相似),所以不能简单的使用最后一层的embedding
(2)不同层的embedding捕捉不同的信息
(3)这样做可以捕捉到self-connections,
定义模型预测结果
用户和商品最后表示的内积
作为推荐生产的排名分数
矩阵形式
A表示用户-商品图的邻接矩阵,形式和GCN的基本相同
但是注意到矩阵都不包含self-connections(不包含单位矩阵)
模型分析
(1)和SGCN比较:通过层结合,LightGCN加入了节点自连接的效果所以LightGCN没有再邻接矩阵中加入自连接(就是在邻接矩阵的基础上加上单位阵)
SGCN就在邻接矩阵中就加入自连接(单位阵)如下图所示
模型训练
总流程
如下图所示
预测头 prediction head
该部分为课程链接的笔记,P24
为什么需要预测头:因为同一个图可能需要解决不同类型的问题(节点层面的问题,边层面的问题,图整个全局层面的问题)
节点层面的预测:见下图
GNN计算后,得到d维向量,如果想做k种分类任务,就用矩阵W乘上embedding得到预测结果,其中矩阵W把embedding从d维空间映射到k维空间
边层面的预测:同时使用两个节点的信息
第一种方法:见下图
先把两个节点的embedding连接起来concatenate,再做linear,把2d维的向量变成k维的向量
第二种方法:见下图
做点积,但是只能得到一个预测结果
为了得到多个结果:使用可训练的不同的矩阵W,再concatenate得到最终的一个预测结果
图层面的预测:使用所有节点的embedding
global pooling的方法包括global mean pooling,global max pooling,global sum pooling
但是global pooling可能无法有效的区分两个结构非常不同的图,见下图所示
解决方法:分层池化,具体如下图所示
aggregate hierarchically
怎样得知哪些节点先放在一起被池化?(正如上图所示的节点分组,先2再3)-------利用图的社区结构-------集群
要做到这一点,只需要应用简单的识别图中聚类的算法
如下图所示
Loss Function
不同的loss function在不同的任务中使用:
for classification对于分类:最常用交叉熵损失函数cross entropy loss(Lecture 6)如下图所示
模型的总损失就是单个数据loss的和
for regression对于回归:mean squared error (MSE)a.k.a. L2 Loss,如下图所示
evaluation metric评价模型好坏
对于稀疏的任务,eg.欺诈预测中99%的边是诈骗,那么有偏见的模型只要一直预测诈骗就可以得到99%的准确率,这显然是不合理的
下面是一些评价指标:如图所示,使用confusion matrix
accuracy:预测结果正确的样本数/(预测样本数+实际结果数,即数据集)
precision:在预测为1的样本中,有多少样本是预测正确的
recall:在实际为1的样本中,有多少样本是预测正确的
ROC Curve:如下图所示
完美的分类器的曲线是:先迅速上升然后在1处保持直线-------所以完美的分类器在图中所占面积为1
虚线为随机分类器的曲线,所占面积为0.5
回到论文:
loss function是BPR加L2
minibatch
不使用dropout机制-------dropout为了防止过拟合,但是没有特征变换矩阵W,所以加上的L2正则足够防止过拟合
实验部分
yelp2018的数据版本不同
evaluation metric是recall@20 and ndcg@20
LightGCN既和NGCF比,又和其他SOTA方法比
对LightGCN做了消融实验
(1)比较LightGCN and its variant LightGCN-single(不包含最后的层结合):GCN层数作为图像横轴
随着层数加大,LightGCN-single的效果先变好在变坏,而LightGCN的效果没有变坏,说明层结合可以解决过平滑问题
因为在不同数据集上LightGCN有可能表现的不如LightGCN-single,而LightGCN-single是LightGCN在超参数ak上的变体,说明调节超参数ak可以提高LightGCN的效果
(2)symmetric sqrt normalization
比较LightGCN和LightGCN-L,LightGCN和LightGCN-R:把两边任意一个sqrt normalization去掉都会导致模型效果下降
(3)Embedding Smoothness:embedding相似性
LightGCN高效的关键是Embedding Smoothness
定义了用户embedding的相似性的公式
用SU和MF比较:用轻量级的图卷积,embedding就变得更相似/平滑-----更适合推荐
研究超参数λ:
LightGCN对λ不敏感------说明LightGCN不太容易过拟合