Embedding方法:从Word2Vec到Item2Vec

331 阅读3分钟

引言

在推荐系统领域,如何有效表征物品特征始终是核心挑战。传统协同过滤方法受限于稀疏性问题,直到2016年微软研究院提出的Item2Vec方法,将自然语言处理中的Word2Vec技术创造性应用于物品表征学习,开启了嵌入学习的新纪元。

Item2vec 脱胎于自然语言处理领域中的 word2vec 技术。word2vec 的核心目标是将文本中的单词转化为低维向量,使得语义相近的单词在向量空间中距离相近。item2vec 则将这一思想拓展到了更广泛的领域,它可以将任何类型的 “item”,如商品、电影、音乐、文章等,映射为低维向量,从而捕捉 item 之间的相似性和关联性。这种向量表示为后续的数据分析、推荐系统、聚类等任务提供了坚实的基础。

Word2vec核心思想

Word2Vec借鉴自然语言处理中的分布式假设:

"出现在相似上下文中的词语具有相似语义"

将这一思想迁移到推荐场景:

  • 用户行为序列视作"句子"
  • 单个物品视为"词语"
  • 共同出现的物品构成"上下文"

通过神经网络学习物品的稠密向量表示,使得相似物品在向量空间中距离相近。

数学原理

1. Skip-Gram模型

给定长度为T的物品序列 w1,w2,...,wTw_1,w_2,...,w_T,最大化对数似然:

1Tt=1Tkjk,j0logp(wt+jwt)\frac{1}{T} \sum_{t=1}^T \sum_{-k \leq j \leq k,j\neq0} \log p(w_{t+j}|w_t)

其中k为上下文窗口大小,条件概率通过softmax计算:

p(wjwi)=exp(ujTvj)w=1Wexp(uiTvk)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})}

2. 负采样优化

为了解决计算量过大的问题,负采样技术应运而生。负采样通过将公式中的 Softmax 函数替换为

p(wjwi)=σ(ujTvi)k=1Nσ(uikTvi)p(w_j | w_i) = \sigma(u_j^T v_i)\prod_{k = 1}^{N}\sigma(-u_{i_k}^T v_i)

其中:

其中,σ(x)=11+exp(x)\sigma(x) = \frac{1}{1 + \exp(-x)}NN是每个正样本对应的负样本数量。负样本是从 unigram distribution 中按 3/4 次方采样的。

Pn(w)=f(w)34wf(w)34P_n(w) = \frac{f(w)^{\frac{3}{4}}}{\sum_{w'} f(w')^{\frac{3}{4}}}

其中: f(w)f(w)是词 ww 在语料库中的频率。

  • f(w)f(w') 是语料库中每个词 ww'的频率。

实验证明,这种分布显著优于普通的一元分布。负采样大大减少了计算量,因为它只需要考虑少数几个负样本,而不是整个词汇表,使得模型能够在大规模数据上高效训练。

3.处理单词频率不平衡:子采样过程

在实际数据中,单词的频率往往存在很大差异,高频词出现的次数远远多于低频词。这种不平衡会影响模型的学习效果,因为模型可能会过度关注高频词,而忽略低频词的信息。为了解决这个问题,引入了子采样过程。

给定输入单词序列,每个单词w以概率p(discard|w)被丢弃

p(discardw)=1pf(w)p(discard|w) = 1 -\sqrt{ \frac{p}{f(w)}}

其中fwf(w)是单词w的频率,p是预定阈值。

这样的结果是:

1.频率较低的词会被保留,频率较高的词则可能会被丢弃
2.加速了学习过程因为他降低了高频词的数量,降低了计算量,还显著改善了低频词的表示。通过子采样,模型能够更加平衡地学习高频词和低频词的特征,提高了模型的泛化能力。

Item2Vec 原理

在商品推荐中的应用 在传统的基于协同过滤(Collaborative Filtering, CF)的推荐系统中,商品之间的相似性通常是基于用户的行为数据来计算的。Item2Vec 通过将商品的购买历史转换为一个序列,类似于处理自然语言中的单词序列,来学习商品的嵌入表示。通过学习商品间的相似度,推荐系统可以根据用户的购买历史推荐相似的商品。

序列 vs. 集合

与传统的自然语言处理任务不同,Item2Vec 处理的是商品的集合(如用户购买的商品列表),而不是一个有序的商品序列。因此,在训练过程中,Item2Vec 会忽略商品顺序的信息,认为同一集合中的商品是相似的,不考虑其出现的顺序或时间。

训练过程

Item2Vec 的训练过程与 Skip-gram with Negative Sampling 类似,模型的输入是用户的商品购买集合,目标是最大化目标商品与其上下文商品之间的相似度。 对于一个包含 KK 个商品的集合,Item2Vec 的目标函数可以表示为:

Objective=i=1Kjilogp(wjwi)\text{Objective} = \sum_{i=1}^{K} \sum_{j \neq i} \log p(w_j | w_i)

其中, wiw_iwjw_j 是同一集合中的商品,模型的目标是学习每一对商品之间的相似度。

负采样和子采样代码实现

负采样

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

  1. 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
  2. 王喆《深度学习推荐系统》