2 u012355629 u012355629 于 2016.04.12 15:23 提问

Python 计算 tfidf ,数据较大,报错memory error 1C

我的工作环境是,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
oyljerry   Ds   Rxr 2016.04.12 15:33

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

zyx_cambridge
zyx_cambridge 我的16G也不行
大约一个月之前 回复
u012355629
u012355629 我已经加了4G的内存条了==现在拢共有八个G的内存来跑,还是不行
一年多之前 回复
u012355629
u012355629   2016.04.12 18:53

没有人了么==好心塞==快来人啊

naifan_
naifan_   2016.06.03 10:00

你最后解决了吗?我遇到了相同的问题。

qq_24017413
qq_24017413   2016.12.29 17:00

同样的错误,楼主有没有解决?

tczl1992
tczl1992   2017.09.21 09:50

内存不足的情况下 用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

Csdn user default icon
上传中...
上传图片
插入图片
准确详细的回答,更有利于被提问者采纳,从而获得C币。复制、灌水、广告等回答会被删除,是时候展现真正的技术了!