问题描述
- Python 计算 tfidf ,数据较大,报错memory error
-
我的工作环境是,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教程中对求解相似度的程序。问题出在最后求相似度的时候,求大侠指教!!很急!!
******首先是用于将商品标题分词建成词袋(稀疏矩阵)的程序1,花了2分多,运行结束******
# -*- 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)
## 然后是程序2,词袋->tfidf->LSI,LSI可要可不要,跑了三分多
# -*- 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)
最后是实际计算商品间相似度的程序三,这个用LSI模型来比对的话,2k行要跑四五十分钟,但我的数据量有50w。用tfidf模型来算直接报memory error 不给跑
# -*- 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)
解决方案
内存不够的情况,一般就是要升级内存,还更强劲的机器等来处理了。
解决方案二:
没有人了么==好心塞==快来人啊
时间: 2024-09-14 20:43:11