2017-03-27 14 views
1

특정 문서와 유사한 상위 n 개의 문서를 표시 할 수있는 알고리즘을 만들려고합니다. 나는 gensim doc2vec를 사용했다. 코드는 울부 짖는 소리입니다 :Gensim docvecs.most_similar는 존재하지 않는 Id를 반환합니다.

model = gensim.models.doc2vec.Doc2Vec(size=400, window=8, min_count=5, workers = 11, 
dm=0,alpha = 0.025, min_alpha = 0.025, dbow_words = 1) 

model.build_vocab(train_corpus) 

for x in xrange(10): 
    model.train(train_corpus) 
    model.alpha -= 0.002 
    model.min_alpha = model.alpha 
    model.train(train_corpus) 

model.save('model_EN_BigTrain') 

sims = model.docvecs.most_similar([408], topn=10) 

심즈 var에 첫 번째 요소 문서의 ID와 점수는 두 번째 인 나에게 10 개 튜플을 제공해야합니다. 문제는 일부 ID가 교육 데이터의 어떤 문서에도 해당하지 않는다는 것입니다.

나는 지금 내 훈련 데이터에없는 ID를 이해하려고 노력했지만 어떤 논리도 보지 못했다.

시 : 이것은 내 train_corpus

def readData(train_corpus, jData): 

print("The response contains {0} properties".format(len(jData))) 
print("\n") 
for i in xrange(len(jData)): 
    print "> Reading offers from Aux array" 
    if i % 10 == 0: 
     print ">>", i, "offers processed..." 

     train_corpus.append(gensim.models.doc2vec.TaggedDocument(gensim.utils.simple_preprocess(jData[i][1]), tags=[jData[i][0]])) 
print "> Finished processing offers" 

(I 이드 할 것인지) 위치 0은 INT이다 마녀의 AUX 배열 한 어레이의 각 위치 복지를 만드는 데 사용되는 코드 위치 1 설명

미리 감사드립니다.

답변

1

일반 정수 ID를 tags으로 사용하고 있지만 0에서부터 MAX_DOC_ID까지의 모든 정수를 정확하게 사용하지 않습니까?

그렇다면 해당 범위 내의 태그 모양을 설명 할 수 있습니다. 일반 int를 사용하면 gensim Doc2Vec은 내부 벡터 배열의 태그 위치에 태그를 제공하여 dict 매핑을 작성하지 않고 int 자체 만 사용합니다.

따라서 내부 벡터 배열은 MAX_DOC_ID + 1 행을 포함하도록 할당되어야합니다. 사용되지 않은 ID에 해당하는 행은 모든 위치와 마찬가지로 임의의 벡터로 초기화되지만 실제 텍스트 예제에서 의미있는 상대 위치로 푸시 할 수있는 교육을받지 않습니다. 따라서 이러한 무작위 초기화 된 벡터는 나중에 most_similar() 결과에 나타날 수 있습니다.

피하려면 0에서 마지막 ID까지 인접한 int 만 사용하십시오. 또는 문자열 - 인덱스 매핑의 메모리 비용을 감당할 수 있으면 일반 int 대신 문자열 태그를 사용하십시오. 또는 유효한 ID에 대한 추가 기록을 유지하고 결과에서 원하지 않는 ID를 수동으로 필터링하십시오.

따로 : 당신의 Doc2Vec 모델 초기화에 iter=1를 지정하지 않음으로써, iter=5의 기본 train()에 각 호출을 의미하는 효과가있을 것입니다 귀하의 데이터에 5 번 반복한다. 이상하게도 또한 xrange(10) for-loop에는 train() 번의 두 번의 반복 호출이 포함됩니다. 첫 번째 호출은 이미 alpha/min_alpha가 사용 된 모든 것을 사용합니다. 따라서 실제로 이상한 학습률 일정으로 데이터에 대해 10 * 2 * 5 = 100 패스를 수행하고 있습니다. 10 개 개의 패스 그냥 alpha/min_alpha의 손길이 닿지 않은 기본값 그대로두고 한 번만 train() 전화, iter=10을 설정하려면

내가 대신 좋습니다. 모델은 10 개의 패스를 수행하여 시작부터 끝까지 알파를 부드럽게 관리합니다. 내가 몇 wonk 인덱스를 가진 dataframe를 통과했다

for idx,doc in data.iterrows(): 
    alldocs.append(TruthDocument(doc['clean_text'], [idx], doc['label'])) 

:

+0

안녕하세요 gojomo, 빠른 응답을 주셔서 감사합니다. 내가 여기에 설명했던 것을 알아 냈습니다. 첫 번째 ID가 408 인 경우 벡터의 위치는 409 개였습니다. 이를 해결하기 위해 데이터베이스에서 문자열로 얻은 ID를 사용하고 문제가 해결되었습니다. doc2vec의 모델은 iter를 1로 지정했지만이 코드에서는 변경하지 않았습니다. 이주기를 doc2vec 자습서에서 보았습니다. 거기서 더 나은 결과를 얻었습니다. 그것에 대해 의견이 있으십니까? iter가 10 또는 0 인 모델로주기 또는 열차를 수행하는 것이 유익한가요? – JoaoSilva

+1

덜 매끄러운 학습 속도의 부식으로 루핑을 수행하기 만하면 더 나은 결과를 얻지 못할 수 있습니다. 실수로 10 반복을한다고 생각할 때 실수로 100 반복을 수행하면 실수로 'iter = 10'과 비교할 때 (그리고 사용 된 여분의 시간을 무시하고) 인식이 향상 될 수 있습니다. 명시적인 alpha/min_alpha 땜질과 함께'train()'을 여러 번 호출하는 것은 보통 오류가 발생하기 쉬운 문제이며, 어떤 경우 든 반복 당 두 개의'train()'이 길잃은 잘못된 편집처럼 보입니다. 그래서 나는 그 패턴을 피할 것입니다. – gojomo

+0

명시 적으로'iter = 10'을 사용하면, 디폴트'alpha' /'min_alpha'가 그 자리에 남아있을 수 있다는 위의 편집 설명에 유의하십시오. – gojomo

0

은 내가 다음 내 doc2vec를 초기화하고,뿐만 아니라이 문제가되었다. 내가해야만하는 것은 전부였다.

df.reset_index(inplace=True)