【发布时间】:2017-02-24 01:52:43
【问题描述】:
由于我在this page 中提出的问题,我的代码内存不足。然后,我编写了第二个代码以获得可迭代的alldocs,而不是全内存alldocs。我根据this page的解释更改了我的代码。我不熟悉流概念,无法解决我遇到的错误。
此代码读取给定路径的所有文件夹的所有文件。每个文件的上下文由两行文件名及其上下文组成。例如:
clueweb09-en0010-07-00000
鸽子 gif 剪贴画鸽子剪贴画图片图像 hiox 免费鸟类印度 web 图标剪贴画添加偶然发现
clueweb09-en0010-07-00001
google 书签 yahoo 书签 php 脚本 java 脚本 jsp 脚本 授权脚本 html 教程 css 教程
第一个代码:
# coding: utf-8
import string
import nltk
import nltk.tokenize
from nltk.corpus import stopwords
import re
import os, sys
import MySQLRepository
from gensim import utils
from gensim.models.doc2vec import Doc2Vec
import gensim.models.doc2vec
from gensim.models.doc2vec import LabeledSentence
from boto.emr.emrobject import KeyValue
def readAllFiles(path):
dirs = os.listdir( path )
for file in dirs:
if os.path.isfile(path+"/"+file):
prepareDoc2VecSetting(path+'/'+file)
else:
pf=path+"/"+file
readAllFiles(pf)
def prepareDoc2VecSetting (fname):
mapDocName_Id=[]
keyValues=set()
with open(fname) as alldata:
a= alldata.readlines()
end=len(a)
label=0
tokens=[]
for i in range(0,end):
if a[i].startswith('clueweb09-en00'):
mapDocName_Id.insert(label,a[i])
label=label+1
alldocs.append(LabeledSentence(tokens[:],[label]))
keyValues |= set(tokens)
tokens=[]
else:
tokens=tokens+a[i].split()
mydb.insertkeyValueData(keyValues)
mydb.insertDocId(mapDocName_Id)
mydb=MySQLRepository.MySQLRepository()
alldocs = []
pth='/home/flr/Desktop/newInput/tokens'
readAllFiles(ipth)
model = Doc2Vec(alldocs, size = 300, window = 5, min_count = 2, workers = 4)
model.save(pth+'/my_model.doc2vec')
第二个代码:(我没有考虑与DB相关的部分)
import gensim
import os
from gensim.models.doc2vec import Doc2Vec
import gensim.models.doc2vec
from gensim.models.doc2vec import LabeledSentence
class prepareAllDocs(object):
def __init__(self, top_dir):
self.top_dir = top_dir
def __iter__(self):
mapDocName_Id=[]
label=1
for root, dirs, files in os.walk(top_directory):
for fname in files:
print fname
inputs=[]
tokens=[]
with open(os.path.join(root, fname)) as f:
for i, line in enumerate(f):
if line.startswith('clueweb09-en00'):
mapDocName_Id.append(line)
if tokens:
yield LabeledSentence(tokens[:],[label])
label+=1
tokens=[]
else:
tokens=tokens+line.split()
yield LabeledSentence(tokens[:],[label])
pth='/home/flashkar/Desktop/newInput/tokens/'
allDocs = prepareAllDocs('/home/flashkar/Desktop/newInput/tokens/')
for doc in allDocs:
model = Doc2Vec(allDocs, size = 300, window = 5, min_count = 2, workers = 4)
model.save(pth+'/my_model.doc2vec')
这是错误:
Traceback(最近一次调用最后一次):文件 “/home/flashkar/git/doc2vec_annoy/Doc2Vec_Annoy/KNN/testiterator.py”, 第 44 行,在 model = Doc2Vec(allDocs, size = 300, window = 5, min_count = 2, >workers = 4) 文件 “/home/flashkar/anaconda/lib/python2.7/site->packages/gensim/models/doc2vec.py”, 第 618 行,在 init 中 self.build_vocab(documents, trim_rule=trim_rule) 文件 >"/home/flashkar/anaconda/lib/python2.7/site->packages/gensim/models/word2vec.py", 第 523 行,在 build_vocab self.scan_vocab(sentences, progress_per=progress_per, >trim_rule=trim_rule) # 初始调查文件 “/home/flashkar/anaconda/lib/python2.7/site->packages/gensim/models/doc2vec.py”, 第 655 行,在 scan_vocab 中 对于document_no,枚举中的文档(文档):文件>“/home/flashkar/git/doc2vec_annoy/Doc2Vec_Annoy/KNN/testiterator.py”, 第 40 行,在 iter 中 yield LabeledSentence(tokens[:],tpl1) IndexError: list index out of range
【问题讨论】:
-
您的“第二个代码”在正确的轨道上,但是:(1)您仍然将每个
line附加到mapDocName_Id- 因此将所有内容都放入一个内存列表中; (2)tokens在你测试它的地方不可能是非空的,因为它只是在每次循环迭代之前设置为[]- 所以你永远不会产生任何东西; (3) 您现在将一个元组传递给 LabeledSentence,而不是它期望的两个列表; (4) 你不需要自己循环alldocs,当它正常工作时,你只需将alldocs传递给Doc2Vec 一次。
标签: python iterator gensim doc2vec