我的工作环境是,win7,python2.7.10,gensim
任务内容是根据商品信息(所属类目、分词)来确定商品间的相似度。
商品信息由50w行文本组成。
例如:
自左向右,分别为,商品ID/所属类目ID/商品标题分词
29 155 123950,53517,106068,59598,7503,171811,25618,147905,203432
49 228 73035,33202,116593,48909,92233,181255,127004,38910
59 284 123950,38910,22837,5026,15459,47776,158346,101881,131272
我基本套用了网上的gensim教程中对求解相似度的程序。问题出在最后求相似度的时候,求大侠指教!!很急!!
# -*- coding: utf-8 -*-
# 激活日志
import logging,time
logging.basicConfig(format='%(asctime)s : %(levelname)s : %(message)s', level=logging.INFO)
start=time.clock()
# 导入gensim工具包
from gensim import corpora, models, similarities
# 数据源
fsource='C:\\Users\\Administrator\\Desktop\\data_after_deal\\for_python_deal\\fomal\\dim_items_terms.csv'
# 文件目录
fcontent='C:\\Users\\Administrator\\Desktop\\data_after_deal\\for_python_deal\\fomal\\test01_with_lis\\'
# 读入本地文件,用readlines()方法自动将文件内容分析成一个行的列表
f0=open(fsource)
lines=f0.readlines()
terms_list=[]
for line in lines:
line=line.strip('\n') # 去除当前行文本末尾的换行符
terms_single_line=line.split(',') # 按“,”分割当前行文本 es:['48909,53517,116593,55095']->['48909','53517','116593','55095']
terms_list.append(terms_single_line) # 向列表尾部添加新列表元素
f0.close()
# 去除语料库中仅出现过一次的分词
from collections import defaultdict
frequency = defaultdict(int)
for text in terms_list:
cnt_single=defaultdict(int)
for token in text:
frequency[token] += 1
terms_list = [[token for token in text if frequency[token] > 1] for text in terms_list]
# 描述同一商品的分词去重
terms_list_qc=[]
for text in terms_list:
cnt_single=defaultdict(int)
terms_list_qc_item=[]
for token in text:
cnt_single[token]+=1
if(cnt_single[token]<=1):
terms_list_qc_item.append(token)
terms_list_qc.append(terms_list_qc_item)
dictionary = corpora.Dictionary(terms_list)
# 通过 gensim.corpora.dictionary.Dictionary 给所有在语料库中出现过的分词各分配唯一的整型ID
# 通过扫描整个文本,收集词汇数与相应的统计。
# 可以通过 dictionary 了解到处理的预料中所包含的不同分词数以及分词与ID间的映射关系(dictionary.token2id)
dictionary.save(fcontent+'dim_items_terms.dict')
# 保存 dictionary ,以备后用
corpus = [dictionary.doc2bow(text) for text in terms_list]
# 函数 doc2bow() 可以统计出每个不同分词的出现次数,将该分词转换为其所对应的整型ID,并返回一个稀疏矩阵
# 稀疏矩阵示例:[(2,1),(3,1)],可理解为该矩阵所对应的文本中,ID为2的分词出现1次,ID为3的分词出现1次
corpora.MmCorpus.serialize(fcontent+'dim_items_terms.mm', corpus)
# 序列化向量空间语料库并保存到本地,以备后用
end=time.clock()
print "Time Cost for Program 00_a_trim_items_terms_to_sparse_matrix.py: %f s" % (end-start)
# -*- coding: utf-8 -*-
import logging,time
logging.basicConfig(format='%(asctime)s : %(levelname)s : %(message)s', level=logging.INFO)
start=time.clock()
from gensim import corpora, models, similarities
# 文件目录
fcontent='C:\\Users\\Administrator\\Desktop\\data_after_deal\\for_python_deal\\fomal\\test01_with_lis\\'
# 使用 step1 中创建的用向量流表示文档的语料库
dictionary = corpora.Dictionary.load(fcontent+'dim_items_terms.dict')
corpus = corpora.MmCorpus(fcontent+'dim_items_terms.mm')
# 使用 step1 中创建的语料库来初始化此转换模型
tfidf = models.TfidfModel(corpus)
# 将词袋整数计数表示的向量转换为TFIDF实数权重表示方法
corpus_tfidf = tfidf[corpus]
# 初始化一个LSI转换
lsi = models.LsiModel(corpus_tfidf, id2word=dictionary, num_topics=2)
# 在原始语料库上加上双重包装: bow->tfidf->fold-in-lsi
corpus_lsi = lsi[corpus_tfidf]
# tfidf语料通过LSI (Latent Sematic Indexing,潜在语义索引)
# 变换为一个隐含语义的2D空间(2D,通过设置num_topics=2来完成)
# LSI模型持久化
lsi.save(fcontent+'dim_items_terms_model.lsi')
# lsi = models.LsiModel.load('C:\\Users\\Administrator\\Desktop\\data_after_deal\\for_python_deal\\fomal\\dim_items_terms_model.lsi')
end=time.clock()
print "Time Cost for Program 00_b_bagofwords_to_tfidf_to_lsi.py: %f s" % (end-start)
# -*- coding: utf-8 -*-
import logging,time
logging.basicConfig(format='%(asctime)s : %(levelname)s : %(message)s', level=logging.INFO)
start=time.clock()
from gensim import corpora, models, similarities
# 数据源
fsource='C:\\Users\\Administrator\\Desktop\\data_after_deal\\for_python_deal\\fomal\\dim_items_terms_pre.csv'
# 文件目录
fcontent='C:\\Users\\Administrator\\Desktop\\data_after_deal\\for_python_deal\\fomal\\test01_with_lis\\'
# 可以如下面三行所示根据step1中创建的语料库来初始化lsi模型,亦可直接使用step2中已初始化的lsi模型
dictionary = corpora.Dictionary.load(fcontent+'dim_items_terms.dict')
corpus = corpora.MmCorpus(fcontent+'dim_items_terms.mm')
tfidf = models.TfidfModel(corpus)
#lsi = models.LsiModel(corpus, id2word=dictionary, num_topics=2)
# lsi = models.LsiModel.load(fcontent+'dim_items_terms_model.lsi')
index = similarities.MatrixSimilarity(tfidf[corpus])
# 将语料库转换到LSI空间并对它进行索引
#index = similarities.MatrixSimilarity(lsi[corpus])
# 百万文档以上,内存不足时可以使用similarities.Similarity类
# 索引的存储
index.save(fcontent+'dim_items_terms_tfidf.index')
# index = similarities.MatrixSimilarity.load('C:\\Users\\Administrator\\Desktop\\data_after_deal\\for_python_deal\\dim_items_terms_pre.index')
# 查询对象doc -> 创建doc的稀疏矩阵 -> 将查询转换入LSI空间
# 读入本地文件,用readlines()方法自动将文件内容分析成一个行的列表
f0=open(fsource)
lines=f0.readlines()
#terms_list=[]
f1=open(fcontent+'out_recordid_tfidf.txt',"w")
f2=open(fcontent+'out_cosine_tfidf.txt',"w")
for line in lines:
line=line.strip('\n') # 去除当前行文本末尾的换行符
doc = line
vec_bow = dictionary.doc2bow(doc.split(','))
vec_lsi = tfidf[vec_bow]
sims = index[vec_lsi]
# 获得查询文档相对于其他经过索引的文档的相似度
# 余弦方法返回的相似度在[-1,1]之间,越大越相似
# 以下将相似性倒序排列
sims = sorted(enumerate(sims), key=lambda item: -item[1])
for i in range(500):
f1.write(str(sims[i][0]+1)+',')# 商品记录序号
f2.write(str(sims[i][1])+',')# 相似度
f1.write('\n')
f2.write('\n')
f0.close()
f1.close()
f2.close()
end=time.clock()
print "Time Cost for Program 00_c_get_sim_itemsid_top_fh.py: %f s" % (end-start)
内存不够的情况,一般就是要升级内存,还更强劲的机器等来处理了。
没有人了么==好心塞==快来人啊
你最后解决了吗?我遇到了相同的问题。
同样的错误,楼主有没有解决?
内存不足的情况下 用similarities.Similarity
The class similarities.MatrixSimilarity is only appropriate when the whole set of vectors fits into memory. For example, a corpus of one million documents would require 2GB of RAM in a 256-dimensional LSI space, when used with this class.
Without 2GB of free RAM, you would need to use the similarities.Similarity class. This class operates in fixed memory, by splitting the index across multiple files on disk, called shards. It uses similarities.MatrixSimilarity and similarities.SparseMatrixSimilarity internally, so it is still fast, although slightly more complex.
https://radimrehurek.com/gensim/tut3.html#similarity-interface