面向第三方库推荐领域的高阶协同过滤方法

2024-01-08 18:22:20

经典开头

这次放个大招,和大家分享一个去年花了很大心血的工作。这个工作是推荐领域的,我们都知道,现在的app市场已经蓬勃发展,来到了成熟期,移动端设备已经是人手必备。那么,这么多的app在被开发的过程中,肯定会用到很多第三方的库,我们的研究就是针对这一问题,为开发人员设计一种推荐算法,便于他们更高效地开发app。


摘要

移动应用程序(app)的开发人员可以通过重用合适的第三方库(TPL)来提高他们的工作效率。为了帮助开发者快速找到有用的TPL,现有的方法如基于图神经网络(GNN)的方法,在提取可以增强节点表示能力的高阶邻域信息方面存在局限性。为了解决该问题,本文提出了一种新的基于协同过滤的超图神经网络方法,称为高阶协同过滤(HCF)。与经典GNN相比,提取的邻域信息包含更少的噪声,从而缓解了GNN节点表示中的过平滑问题。这一优势使HCF能够为app开发推荐更准确和多样化的TPL。实验表明。HCF在推荐准确性和多样性方面明显优于SOTA。


问题描述

我们将第三方库推荐定义为基于TPL使用记录向app推荐TPL的过程,目的是为app或其开发人员找到潜在有用的TPL。这里给出一个示例图,其中有6个app,表示为A1 ~ A6;有7个TPL,表示为L1 ~ L7。它们的使用关系可以表示为app-TPL交互图。app与TPL若有边相连,则表示app使用了TPL。例如,A1L5之间的边表示A1使用L5,而A1A2共同使用L1L3L5,表明他们有相似的特征或有相似的偏好。

问题抽象


研究动机

传统的协同过滤方法仅利用低阶连通性从邻居节点中提取信息。然而,为了学习更准确的节点表示,基于GNN的方法需要多轮信息传播来提取邻域信息。经过两轮传播,A1不仅可以通过L1L3L5获得A2的信息,还可以通过L5获得A4A5的信息。从A2中学到的信息与A1的相关性应该比从A4A5中学到的信息要高得多,因为从它们共同使用的TPL数量来看,A1A2的相似度要高于A4A5。当A1接收到有关A4A5的信息时,A4A5也接收到有关A1的信息。这个过程可能会引入噪声,导致图节点表示的过度平滑效应。为了提高TPL推荐的准确性,需要减少不必要的噪声,获得更纯的邻域信息。


方法详述

1. 相似度计算&寻找邻居节点

使用Jaccard相似度计算基于app-TPL交互记录的app-app相似度和TPL-TPL相似度。

SimApp ? ( A i , A j ) = ∣ L ( A i ) ∩ L ( A j ) ∣ ∣ L ( A i ) ∣ + ∣ L ( A j ) ∣ ? ∣ L ( A i ) ∩ L ( A j ) ∣ \begin{equation} \operatorname{SimApp}\left(A_i, A_j\right)=\frac{\left|L\left(A_i\right) \cap L\left(A_j\right)\right|}{\left|L\left(A_i\right)\right|+\left|L\left(A_j\right)\right|-\left|L\left(A_i\right) \cap L\left(A_j\right)\right|} \end{equation} SimApp(Ai?,Aj?)=L(Ai?)+L(Aj?)?L(Ai?)L(Aj?)L(Ai?)L(Aj?)???

SimTPL ? ( L i , L j ) = ∣ A ( L i ) ∩ A ( L j ) ∣ ∣ A ( L i ) ∣ + ∣ A ( L j ) ∣ ? ∣ A ( L i ) ∩ A ( L j ) ∣ \begin{equation} \operatorname{SimTPL}\left(L_i, L_j\right)=\frac{\left|A\left(L_i\right) \cap A\left(L_j\right)\right|}{\left|A\left(L_i\right)\right|+\left|A\left(L_j\right)\right|-\left|A\left(L_i\right) \cap A\left(L_j\right)\right|} \end{equation} SimTPL(Li?,Lj?)=A(Li?)+A(Lj?)?A(Li?)A(Lj?)A(Li?)A(Lj?)???

