2017-12-31 144 views
0

에폭에서 셔플의 문장과 문제는 word2vecdoc2vec이 우수한 자습서, herehere을 사용하고 코드 샘플을 사용하려고 시작합니다. 나는 line_clean() 구두점, 불어 등을 제거하는 방법을 추가했습니다.이 doc2vec/gensim - 내가 노력하고

그러나 훈련 반복에서 호출 된 line_clean() 메서드에 문제가 있습니다. 전 세계적인 방법에 대한 호출이 그것을 망쳐 놓는 것을 이해합니다. 그러나이 문제를 피하는 방법을 모르겠습니다.

Iteration 1 
Traceback (most recent call last): 
    File "/Users/santino/Dev/doc2vec_exp/doc2vec_exp_app/doc2vec/untitled.py", line 96, in <module> 
    train() 
    File "/Users/santino/Dev/doc2vec_exp/doc2vec_exp_app/doc2vec/untitled.py", line 91, in train 
    model.train(sentences.sentences_perm(),total_examples=model.corpus_count,epochs=model.iter) 
    File "/Users/santino/Dev/doc2vec_exp/doc2vec_exp_app/doc2vec/untitled.py", line 61, in sentences_perm 
    shuffled = list(self.sentences) 
AttributeError: 'TaggedLineSentence' object has no attribute 'sentences' 

내 코드는 다음과 같습니다 :

import gensim 
from gensim import utils 
from gensim.models.doc2vec import TaggedDocument 
from gensim.models import Doc2Vec 
import os 
import random 
import numpy 
from sklearn.linear_model import LogisticRegression 
import logging 
import sys 
from nltk import RegexpTokenizer 
from nltk.corpus import stopwords 

tokenizer = RegexpTokenizer(r'\w+') 
stopword_set = set(stopwords.words('english')) 


def clean_line(line): 
    new_str = unicode(line, errors='replace').lower() #encoding issues 
    dlist = tokenizer.tokenize(new_str) 
    dlist = list(set(dlist).difference(stopword_set)) 
    new_line = ' '.join(dlist) 
    return new_line 


class TaggedLineSentence(object): 
    def __init__(self, sources): 
     self.sources = sources 

     flipped = {} 

     # make sure that keys are unique 
     for key, value in sources.items(): 
      if value not in flipped: 
       flipped[value] = [key] 
      else: 
       raise Exception('Non-unique prefix encountered') 

    def __iter__(self): 
     for source, prefix in self.sources.items(): 
      with utils.smart_open(source) as fin: 
       for item_no, line in enumerate(fin): 
        yield TaggedDocument(utils.to_unicode(clean_line(line)).split(), [prefix + '_%s' % item_no]) 

    def to_array(self): 
     self.sentences = [] 
     for source, prefix in self.sources.items(): 
      with utils.smart_open(source) as fin: 
       for item_no, line in enumerate(fin): 
        self.sentences.append(TaggedDocument(utils.to_unicode(clean_line(line)).split(), [prefix + '_%s' % item_no])) 
     return(self.sentences) 

    def sentences_perm(self): 
     shuffled = list(self.sentences) 
     random.shuffle(shuffled) 
     return(shuffled) 


def train(): 
    #create a list data that stores the content of all text files in order of their names in docLabels 
    doc_files = [f for f in os.listdir('./data/') if f.endswith('.csv')] 

    sources = {} 
    for doc in doc_files: 
     doc2 = os.path.join('./data',doc) 
     sources[doc2] = doc.replace('.csv','') 

    sentences = TaggedLineSentence(sources) 


    # #iterator returned over all documents 
    model = gensim.models.Doc2Vec(size=300, min_count=2, alpha=0.025, min_alpha=0.025) 
    model.build_vocab(sentences) 

    #training of model 
    for epoch in range(10): 
     #random.shuffle(sentences) 
     print 'iteration '+str(epoch+1) 
     #model.train(it) 
     model.alpha -= 0.002 
     model.min_alpha = model.alpha 
     model.train(sentences.sentences_perm(),total_examples=model.corpus_count,epochs=model.iter) 
    #saving the created model 
    model.save('reddit.doc2vec') 
    print "model saved" 

train() 

답변

3

사람들은 gensim의 최신 버전에 대한 좋은 자습서는 없습니다. 특히 자신의 수동 관리가 alpha/min_alpha 인 루프에서 train()을 여러 번 호출하는 것은 좋지 않습니다. 엉망진창은 쉽습니다. 예를 들어, 코드에서 잘못된 일이 일어나고 대부분의 사용자에게 도움이되지 않습니다. min_alpha을 기본값에서 변경하지 말고 train()을 정확히 한 번 호출하십시오. 정확히 epochs 반복을 수행하여 학습 속도 alpha을 최대 값에서 최소값으로 적절하게 감소시킵니다. to_array()를 호출 적어도까지 후 - - 아직 코드가 존재하지 않는 속성에 액세스하려고하는 당신의 TaggedLineSentence 클래스는 sentences 속성을 갖고 있지 않기 때문에

특정 오류이다.

전체 to_array()/sentences_perm() 접근 방식이 약간 손상되었습니다. 그러한 반복 가능한 클래스를 사용하는 이유는 대개 큰 데이터 세트를 주 메모리에서 꺼내 디스크에서 스트리밍하는 것입니다. 그러나 to_array()은 모든 것을로드하고 내부에 내부에 캐싱하므로 반복 가능한 이점이 없어집니다. 당신이 줄 수있는 경우에 전체 데이터 세트를 쉽게 메모리에 적합하기 때문에, 당신은 단지

sentences = list(TaggedLineSentence(sources) 

는 ... 반복-에서 디스크 한 번, 다음의 메모리 목록에 코퍼스를 유지 ... 할 수있는 .

그리고 훈련 중에 반복적으로 셔플하는 것은 일반적으로 필요하지 않습니다. 트레이닝 데이터에 기존의 덩어리가있는 경우에만 - 특정 단어/주제를 가진 모든 예제가 주문의 상단 또는 하단에 함께 붙어있는 것처럼 - 네이티브 주문이 교육 문제를 일으킬 수 있습니다. 그리고 그 경우, 어떤 훈련을하기 전에 하나의 셔플이 덩어리를 제거하기에 충분해야합니다. 그래서 다시 데이터를 가정하는 것은 메모리에 맞는, 당신은 단지

sentences = random.shuffle(list(TaggedLineSentence(sources) 

... 한 번, 당신은 (한 번) 모두 build_vocab()train() 아래에 Doc2Vec에 전달할 괜찮 sentences있어 ... 할 수있는 .