引言
在推荐系统领域,如何有效表征物品特征始终是核心挑战。传统协同过滤方法受限于稀疏性问题,直到2016年微软研究院提出的Item2Vec方法,将自然语言处理中的Word2Vec技术创造性应用于物品表征学习,开启了嵌入学习的新纪元。
Item2vec 脱胎于自然语言处理领域中的 word2vec 技术。word2vec 的核心目标是将文本中的单词转化为低维向量,使得语义相近的单词在向量空间中距离相近。item2vec 则将这一思想拓展到了更广泛的领域,它可以将任何类型的 “item”,如商品、电影、音乐、文章等,映射为低维向量,从而捕捉 item 之间的相似性和关联性。这种向量表示为后续的数据分析、推荐系统、聚类等任务提供了坚实的基础。
Word2vec核心思想
Word2Vec借鉴自然语言处理中的分布式假设:
"出现在相似上下文中的词语具有相似语义"
将这一思想迁移到推荐场景:
- 用户行为序列视作"句子"
- 单个物品视为"词语"
- 共同出现的物品构成"上下文"
通过神经网络学习物品的稠密向量表示,使得相似物品在向量空间中距离相近。
数学原理
1. Skip-Gram模型
给定长度为T的物品序列 ,最大化对数似然:
其中k为上下文窗口大小,条件概率通过softmax计算:
2. 负采样优化
为了解决计算量过大的问题,负采样技术应运而生。负采样通过将公式中的 Softmax 函数替换为
其中:
其中,,是每个正样本对应的负样本数量。负样本是从 unigram distribution 中按 3/4 次方采样的。
其中: 是词 在语料库中的频率。
- 是语料库中每个词 的频率。
实验证明,这种分布显著优于普通的一元分布。负采样大大减少了计算量,因为它只需要考虑少数几个负样本,而不是整个词汇表,使得模型能够在大规模数据上高效训练。
3.处理单词频率不平衡:子采样过程
在实际数据中,单词的频率往往存在很大差异,高频词出现的次数远远多于低频词。这种不平衡会影响模型的学习效果,因为模型可能会过度关注高频词,而忽略低频词的信息。为了解决这个问题,引入了子采样过程。
给定输入单词序列,每个单词w以概率p(discard|w)被丢弃
其中是单词w的频率,p是预定阈值。
这样的结果是:
1.频率较低的词会被保留,频率较高的词则可能会被丢弃
2.加速了学习过程因为他降低了高频词的数量,降低了计算量,还显著改善了低频词的表示。通过子采样,模型能够更加平衡地学习高频词和低频词的特征,提高了模型的泛化能力。
Item2Vec 原理
在商品推荐中的应用 在传统的基于协同过滤(Collaborative Filtering, CF)的推荐系统中,商品之间的相似性通常是基于用户的行为数据来计算的。Item2Vec 通过将商品的购买历史转换为一个序列,类似于处理自然语言中的单词序列,来学习商品的嵌入表示。通过学习商品间的相似度,推荐系统可以根据用户的购买历史推荐相似的商品。
序列 vs. 集合
与传统的自然语言处理任务不同,Item2Vec 处理的是商品的集合(如用户购买的商品列表),而不是一个有序的商品序列。因此,在训练过程中,Item2Vec 会忽略商品顺序的信息,认为同一集合中的商品是相似的,不考虑其出现的顺序或时间。
训练过程
Item2Vec 的训练过程与 Skip-gram with Negative Sampling 类似,模型的输入是用户的商品购买集合,目标是最大化目标商品与其上下文商品之间的相似度。 对于一个包含 个商品的集合,Item2Vec 的目标函数可以表示为:
其中, 和 是同一集合中的商品,模型的目标是学习每一对商品之间的相似度。
负采样和子采样代码实现
负采样
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
- 王喆《深度学习推荐系统》