L(Ai)L(Aj)分别表示app AiAj所使用的TPL集合,|L(Ai)∩L(Aj)| 表示AiAj共用的TPL集合。A(Li)A(Lj)分别表示使用TPL LiLj的app集合;|A(Li)∩A(Lj)| 表示同时使用A(Li)A(Lj)的app的数量。α1用于确定两个app是否相似。如果两个app之间的相似度得分超过α1,我们认为它们相似;否则,认为它们是不同的。同样,α2用于度量两个TPL之间的相似性。如果两个节点相似,则它们被视为邻居节点。app Ai的邻居集记为N(Ai), TPL Lj的邻居节点集合记为N(Lj)。我们识别每个app(TPL)的邻居节点,并记录它们与app(TPL)的相似度得分。下图是说明这一阶段的一个示例,左侧为app-TPL交互矩阵。其中数字1表示app与TPL之间存在使用关系,0表示不存在使用关系。下图中间是根据相似度公式生成的相似度计算结果。将α1α2的值设置为0.6,我们可以识别出每个app(TPL)的相邻节点。右侧为邻域识别结果,其中符号“”表示两个节点之间的邻居关系。

在这里插入图片描述

2. 构建超图

在该阶段,使用前一阶段为app和TPL找到的相邻节点构建两个超图G1G2G1只包含app节点,G2只包含TPL节点。首先将app节点放入超图G1,将TPL节点放入超图G2。然后,对于每个app(TPL)及其邻居节点,我们使用超边连接它们。例如,使用超边e1连接A1N(A1)。一旦所有超边都连接起来,我们就得到了两个期望的超图G1G2。超图可以定义为G=(V,E),其中V为超图的节点集,E为超边集。超图也可以表示为大小为 |V|x|E| 的关联矩阵H。与传统的超图关联矩阵表示不同,我们为超边的每个节点分配了权重。因此,超图 G1=(V1,E1) 的加权关联矩阵定义为:

