item2vec

转载于https://zhuanlan.zhihu.com/p/126735057

i t e m 2 v e c item2vec item2vec

from gensim.models.word2vec import *
import pandas as pd
from time import *
from tqdm import *
import numpy as np
import os
import numpy as np
from tqdm import *
import re
pd.set_option('max_columns',200)
import pickle

train_dir = './underexpose_train/'
test_dir = './underexpose_test/'

# 获取数据
def get_data(train_dir,test_dir):
    """get data"""

    TrainItemFeat = pd.read_csv(train_dir + 'underexpose_item_feat.csv',header=None)
    TrainItemFeat.iloc[:,1] = TrainItemFeat.iloc[:,1].apply(lambda x:float(x[1:]))
    TrainItemFeat.iloc[:,-1] = TrainItemFeat.iloc[:,-1].apply(lambda x:float(x[:-1]))
    feat_col = ['eb'+str(i) for i in TrainItemFeat.columns[1:]]
    feat_col.insert(0,'items')
    TrainItemFeat.columns = feat_col

    TrainUserFeat = pd.read_csv(train_dir + 'underexpose_user_feat.csv',header=None)
    TrainUserFeat.columns = ['userid','age','gender','city']
    TrainClick = pd.read_csv(train_dir + 'underexpose_train_click-0.csv',header=None)
    TrainClick.columns = ['userid','items','time']
    TrainClick['flag'] = 0
    TestQtime = pd.read_csv(test_dir + 'underexpose_test_qtime-0.csv',header=None)
    TestQtime.columns = ['userid','time']
    TestQtime['flag'] = 1
    TestClick = pd.read_csv(test_dir + 'underexpose_test_click-0.csv',header=None)
    TestClick.columns = ['userid','items','time']
    TestClick['flag'] = 2
    click = pd.concat([TrainClick,TestClick,TestQtime],axis=0 ,sort=False)
    return click,TrainItemFeat,TrainClick,TrainUserFeat,TestQtime,TestClick
    # 返回
    # click,
    # TrainItemFeat, item特征
    # TrainClick,
    # TrainUserFeat, 用户特征
    # TestQtime, 查询时间
    # TestClick



#在机器学习中,我们常常需要把训练好的模型存储起来,这样在进行决策时直接将模型读出,而不需要重新训练模型,这样就大大节约了时间,同时也可以结构化以及非结构化的数据也可以按原始格式进行保存。Python提供的pickle模块就很好地解决了这个问题,它可以序列化对象并保存到磁盘中,并在需要的时候读取出来,任何对象都可以执行序列化操作
# 保存变量
def save_variable(v,filename):
    f=open(filename,'wb')
    pickle.dump(v,f)
    f.close()
    return filename
# 加载变量
def load_variavle(filename):
    f=open(filename,'rb')
    r=pickle.load(f)
    f.close()
    return r
# 获取前k个item相似度
def get_top_similar(items,k = 50):
    """计算item的相似度"""
    re_list = list(map(lambda x:[x[0],x[1]],model.most_similar(positive=[items],topn=k)))
    return re_list

# 获取推荐列表
def recommendation(uid):
    """每个用户去重的推荐列表"""
    tg_id = data[data['userid']==uid].copy()
    have_read_list = tg_id['items_last'].values[0]
    re_list = list()
    for i in have_read_list:
        re_list.extend(get_top_similar(i))
        re_list = list(set(re_list)-set(have_read_list))
    return re_list

# 多线程处理
def multi_process(func_name,process_num,deal_list):
    """
    多线程
    """
    from multiprocessing import Pool
    pool = Pool(process_num)
    result_list = pool.map(func_name,deal_list)
    pool.close()
    pool.join()
    return result_list

# 训练模型
def train_model(data):
    """训练模型"""
    begin_time = time()
    model = Word2Vec(data['items'].values, size=1000, window=30, min_count=1, workers=40)
    end_time = time()
    run_time = end_time-begin_time
    print ('该循环程序运行时间:',round(run_time,2)) #该循环程序运行时间: 1.4201874732
    return model

# 聚合数据?
def melt_data():
    z = test_df.groupby(['userid'])['items_last_all'].apply(lambda x:np.concatenate(list(x))).reset_index()
    i = pd.concat([pd.Series(row['userid'], row['items_last_all']) for _, row in z.iterrows()]).reset_index()
    i.columns = ['items_new','userid']
    i['items'] = i['items_new'].apply(lambda x:x[0])
    i['weights'] = i['items_new'].apply(lambda x:x[1])
    return i.iloc[:,1:]



