引言
在推荐系统领域,如何有效表征物品特征始终是核心挑战。传统协同过滤方法受限于稀疏性问题,直到2016年微软研究院提出的Item2Vec方法,将自然语言处理中的Word2Vec技术创造性应用于物品表征学习,开启了嵌入学习的新纪元。
Item2vec
脱胎于自然语言处理领域中的 word2vec
技术。word2vec 的核心目标是将文本中的单词转化为低维向量,使得语义相近的单词在向量空间中距离相近。item2vec 则将这一思想拓展到了更广泛的领域,它可以将任何类型的 “item”,如商品、电影、音乐、文章等,映射为低维向量,从而捕捉 item 之间的相似性和关联性。这种向量表示为后续的数据分析、推荐系统、聚类等任务提供了坚实的基础。
Word2vec核心思想
Word2Vec借鉴自然语言处理中的分布式假设:
“出现在相似上下文中的词语具有相似语义”
将这一思想迁移到推荐场景:
- 用户行为序列视作"句子"
- 单个物品视为"词语"
- 共同出现的物品构成"上下文"
通过神经网络学习物品的稠密向量表示,使得相似物品在向量空间中距离相近。
数学原理
1. Skip-Gram模型
给定长度为T的物品序列 w 1 , w 2 , . . . , w T w_1,w_2,...,w_T w1,w2,...,wT,最大化对数似然:
1 T ∑ t = 1 T ∑ − k ≤ j ≤ k , j ≠ 0 log p ( w t + j ∣ w t ) \frac{1}{T} \sum_{t=1}^T \sum_{-k \leq j \leq k,j\neq0} \log p(w_{t+j}|w_t) T1t=1∑T−k≤j≤k,j=0∑logp(wt+j∣wt)
其中k为上下文窗口大小,条件概率通过softmax计算:
p ( w j ∣ w i ) = exp ( u j T v j ) ∑ w = 1 W exp ( u i T v k ) p(w_j|w_i) = \frac{\exp(\mathbf{u_j}^T \mathbf{v_j})}{\sum_{w=1}^W \exp(\mathbf{u_i}^T \mathbf{v_k})} p(wj∣wi)=∑w=1Wexp(uiTvk)exp(ujTvj)
2. 负采样优化
为了解决计算量过大的问题,负采样技术应运而生。负采样通过将公式中的 Softmax 函数替换为
p ( w j ∣ w i ) = σ ( u j T v i ) ∏ k = 1 N σ ( − u i k T v i ) p(w_j | w_i) = \sigma(u_j^T v_i)\prod_{k = 1}^{N}\sigma(-u_{i_k}^T v_i) p(wj∣wi)=σ(ujTvi)k=1∏Nσ(−uikTvi)
其中:
其中, σ ( x ) = 1 1 + exp ( − x ) \sigma(x) = \frac{1}{1 + \exp(-x)} σ(x)=1+exp(−x)1, N N N是每个正样本对应的负样本数量。负样本是从 unigram distribution 中按 3/4 次方采样的。
P n ( w ) = f ( w ) 3 4 ∑ w ′ f ( w ′ ) 3 4 P_n(w) = \frac{f(w)^{\frac{3}{4}}}{\sum_{w'} f(w')^{\frac{3}{4}}} Pn(w)=∑w′f(w′)43f(w)43
其中: f ( w ) f(w) f(w)是词 $w $ 在语料库中的频率。
- f ( w ′ ) f(w') f(w′) 是语料库中每个词 w ′ w' w′的频率。
实验证明,这种分布显著优于普通的一元分布。负采样大大减少了计算量,因为它只需要考虑少数几个负样本,而不是整个词汇表,使得模型能够在大规模数据上高效训练。
3.处理单词频率不平衡:子采样过程
在实际数据中,单词的频率往往存在很大差异,高频词出现的次数远远多于低频词。这种不平衡会影响模型的学习效果,因为模型可能会过度关注高频词,而忽略低频词的信息。为了解决这个问题,引入了子采样过程。
给定输入单词序列,每个单词w以概率p(discard|w)被丢弃
p ( d i s c a r d ∣ w ) = 1 − p f ( w ) p(discard|w) = 1 -\sqrt{ \frac{p}{f(w)}} p(discard∣w)=1−f(w)p
其中 f ( w ) f(w) f(w)是单词w的频率,p是预定阈值。
这样的结果是:
1.频率较低的词会被保留,频率较高的词则可能会被丢弃
2.加速了学习过程因为他降低了高频词的数量,降低了计算量,还显著改善了低频词的表示。通过子采样,模型能够更加平衡地学习高频词和低频词的特征,提高了模型的泛化能力。
Item2Vec 原理
在商品推荐中的应用 在传统的基于协同过滤(Collaborative Filtering, CF)的推荐系统中,商品之间的相似性通常是基于用户的行为数据来计算的。Item2Vec 通过将商品的购买历史转换为一个序列,类似于处理自然语言中的单词序列,来学习商品的嵌入表示。通过学习商品间的相似度,推荐系统可以根据用户的购买历史推荐相似的商品。
序列 vs. 集合
与传统的自然语言处理任务不同,Item2Vec 处理的是商品的集合(如用户购买的商品列表),而不是一个有序的商品序列。因此,在训练过程中,Item2Vec 会忽略商品顺序的信息,认为同一集合中的商品是相似的,不考虑其出现的顺序或时间。
训练过程
Item2Vec 的训练过程与 Skip-gram with Negative Sampling 类似,模型的输入是用户的商品购买集合,目标是最大化目标商品与其上下文商品之间的相似度。 对于一个包含 K K K 个商品的集合,Item2Vec 的目标函数可以表示为:
Objective = ∑ i = 1 K ∑ j ≠ i log p ( w j ∣ w i ) \text{Objective} = \sum_{i=1}^{K} \sum_{j \neq i} \log p(w_j | w_i) Objective=i=1∑Kj=i∑logp(wj∣wi)
其中, w i w_i wi 和 w j w_j wj 是同一集合中的商品,模型的目标是学习每一对商品之间的相似度。
负采样和子采样代码实现
负采样
def get_negative_samples(word_prob, k = 5):"""从采样分布中随机抽取负样本:param word_prob: 采样分布, 字典形式, key为单词索引, value为概率:param words: 单词索引列表:param num_samples: 每个单词的负样本数量:return: 负样本列表"""# 从采样分布中随机抽取负样本word = list(word_prob.keys())prob = list(word_prob.values())negative_samples = np.random.choice(word, size=k, p=prob)return negative_samples
子采样
def get_unigram_distribution(words,power):"""子采样函数:param words: 单词索引列表:param power: 次方:return: 采样分布"""# 使用 collections.Counter 统计每个单词的频率word_counts = collections.Counter(words)total_words = len(words)# 计算每个单词的频率word_freq_power = {word: np.power(count / total_words, power) for word, count in word_counts.items()}word_sum = sum(word_freq_power.values())# 计算每个单词的概率word_prob = {word: freq_power / word_sum for word, freq_power in word_freq_power.items()}return word_prob
结论
Item2Vec 利用 SGNS(Skip-gram with Negative sampling)
方法通过学习商品的嵌入向量来捕捉商品间的相似性,从而提升推荐系统的性能。它将商品看作是无序集合的元素,忽略了顺序信息,但仍然能够有效地通过计算商品间的相似度来进行推荐。在实际应用中,Item2Vec 为商品推荐系统提供了一种高效、准确的解决方案。
Reference
- Barkan, O., & Koenigstein, N. (2016). Item2Vec: Neural item embedding for collaborative filtering. Proceedings of the 10th ACM Conference on Recommender Systems (RecSys '16) , 143-150. DOI: 10.1145/2959100.2959167
- 王喆《深度学习推荐系统》