H 1 ( A i , e j ) = { Sim ? A p p ( A i , A j ) ?if? Sim ? A p p ( A i , A j ) ≥ α 1 0 ?if? SimApp ? ( A i , A j ) < α 1 \begin{equation} H_1\left(A_i, e_j\right)=\left\{\begin{array}{cl} \operatorname{Sim} A p p\left(A_i, A_j\right) & \text { if } \operatorname{Sim} A p p\left(A_i, A_j\right) \geq \alpha_1 \\ 0 & \text { if } \operatorname{SimApp}\left(A_i, A_j\right)<\alpha_1 \end{array}\right. \end{equation} H1?(Ai?,ej?)={SimApp(Ai?,Aj?)0??if?SimApp(Ai?,Aj?)α1??if?SimApp(Ai?,Aj?)<α1????

其中,Ai∈V1G1的第i个app节点,ej∈E1G1连接AjAi的第j个超边,给定Ai∈N(Aj)SimApp(Ai, Aj)表示计算得到的AiAj之间的相似度,设为超边缘ej上顶点Ai的权值。同理,超图G2=(V2,E2)可以用H2表示:

H 2 ( L i , e j ) = { SimTPL ? ( L i , L j ) ?if? SimTPL ? ( L i , L j ) ≥ α 2 0 ?if? SimTPL ? ( L i , L j ) < α 2 \begin{equation} H_2\left(L_i, e_j\right)=\left\{\begin{array}{cc} \operatorname{SimTPL}\left(L_i, L_j\right) & \text { if } \operatorname{SimTPL}\left(L_i, L_j\right) \geq \alpha_2 \\ 0 & \text { if } \operatorname{SimTPL}\left(L_i, L_j\right)<\alpha_2 \end{array}\right. \end{equation} H2?(Li?,ej?)={SimTPL(Li?,Lj?)0??if?SimTPL(Li?,Lj?)α2??if?SimTPL(Li?,Lj?)<α2????

在我们提出的方法中,因为每个超边对应一个节点的邻居,所以 |V|=|E| 。也就是说,一个节点的邻居可以转换为连接它与所有邻居的超边。下图给出了H1H2的示例,代表关联矩阵,阈值同样为0.6。

在这里插入图片描述

3. 节点嵌入

HCF将app和TPL嵌入到一个d维潜在因子空间中,其中每个app 和Ai表示为一个潜在因子向量,每个TPL 和Lj表示为一个潜在因子向量。这些向量用于表示app或TPL的特征,和Ai与和Lj潜在因子向量的内积可以用来表示TPL Lj在应用和Ai中潜在使用的可能性。其计算公式为:

R ^ i , j = A i → ? L j → \begin{equation} \hat{R}_{i, j}=\overrightarrow{A_i} \cdot \overrightarrow{L_j} \end{equation} R^i,j?=Ai? ??Lj? ???

4. 提取高阶邻域信息

在该阶段,HCF利用超图结构,通过聚合相邻节点的信息来提取每个节点的高阶邻域信息。
(1)基于节点表示生成超边表示
超图G的每个超边和ej将从它所连接的所有节点中提取信息,并将其各自的权值加权,生成一个超边表示(一个向量)。

e j → = ∑ i = 1 ∣ V ∣ H 1 ( A i , e j ) ? A i → \begin{equation} \overrightarrow{e_j}=\sum_{i=1}^{|\mathcal{V}|} H_1\left(A_i, e_j\right) * \overrightarrow{A_i} \end{equation} ej? ?=i=1V?H1?(Ai?,ej?)?Ai? ???

在多层神经网络中,其中H为关联矩阵H1,其中第l个嵌入传播层的输入为节点表示X(l),第l个嵌入传播层的超边表示为E(l)。则基于第l个嵌入传播层的节点表示生成超边缘表示的过程可表示为:

E ( l ) = H T X ( l ) \begin{equation} E^{(l)}=H^T X^{(l)} \end{equation} E(l)=HTX(l)??

(2)基于超边表示生成节点表示
从节点获得超边表示后,每个节点依次从连接它的超边提取信息。设X(l+1)为第个嵌入传播层提取超边信息后的节点表示。那么,这个过程可以表示为:

X ( l + 1 ) = H E ( l ) \begin{equation} X^{(l+1)}=H E^{(l)} \end{equation} X(l+1)=HE(l)??

结合上面两个公式,提取高阶邻域信息的整个过程可以总结为:

X ( l + 1 ) = H H T X ( l ) \begin{equation} X^{(l+1)}=H H^T X^{(l)} \end{equation} X(l+1)=HHTX(l)??

在上式的基础上,我们对从节点中提取的超边信息和从超边中提取的节点信息进行归一化,最终得出了提取高阶邻域信息的标准化公式:

X ( l + 1 ) = D v ? 1 H D e ? 1 H T X ( l ) \begin{equation} X^{(l+1)}=D_v^{-1} H D_e^{-1} H^T X^{(l)} \end{equation} X(l+1)=Dv?1?HDe?1?HTX(l)??

其中DvDe是对角矩阵,分别表示节点和超边的度。Dv-1De-1分别用于规范化节点表示和超边表示。节点和超边的度定义如下:

d ( v i ) = ∑ e j ∈ E H ( v i , e j ) \begin{equation} \begin{aligned} \mathrm{d}\left(v_i\right) & =\sum_{e_j \in \mathcal{E}} H\left(v_i, e_j\right) \end{aligned} \end{equation} d(vi?)?=ej?E?H(vi?,ej?)???

d ( e j ) = ∑ v i ∈ V H ( v i , e j ) \begin{equation} \begin{aligned} \mathrm{d}\left(e_j\right) & =\sum_{v_i \in \mathcal{V}} H\left(v_i, e_j\right) \end{aligned} \end{equation} d(ej?)?=vi?V?H(vi?,ej?)???

5. 通过聚合更新节点表示

在该阶段,我们将第四阶段不同嵌入传播层得到的节点表示进行聚合,生成新的节点表示X。在本工作中采用加权和聚合方法。

X = ∑ i = 0 m α i X ( i ) \begin{equation} X=\sum_{i=0}^m \alpha_i X^{(i)} \end{equation} X=i=0m?αi?X(i)??

式中m为嵌入传播层数,αi为权重系数。X(i)表示第i个嵌入传播层的节点表示,X(0)表示原始节点表示。本文设αi的值为1/(m+1)

6. 推荐有用的TPLs

我们已经获得了包含高阶邻域信息的app和TPL的节点表示。在这个阶段,我们预测应用程序中每个TPL使用的可能性,并向app推荐潜在有用的TPL。计算使用可能性之后,对所有分数降序排序,得到一个TPL列表。从TRL列表中删除app使用过的TPL,并从列表中选择top-k个TPL作为推荐结果。

7. 方法整体流程图

在这里插入图片描述

实验

实验设置

使用MALib数据集,该数据集共包含31421个app,727个TPL和530198个app-TPL使用记录。我们进一步使用MALib生成三个子数据集(也就是将数据集进行切分),分别表示为rm=1, rm=3, rm=5。rm=1表示从MALib数据集中每个app的TPL使用记录中删除一个TPL,形成测试集,其余记录作为训练集。rm=3和rm=5同理。

超参数设置如下:默认使用3层神经网络,128个节点向量维度,正则化权值为1e?4,batch size为8192,学习率为2e?3,学习率衰减为14,衰减因子为0.95。

实验动机

  • 与现有的TPLs推荐方法相比,HCF的表现如何?
  • 加权节点能提高模型性能吗?
  • HCF能否缓解图神经网络节点表示中的过度平滑问题?
  • 不同的相似性阈值对HCF性能的影响是什么?
  • 向量的维数如何影响HCF性能?
  • 嵌入传播层的数量如何影响HCF性能?

指标选择

  • 平均精度(MP):精度是指推荐列表中正确推荐的tpl与列表长度的比率。平均精度是指所有推荐列表的平均精度。
  • 平均召回率(MR):召回率是指推荐列表中正确推荐的tpl与应用程序在测试数据集中使用的tpl数量的比率。平均召回率是指所有推荐列表的平均召回率。
  • 平均F1分数(MF):F1分数通过在推荐列表中组合它们来平衡精度和召回率。MF为所有推荐列表F1得分的平均值。
  • 平均精度(MAP):MAP同时考虑推荐列表中检索到的相关tpl的排名质量和数量。
    覆盖度(COV):COV是衡量推荐结果多样性的指标,定义为推荐列表中出现的不同tpl与训练集中出现的不同tpl的比例。
  • 平均距离(MAD):MAD通过计算图中节点表示之间的平均距离来衡量图的平滑度。
    MADGap:MADGap用于测量图的过平滑度,在本文中是指图节点与其非相邻节点具有相似的节点表示。MADGap定义为

M A D G a p = M A D r m t ? M A D n e b \begin{equation} M A D G a p=M A D^{r m t}-M A D^{n e b} \end{equation} MADGap=MADrmt?MADneb??

其中,MADrmt表示非邻居节点间的平均距离,MADneb表示邻居节点间的平均距离。MADGap越小,表示图的节点表示中的过平滑程度越高。

实验一 — 整体性能对比

为了保证实验比较的公正性,我们直接使用了除LightGCN外的5个baseline的公开性能数据。实验设置保持一致,LightGCN和HCF的潜在因子向量的维数设置为128,层数设置为3。对于不同的数据集,HCF的最优超参数是不同的。在实验中,我们将学习率从0.001调整到0.005,正则化系数从0.01调整到1e-5, α1和α2从0.35调整到0.55。根据实验结果选择了LightGCN和HCF的最佳超参数。

在这里插入图片描述

HCF不仅大大提高了基线方法推荐结果的准确性,而且大大提高了推荐的多样性。这是因为HCF可以更好地提取高阶邻域信息,这些信息通常来自高度相似的节点,并且包含较少的噪声。

实验二 — 超图结点权值的影响

为了评估具有节点权重的超图关联矩阵的有效性,我们进行了一系列控制实验,将SimApp(Ai, Aj)SimTPL(Li, Lj)替换为1。实验中α1和α2均设为0.4。实验结果表明在所有三个数据集上,具有节点权值的超图关联矩阵在MR、MAP和COV方面都优于不具有节点权值的超图关联矩阵。这一观察结果验证了在超图关联矩阵中加入节点权重可以提高HCF推荐结果的准确性和多样性。

在这里插入图片描述

实验三 — 过平滑问题分析

为了研究HCF是否能有效缓解图神经网络中的过平滑问题,我们使用MADGap来衡量图的过平滑程度。我们假设相似的节点是相邻节点,不相似的节点是远节点。我们将HCF与LightGCN进行了比较,LightGCN是与HCF最相似的模型,因为这两个模型都不涉及特征空间变换和激活函数,并且使用加权和进行聚合。

我们在rm=1、rm=3、rm=5上进行了实验,HCF和LightGCN的网络层数都设置为5。此外,我们将α1,α2和学习率设置为在RQ1中获得的最优值,而所有其他设置保持默认超参数。在对模型进行训练后,我们得到了HCF和LightGCN从第0到第5网络层的图节点表示,其中第0层为嵌入层。然后我们为这6个层的节点表示计算MADGap。

实验结果表明,LightGCN中节点表示的MADGap在第二层明显减小。并且,MADGap值在第4层趋近于0,说明此时的节点表示可能被大量噪声填充,有价值的邻域信息减少,从而导致节点表示过度平滑。相比之下,HCF各层节点表示的MADGap值都远大于0,并保持在一个相对稳定的水平,说明HCF节点表示的过平滑效果有限。这是因为HCF从高度相似的节点中提取图节点的高阶邻域信息,有效地减少了噪声的引入,使得HCF可以缓解过平滑问题。

在这里插入图片描述

实验四 — 相似度阈值对HCF的影响

阈值α1α2是影响HCF性能的关键因素。需要注意的是,α1α2的最优值可能因数据集的不同而不同。在本节中,我们使用rm=5数据集研究这些阈值对HCF性能的影响。通过预实验,我们确定阈值的合理范围在39% ~ 54%之间。我们将α1的值从0.39变化到0.54,步长为0.3,同时将α2固定在0.45,以此来评估α1在实验中的影响。同样,我们将α1固定为0.45,并改变α2的值来评估α2对HCF性能的影响。所有其他超参数都保持默认值。实验结果如图9所示。总体而言,α1对HCF性能的影响比α2更显著。这可能是因为α1负责确定两个应用程序之间的相似性,而α2负责确定两个TPL之间的相似性。由于数据集包含的应用程序数量比TPL大得多,α1对整体HCF性能的影响比α2更明显。从图9中我们还可以看到,当α1α2的值从0.39增加到0.42时,HCF的整体性能显著提高,说明在合理的范围内增加阈值可以有效地提高性能。然而,当α1α2的值从0.45进一步增大到0.54时,HCF的整体性能下降。这意味着过大的相似性阈值会损害HCF的性能。

在这里插入图片描述

实验五 — 潜在因子向量维数的影响

为了评估潜在因素向量的维度d对HCF性能的影响,我们在rm=5数据集上进行了一些实验,将d的值改变为32、64、128、256和512。考虑到每个模型需要学习的参数数量不同,我们在5e?45e?3的范围内选择每个模型的最优学习率。除d和学习率外,其他超参数保持默认值。

如下图,当潜在因子向量d的维数从32增加到128时,HCF的整体性能呈增加趋势。MR和MAP都在快速增加,同时COV也在显著增加,说明将d增加到一定值可以增强节点的代表能力,从而使推荐更加准确和多样化。然而,在128 ~ 512的范围内,MR和MAP的增长速度减慢,COV的值开始下降。这突出表明,过高的d值可能并不总是产生显著的性能改进。因此,选择在准确性、多样性和计算复杂性之间取得平衡的d值至关重要,并且应该基于应用程序的特定需求。

在这里插入图片描述

实验六 — 网络层深度的影响

我们还在rm=5数据集上进行了一些实验,以评估网络层深度对HCF性能的影响。实验中,潜因子向量的维数设置为128,层数设置为1,2,3,4,5。

下图展示了不同层数下HCF的性能。通过将层数从1层增加到3层,HCF在MR、MAP和COV方面的性能得到了显著提高,这表明更深的网络可以提取更复杂的特征。然而,当我们进一步将层数从3层增加到4层时,只观察到边际改进。当我们继续将层数从4层增加到5层时,MR和MAP略有改善,而COV明显下降。这表明HCF已经可以用3或4层捕获足够的高阶邻域信息。

注:边际改善(marginal improvement)指的是当增加模型的层数时,模型性能或指标的改善幅度逐渐减小的情况。换句话说,当增加层数时,初始的层数增加可能会带来较大的性能提升,但随着层数进一步增加,性能的改善变得更加微小,不再显著。总之,边际改进指的是随着变量或因素的改变,其对结果的影响逐渐减小,从而导致性能的改善不再显著。

在这里插入图片描述

结论

在本文中,我们提出了HCF,一种基于超图神经网络的新方法,用于向app推荐潜在且有用的TPL。HCF通过探索app和TPL之间的相似性,将app和TPL建模为两个超图,从而通过超边获得更有效的高阶邻域信息。与LightGCN和其他最先进的TPLs推荐方法相比,HCF在TPLs推荐中可以返回更准确和多样化的结果。此外,我们还验证了HCF可以显著缓解图神经网络中节点表示的过度平滑问题。本工作使用Jaccard指数来计算应用程序之间和TPL之间的相似性,但由于其简单性,可能不够准确。也许未来我们会探索更有效的方法,同时考虑各种库被使用的频率(受欢迎程度),以获得准确的相似度评价指标。

结合数据详述方法

1、原始数据

原始数据集包含3个csv文件:app信息(编号-名称)、TPL信息(编号-名称)、app-TPL关对应关系(编号-编号)。

  • App数据集(app_info.csv):包含了56091个App的基本信息,包括App ID以及App名称;
  • TPLs数据集(lib_info.csv):包含了763个TPLs的基本信息,TPL ID以及TPL名称;
  • App-TPLs交互记录(relation.csv):包含了704128条App-TPLs交互记录,记录了App使用TPLs的情况,具体而言是App ID与TPL ID对应的数据。

这是数据的初始状态,为了应用于我们的研究中,我们对数据进行了预处理(图片仅为示例)。

请添加图片描述

2、数据处理

因为要挖掘app和TPL的深层次关联信息,我们将相似的app聚合,具体而言,我们将前缀相似、关键词相似、使用的第三方库相似的app聚合,类似于去重的操作,得到新的app信息数据。同时,对app和库进行分组整合,以及一系列的remove操作,得到几个新的csv文件,也就是训练集和测试集(图片仅为示例)。

请添加图片描述

请添加图片描述

假如我们的算法可以在具体的系统上应用,假定输入的是app使用的TPL记录,则不需要app的信息,只输入库的使用记录即可。因为计算相似度利用的是TPL记录,和app无关。为了让研究具有应用价值,应该根据使用的库进行推荐,不然只是为数据集中固定的app做推荐,价值和意义不大。

3、GUI可视化

为了检验算法的效果,我们写了一个GUI界面,对算法的效果进行简单的可视化。为了使系统能对用户的输入快速地进行响应,我们提前训练好每个app以及TPL的embeddings,并保存至embeddings.pt文件,当用户输入app所使用的TPL列表时,系统能够根据已有的embeddings来快速生成用户所输入的app的embeddings,并快速生成推荐结果。数据训练得到每个app以及TPL的embeddings的过程如下:

首先对数据进行清洗,去除使用TPL数量少于10的app以及同名且使用几乎一样的TPL的app。接着从每个app使用TPL的记录中都移除(remove)出1个TPL作为测试集,余下记录作为训练集。随后将生成的训练集放入模型中训练,直至在测试集上取得最好的结果,保存在测试集上取得最好性能时模型的embeddings,导出为embeddings.pt文件,在系统初始化时载入该文件。

最终效果图如下:

在这里插入图片描述

在这里插入图片描述


尾声

这个工作整体而言是有应用价值的,也许和目前的推荐算法方向不太一样,但也非常有可能落实到具体的应用开发上,比如设计一些插件集成到编译器中。其实在实际的工程开发中,底层库之间很容易冲突,所以应当尽量减少app不同组件之间的依赖关系,将不同的功能分成独立的模块或服务,降低库冲突的风险。或者尽量减少app中的复杂依赖关系,使用库时,尽量选择稳定、广泛使用并有良好维护记录的库。项目代码已开源,感兴趣的小伙伴可以在这里查看~ 这篇文章非常长,感谢你的阅读💜。

文章来源:https://blog.csdn.net/m0_51495585/article/details/135456029
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。