click,TrainItemFeat,TrainClick,TrainUserFeat,TestQtime,TestClick = get_data(train_dir,test_dir)
print(click)
print("=====================")
print(TrainItemFeat)
print("=====================")
print(TrainClick)
print("=====================")
print(TrainUserFeat)
print("=====================")
print(TestQtime)
print("=====================")
print(TestClick)


#用户的点击物品以及对应的时间,此时,我们更加考虑是否推荐一些与用户曾经点击过的物品类似的东西,这样更有可能点击。试想一下,假如我们最近喜欢新出的iphone,是否很大概率喜欢iphone的一些配件,按照这个道理,我们建立模型。
df = click.merge(TrainUserFeat,on = 'userid',how = 'left')
df = df.merge(TrainItemFeat,on='items',how = 'left')
df = df.sort_values(['userid','time']).reset_index(drop = True)

#重新划分训练集和测试集,并按时间排序,反应用户的点击行为。
train = df[df['flag']!=1].copy()
train = train.sort_values(['userid','time']).reset_index(drop = True)
test = df[df['flag']==1].copy()
test = test.sort_values(['userid','time']).reset_index(drop = True)

#训练模型,因为Word2vec的输入是string格式,需要提前处理,同时,把数据格式处理成uid=['itme1',itme2',...itmen']这种格式,其中items_last为用户点击的最后3个物品,因为跟时间有关系,我们更加会推与用户最近点击的相关物品
tr = train.copy()
tr['items']  = tr['items'].astype(str)
items_all = tr['items'].unique()
tr = tr.groupby('userid')['items'].apply(lambda x:list(x)).reset_index()
tr['items_last'] = tr['items'].apply(lambda x:x[-3:])
model = train_model(tr)

#训练完模型后,我们需要计算用户点击过的物品相似度,一般而言,物品相似度是根据用户点击过的物品序列,计算embedding,从而计算相似度
recommendation_items = dict()
print('获取相似item')
for i in tqdm(items_all):
    recommendation_items[i] = get_top_similar(i)

#计算用户最后点击的2个物品以及他们所对应的物品,每个物品包括物品代号以及相似度['itmes','sim']
tr['items_last_1'] = tr['items_last'].apply(lambda x:recommendation_items[x[-1]])
tr['items_last_2'] = tr['items_last'].apply(lambda x:recommendation_items[x[-2]])
tr['items_last_all'] = tr['items_last_1']+tr['items_last_2']
#根据相似度排序,越是相似的,优先推荐
tr['items_last_all'] = tr['items_last_all'].apply(lambda x:sorted(x,key = lambda x:x[1],reverse=True))




test_df = test[['userid']].merge(tr,on = 'userid',how = 'left')
test_df = melt_data()
test_df['items'] = test_df['items'].astype(float)
test_df = test_df.merge(TrainUserFeat,on = 'userid',how = 'left')
test_df = test_df.merge(TrainItemFeat,on='items',how = 'left')


test_df = test_df.sort_values(['userid','weights'],ascending=False).reset_index()
submit = test_df.groupby(['userid'])['items'].apply(lambda x:list(x)[:50]).reset_index()
sub = pd.DataFrame(list(submit['items'].values))
sub.columns = ['item_id_'+str(i).zfill(2) for i in range(1,51)]

分析

click

在这里插入图片描述

TestClick

在这里插入图片描述

TrainClick

在这里插入图片描述

TestQtime

在这里插入图片描述

TrianUserFeat

在这里插入图片描述

TrainItemFeat (257 columns)

在这里插入图片描述

在这里插入图片描述

gensim中word2vec使用

