云起2013 2016-04-12 07:23 采纳率: 0%
浏览 7161
已结题

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)

  • 写回答

5条回答

  • oyljerry 2016-04-12 07:33
    关注

    内存不够的情况,一般就是要升级内存,还更强劲的机器等来处理了。

    评论

报告相同问题?

悬赏问题

  • ¥15 fesafe材料库问题
  • ¥35 beats蓝牙耳机怎么查看日志
  • ¥15 Fluent齿轮搅油
  • ¥15 八爪鱼爬数据为什么自己停了
  • ¥15 交替优化波束形成和ris反射角使保密速率最大化
  • ¥15 树莓派与pix飞控通信
  • ¥15 自动转发微信群信息到另外一个微信群
  • ¥15 outlook无法配置成功
  • ¥30 这是哪个作者做的宝宝起名网站
  • ¥60 版本过低apk如何修改可以兼容新的安卓系统