2017-02-21 104 views
0

У моего кода заканчивается память из-за вопроса, который я задал в this page. Затем я написал второй код, чтобы иметь итеративный alldocs, а не все-в-памяти alldocs. Я изменил свой код на основе объяснения this page. Я не знаком с концепцией потока, и я не мог решить ошибку, которую я получил.Как построить модель Doc2Vec, используя объект «итерабельный»

Этот код прочитать все файлы всех папок данного path.The контекста каждого файла состоит из имени документа и его контекст в двух lines.For Например:

clueweb09-en0010-07-00000

dove gif clipart pigeon clip art picture image hiox free birds india web icons clipart add stumble upon

clueweb09-en0010-07-00001

google bookmarks yahoo bookmarks php script java script jsp script licensed scripts html tutorials css tutorials

Первый код:

# 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') 

Второй код: (я не рассматривал детали, связанные с БД)

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 (most recent call last): File "/home/flashkar/git/doc2vec_annoy/Doc2Vec_Annoy/KNN/testiterator.py", line 44, in model = Doc2Vec(allDocs, size = 300, window = 5, min_count = 2, >workers = 4) File "/home/flashkar/anaconda/lib/python2.7/site->packages/gensim/models/doc2vec.py", line 618, in init self.build_vocab(documents, trim_rule=trim_rule) File >"/home/flashkar/anaconda/lib/python2.7/site->packages/gensim/models/word2vec.py", line 523, in build_vocab self.scan_vocab(sentences, progress_per=progress_per, >trim_rule=trim_rule) # initial survey File "/home/flashkar/anaconda/lib/python2.7/site->packages/gensim/models/doc2vec.py", line 655, in scan_vocab for document_no, document in enumerate(documents): File >"/home/flashkar/git/doc2vec_annoy/Doc2Vec_Annoy/KNN/testiterator.py", line 40, in iter yield LabeledSentence(tokens[:],tpl 1) IndexError: list index out of range

+0

Ваш «второй код» находится на правильном пути, но: (1) вы по-прежнему добавляете каждую строку в 'mapDocName_Id' - таким образом, принося все в один список в памяти; (2) невозможно, чтобы «токены» никогда не были пустыми, где вы его тестировали, потому что перед каждой итерацией цикла он был установлен как '[]', поэтому вы никогда ничего не дадите; (3) теперь вы передаете один кортеж в LabeledSentence, а не в два списка, которые он ожидает; (4) вам не нужно перебирать «alldocs» самостоятельно, когда он работает правильно, вы просто передаете «alldocs» в Doc2Vec один раз. – gojomo

ответ

1

Вы используете функцию генератора, потому что вы не хотите, чтобы хранить все ваши документы, но вы по-прежнему хранить все документы в alldocs. Вы можете просто yield LabeledSentence(tokens[:], tpl[1]])).

В настоящее время происходит добавление к списку и возврат списка. вот почему вы получаете AttributeError. Кроме того, на каждой итерации вы добавляете список, что означает, что на каждой итерации я возвращаю i и все документы, которые были до i!

+0

Я обновляю свой код, но у меня есть новая ошибка. Также вы могли бы объяснить больше о второй части вашего ответа. Я не смог ее получить. – user3092781

+0

Я думаю, вы должны сначала попробовать отладить свой код и прийти к тому, когда вы действительно застряли в конкретной проблеме. Чтобы указать вам в правильном направлении, вы должны объединить iter_document с iter в prepareAllDocs, чтобы сделать вещи проще. Вы также должны проверить перечисление в Python, чтобы вам не нужно было считывать все ваши данные с помощью readlines(), и вам не нужно увеличивать метку в iter_document. – aberger

+0

Я пытаюсь отлаживать, но я мог найти проблему. Вы имеете в виду, что я читал строки за строкой вместо _readlines() _ почему? – user3092781