源码分析:LightGCN的构图过程

604 阅读2分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第1天,点击查看活动详情

通过对LightGCN源码进行分析,学习LightGCN的建图的初始化过程以更好的使用该模型,后续建图可结合上一篇构造拉普拉斯矩阵

LightGCN

LightGCN和NGCF一样都是获取协同过滤中的高阶连通信号,本质上还是构建了多个子图,把子图拼接为一个大图的形式进行邻域传播

  1. LightGCN作为NGCF的优化版,去掉了邻域聚合过程中的特征变换和非线性激活部分
  2. LightGCN和NGCF一样,其输入只有user和item的id_embedding信息,没有携带更多的特征信息,直接把LightGCN应用到diffnet系列模型上需要考虑处理补充的特征信息问题

LightGCN使用的数据集

以论文中源码给出的yelp2018数据集为例,

通过item_list.txt和user_list.txt中给出的映射表,把用22位字符串表示的user_id和item_id映射为对应的数值型表示。其中item有28048项,user有31668项。交互的分布符合长尾理论的结果,但与原yelp数据集相比缺失了描述user和item分组信息。

最新的yelp数据集中item已经超过了两百万条,如果还是用该方法做映射容易发生丢失等问题。

在train.txt和test.txt中,第一列记录user_id,其余列记录的和该user有交互的item_id列表。 train、节选.png

上图为train.txt截选展示

LightGCN加载数据和生成初始图表示的过程

在dataloader.py\Loader\init()中

过程简述:

  1. 读取train.txt,生成对应的三个array数组:trainUinqueUsers, trainUser, trainItem
  2. 生成初始的稀疏CSR矩阵:UserItemNet
  3. 生成拉普拉斯矩阵,用于矩阵传播

源码分析

with open(train_file) as f:     # 打开训练集
    for l in f.readlines():     # 按行读取
        if len(l) > 0:
            l = l.strip('\n').split(' ')    # 去除前后的换行符,然后根据空格分割
            items = [int(i) for i in l[1:]] # 第一列是user_id,后面的是item_id
            uid = int(l[0])                 # 提取user_id
            trainUniqueUsers.append(uid)    # 添加到列表中
            trainUser.extend([uid] * len(items))    # extend在表尾追加元素
            trainItem.extend(items)                 # 表尾追加元素
            self.m_item = max(self.m_item, max(items))  # max_item_id
            self.n_user = max(self.n_user, uid)         # max_user_id
            self.traindataSize += len(items)            # size扩大
self.trainUniqueUsers = np.array(trainUniqueUsers)      # 转为数组
self.trainUser = np.array(trainUser)                    
self.trainItem = np.array(trainItem)                    

步骤1:读取文件生成数组

self.UserItemNet = csr_matrix((np.ones(len(self.trainUser)),(self.trainUser, self.trainItem)),\
shape=(self.n_user, self.m_item))

步骤2:生成CSR稀疏矩阵

scipy.sparse.csr_matrix((data, (row_ind, col_ind)), shape=(x,y))矩阵的压缩表示

数据集中只考虑有无交互而没考虑是隐式或显示交互,可直接用0和1表示有无交互;row和col表示该非0元素的位置,shape为整个矩阵的形状