精华内容
下载资源
问答
  • 推荐算法中的word2vec大牛直接用的该库源码,然后这个玩意目前我无法得到,所以有看到word2vec库,然而这个库不能直接在win下用pip安装,所以我先试试在服务器能不能行? 服务器是可以的,依赖环境Cython。不过有个...
  • Item2vec_Tutorial 本教程将带您了解非自然语言处理领域中Word2Vec及其扩展之一-Item2Vec背后的思想。 具体来说,使用Word2Vec的概念和Gensim软件包提供的模块,我们将构建一个轻量级的电影推荐系统。 诸如Word2...
  • item2vec代码

    千次阅读 2019-08-22 09:07:56
    item2vec = SGNS(len(item), 10) # ~ print(item2vec) optimizer = optim.Adam(item2vec.parameters(), lr=0.001) for epoch in range(1): for i, batch in enumerate(get_batch_sample(100, train_data)):...
    #-*-coding:utf-8-*-
    """
    @author:taoshouzheng
    @time:2019/8/20 10:46
    @email:tsz1216@sina.com
    """
    
    import torch
    import torch.nn as nn
    from torch.autograd import Variable
    import torch.optim as optim
    import random
    from collections import Counter
    
    
    class SGNS(nn.Module):
    
    	def __init__(self, vocab_size, projection_dim):
    
    		super(SGNS, self).__init__()
    
    		self.embedding_v = nn.Embedding(vocab_size, projection_dim)		# center embedding
    		self.embedding_u = nn.Embedding(vocab_size, projection_dim)		# out embedding
    		self.log_sigmoid = nn.LogSigmoid()
    
    		init_range = (2.0 / (vocab_size + projection_dim)) ** 0.5		# Xavier init
    		self.embedding_v.weight.data.uniform_(-init_range, init_range)		# init
    		# self.embedding_u.weight.data.uniform_(-0.0, 0.0)		# init
    		self.embedding_u.weight.data.uniform_(-init_range, init_range)  # init
    
    	def forward(self, center_words, target_words, negative_words):
    		center_embeds = self.embedding_v(center_words)		# B * 1 * D
    		target_embeds = self.embedding_u(target_words)		# B * 1 * D
    		neg_embeds = -self.embedding_u(negative_words)		# B * K * D
    		positive_score = target_embeds.bmm(center_embeds.transpose(1, 2)).squeeze(2)		# B * 1
    		negative_score = torch.sum(neg_embeds.bmm(center_embeds.transpose(1, 2)).squeeze(2), 1).view(center_words.size(0), -1)		# B * K ---> B * 1
    		los = self.log_sigmoid(positive_score) + self.log_sigmoid(negative_score)
    
    		return -torch.mean(los)
    
    	# 获取单词的embedding
    	def prediction(self, inputs):
    		embeds = self.embedding_v(inputs)
    		return embeds
    
    
    def get_batch_sample(bat_size, tra_data):		# ~
    	random.shuffle(tra_data)		# 随机打乱数据
    	s_index = 0
    	e_index = bat_size
    
    	while e_index < len(tra_data):
    		bat = tra_data[s_index: e_index]
    		temp = e_index
    		e_index = e_index + bat_size
    		s_index = temp
    		yield bat
    
    	if e_index >= len(tra_data):
    		bat = train_data[s_index:]
    		yield bat
    
    
    # 生成正样本
    def get_positive_sample(samp_lists):		# ~
    	"""
    	:param :list: 二维列表
    	:return:
    	"""
    
    	positive_samples = []
    
    	for sublist in samp_lists:
    
    		sublist_length = len(sublist)
    
    		for ite in sublist:
    
    			ite_index = sublist.index(ite)
    
    			for j in range(sublist_length):
    
    				if ite_index != j:
    					positive_samples.append([ite, sublist[j]])
    
    	target_words = []
    	context_words = []
    
    	for word_pair in positive_samples:
    		target_words.append(word_pair[0])
    		context_words.append(word_pair[1])
    
    	return target_words, context_words		# 一维列表
    
    
    # 生成负样本
    def get_negative_sample(centers, targets, un_table, dict, k):
    
    	batch_size = len(targets)		# 批次大小
    
    	negative_samples = []
    
    	for i in range(batch_size):
    
    		neg_sample = []
    		center_index = centers[i][0]		# !!!
    		target_index = targets[i][0]		# !!!
    
    		while len(neg_sample) < k:
    
    			neg = random.choice(un_table)
    			if neg == target_index or neg == center_index:
    				continue
    			neg_sample.append(dict[neg])
    		negative_samples.append(neg_sample)
    
    	# 返回一个二维列表
    	return negative_samples
    
    
    if __name__ == '__main__':
    
    	movie_lists = []
    
    	with open(r'E:\Experiment\Algorithms\Item2vec-pytorch\1.csv', 'r', encoding='utf8') as f:
    		contents = f.readlines()
    		for content in contents:
    			content = content.strip().split(',')
    			if content[0] == '':
    				continue
    			movie_list = [int(m) for m in content]
    			if len(movie_list) > 1:
    				movie_lists.append(movie_list)		# 二维列表
    
    	fla = lambda k: [i for sublist in k for i in sublist]
    	item_counter = Counter(fla(movie_lists))
    	item = [w for w, c in item_counter.items()]  # item列表
    
    	item2index = {}
    	for vo in item:
    		if item2index.get(vo) is None:
    			item2index[vo] = len(item2index)
    
    	index2item = {v: k for k, v in item2index.items()}
    
    	new_movie_lists = []
    	for m in movie_lists:
    		m = [item2index[n] for n in m]
    		new_movie_lists.append(m)
    
    	cent_words, cont_words = get_positive_sample(new_movie_lists)  # 一维列表
    
    	uni_table = []
    	f = sum([item_counter[it] ** 0.75 for it in item])		# 这边有个地方索引没转过来
    	z = 0.0001
    	for it in item:
    		uni_table.extend([it] * int(((item_counter[it] ** 0.75) / f) / z))
    
    	train_data = [[cent_words[i], cont_words[i]] for i in range(len(cent_words))]		# 二维列表
    
    	item2vec = SGNS(len(item), 10)		# ~
    	print(item2vec)
    	optimizer = optim.Adam(item2vec.parameters(), lr=0.001)
    
    	for epoch in range(1):
    
    		for i, batch in enumerate(get_batch_sample(100, train_data)):
    
    			target = [[p[0]] for p in batch]
    			context = [[q[1]] for q in batch]
    			negative = get_negative_sample(centers=target, targets=context, un_table=uni_table, dict=item2index, k=10)
    
    			target = Variable(torch.LongTensor(target))
    			# print(target)
    			context = Variable(torch.LongTensor(context))
    			# print(context)
    			negative = Variable(torch.LongTensor(negative))
    			# print(negative)
    			item2vec.zero_grad()
    
    			loss = item2vec(target, context, negative)
    
    			loss.backward()
    			optimizer.step()
    
    			print('Epoch : %d, Batch : %d, loss : %.04f' % (epoch + 1, i + 1, loss))
    
    item2vec.eval()
    
    
    print(item2vec.prediction(torch.LongTensor([1])))
    print(item2vec.prediction(torch.LongTensor([1])).data.numpy().tolist())
    print(item2vec.prediction(torch.LongTensor([1])).data.size())
    
    item_embeddings = []
    
    for item, index in item2index.items():
    
    	print(item)
    	print(index)
    	print(torch.flatten(item2vec.prediction(torch.LongTensor([index]))).data)
    
    	item_embedding_str = str(item) + ';' + ','.join([str(a) for a in torch.flatten(item2vec.prediction(torch.LongTensor([index]))).data.numpy().tolist()])
    
    	item_embeddings.append(item_embedding_str)
    
    
    with open(r'E:\Experiment\Algorithms\Item2vec-pytorch\em.txt', 'w', encoding='utf8') as g:
    	for st in item_embeddings:
    		g.write(st + '\n')
    
    print('完成!')
    

    输入数据如下:

    结果如下:

     

    展开全文
  • item2vec详解

    千次阅读 2020-04-07 23:04:13
    1.item2vec的兴起 自从word2vec被证明效果不错以后,掀起了一股embedding的热潮。item2vec, doc2vec,总结起来就是everything2vec。在实际工作中,embedding的使用也非常广泛,今天我们就来说说常用的item2vec。 ...

    项目github地址:bitcarmanlee easy-algorithm-interview-and-practice
    欢迎大家star,留言,一起学习进步

    1.item2vec的兴起

    自从word2vec被证明效果不错以后,掀起了一股embedding的热潮。item2vec, doc2vec,总结起来就是everything2vec。在实际工作中,embedding的使用也非常广泛,今天我们就来说说常用的item2vec。

    word2vec构建样本时,句子分词以后就构成了一个天然的序列。那么在推荐的应用场景下,如何生成这个序列,或者说如何生成训练样本,成为了一个必须要解决的问题。

    一般来说,有如下两种方式构建训练样本
    1.基于时序的关系
    我们会认为item之间存在时序关系,相当于我们将各个不同的item类比为word2vec的单词,那么将这些item串联起来就相当于将word连起来组成一个句子,这样不管是构造训练集的方式或者训练的方式都可以按照word2vec的方式来进行了。
    比如视频网站的用户观看的视频序列,音乐网站用户听的歌曲序列,我们都可以认为是这种方式。

    2.基于集合的关系
    认为 item 之间存在非常弱的时序关系,或者因为某种原因,我们无法获得 item 的序列。那么这种情况只能放弃考虑 item 间的时空信息,转而使用 item 集合来取代序列。通常我们把用户的行为序列视为一个集合(当然还有其他集合构造方式),我们假定一个静态的环境,在这个环境中,共现在同一个集合的 item 就可以认为它们是相似的,然后视为正样本,不管它们是以什么样的顺序产生的,如果某两个 item 频繁共现,二者的 Embedding 则可能也很相似。很明显,这种利用集合共现性构建样本的方式与 Word2Vec 的输入样本还是不一样的,因此无法直接应用 Word2Vec 的算法,这就需要对 Word2Vec 的过程进行调整。另外还需要注意的是,上面的这种的假设是有局限性的,不一定适用于其它场景。
    基于集合的示例比如电商网站订单中的商品集合, 另外比如用户的浏览物料item的集合。

    2.常用的Embedding方式

    1.以SVD为代表的MF方式。通过对user-item-score矩阵的分解,或者user-item的隐式矩阵分解,可以获取user与item的隐向量,该向量可以作为embedding向量使用。
    2.FM算法。FM学习了各个特征的隐向量表示,从而可以将这些学习到的隐向量作为特征的embedding使用。
    3.DNN-Embedding 通过神经网络,利用接入Embedding层与目标loss进行joint train,从而学习其特征表达,这是一种端到端的embedding训练方式(end-to-end)。
    4.item2vec 与word2vec类似的方式。
    5.graph embedding,是基于图模型的方法,包括deep walk, node2vec, eges等方法。

    3.item2vec与MF的区别

    首先,二者都应用了隐向量来表征实体特征,不同的是,传统的 MF 通常是 user-item 矩阵,而 Item2Vec 通过滑动窗口样本生成的方式构造出的则更像是 item-item 矩阵;另外,二者得到隐向量的方式也不同,MF 利用均方差损失,使预测得分与已有得分之间的误差尽可能地小,而 Item2Vec 则是利用空间信息并借助了最大似然估计的思想,使用对数损失,使上下文关系或者共现关系构造出的正样本的 item Pair 出现的概率可能地大;此外训练 Item2Vec 的时候还要引入负样本,这也是与 MF 不同的地方。

    对于二者在推荐效果上的差异,一个经验是传统 MF 推荐会让热门内容经常性排在前面,而 Item2vec 能更好的学到中频内容的相似性。Iterm2Vec 加上较短的时间窗口,相似推荐会比 MF 好很多。

    4.原理

    对于出现在同一个集合的item对我们视为正样本,对于集合 ω 1 , ω 2 , ⋯   , ω K \omega_1, \omega_2, \cdots, \omega_K ω1,ω2,,ωK,目标函数为
    1 K ∑ i = 1 K ∑ j ≠ i K log ⁡ p ( w j ∣ w i ) \frac{1}{K} \sum_{i=1}^{K}\sum_{j \neq i}^{K} \log p(w_j | w_i) K1i=1Kj=iKlogp(wjwi)
    利用负采样,将 p ( w j ∣ w i ) p(w_j | w_i) p(wjwi)可以定义为
    p ( w j ∣ w i ) = e x p ( u i T v j ) ∑ k ∈ I W e x p ( u k T v j ) p(w_j | w_i) = \frac{exp(u_i ^T v_j)}{\sum_{k \in I_W} exp(u_k ^T v_j)} p(wjwi)=kIWexp(ukTvj)exp(uiTvj)

    简单而言,对于给定的item序列,选择窗口大小为c,skip-gram通过当前item来预测前后c个item的概率,从而使得其后验概率最大,通过极大似然进行优化整体损失。

    负采样的词频计算方式跟word2vec一样。

    参考文献

    1.https://lumingdong.cn/application-practice-of-embedding-in-recommendation-system.html

    展开全文
  • 微软研究人员发表的一篇关于将word2vec模型应用到协同过滤中的Items集合中,来计算items的向量化表示的论文。
  • item2vec等召回

    2020-09-01 15:07:05
    item2vecitem2vec 主流程: 从log中抽取用户行为序列 将行为序列当成预料训练word2Vec得到item embedding:把用户浏览的商品集合等价于word2vec中的word的序列. 得到item sim关系用于推荐 1、首先第一步:这是...

    item2vec等

    item2vec

    主流程:
    
    从log中抽取用户行为序列
    将行为序列当成预料训练word2Vec得到item embedding:把用户浏览的商品集合等价于word2vec中的word的序列.
    得到item sim关系用于推荐
    
    1、首先第一步:这是我们从推荐系统log中获得的,也就是说User A行为过item a、item b、item d,User B行为过item a、item c,User C行为过item b、item e。
    
    2、继而我们需要将这些转化成句子。句子1就是a、b、d。句子2就是a、c。句子3就是b、e。这里我们已经没有了user之间的关系,只留下item组成的句子。
    
    3、将句子放入到放入word2vec模型,这里就是一个输入(word2vec模型是一个三层的神经网络:输入层、隐含层、输出层)
    
    经过word2vec模型的训练,会得到每一个item对应的embedding层向量。这里只写了item a [0.1,0.2,0.14…0.3] ,item b [0.4,0.6,0.14…0.3]。item c,item d,item e也是可以得到的。
    
    4、得到item向量之后,就得到item的sim关系。基于item sim的关系,我们便完成了用户的推荐。
    
     ( 出现在同一个集合的商品被视为positive
    

    word2vec 几大步骤

    读取查看、点击、播放等行为数据,我用的是播放数据;
    数据整理成(userid, itemid, playcnt)的形式,这个数据可能是聚合N天得到的;
    过滤掉playcnt为小于3的数据,我把这些过滤掉,觉得这个数据没有贡献;
    按照userid聚合,得到(userid, list(itemid))的形式;
    训练word2vec;
    导出model.vectors(),里面包括word和对应的向量vector,其中word其实就是itemid
    crossjoin计算两两相似度,取相似度TOP N;
    将结果存入mysql,后续可以加载到REDIS实现实时相似推荐;
    

    对比ItemCF,Item2vec有更好的泛化能力,我们可以基于训练出来的item Embedding,召回邻近topK items,这突破了ItemCF邻域关系的限制。

    Item2vec

    • 主要做法是把item视为word,用户的行为序列视为一个集合,item间的共现为正样本,并按照item的频率分布进行负样本采样。
    • 缺点是相似度的计算还只是利用到了item共现信息,(1)忽略了user行为序列信息;(2)没有建模用户对不同item的喜欢程度高低。
    • 无法解决覆盖率问题,在合理阈值下,只能覆盖出现在用户行为序列中的物品集,但对于低频物品和新物品,还是没有召回结果的。
    • 虽然覆盖率略高于ItemCF,但点击率低于ItemCF,整体收益仍是负向的,位置比较尴尬。

    item2item

    很多场景下item2item的推荐方式要优于user2item;

    item2item的推荐方式:在获取item相似度矩阵之后,根据用户的最近的行为,根据行为过的item找到相似的item,完成推荐,如itemCF。

    user2item:根据用户的基本属性和历史行为等基于一定的模型,算出最可能喜欢的item列表写在KV存储中;当用户访问系统的时候,将这些item列表推荐给用户,像userCF、LFM、personal rank算法等都是这种方式。

    user2vec

    推荐看比如YouTube DNN, DIN,wide&deep,沿着这几篇paper就可以搜出很多应该怎么样向量化表达用户的做法了。

    给定一个用户,找到联合表征向量空间中的前K个相近的产品。
    训练数据集分为用户购买顺序S,即给定用户un,其按照时间来排序的已经购买的产品。un = (pn1, pn2, . . . pnUn),Un表示用户un的项目购买数量。
    

    怎么训练和生成user的Embedding?

    item和user的量可以认为是无限的,所以不能直接使用它们的index来构建。我们可以用其某些有限的属性来表达它们。比如,说user,其实聊的是user喜欢什么item,接触过什么item,那么其中的核心其实还是item,这样理解的话,user的Embedding其实就源自于若干个与之相关的item的Embedding。

    这里的核心就在于,如何结合用户有过行为的若干个item的Embedding,合成一个User Embedding。

    最粗暴的方法是采用item-embedding进行平均,而序列的长度很关键,太短了无法完全表征,太长了无法可能用户兴趣发生了偏移效果不好,因而可以作为baseline(大多数情况下,效果说的过去)在上面的加上一点点改进,对应不同的推荐商品召回的情况下,采用不同的embedding,或者加上attention-layer,相当于用户的兴趣是多峰的,每次只有单峰激活(参考DIN)加上序列和时间考量,用LSTM(GRU)等处理这个“sentence”,最终最终得到的编码可以是user-embedding(DIEN)
    
    生成item vector之后,可以根据用户历史上与item的交互行为,求avg/max/ pooling获取用户的向量表达。这是最直接的user vector生成方式,但是在实际使用中往往效果一般。主要原因是泛化能力差,对user embedding的学习是无监督的。
    
    
    User Embedding的方法非常多,取决与你想怎么用,这里介绍几种工业界的方法。召回侧:
    1.用户行为序列的item embedding求平均,这样求出的user embedding和item embedding是在同一个空间里的,可以直接通过user embedding和item embedding的内积形式做在线knn召回
    2.进一步考虑到用户兴趣随时间的变化,把平均改为时间衰减的加权平均
    3.更粗暴一些,直接用用户最近点击的那个item emebdding做user embedding,在某些业务场景下也有很好的效果
    4.把召回看作在item全集上的超大规模多分类问题,用神经网络建模,输入user,context等特征,最上层是一个softmax的多分类,网络的最后一个隐层作为user embedding,隐层和每个类别的全连接权重作为item embedding,相当于user embedding和item embedding联合学习。线上使用和上述几种方法一样都是内积knn召回不走神经网络预测。具体可以参考youtubeDNN排序侧和召回侧不同,因为现在主流排序算法都是深度模型端到端训练,不需要一个额外输入的embedding。
    

    几种DNN的方式构建user embedding。

    FM

    YOUTUBEDNN

    介绍:https://juejin.im/post/6844904078619738126

    ,只需要将User Embedding和video Embedding存储到线上内存数据库,通过内积运算再排序的方法就可以得到video的排名,这大大加快了召回效率。

    使用特征:用户观看过视频的 embedding 向量、用户搜索词的 embedding 向量、用户画像特征、context 上下文特征等。
    
    训练方式:三层 ReLU 神经网络之后接 softmax 层,去预测用户下一个感兴趣的视频,输出是在所有候选视频集合上的概率分布。训练完成之后,最后一层 Relu 的输出作为 user embedding,softmax 的权重可当做当前预测 item 的 embedding 表示。
    
    线上预测:通过 userId 找到相应的 user embedding,然后使用 KNN 方法 ( 比如 faiss ) 找到相似度最高的 top-N 条候选结果返回。
    
    YouTubeNet 是 Google 于 2016 年提出的。与 item2vec 不同,YouTubeNet 在学习 item 向量的时候考虑了用户向量。从模型的优化目标上可以看出,是在给定用户向量的情况下,从候选池中筛选出该用户最感兴趣的 item 列表。
    

    在召回DNN中,引入丰富的用户侧特征(包括用户的观看和搜索历史),模型的最后一层全连接的输出作为user embedding表达,item embedding则使用softmax+negative sampling有监督训练该DNN时,生成的softmax权重向量来表示

    DSSM

    DSSM及微软后续推出的multi-view DSSM也代表了一种思路。这种多塔的结构,可以为user,item构造不同的塔,通过n层全连接之后,将最后一层输出层的向量拼接在一起做softmax,或者直接通过cosine衡量两者的相似性。训练完成后,模型全连接层的输出向量可以作为user,item的embedding表达,而且向量处在同一个向量空间,可以在线进行ANN查找,有效提高线上serving的性能。

    总结

    user embedding就是网络的最后一个隐层,video embedding是softmax的权重.
    将最后softmax层的输出矩阵的列向量当作item embedding vector,而将softmax之前一层的值当作user embedding vector。
    

    链接

    Spark使用word2vec训练item2vec实现内容相关推

    https://www.crazyant.net/2447.html

    改进:

    Topic2vec:https://lxmly.github.io/2019/02/15/embedding/

    w-item2vec:https://www.cnblogs.com/simplekinght/p/11545180.html

    https://www.infoq.cn/article/0ueIPm2VFrOqECLU3316 (深度学习技术在美图个性化推荐的应用实践)

    其他代码

    MF的embdding

    def build_model(user_indices, item_indices, rank, ratings, user_cnt, item_cnt, lr, lamb, mu, init_value):
        
        W_user = tf.Variable(tf.truncated_normal([user_cnt, rank], stddev=init_value/math.sqrt(float(rank)), mean=0), 
                             name = 'user_embedding', dtype=tf.float32)
        W_item = tf.Variable(tf.truncated_normal([item_cnt, rank], stddev=init_value/math.sqrt(float(rank)), mean=0), 
                             name = 'item_embedding', dtype=tf.float32)
        
        W_user_bias = tf.concat([W_user, tf.ones((user_cnt,1), dtype=tf.float32)], 1, name='user_embedding_bias')
        W_item_bias = tf.concat([tf.ones((item_cnt,1), dtype=tf.float32), W_item], 1, name='item_embedding_bias')
        
        user_feature = tf.nn.embedding_lookup(W_user_bias, user_indices, name = 'user_feature')
        item_feature = tf.nn.embedding_lookup(W_item_bias, item_indices, name = 'item_feature') 
        
        preds = tf.add(tf.reduce_sum( tf.multiply(user_feature , item_feature) , 1), mu)
        
        square_error = tf.sqrt(tf.reduce_mean( tf.squared_difference(preds, ratings)))
        loss = square_error + lamb*(tf.reduce_mean(tf.nn.l2_loss(W_user)) + tf.reduce_mean(tf.nn.l2_loss(W_item)))
            
        tf.summary.scalar('square_error', square_error)
        tf.summary.scalar('loss', loss)
        merged_summary = tf.summary.merge_all()
        #tf.global_variables_initializer()
        train_step = tf.train.GradientDescentOptimizer(lr).minimize(loss)   # tf.train.AdadeltaOptimizer(learning_rate=lr).minimize(loss)    #
    
        return train_step, square_error, loss, merged_summary
    
    
    
    展开全文
  • 【推荐系统】item2vec

    千次阅读 热门讨论 2019-03-14 20:16:39
    Item2Vec: Neural Item Embedding for Collaborative Filtering,2016 abstract 该工作借鉴了word2vec的思想,学习item在低维隐含空间的嵌入表示,类似item-based CF用于推荐。item的序列等价于词的序列,将训练...

    Item2Vec: Neural Item Embedding for Collaborative Filtering,2016

    abstract

    该工作借鉴了word2vec的思想,学习item在低维隐含空间的嵌入表示,类似item-based CF用于推荐。item的序列等价于词的序列,将训练样本由句子该为item序列即可,item间共现为正样本,按照item的概率分布进行负采样。实验结果表明比SVD的效果更好。

    模型

    skip-gram:最小化目标函数
    1 K ∑ i = 1 K ∑ − c ≤ j ≤ c , j ≠ 0 l o g   p ( w i + j ∣ w i ) \frac{1}{K} \sum_{i=1}^{K} \sum_{-c\leq j \leq c , j\neq0}{{\rm log \ } p(w_{i+j} | w_i)} K1i=1Kcjc,j̸=0log p(wi+jwi)

    子采样

    为了解决热门物品和冷门物品之间的不平衡,引入子采样 (subsampling),对于输入的序列,一定概率丢弃词w
    p ( d i s c a r d ∣ w ) = 1 − ρ f ( w ) p(discard|w) = 1-\sqrt{\frac{\rho}{f(w)}} p(discardw)=1f(w)ρ
    其中 f ( w ) f(w) f(w) 为w的频率, ρ \rho ρ 是预设的阈值。在本文两个数据集中分别取 1 0 − 5 10^{-5} 105 1 0 − 3 10^{-3} 103

    负采样

    为了加快训练,引入负采样(negtive sampling):
    p ( w j ∣ w i ) = σ ( u i T v j ) ∏ k = 1 N σ ( − u i T v k ) p(w_j|w_i) = \sigma(u_i^Tv_j) \prod_{k=1}^N \sigma(-u_i^Tv_k) p(wjwi)=σ(uiTvj)k=1Nσ(uiTvk)
    σ ( x ) = 1 1 + e x p ( − x ) \sigma(x) = \frac{1}{1+exp(-x)} σ(x)=1+exp(x)1 ,N是负样本数目

    在item2vec中,将序列当作集合来处理,只要共现就视为正样本。优化的目标函数替代为
    1 K ∑ i = 1 K ∑ j ≠ i K l o g   p ( w j ∣ w i ) \frac{1}{K} \sum_{i=1}^{K} \sum_{j\neq i}^{K}{{\rm log \ } p(w_{j} | w_i)} K1i=1Kj̸=iKlog p(wjwi)
    具体的处理方法有以下2种

    (1)将窗口设置足够大,同个序列中的数据都视为正样本

    (2)每次训练时打乱原序列

    最终将训练好的target representation u i u_i ui 作为最终 i t e m i item_i itemi 的表示

    代码实现:https://github.com/zhengjingwei/recommender-system

    讨论

    在实际应用中item2vec的得到的embedding聚类效果好。

    在推荐时,直接计算embedding的相似度取TopN作为推荐结果容易得到过于相似的商品(如同款商品的不同型号)。

    代码实现

    以下是参考tensorflow中word2vec basic代码改的

    from __future__ import absolute_import
    from __future__ import division
    from __future__ import print_function
    
    import tensorflow as tf
    import numpy as np
    import math
    import collections
    import random
    from six.moves import xrange  
    
    
    local_file = '../data/trans_all_incode.csv' # 每行一个订单
    log_dir = './log'
    

    读数据

    def read_data(filename):
        corpus = []
        vocabulary = set()
        words = []
        max_len = 0
        with open(filename,'r') as f:
            for line in f:
                sentence =  line.strip().split('|')
                corpus.append(sentence)
                max_len = max(max_len,len(sentence))
                words += sentence
        print('corpus size: %s sentence %s words' %(len(corpus), len(words)))
        print('sentence max len: %s' %(max_len))
        return corpus,words
    
    def generate_batch_from_sentence(sentence, num_skips, skip_window):
        batch_inputs = []
        batch_labels = []
        for i in range(len(sentence)):
            window = list(range(len(sentence))) # 句子内除该元素外所有元素
            window.remove(i)
            sample_index = random.sample(window,min(num_skips,len(window)))
            input_id = word2id.get(sentence[i])
            for index in sample_index:
                label_id = word2id.get(sentence[index])
                batch_inputs.append(input_id)
                batch_labels.append(label_id)
                
        batch_inputs = np.array(batch_inputs,dtype=np.int32)
        batch_labels = np.array(batch_labels,dtype=np.int32)
        batch_labels = np.reshape(batch_labels,[batch_labels.__len__(),1])
        return batch_inputs,batch_labels    
    

    建立item到id以及id到item的映射

    corpus,words = read_data(local_file)
    vocabulary = collections.Counter(words)
    count = []
    count.extend(collections.Counter(words).most_common(len(words) - 1))
    word2id = dict()   
    for word , _ in count:
        word2id[word] = len(word2id)
        
    id2word = dict(zip(word2id.values(), word2id.keys()))    
    

    模型设置

    embedding_size = 100 # embedding维度
    skip_window = 50     # 单边窗口长度
    num_skips = 4        # 从整个窗口中选取多少个不同的词作为我们的output word
    num_sampled = 50     # 负采样样本数
    
    valid_size = 16      # 选取验证的样本数
    valid_window = 500   # 在前100个的中挑选验证样本
    valid_examples = np.random.choice(valid_window, valid_size, replace=False)
    
    vocabulary_size = len(vocabulary)
    batch_size = None
    
    
    graph = tf.Graph()
    with graph.as_default():
        # Input data.
        with tf.name_scope('inputs'):
            train_inputs = tf.placeholder(tf.int32, shape=[batch_size])
            train_labels = tf.placeholder(tf.int32, shape=[batch_size, 1]) 
            valid_dataset = tf.constant(valid_examples, dtype=tf.int32)
        
        # 查找输入的embedding
        with tf.name_scope('embeddings'):
            embeddings = tf.Variable(tf.random_uniform([vocabulary_size, embedding_size], -1.0, 1.0)) # 随机均匀分布
            embed = tf.nn.embedding_lookup(embeddings, train_inputs)
            
        # 模型内部参数矩阵初始化
        with tf.name_scope('weights'):
            nce_weights = tf.Variable(
                tf.truncated_normal([vocabulary_size, embedding_size],
                                    stddev=1.0 / math.sqrt(embedding_size)))
        
        with tf.name_scope('biases'):
            nce_biases = tf.Variable(tf.zeros([vocabulary_size]))
        
        # 得到NCE损失
        with tf.name_scope('loss'):
            loss = tf.reduce_mean(tf.nn.nce_loss(
                weights = nce_weights,
                biases = nce_biases,
                labels = train_labels,
                inputs = embed,
                num_sampled = num_sampled,
                num_classes = vocabulary_size))
        
        tf.summary.scalar('loss', loss)
        
        with tf.name_scope('optimizer'):
            optimizer = tf.train.GradientDescentOptimizer(0.1).minimize(loss)
            
        # 计算与指定若干单词的相似度
        norm = tf.sqrt(tf.reduce_sum(tf.square(embeddings), 1 ,keep_dims=True))
        normalized_embedding = embeddings / norm
        valid_embeddings = tf.nn.embedding_lookup(normalized_embedding, valid_dataset)
        
        similarity = tf.matmul(valid_embeddings,  normalized_embedding, transpose_b=True)
        
        merged = tf.summary.merge_all()
        
        # 变量初始化
        init = tf.global_variables_initializer()
        
        saver = tf.train.Saver()
    

    训练

    num_steps = 1000001
    with tf.Session(graph=graph) as sess:
        train_loss_records = collections.deque(maxlen=10) # 保存最近10次的误差
        train_loss_k10 = 0
        train_sents_num = 0
        
        # 写入summary
        writter = tf.summary.FileWriter(log_dir, sess.graph)
        
        # 初始化全局参数
        init.run()
        aver_loss = 0
        
        for step in xrange(num_steps):
            sentence = corpus[step % len(corpus)] # 逐句训练
            batch_inputs, batch_labels = generate_batch_from_sentence(sentence, num_skips, skip_window)
            
            feed_dict = {train_inputs: batch_inputs, train_labels: batch_labels}
            
             # Define metadata variable.
    #         run_metadata = tf.RunMetadata()
            _, summary, loss_val = sess.run([optimizer, merged, loss],
                                             feed_dict=feed_dict)
    #         average_loss += loss_val
            train_sents_num += 1
            # 每一步将summary写入writer
            writter.add_summary(summary, step)
            train_loss_records.append(loss_val)
            train_loss_k10 = np.mean(train_loss_records)
            
            if train_sents_num % 1000 == 0:
                print('{a} sentences dealed, loss: {b}'
                      .format(a=train_sents_num,b=train_loss_k10))
                
            if train_sents_num % 5000 == 0:
                sim = similarity.eval()
                for i in xrange(valid_size):
                    valid_word = id2word[valid_examples[i]]
                    top_k = 8
                    nearest = (-sim[i, :]).argsort()[1:top_k + 1]
                    log_str =  'Nearest to %s:' % valid_word
                    
                    for k in xrange(top_k):
                        close_word = id2word[nearest[k]]
                        log_str = '%s %s,' % (log_str, close_word)
                    print(log_str)
                    
            final_embeddings = normalized_embedding.eval()
            
    
    展开全文
  • 推荐系统——Item2vec

    千次阅读 2020-06-03 18:40:44
    推荐系统中,传统的CF算法都是利用 item2item 关系计算商品间相似性。i2i数据在业界的推荐系统中起着非常重要的作用。传统的i2i的主要计算方法分两类,memory-based和model-based。 本文主要介绍了microsoft和airbnb...
  • pyspark做Item2vec

    2021-02-13 17:09:10
    Item2vec 是基于自然语言处理模型 Word2vec 提出的,所以 Item2vec 要处理的是类似文本句子的观影序列: def processItemSequence(spark, rawSampleDataPath): # 读取 ratings 原始数据到 Spark 平台 ...
  • item2vec的相似度

    2020-03-23 14:52:32
    在上面的word2vec中,可以训练得到每个itemvec,当然也可根据每个item的vector计算他们之间的相似度,我推荐直接采用similar by vector,这样可以由query得到topk个最接近的词,如下: similar_by_vector(vector...
  • 推荐系统召回之item2vec召回

    千次阅读 2019-09-29 15:47:20
    该召回手段,是基于google提出的word2vec方法,来计算不同items的隐向量,并通过计算不同items间的向量距离,来判断item-to-item间的相似度。 参考paper如下: ...综述 许多协作过滤(CF)算法是通过分析items间的关系...
  • 文章目录简介简单介绍一下word2vecitem2vec的原理 简介 本文可以算是一遍item2vector的工程化教程,其基本理论源自于论文《Item2Vec: Neural Item Embedding for Collaborative Filtering》...
  • 点击标题下「小小挖掘机」可快速关注本主题文章将会分为三部分介绍,每部分的主题为:word2vec的前奏-统计语言模型word2vec详解-风华不减其他xxx2vec论文和应用介绍后续会更...
  • Item2Vec算法介绍

    千次阅读 2019-03-01 22:46:18
    最早看到Item2vec是微软研究院的这篇文章(https://arxiv.org/vc/arxiv/papers/1603/1603.04259v2.pdf),本文主要是对这篇论文做一些介绍,Item2vec主要思想是借鉴了Word2Vec,并且采用SGNS(Skip-gram + Negative ...
  • 推荐系列论文一:Item2vec

    千次阅读 2019-06-12 23:52:44
    通过数据统计可以发现,在q增大以后Item2vec的准确度开始显著领了SVD,在统计最不热门的10k的item过程中,发现Item2vec的准确度领先了SVD 10个百分点,说明Item2vec对于一些不热门的item也取得了较好的学习效果。...
  • 输出端是与输入端的 target item 邻近的多个item,基本思想是用户输入某个商品后,使用embedding后的物品为输入向量,从而训练出一个向量空间,在此空间中,类似的物品的值相近,item2vec可以从已经训练好的模型...
  • https://www.jianshu.com/p/0ecc53bba169推荐系统入门实践(4)召回之item2vec
  • item2vec的理解

    千次阅读 2017-10-07 11:05:30
    最早提出 item2vec 这个方法是在这篇论文中Item2Vec: Neural Item Embedding for Collaborative Filtering 这里的 item2vec 用到的方法和 word2vec 中的方法基本类似。可以说是把 word2vec 中的方法迁移到了推荐...
  • 用spark的机器学习库怼出一个推荐系统(二)—Word2Vec 个人观点,为了适应潮流,spark后续为一直维护它的机器学习库,目前提供的模型自然不多,本人从事的是推荐方向,推荐方向的话,工业界肯定是要排序+召回的,...
  • total_words=max_vocabulary_size, epochs=500, start_alpha=0.1, end_alpha=0.02, compute_loss=True) model.save("gensim/item2vec.model") model.wv.save_word2vec_format("gensim/item2vec.txt", total_vec=max...
  • 论文题目:《Item2Vec: Neural Item Embedding for Collaborative Filtering》 发表时间:RecSys 2016 作者及单位: 论文地址:http://ceur-ws.org/Vol-1688/paper-13.pdf 二、摘要 许多协作过滤(CF)...
  • from gensim.models import Word2Vec import logging import sys reload(sys) sys.setdefaultencoding('utf8') from sklearn.model_selection import train_test_split c = [] def load_sequence(from_path): ...
  • gensim中word2vec API参数说明 api具体含义 model = Word2Vec(sentence, # sg=1, # sg=1则采用skip-gram算法 size=100, # 特征向量的维度,默认为100。大的size需要更多的训练数据但是效果会更好 window=5, #...
  • 【推荐系统】Item2vec

    2020-08-25 00:00:22
    已经了解了Word2vec,怎么应用于推荐场景中,形成item2vec呢?【深度学习】word2vec(上) 在Item2Vec中,一个物品集合被视作nlp中的一个段落,物品集合的基本元素-物品等价于段落中的单词。因此在论文中,一个...
  • 嵌入表示学习是当下研究热点,从word2vec,到node2vec, 到graph2vec,出现大量X2vec的算法。但如何构建向量嵌入理论指导算法设计?最近RWTH Aachen大学的计算机科学教授ACM Fellow Martin Grohe教授给了《X2vec: ...
  • item2vec:协作过滤的项目向量化映射

    千次阅读 2017-11-03 21:21:57
    ITEM2VEC:协同过滤中items的向量化表示
  • MovieTaster-使用Item2Vec做电影推荐

    千次阅读 2018-08-27 13:00:08
    前言 自从Mikolov在他2013年的论文“Efficient Estimation of Word Representation in Vector Space”[1]提出词向量的概念后,NLP领域仿佛一下子进入了embedding的世界,Sentence2Vec、Do...
  • item2vec

    2021-04-27 11:00:36
    本主题文章将会分为三部分介绍,每部分的主题为: ...来自于微软2016年发表在RecSys上的,因为word2vecitem2vec是在做推荐系统过程中比较常用的两个算法,所以该部分先介绍item2vec,然后再展开其他xxx2.

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 10,190
精华内容 4,076
关键字:

item2vec