数学基础
- 线性代数
- 概率论与随机过程
- 数值计算
- 蒙特卡洛方法与 MCMC 采样
- 机器学习方法概论
统计学习
深度学习
- 深度学习简介
- 深度前馈网络
- 反向传播算法
- 正则化
- 深度学习中的最优化问题
- 卷积神经网络
- CNN:图像分类
- 循环神经网络 RNN
- Transformer
- 一、Transformer [2017]
- 二、Universal Transformer [2018]
- 三、Transformer-XL [2019]
- 四、GPT1 [2018]
- 五、GPT2 [2019]
- 六、GPT3 [2020]
- 七、OPT [2022]
- 八、BERT [2018]
- 九、XLNet [2019]
- 十、RoBERTa [2019]
- 十一、ERNIE 1.0 [2019]
- 十二、ERNIE 2.0 [2019]
- 十三、ERNIE 3.0 [2021]
- 十四、ERNIE-Huawei [2019]
- 十五、MT-DNN [2019]
- 十六、BART [2019]
- 十七、mBART [2020]
- 十八、SpanBERT [2019]
- 十九、ALBERT [2019]
- 二十、UniLM [2019]
- 二十一、MASS [2019]
- 二十二、MacBERT [2019]
- 二十三、Fine-Tuning Language Models from Human Preferences [2019]
- 二十四 Learning to summarize from human feedback [2020]
- 二十五、InstructGPT [2022]
- 二十六、T5 [2020]
- 二十七、mT5 [2020]
- 二十八、ExT5 [2021]
- 二十九、Muppet [2021]
- 三十、Self-Attention with Relative Position Representations [2018]
- 三十一、USE [2018]
- 三十二、Sentence-BERT [2019]
- 三十三、SimCSE [2021]
- 三十四、BERT-Flow [2020]
- 三十五、BERT-Whitening [2021]
- 三十六、Comparing the Geometry of BERT, ELMo, and GPT-2 Embeddings [2019]
- 三十七、CERT [2020]
- 三十八、DeCLUTR [2020]
- 三十九、CLEAR [2020]
- 四十、ConSERT [2021]
- 四十一、Sentence-T5 [2021]
- 四十二、ULMFiT [2018]
- 四十三、Scaling Laws for Neural Language Models [2020]
- 四十四、Chinchilla [2022]
- 四十七、GLM-130B [2022]
- 四十八、GPT-NeoX-20B [2022]
- 四十九、Bloom [2022]
- 五十、PaLM [2022] (粗读)
- 五十一、PaLM2 [2023](粗读)
- 五十二、Self-Instruct [2022]
- 句子向量
- 词向量
- 传统CTR 预估模型
- CTR 预估模型
- 一、DSSM [2013]
- 二、FNN [2016]
- 三、PNN [2016]
- 四、DeepCrossing [2016]
- 五、Wide 和 Deep [2016]
- 六、DCN [2017]
- 七、DeepFM [2017]
- 八、NFM [2017]
- 九、AFM [2017]
- 十、xDeepFM [2018]
- 十一、ESMM [2018]
- 十二、DIN [2017]
- 十三、DIEN [2019]
- 十四、DSIN [2019]
- 十五、DICM [2017]
- 十六、DeepMCP [2019]
- 十七、MIMN [2019]
- 十八、DMR [2020]
- 十九、MiNet [2020]
- 二十、DSTN [2019]
- 二十一、BST [2019]
- 二十二、SIM [2020]
- 二十三、ESM2 [2019]
- 二十四、MV-DNN [2015]
- 二十五、CAN [2020]
- 二十六、AutoInt [2018]
- 二十七、Fi-GNN [2019]
- 二十八、FwFM [2018]
- 二十九、FM2 [2021]
- 三十、FiBiNET [2019]
- 三十一、AutoFIS [2020]
- 三十三、AFN [2020]
- 三十四、FGCNN [2019]
- 三十五、AutoCross [2019]
- 三十六、InterHAt [2020]
- 三十七、xDeepInt [2023]
- 三十九、AutoDis [2021]
- 四十、MDE [2020]
- 四十一、NIS [2020]
- 四十二、AutoEmb [2020]
- 四十三、AutoDim [2021]
- 四十四、PEP [2021]
- 四十五、DeepLight [2021]
- 图的表达
- 一、DeepWalk [2014]
- 二、LINE [2015]
- 三、GraRep [2015]
- 四、TADW [2015]
- 五、DNGR [2016]
- 六、Node2Vec [2016]
- 七、WALKLETS [2016]
- 八、SDNE [2016]
- 九、CANE [2017]
- 十、EOE [2017]
- 十一、metapath2vec [2017]
- 十二、GraphGAN [2018]
- 十三、struc2vec [2017]
- 十四、GraphWave [2018]
- 十五、NetMF [2017]
- 十六、NetSMF [2019]
- 十七、PTE [2015]
- 十八、HNE [2015]
- 十九、AANE [2017]
- 二十、LANE [2017]
- 二十一、MVE [2017]
- 二十二、PMNE [2017]
- 二十三、ANRL [2018]
- 二十四、DANE [2018]
- 二十五、HERec [2018]
- 二十六、GATNE [2019]
- 二十七、MNE [2018]
- 二十八、MVN2VEC [2018]
- 二十九、SNE [2018]
- 三十、ProNE [2019]
- Graph Embedding 综述
- 图神经网络
- 一、GNN [2009]
- 二、Spectral Networks 和 Deep Locally Connected Networks [2013]
- 三、Fast Localized Spectral Filtering On Graph [2016]
- 四、GCN [2016]
- 五、神经图指纹 [2015]
- 六、GGS-NN [2016]
- 七、PATCHY-SAN [2016]
- 八、GraphSAGE [2017]
- 九、GAT [2017]
- 十、R-GCN [2017]
- 十一、 AGCN [2018]
- 十二、FastGCN [2018]
- 十三、PinSage [2018]
- 十四、GCMC [2017]
- 十五、JK-Net [2018]
- 十六、PPNP [2018]
- 十七、VRGCN [2017]
- 十八、ClusterGCN [2019]
- 十九、LDS-GNN [2019]
- 二十、DIAL-GNN [2019]
- 二十一、HAN [2019]
- 二十二、HetGNN [2019]
- 二十三、HGT [2020]
- 二十四、GPT-GNN [2020]
- 二十五、Geom-GCN [2020]
- 二十六、Graph Network [2018]
- 二十七、GIN [2019]
- 二十八、MPNN [2017]
- 二十九、UniMP [2020]
- 三十、Correct and Smooth [2020]
- 三十一、LGCN [2018]
- 三十二、DGCNN [2018]
- 三十三、AS-GCN
- 三十四、DGI [2018]
- 三十五、DIFFPOLL [2018]
- 三十六、DCNN [2016]
- 三十七、IN [2016]
- 图神经网络 2
- 图神经网络 3
- 推荐算法(传统方法)
- 一、Tapestry [1992]
- 二、GroupLens [1994]
- 三、ItemBased CF [2001]
- 四、Amazon I-2-I CF [2003]
- 五、Slope One Rating-Based CF [2005]
- 六、Bipartite Network Projection [2007]
- 七、Implicit Feedback CF [2008]
- 八、PMF [2008]
- 九、SVD++ [2008]
- 十、MMMF 扩展 [2008]
- 十一、OCCF [2008]
- 十二、BPR [2009]
- 十三、MF for RS [2009]
- 十四、 Netflix BellKor Solution [2009]
- 推荐算法(神经网络方法 1)
- 一、MIND [2019](用于召回)
- 二、DNN For YouTube [2016]
- 三、Recommending What Video to Watch Next [2019]
- 四、ESAM [2020]
- 五、Facebook Embedding Based Retrieval [2020](用于检索)
- 六、Airbnb Search Ranking [2018]
- 七、MOBIUS [2019](用于召回)
- 八、TDM [2018](用于检索)
- 九、DR [2020](用于检索)
- 十、JTM [2019](用于检索)
- 十一、Pinterest Recommender System [2017]
- 十二、DLRM [2019]
- 十三、Applying Deep Learning To Airbnb Search [2018]
- 十四、Improving Deep Learning For Airbnb Search [2020]
- 十五、HOP-Rec [2018]
- 十六、NCF [2017]
- 十七、NGCF [2019]
- 十八、LightGCN [2020]
- 十九、Sampling-Bias-Corrected Neural Modeling [2019](检索)
- 二十、EGES [2018](Matching 阶段)
- 二十一、SDM [2019](Matching 阶段)
- 二十二、COLD [2020 ] (Pre-Ranking 模型)
- 二十三、ComiRec [2020](https://www.wenjiangs.com/doc/0b4e1736-ac78)
- 二十四、EdgeRec [2020]
- 二十五、DPSR [2020](检索)
- 二十六、PDN [2021](mathcing)
- 二十七、时空周期兴趣学习网络ST-PIL [2021]
- 推荐算法之序列推荐
- 一、FPMC [2010]
- 二、GRU4Rec [2015]
- 三、HRM [2015]
- 四、DREAM [2016]
- 五、Improved GRU4Rec [2016]
- 六、NARM [2017]
- 七、HRNN [2017]
- 八、RRN [2017]
- 九、Caser [2018]
- 十、p-RNN [2016]
- 十一、GRU4Rec Top-k Gains [2018]
- 十二、SASRec [2018]
- 十三、RUM [2018]
- 十四、SHAN [2018]
- 十五、Phased LSTM [2016]
- 十六、Time-LSTM [2017]
- 十七、STAMP [2018]
- 十八、Latent Cross [2018]
- 十九、CSRM [2019]
- 二十、SR-GNN [2019]
- 二十一、GC-SAN [2019]
- 二十二、BERT4Rec [2019]
- 二十三、MCPRN [2019]
- 二十四、RepeatNet [2019]
- 二十五、LINet(2019)
- 二十六、NextItNet [2019]
- 二十七、GCE-GNN [2020]
- 二十八、LESSR [2020]
- 二十九、HyperRec [2020]
- 三十、DHCN [2021]
- 三十一、TiSASRec [2020]
- 推荐算法(综述)
- 多任务学习
- 系统架构
- 实践方法论
- 深度强化学习 1
- 自动代码生成
工具
- CRF
- lightgbm
- xgboost
- scikit-learn
- spark
- numpy
- matplotlib
- pandas
- huggingface_transformer
- 一、Tokenizer
- 二、Datasets
- 三、Model
- 四、Trainer
- 五、Evaluator
- 六、Pipeline
- 七、Accelerate
- 八、Autoclass
- 九、应用
- 十、Gradio
Scala
- 环境搭建
- 基础知识
- 函数
- 类
- 样例类和模式匹配
- 测试和注解
- 集合 collection(一)
- 集合collection(二)
- 集成 Java
- 并发
十九、CSRM [2019]
传统的推荐方法通常基于显式的
user-item
偏好(如,评分),其中关于用户的信息和item
的信息是必不可少的。例如,content-based
方法通过评估用户画像user profile
(即,用户历史行为记录)和item
特征之间的相似性来生成推荐列表。然而,在许多现实场景中,用户没有登录,并且也不知道用户历史的交互:没有显式的偏好,只有positive
的观察(如,点击)可用。在这种情况下,传统的推荐方法表现不佳。为了解决这个问题,人们已经提出了session-based
推荐,从而仅基于匿名行为session
来生成推荐。给定用户在当前session
中的行为的短期历史,session-based
推荐旨在预测该用户可能感兴趣的next item
。session-based
推荐的早期研究主要基于item-to-item
的推荐,并产生的预测依赖于计算session
内item
之间相似性(如,基于共现co-occurrence
),而忽略了当前session
中点击序列的序列信息sequential information
。后续的工作研究了使用马尔科夫链来利用序列行为数据并根据用户的最近动作last action
来预测用户的next action
。然而,这些工作仅建模相邻item
之间的局部顺序行为local sequential behavior
。基于马尔科夫链的方法的一个主要问题是,当试图在所有item
上包含所有潜在的、用户选择user selection
的序列时,状态空间很快变得难以管理。最近的研究将深度学习(如
RNN
)用于session-based
的推荐,因此可以考虑整个session
的信息。例如:《Session-based recommendations with recurrent neural networks》
使用Gated Recurrent Unit: GRU
来建模session
中的动作序列。《Neural attentive session-based recommendation》
通过引入注意力机制来捕获用户在当前session
中的主要意图main purpose
,从而实现进一步的改进。
尽管这些
RNN-based
方法比传统的推荐方法有了显著的提升,但它们的短期记忆short-term memory
通常有限,并且难以执行记忆memorization
。人们已经将memory network
引入推荐系统,其动机是拥有一个长期记忆long-term memory
模块的优势。《Sequential recommendation with user memory networks》
通过首次引入user memory network
,利用用户的历史记录,显式地捕获item-level
和feature-level
的序列模式sequential pattern
,从而改进序列推荐。《Improving sequential recommendation with knowledge-enhanced memory networks》
提出了一种知识增强knowledge enhanced
的序列推荐器,它将RNN-based
网络与Key-Value Memory Network: KV-MN
相结合。
现有的
memory network-based
的推荐方法取得了令人鼓舞的结果。但是它们仅利用了用户自己的信息,而忽略了所谓的neighborhood session
中协同信息collaborative information
的潜力。neighborhood session
是由任何用户(不一定是当前session
的同一用户,因为这里的session
是匿名的)生成的session
,它们显示出与当前session
相似的行为模式similar behavior pattern
,并反映出与当前session
相似的用户意图similar user intent
。例如,考虑session
$ [\text{phone}_1,\text{phone}_2,\text{phone}_3] $ 和另一个session
$ [\text{phone}_1,\text{phone}_3,\text{phone}_4] $ 。 当与推荐系统交互时,生成这些session
的用户都点击了某些手机,因此可以推测他们具有类似的兴趣,可以进行比较。这两个用户可能有相似的意图来寻找合适的手机,因此,生成第二个session
的用户可能对 $ \text{phone}_2 $ 感兴趣。论文《A Collaborative Session-based Recommendation Approach with Parallel Memory Modules》
假设neighborhood session
可能有助于改善当前session
中的推荐。论文
《A Collaborative Session-based Recommendation Approach with Parallel Memory Modules》
提出了一种新颖的神经网络框架,即Session-based Recommendation Machine: CSRM
,用于session-based
推荐。该框架由两个并行模块组成:一个Inner Memory Encoder: IME
模块、一个Outer Memory Encoder: OME
模块。IME
在RNN
固有的dynamic memory
的帮助下对当前session
中包含的信息进行建模。它学习一个统一的representation
来结合两种编码方案:一个全局编码器global encoder
和一个局部编码器local encoder
。IME
其实就是《Neural attentive session-based recommendation》
提出的NARM
。OME
利用协同过滤技术通过利用一个external memory
模块来研究investigate
neighborhood session
从而更好地预测当前session
的意图。OME
包含一个关联的寻址机制associative addressing mechanism
来自动识别neighborhood session
。
最后,
CSRM
引入了一种融合门控机制fusion gating mechanism
来组合IME
和OME
产生的representation
,并根据fused representation
来计算每个候选item
的推荐分。论文对三个
benchmark
数据集进行了广泛的实验。结果表明,CSRM
在所有三个数据集上的Recall
和MRR
均优于state-of-the-art
的session-based
的推荐baseline
。论文进行了进一步的实验以深入分析IME
和OME
,从而探索CSRM
的推荐过程,并确定协同邻域信息collaborative neighborhood information
和融合门控机制如何影响session-based
推荐的性能。论文的贡献如下:
- 据作者所知,论文是第一个考虑在
session-based
推荐中用端到端的神经网络模型进行协同建模collaborative modeling
的。 - 论文提出了一种新颖的
CSRM
模型,该模型集成了IME
和OME
,从而将来自current session
和neighborhood session
的信息纳入session-based
的推荐。 - 论文引入了一种融合门控机制,以选择性地结合
current session
和neighborhood session
的信息从而获得更好的推荐。 - 论文对三个
benchmark
数据集进行了广泛的实验。在session-based
的推荐任务上,CSRM
在Recall
和MRR
方面显著优于state-of-the-art
模型。
相关工作:
协同过滤
collaborative filtering
:协同过滤是一种广泛使用的推荐方法。它通过建模user-item
交互来识别用户偏好,并基于 “具有相似偏好的人倾向于作出相似选择” 的假设来向用户推荐item
。先前关于协同过滤的工作可以分为两类:KNN-based
方法、model-based
方法。KNN-based
方法使用预定义的相似性函数来查找相似的用户或item
,从而促进promote
推荐。它们可以进一步分为user-based KNN
和item-based KNN
。user-based KNN
计算用户之间的相似性,并推荐相似用户可能喜欢的item
。《An automatic weighting scheme for collaborative filtering》
提出了一种算法,用于在识别两个用户之间的相似性时学习不同item
的权重。《A new user similarity model to improve the accuracy of collaborative filtering》
提出了一种启发式相似性度量方法来改进协同过滤,该方法结合了用户评分的上下文信息以及用户行为的偏好。
item-based KNN
计算item
之间的相似性,并使用这些相似性来预测user-item pair
对的评分。《Item-based collaborative filtering recommendation algorithms》
提出使用correlation-based
和cosine-based
技术来计算item
之间的相似性。《Item-based top-n recommendation algorithms》
将item-to-item
相似性扩展到用户的所有消费consumed
的item
与候选item
之间的相似性概念从而用于top-N
推荐。
给定
user-item
评分矩阵,model-based
方法将用户和item
映射到共享的潜在因子空间shared latent factor space
中从而表征用户和item
,并通过用户和item
的潜在因子latent factor
之间的内积来生成预测。这些方法的例子包括矩阵分解matrix factorization
、奇异值分解Singular Value Decomposition: SVD
、SVD++
。《Collaborative denoising auto-encoders for top-n recommender systems》
通过将一个user-specific bias
集成到自编码器中来推广协同过滤模型。《Neural collaborative filtering》
通过使用深度学习而不是内积来建模user-item
交互。
尽管这些方法通过探索协同过滤取得了可喜的成果,但是它们都有局限性。
- 一方面,
KNN-based
方法无法识别序列信号sequential signal
。 - 另一方面,当用户画像(即,用户历史行为序列)不可用时,
model-based
方法不能用于session-based
推荐。
最近,
《When recurrent neural networks meet the neighborhood for session-based recommendation》
结合了一个GRU
模型和co-occurrence-based KNN
模型来探索session-based
推荐中的协同信息。他们的方法与我们的工作之间的差异至少有两个方面。- 首先,我们的模型是一个端到端的
memory network
,而他们使用简单的加权方案将GRU
模型和KNN
模型的分数以手工制作的超参数结合起来。 - 其次,我们的模型中用于查找
k
近邻k-nearest neighbor
的相似性是自动学习到的,而他们使用一个启发式的、co-occurrence-based
相似性度量。
记忆增强的神经网络
memory augmented neural network
:Memory Augmented Neural Network: MANN
通常由两个组件组成:一个存储长期历史信息的memory
、一个在memory
上执行read/write
操作的控制器controller
。最近,用于推荐系统的
memory network
因其state-of-the-art
的性能而受到了相当大的关注。《Sequential recommendation with user memory networks》
首个提出将矩阵分解与MANN
集成从而进行序列推荐sequential recommendation
。他们提出了具有两种变体的Recommendation with User Memory network: RUM
:item-level RUM
和feature-level RUM
。item-level RUM
将每个item
视为一个单元unit
,并将item embedding
直接存储在memory matrix
中。feature-level RUM
将用户在不同潜在特征上的偏好的embedding
存储在memory matrix
中。
《Improving sequential recommendation with knowledge-enhanced memory networks》
提出了一种知识增强knowledge enhanced
的序列推荐器,它结合了知识库knowledge base
信息来捕获attribute-level
的用户偏好。《Mention recommendation for multimodal microblog with cross-attention memory network》
将MANN
与交叉注意力机制cross-attention mechanism
相结合,为多模态推文tweet
执行mention
推荐任务,其中他们使用MANN
来存储图片和推文的历史兴趣。
尽管这些方法都取得了可喜的成果,但他们都忽略了协同的邻域信息。
与我们最相似的工作涉及协同记忆网络
Collaborative Memory Network: CMN
(《Collaborative memory network for recommendation systems》
)。它统一了两类协同过滤模型:矩阵分解、neighborhood-based
方法。CMN
利用三种memory state
来建模user-item
交互,包括:一个内部的user-specific memory state
、一个内部的item-specific memory state
、以及一个collective neighborhood state
。我们的工作与CMN
之间的差异至少有三点:- 首先,
CMN
不能直接应用于session-based
的推荐,因为没有可用的用户信息。尽管我们可以对CMN
进行一些改变,但我们发现它对session-based
推荐没有效果。 - 其次,
CMN
通过寻找相似的user-item
交互模型interaction pattern
找执行协同过滤。相比之下,我们的模型通过探索neighborhood session
来利用协同信息。 - 第三,
CMN
简单地结合协同特征collaborative feature
和user-item
潜在特征来预测评分。相反,我们引入了一种融合门控机制来学习选择性地组合selectively combine
不同的特征源。
19.1 模型
令
$ \mathcal I $ 表示所有item
的集合。令 $ \mathcal X_t = [x_1,x_2,\cdots,x_{\tau},\cdots,x_n] $ 表示推荐过程中时间戳 $ t $ ( $ t\ge 1 $ ) 的session
,其中每个 $ x_\tau\in \mathcal I $ 是用户在session
期间所交互的item
,如听一首歌、看一个视频。给定一个session
$ \mathcal X $ ,session-based
推荐系统的任务是预测用户可能交互的next item
。正式地,给定当前session
$ \mathcal X_t $ ,任务的目标是通过从所有item
$ \mathcal I $ 中推荐用户可能感兴趣的top-N item
( $ 1\le N\le |\mathcal I| $ )从而来预测 $ x_{n+1} $ 。我们提出了一个
Collaborative Session-based Recommendation Machine: CSRM
框架来生成session-based
的推荐。CSRM
背后的关键思想是:利用来自neighborhood session
的信息来提高current session
的推荐性能。neighborhood session
是展示与current session
相似的行为模式的session
。具体而言,我们将最近
$ m $ 个session
存储在一个outer memory
中作为潜在的neighborhood session
。给定当前session
,CSRM
会自动从outer memory
中查找neighborhood session
并抽取有用的特征来提升针对当前session
的推荐。如下图所示,
CSRM
由三个主要组件组成:一个Inner Memory Encoder: IME
、一个Outer Memory Encoder: OME
、一个推荐解码器recommendation decoder
。融合门控机制fusion gating mechanism
用于控制IME
和OME
组件之间的信息流。- 首先,
IME
将input session
转换为两个高维的hidden representation
:一个用于summarize
整个session
,另一个用于在当前session
中选择相对重要的item
(因为当前session
中可能包含意外或出于好奇而点击的item
)。这两个session
被拼接成一个统一的session representation
。 - 其次,
OME
在outer memory network
的帮助下将当前session
的collaborative neighborhood information
编码为collaborative session representation
。这个过程可以被看作是一种session-based
的最近邻方法,它对与当前session
具有相似行为模式的特定session
子集赋予更高的权重。 - 最后,
IME
和OME
的输出作为推荐解码器的输入,其中使用融合门控机制来选择性地组合来自IME
和OME
的信息从而进行推荐。输出是基于双线性解码方案bi-linear decoding scheme
的、每个候选item
的推荐分。
接下来我们详细介绍每个部分。
- 首先,
19.1.1 Inner Memory Encoder
IME
尝试对当前session
中包含的有用信息进行编码。遵从《Neural attentive session-based recommendation》
的做法,它由两个组件组成:全局编码器global encoder
和局部编码器local encoder
。- 全局编码器用于建模整个
session
中的序列行为。 - 局部编码器用于关注特定的行为,这体现在当前
session
中相对重要的item
。
- 全局编码器用于建模整个
我们使用
GRU
作为全局编码器,因为已经有论文表明:GRU
在session-based
的推荐方面表现出比LSTM
更好的性能。GRU
的activation
是previous hidden state
$ \mathbf{\vec h}_{\tau-1} $ 和候选的hidden state
$ \widehat{\mathbf{\vec h}}_{\tau} $ 之间的线性插值:其中:
$ \odot $ 为逐元素乘法, $ \mathbf{\vec z}_{\tau} $ 为更新门update gate
。更新门
$ \mathbf{\vec z}_{\tau} $ 定义为 $ \mathbf{\vec z}_{\tau} = \sigma\left(\mathbf W_z \mathbf{\vec x}_{\tau} + \mathbf U_z \mathbf{\vec h}_{\tau-1}\right) $ ,其中: $ \mathbf{\vec x}_{\tau} $ 为输入 $ x_\tau $ 的item embedding
, $ \mathbf W_z,\mathbf U_z $ 为待学习的权重矩阵, $ \sigma(\cdot) $ 为sigmoid
激活函数。候选的
hidden state
$ \widehat{\mathbf{\vec h}}_{\tau} $ 定义为 $ \widehat{\mathbf{\vec h}}_{\tau} =\tanh \left(\mathbf W_h \mathbf{\vec x}_{\tau} + \mathbf U_h\left(\mathbf{\vec r}_{\tau}\odot \mathbf{\vec h}_{\tau-1}\right)\right) $ ,其中: $ \mathbf{\vec r}_{\tau} $ 为复位门reset gate
, $ \mathbf W_h,\mathbf U_h $ 为待学习的权重矩阵, $ \tanh(\cdot) $ 为tanh
激活函数。复位门
$ \mathbf{\vec r}_\tau $ 定义为 $ \mathbf{\vec r}_{\tau} = \sigma\left(\mathbf W_r \mathbf{\vec x}_{\tau} + \mathbf U_r \mathbf{\vec h}_{\tau-1}\right) $ ,其中 $ \mathbf W_r,\mathbf U_r $ 为待学习的权重矩阵。最后,我们使用
final hidden state
$ \mathbf{\vec h}_n $ 作为当前session
的序列行为的representation
:注意,所有的
gate
通常都使用sigmoid
激活函数,因为gate
的输出必须在0
到1
之间。尽管全局编码器考虑了整个序列所反映的行为,但是由于噪音
noise
的item
,很难准确地捕获当前session
的行为模式。为此,我们使用另一个具有item-level
注意力机制的GRU
作为局部编码器。在全局编码器之后,当前session
$ \mathcal X_t $ 被编码到inner memory matrix
$ \mathbf H_t = \left[\mathbf{\vec h}_1,\mathbf{\vec h}_2,\cdots,\mathbf{\vec h}_{\tau},\cdots,\mathbf{\vec h}_n \right] $ (也被称作inner memory network
)。局部编码器仅依赖session
自己的信息从inner memory network
动态读取。注意力机制通过强调某些特定行为而忽略其它行为来密切关注当前session
的意图。我们为相对更重要的item
分配更高的权重。对于当前
session
$ \mathcal X_t $ ,局部编码器首先在注意力权重 $ \alpha_{n,j} $ 的帮助下找到每个点击item
对session
意图的贡献。具体而言,权重因子 $ \alpha_{n,j} $ 通过计算final hidden state
向量 $ \mathbf{\vec h}_n $ 和之前点击item
的representation
$ \mathbf{\vec h}_j $ 之间的相似度来建模二者之间的关系:其中:
$ \sigma(\cdot) $ 为sigmoid
激活函数, $ \mathbf A_1,\mathbf A_2 $ 为待学习的、用于分别将 $ \mathbf{\vec h}_n $ 和 $ \mathbf{\vec h}_j $ 投影到公共空间的投影矩阵。这里也可以使用其他的非线性激活函数,如
relu
。然后我们可以通过自适应地关注更重要的
item
(即,对部分item
分配更高的权重)来捕获当前session
中的session
意图:总之,当前
session
可以通过从inner memory network
$ \mathbf H_t $ 中读取,从而分别转换为两个固定长度的向量 $ \mathbf{\vec c}_t^g $ 和 $ \mathbf{\vec c}_t^l $ 。然后我们将 $ \mathbf{\vec c}_t^g $ 和 $ \mathbf{\vec c}_t^l $ 拼接成一个统一的representation
$ \mathbf{\vec c}_t^{\text{inner}} $ 作为最终的session representation
:其中
$ [\cdot||\cdot] $ 表示向量的拼接。也可以考虑其它融合方式,如最大池化、均值池化、门控融合机制等等。
19.1.2 Outer Memory Encoder
IME
中的全局编码器和局部编码器仅利用当前session
中包含的信息,而忽略了neighborhood session
中协同信息的重要性。为解决这个问题,我们提出了一个Outer Memory Encoder: OME
。outer memory matrix
$ \mathbf M $ 按时间顺序存储最近session
的representation
(它也被称作outer memory network
) 。OME
从 $ \mathbf M $ 中动态选择与当前session
具有更多相似行为模式的previous neighborhood session
。这些neighborhood session
用作辅助信息,从而帮助了解当前session
。OME
使用以下read/write
操作来访问 $ \mathbf M $ 。read
操作:直观而言,读取 $ \mathbf M $ 可以被认为是一种session-based
最近邻方法,它可以选择性地对检索到的、与当前session
相关的neighborhood
进行加权。给定当前
session
$ \mathcal X_t $ ,我们首先要确定在 $ \mathbf M $ 中与当前session
最相似的 $ k $ 个previous session
。具体而言,我们计算当前session
的 $ \mathbf{\vec c}_t^l $ 与存储在memory
矩阵 $ \mathbf M $ 中的previous session
的每个 $ \mathbf{\vec m}_i $ 之间的余弦相似度:其中
$ \cdot $ 为向量内积。为什么不使用
$ \mathbf{\vec c}_t^g $ 或者 $ \mathbf{\vec c}_t^{\text{inner}} $ 而仅使用 $ \mathbf{\vec c}_t^l $ ?论文并未给出任何解释。个人猜测是因为 $ \mathbf{\vec c}_t^l $ 抑制了一些噪音从而效果更好。根据
$ k $ 个最大的相似度得分 $ \left[\text{sim}_1^t,\text{sim}_2^t,\cdots,\text{sim}_{k-1}^t,\text{sim}_k^t\right] $ ,我们从 $ \mathbf M $ 中创建了包含 $ k $ 个session
的subsample
$ \mathbf M_t = \left[\mathbf{\vec m}_1^t,\mathbf{\vec m}_2^t,\cdots,\mathbf{\vec m}_{k-1}^t,\mathbf{\vec m}_k^t\right] $ 作为当前session
的 $ k $ 个最近邻。然后,我们通过
softmax
函数对k largest
相似度值进行处理,得到reading
权重:其中
$ \beta $ 为强度参数。这些
reading
权重还反映了每个neighbor
对当前session
的独特影响unique impact
,这允许模型对neighborhood
中更相似的session
分配更高的权重。最后,我们根据
neighborhood session
对当前session
的影响,通过访问neighborhood memory network
中其它session
的representation
,从而得到OME
模块的输出,即 $ \mathbf{\vec c}_t^{\text{outer}} $ :
write
操作:在我们实验的每个epoch
开始时,outer memory matrix
是空的。我们采用first-in-first-out
机制来更新outer memory matrix
,因此该矩阵总是存储最近的 $ m $ 个session
。写入outer memory
的时候,最早的session
从memory
中移除,新的session
被添加到memory
中。注意,当
outer memory matrix
未填满时,我们直接添加session
而不删除任何现有的session
。存储的
session
的 $ \mathbf{\vec m} $ 是什么?论文并没有解释。个人猜测 $ \mathbf{\vec m} $ 就是session
的 $ \mathbf{\vec c}_t^l $ ,因为计算相似度时使用了当前session
的 $ \mathbf{\vec c}_t^l $ 。
19.1.3 Recommendation Decoder
推荐解码器根据
IME
和OME
的输出来评估点击next item
的概率。为了选择性地组合来自
IME
和OME
的信息,我们使用融合门控机制来构建final session representation
,从而平衡当前session
信息和collaborative neighborhood information
的重要性:其中
$ \mathbf{\vec f}_t $ 为融合门fusion gate
并被定义为:然后我们使用双线性解码方案和
softmax
来计算推荐分。假设 $ \overrightarrow{\text{emb}}_i $ 是单个候选item
的representation
,我们根据当前session
$ \mathcal X_t $ 的final sesssion representation
$ \mathbf{\vec c}_t $ 获得每个候选item
的最终推荐概率:其中:
$ \mathbf B\in \mathbb R^{d_e\times d} $ , $ d_e $ 为每个item embedding
的维度, $ d $ 为final session representation
$ \mathbf{\vec c}_t $ 的维度。
我们的目标函数是:给定当前
session
的情况下最大化actual item
的预测概率。因此,我们采用交叉熵损失函数:其中:
$ \mathbb X $ 是训练集中所有session
的集合。 $ P(i\mid \mathcal X) $ 是给定session
$ \mathcal X $ 的条件下, $ i $ 作为next item
的概率。 $ \mathbb I(i,\mathcal X) $ 为ground truth
函数。如果item
$ i $ 为ground truth
,那么 $ \mathbb I(i,\mathcal X)=1 $ ,否则 $ \mathbb I(i,\mathcal X)=0 $ 。
在学习过程中,我们采用
Back-Propagation Through Time: BPTT
方法来优化CSRM
。
19.1.4 讨论
未来工作:
CSRM
的outer memory network
的slot
有限,因此只能从少数最近的session
中选择neighbor
。在未来的工作中,我们希望结合一种retrieval-based
机制,使得OME
能够根据之前的所有session
来查找neighbor
。- 我们还希望通过引入用户偏好信息、以及
item
属性来改善CSRM
,例如用户评论和item
类别等等。 - 此外,注意力机制和
memory
机制具有很强的泛化能力。所以我们想探索这个框架在其它application
领域的使用。
19.2 实验
我们旨在回答以下研究问题:
RQ1
:CSRM
在session-based
推荐任务中的表现如何?它在Recall
和MRR
指标上是否优于state-of-the-art
的方法?RQ2
:CSRM
使用不同的编码器(而不是结合IME
和OME
)的性能如何?RQ3
:CSRM
使用不同的聚合操作(而不是融合门控机制)的性能如何?RQ4
:CSRM
在OME
中具有不同数量的neighbor
时表现如何?RQ5
:session
长度如何影响session-based
推荐性能?RQ6
:collaborative neighborhood information
如何影响session-based
推荐性能?
数据集:我们在两个公开可用的数据集上进行了实验,即
YOOCHOOSE
和LastFM
。我们通过以下步骤对数据集进行预处理:- 首先,我们确保所有
session
都是按照时间顺序排列。 - 其次,我们过滤掉仅出现在测试集中的
item
。 - 第三,我们执行数据增强来考虑
session
中的时间漂移temporal shift
。
数据集的细节如下:
YOOCHOOSE
:YOOCHOOSE
数据集是RecSys Challenge 2015
发布的公开可用数据集。它包含电商网站中六个月的click-streams
。我们使用最后一天的session
进行测试,用所有其它session
进行训练。我们遵循《Improved recurrent neural networks for session-based recommendations》
的做法,过滤掉长度为1
的session
以及出现次数少于5
次的item
。《Improved recurrent neural networks for session-based recommendations》
发现YOOCHOOSE
的最近部分more recent fraction
足以完成任务,并且增加数据量不会进一步提高性能。我们使用最近的1/64
和1/4
部分的训练session
,分别称作YOOCHOOSE 1/64
数据集和YOOCHOOSE 1/4
数据集。经过预处理之后:
YOOCHOOSE 1/64
数据集包含17702
个item
的637226
次点击,随机分为124279
个训练session
、12309
个验证session
、以及15236
个测试session
。YOOCHOOSE 1/4
数据集包含30672
个item
的8253617
次点击,随机分为1988471
个训练session
、12371
个验证session
、以及15317
个测试session
。
LastFM
:LastFM
是一个音乐推荐数据集,包含从2004
年到2009
年通过LastFM API
获得的(user, time, artist, song)
元组。为了简化数据集,我们将数据集用于音乐艺术家推荐。在我们的实验中,我们选择
top 40000
名最受欢迎的艺术家作为item
集合。然后,我们以8
小时的时间间隔手动将收听历史listening history
划分为session
。也就是说,如果两个连续的动作发生在8
小时时间间隔以内,那么它们就属于同一个session
。否则,我们认为它们属于不同的session
。这个时间间隔使得每个session
不仅包含足够的交互,而且不同的session
在一定程度上相互独立。最后,在我们过滤掉少于2
个item
、以及超过50
个item
的session
之后,剩下281614
个session
和39163
个item
。该数据集称作LastFM
。经过预处理之后,
LastFM
数据集包含对39163
个item
的3804922
次点击,随机分为269847
个训练session
、5996
个验证session
以及5771
个测试session
。
数据集的统计结果如下表所示。
- 首先,我们确保所有
baseline
:我们考虑了三组baseline
方法,即传统的方法、RNN-based
的方法、memory network-based
的方法。传统的方法:
POP
:POP
总是推荐训练集中最流行的item
。这是一个非常简单的baseline
,但它可以在某些领域表现良好。S-POP
:S-POP
推荐当前session
中最流行的item
,而不是全局最流行的item
。Item-KNN
:在这种方法中,推荐与last item
相似的item
。相似性定义为:其中:
occurrence
表示出现了指定item
的session
的数量,co-occurrence
表示出现了指定两个item
的session
的数量。另外,也可以包含正则化项从而避免低频
item
之间的偶然高度相似性。BPR-MF
:BPR-MF
通过使用随机梯度下降来优化pairwise ranking
目标函数。与之前的研究一样,我们将这种方法应用于session-based
推荐,方法是对session
中截止到当前为止出现的item
的latent factor
取平均从而作为session
的representation
。FPMC
:Factorizing Personalized Markov Chain: FPMC
结合马尔科夫链模型和矩阵分解模型,用于next-basket
推荐任务。为了使其适用于session-based
推荐,我们在计算推荐分的时候忽略了user latent representation
。
RNN-based
方法:GRU-Rec
:我们将《Recurrent neural networks with top-k gains for session-based recommendations》
和《Session-based recommendations with recurrent neural networks》
提出的模型表示为GRU-Rec
,它使用session-parallel
的mini-batch
训练过程,还使用ranking-based
损失函数来学习模型。RNN-KNN
:RNN-KNN
将heuristics-based
的最近邻方案和人工制作权重参数weighting parameter
的GRU
结合起来,用于session-based
推荐,并取得了比GRU-Rec
更好的性能。RNN-KNN
使用item co-occurrence
来决定k
近邻session
。Improved GRU-Rec
:我们将《Improved recurrent neural networks for session-based recommendations》
中提出的模型表示为Improved GRU-Rec
。Improved GRU-Rec
采用两种技术:数据增强、以及一种考虑输入数据分布偏移shift
的方法,从而提高GRU-Rec
的性能。NARM
:Neural Attentive Recommendation Machine: NARM
是一种改进的encoder-decoder
架构,用于session-based
推荐。它通过将注意力机制融合到RNN
中来改善Improved GRU-Rec
。
memory network-based
方法:RUM
:RUM
有两种具体的实现方式。item-level RUM: RUM-I
直接将item
嵌入到memory matrix
中,而feature-level RUM: RUM-F
将用户在不同潜在特征latent feature
上的偏好的embedding
存储到memory matrix
中。我们将RUM-I
应用于session-based
推荐任务,通过RNN-based
方法用序列中的item
的latent factor
来表示一个新的session
。但是,RUM-F
无法应用于session-based
推荐,因为很难获得一个新的session
对特定特征的偏好。CMN
:CMN
利用memory network
来解决带隐式反馈的协同过滤问题。我们通过在进行预测时使用session
中出现的item
的平均latent representation
来表示一个session
,从而使得这种方法适用于session-based
推荐。CMN
在测试的时候需要对每个候选item
一个一个地打分,比较耗时。我们不评估所有的item
,而是采样了1000
个negative item
从而加快进程。
实验配置:
我们使用
Tensorflow
实现CSRM
,并在一个GeForce GTX TitanX GPU
上进行实验。为了缓解过拟合,我们采用了两个
dropout layer
:- 第一个
dropout layer
位于item embedding layer
和GRU layer
之间,dropout rate = 25%
。 - 第二个
dropout layer
位于final representation layer
和bilinear decoding layer
之间,dropout rate = 50%
。
- 第一个
在训练期间,我们使用高斯分布(均值为
0
、标准差为0.01
)来随机初始化模型参数。我们使用
mini-batch
的Adam
优化器,分别设置了动量超参数 $ \beta_1=0.9,\beta_2=0.999 $ ,以及 $ \epsilon=10^{-8} $ 。batch size
根据经验设置为512
。我们学习率由
[0.001, 0.0005, 0.0001]
范围内的网格搜索确定。GRU
的item embedding
维度和hidden unit
由[50, 100, 150]
范围内的网格搜索确定。我们将
OME
中最近邻的数量根据[128, 256, 512]
来变化,从而研究该超参数的影响。所有超参数都根据验证集进行调优,其中验证集是训练数据的一小部分。
评估指标:我们的任务是在给定当前
session
的情况下预测用户接下来会点击什么。推荐系统在每个时刻为每个session
生成一个推荐列表,该列表通常包含N
个 根据预测分进行排序的item
。用户接下来点击的实际item
应该包含在推荐列表中。因此我们使用以下指标来评估top-N
推荐:Recall@20
:ground-truth item
排在top-20 item
中的case
的比例。该指标不考虑ground-truth item
的实际排名。MRR@20
:Mean Reciprocal Rank: MRR
考虑item
排名倒数reciprocal rank
。如果排名弱于20
,则排名倒数置为零。MRR
会考虑ground-truth item
的实际排名,这在推荐顺序很重要的场景中很重要(如,排名靠后的item
仅在屏幕滚动后才可见)。
对于显著性检验,我们使用
$ p \lt 0.05 $ 的paired t-test
。性能对比 (
RQ1
):下表说明了在三个数据集上CSRM
和baseline
方法的性能。结果表明,CSRM
在所有数据集的Recall@20
和MRR@20
指标方面始终达到最佳性能。从结果中,我们有四个主要观察结论:在传统方法中,
Item-KNN
在大多数情况下都要比POP
、S-POP
、BPR-MF
取得显著的提升。这意味着KNN-based
的协同过滤方法可以帮助改善session-based
的推荐。至于
FPMC
,考虑到BPR-MF
和FPMC
之间的主要区别在于后者以序列的方式建模用户的历史记录,因此FPMC
比BPR-MF
获得更好结果的观察observation
证实了序列信息有助于推荐性能。我们观察到五种
RNN-based
的方法(GRU-Rec
、Improved GRU-Rec
、RNN-KNN
、NARM
、CSRM
)优于传统方法。这表明RNN-based
的模型擅长处理session
中的序列信息。CSRM
显著优于所有RNN-based
的baseline
方法。一般而言,相对于最佳baseline NARM
,CSRM
在三个数据集上的Recall@20
指标分别提高了1.88%, 2.89%, 7.45%
,MRR@20
指标分别提高了3.48%, 3.12%, 5.77%
。尽管
RNN-KNN
和CSRM
都考了了协同过滤信息,但是我们注意到CSRM
在RNN-KNN
上取得了一致的提升。原因是RNN-kNN
通过人工制作的超参数将RNN
与co-occurrence-based KNN
相结合,缺乏能够捕获更复杂关系的非线性交互。这些观察证实,利用带
memory network
的collaborative neighborhood information
可以显著提高session-based
推荐的性能。对于
MANN-based
方法,我们发现CSRM
在所有数据集上都优于RUM
和CMN
。这是因为在session-based
推荐中没有可用的用户信息,并且RUM
和CMN
在这种case
中根本不适用、也没有效果。一个自然的疑问是:在用户信息可用的场景下,
RUM
、CMN
、CSRM
的效果对比如何?
Encoder
影响(RQ2
):为了进一步说明协同信息和memory network
的效果,我们比较了CSRM
、以及两种CSRM
变体之间的性能: $ \text{CSRM}_\text{ime} $ :指的是没有OME
的CSRM
。它使用RNN
的固有memory
来建模当前session
中的序列行为。它实际上相当于NARM
模型,因为CSRM
在NARM
的基础上进一步考虑了collaborative neighborhood information
。在本节中,我们使用NARM
的结果来表示 $ \text{CSRM}_\text{ime} $ 。 $ \text{CSRM}_\text{ome} $ :指的是没有IME
的CSRM
。它使用external memory
来编码collaborative neighborhood information
。
下表总结了这几个模型在三个数据集上的实验结果。
- 首先,我们发现
$ \text{CSRM}_\text{ime} $ 优于 $ \text{CSRM}_\text{ome} $ 。这表明session
自身的序列信息对于session-based
的推荐任务更重要。 - 其次,
CSRM
在三个数据集上的所有指标都要比 $ \text{CSRM}_\text{ime} $ 和 $ \text{CSRM}_\text{ome} $ 这两个变体要更好。这证实了结合session
自己的信息、以及collaborative neighborhood information
来获得更好的推荐的有效性。以YOOCHOOSE 1/64
数据集为例,与 $ \text{CSRM}_\text{ime} $ 和 $ \text{CSRM}_\text{ome} $ 相比,CSRM
在Recall@20
指标上分别相对提升1.88%
和8.41%
左右,在MRR@20
指标上分别相对提升3.48%
和24.84%
左右。
聚合操作的影响(
RQ3
):接下来,我们带不同聚合操作的CSRM
进行相互比较。这些聚合操作包括:最大池化、均值池化、拼接、融合门控机制。对于最大池化聚合,
final session representation
定义为 $ \mathbf{\vec c}_t = \max\left(\mathbf{\vec c}_t^{\text{inner}},\mathbf{\vec c}_t^{\text{outer}}\right) $ ,其中 $ \max(\cdot,\cdot) $ 为逐元素取max
的操作。对于均值池化聚合,
final session representation
定义为 $ \mathbf{\vec c}_t = \frac{ \mathbf{\vec c}_t^{\text{inner}}+\mathbf{\vec c}_t^{\text{outer}} }{2} $ 。对于拼接聚合,
final session representation
定义为 $ \mathbf{\vec c}_t = \left[\mathbf{\vec c}_t^{\text{inner}}||\mathbf{\vec c}_t^{\text{outer}}\right] $ ,其中 $ [\cdot||\cdot] $ 表示向量拼接操作。对于融合门控机制聚合,
final session representation
如正文部分所示,定义为:其中
$ \mathbf{\vec f}_t $ 为融合门并被定义为:
如下表所示:
- 在
Recall@20
和MRR@20
指标上,带融合门控机制的CSRM
在三个数据集上均优于其它三种聚合操作。这表明融合门控机制更有助于建模IME
和OME
之间的交互。 - 在大多数情况下,带拼接操作的
CSRM
和带均值池化的CSRM
实现了相似的性能,并且在三个数据集上均优于带最大池化的CSRM
。这表明在建模多个因子之间的交互时,均值池化和拼接操作要比最大池化更有利。
邻居数量的影响(
RQ4
):为了研究collaborative neighborhood information
对session-based
推荐的影响,我们在下表中展示了CSRM
关于不同邻居数量的性能。- 对于
YOOCHOOSE 1/64
和YOOCHOOSE 1/4
数据集,CSRM
在Recall@20
指标上的性能随着邻居数量的增加而提高,在MRR@20
指标上的性能随着邻居数量的增加而小幅波动。 - 对于
LastFM
数据集,当 $ k=512 $ 时我们可以获得相对较好的性能。
这表明,准确地预测
session intent
取决于推荐系统将collaborative neighborhood information
纳入模型的程度。- 对于
session
长度的影响(RQ5
):为了了解session
长度对利用collaborative neighborhood information
的影响,我们在LastFM
上比较了不同长度的、各种各样的session
。我们在下表中展示了与session
长度相关的性能。注意,由于session
长度的范围较广,我们将测试集根据每个session
的长度划分为不同的分组。从结果中我们可以观察到:CSRM
整体上表现更好。这表明collaborative neighborhood information
确实有助于捕获session
意图并作出更好的预测。- 一般而言,
session
长度在1
到10
之间时,CSRM
的性能提升更强。这可能是因为当session
很短时,每个session
的点击item
有限,因此很难捕获session
的意图。在这种情况下,CSRM
擅长通过collaborative neighborhood information
来捕获session
的意图。
案例研究(
RQ6
):为了直观地掌握协同信息的效果,我们从YOOCHOOSE 1/64
数据集中选择了一些good case
和bad case
,如下图所示。左侧的数字是current session ID
,右侧的数字是推荐列表中ground truth
的排名。颜色程度表示 $ \text{sim}\left(\mathbf{\vec c}_t^l,\mathbf{\vec m}_i\right) $ 给出的邻居相似性neighbor similarity
的强度,其中较浅的颜色表示较低的值、较深的颜色表示较高的值。图中的每一行代表当前session
的top 10 neighbor
。相似性之间的差异可能非常小,因此在视觉上难以区分。这里的横坐标表示不同的
neighborhood session
(而不是current session
中的不同item
)。总体而言,显然具有高度相似
neighbor
的session
获得了更好的推荐性能,即下图中的session 12475, 12509, 15405
。分配了都是低相似度
neighbor
的session
获得了更差的推荐性能,即下图中的session 12600, 14731, 27355
。这证实了
collaborative neighborhood information
对session-based
推荐的用户意图有很大影响。并非当前
session
的所有neighbor
都同等重要。例如,session 12475
的neighbor
具有非常不同的权重。并非所有
session
都需要依赖collaborative neighborhood information
来获得良好的性能。一些session
将相同的低相似性equal low similarity
分配给neighbor
,这意味着它们使用较少的协同信息。但是它们仍然取得了良好的推荐性能,如下图中的session 9798, 17028, 27197
。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论