2017-02-21 15 views
0

this page에 질문 한 내용으로 인해 코드에 메모리가 부족합니다. 그런 다음, 두 번째 코드를 작성하여 alldocs이 아닌 alldocs을 작성하고, 전체 메모리가 아닌 alldocs을 작성했습니다. this page에 대한 설명을 기반으로 코드를 변경했습니다. 스트림 컨셉에 익숙하지 않아 오류가 해결되지 않았습니다.'iterable'개체를 사용하여 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') 

두 번째 코드 : (I가 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 (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

먼저 코드를 디버그하여 특정 문제에 실제로 걸렸을 때 와야한다고 생각합니다. 올바른 방향으로 당신을 가리 키기 위해서는, prepareAllDocs에서 iter_document와 iter를 병합하여보다 단순하게 만들어야합니다. Python에서 열거 형을 체크 아웃해야하므로 readlines()로 모든 데이터를 읽을 필요가 없으며 iter_document에서 라벨을 증가시킬 필요가 없습니다. – aberger

+0

디버깅을 시도하지만 문제를 찾을 수 있습니다. _readlines() _ 대신에 줄 단위로 읽는 것을 의미합니까? – user3092781