转载于:https://blog.csdn.net/luoxuexiong/article/details/90345143
word2vec的实现是位于gensim包中gensim\models\word2vec.py文件里面的Word2Vec类中
参数24个:
参数名称 默认值 用途
sentences None 训练的语料,一个可迭代对象。对于从磁盘加载的大型语料最好用gensim.models.word2vec.BrownCorpus,gensim.models.word2vec.Text8Corpus ,gensim.models.word2vec.LineSentence 去生成sentences
size 100 生成词向量的维度
alpha 0.025 初始学习率
window 5 句子中当前和预测单词之间的最大距离,取词窗口大小
min_count 5 文档中总频率低于此值的单词忽略
max_vocab_size None 构建词汇表最大数,词汇大于这个数按照频率排序,去除频率低的词汇
sample 1e-3 高频词进行随机下采样的阈值,范围是(0, 1e-5)
seed 1 向量初始化的随机数种子
workers 3 几个CPU进行跑
min_alpha 0.0001 随着学习进行,学习率线性下降到这个最小数
sg 0 训练时算法选择 0:skip-gram, 1: CBOW
hs 0 0: 当这个为0 并且negative 参数不为零,用负采样,1:层次 softmax
negative 5 负采样,大于0是使用负采样,当为负数值就会进行增加噪音词
ns_exponent 0.75 负采样指数,确定负采样抽样形式:1.0:完全按比例抽,0.0对所有词均等采样,负值对低频词更多的采样。流行的是0.75
cbow_mean 1 0:使用上下文单词向量的总和,1:使用均值; 只适用于cbow
hashfxn hash 希函数用于随机初始化权重,以提高训练的可重复性。
iter 5 迭代次数,epoch
null_word 0 空填充数据
trim_rule None 词汇修剪规则,指定某些词语是否应保留在词汇表中,默认是 词频小于 min_count则丢弃,可以是自己定义规则
sorted_vocab 1 1:按照降序排列,0:不排序;实现方法:gensim.models.word2vec.Word2VecVocab.sort_vocab()
batch_words 10000 词数量大小,大于10000 cython会进行截断
compute_loss False 损失(loss)值,如果是True 就会保存
callbacks () 在训练期间的特定阶段执行的回调序列~gensim.models.callbacks.CallbackAny2Vec
max_final_vocab None 通过自动选择匹配的min_count将词汇限制为目标词汇大小,如果min_count有参数就用给定的数值

模型保存使用:完成训练后只存储并使用~gensim.models.keyedvectors.KeyedVectors
该模型可以通过以下方式存储/加载:
~gensim.models.word2vec.Word2Vec.save 保存模型
~gensim.models.word2vec.Word2Vec.load 加载模型

训练过的单词向量也可以从与其兼容的格式存储/加载:
gensim.models.keyedvectors.KeyedVectors.save_word2vec_format实现原始 word2vec

word2vec 的保存
gensim.models.keyedvectors.KeyedVectors.load_word2vec_format 单词向量的加载
模型的属性

wv: 是类 ~gensim.models.keyedvectors.Word2VecKeyedVectors生产的对象,在word2vec是一个属性
为了在不同的训练算法(Word2Vec,Fastext,WordRank,VarEmbed)之间共享单词向量查询代码,gensim将单词向量的存储和查询分离为一个单独的类 KeyedVectors

包含单词和对应向量的映射。可以通过它进行词向量的查询

model_w2v.wv.most_similar(“民生银行”) # 找最相似的词
model_w2v.wv.get_vector(“民生银行”) # 查看向量
model_w2v.wv.syn0 # model_w2v.wv.vectors 一样都是查看向量
model_w2v.wv.vocab # 查看词和对应向量
model_w2v.wv.index2word # 每个index对应的词

小提示:
需要注意的是word2vec采用的是标准hash table存放方式,hash码重复后挨着放 取的时候根据拿出index找到词表里真正单词,对比一下
syn0 :就是词向量的大矩阵,第i行表示vocab中下标为i的词
syn1:用hs算法时用到的辅助矩阵,即文章中的Wx
syn1neg:negative sampling算法时用到的辅助矩阵
Next_random:作者自己生成的随机数,线程里面初始化就是:

vocabulary:是类 ~gensim.models.word2vec.Word2VecVocab
模型的词汇表,除了存储单词外,还提供额外的功能,如构建一个霍夫曼树(频繁的单词更接近根),或丢弃极其罕见的单词。
trainables 是类 ~gensim.models.word2vec.Word2VecTrainables

训练词向量的内部浅层神经网络,CBOW和skip-gram(SG)略有不同,它的weights就是我们后面需要使用的词向量,隐藏层的size和词向量特征size一致
sentences相关

训练首先是语料集的加载。首先要生成Word2Vec需要的语料格式:
1.对于简单的句子可以:

from gensim.models import Word2Vec

sentences只需要是一个可迭代对象就可以

sentences = [[“cat”, “say”, “meow”], [“dog”, “say”, “woof”]]
model = Word2Vec(sentences, min_count=1) # 执行这一句的时候就是在训练模型了

2.对于大型语料库:
Gemsim 的输入只要求序列化的句子,而不需要将所有输入都存储在内存中。简单来说,可以输入一个句子,处理它,删除它,再载入另外一个句子。
gensim.models.word2vec.BrownCorpus: BrownCorpus是一个英国语料库,可以用这个直接处理
gensim.models.word2vec.Text8Corpus ,
gensim.models.word2vec.LineSentence

使用LineSentence()

sentences = LineSentence(‘a.txt’) # 文本格式是 单词空格分开,一行为一个文档

使用Text8Corpus()

sentences = Text8Corpus(‘a.txt’) # 文本格式是 单词空格分开,一行为一个文
model = Word2Vec(sentences, min_count=1) # 执行这一句的时候就是在训练模型了

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值