Gensim 패키지의 doc2vec 모델을 사용해 문서간 유사도 계산하기
* 아래 예제는 Github의 IPython notebook으로 공유되어 있습니다.
입력 데이터
kaggle에 오픈되어 있는 hotel review 데이터를 사용해 보자데이터 포멧
테이터 형태를 살펴 보면 User_ID, Description, Browser, Device, Is_Response 형태로 구성되어 있다.Imports package
import pandas , nltk from gensim.models.doc2vec import Doc2Vec, TaggedDocument from nltk.tokenize import RegexpTokenizer
load Data
데이터를 RegexpTokenizer를 사용해 list type으로 변경한다.
filename = 'data/hotel-reviews.csv' df = pandas.read_csv(filename, sep=',') def nltk_tokenizer(_wd): return RegexpTokenizer(r'\w+').tokenize(_wd.lower()) df['Token_Description'] = df['Description'].apply(nltk_tokenizer) df.head()
Great Input Data
doc2vec 입력 형식에 맞게 데이터를 수정한다.
tags = 문서 ID
words = 단어 list
tags = 문서 ID
words = 단어 list
doc_df = df[['User_ID','Token_Description']].values.tolist() tagged_data = [TaggedDocument(words=_d, tags=[uid]) for uid, _d in doc_df]
Training
max_epochs = 10 model = Doc2Vec( window=10, size=150, alpha=0.025, min_alpha=0.025, min_count=2, dm =1, negative = 5, seed = 9999) model.build_vocab(tagged_data) for epoch in range(max_epochs): print('iteration {0}'.format(epoch)) model.train(tagged_data, total_examples=model.corpus_count, epochs=model.iter) # decrease the learning rate model.alpha -= 0.002 # fix the learning rate, no decay model.min_alpha = model.alpha
파라메터 설명
window: 모델 학습할때 앞뒤로 보는 단어의 수size: 벡터 차원의 크기
alpha: learning rate
min_count: 학습에 사용할 최소 단어 빈도 수
dm: 학습방법 1 = PV-DM, 0 = PV-DBOW
negative: Complexity Reduction 방법, negative sampling
max_epochs: 최대 학습 횟수
결과 확인
특정 문서와 유사한 문서를 찾기 위해서는 2단계를 거친다.1. 문서의 vector화
2. 변환된 vector와 가장 가까운 vector 추출
* infer_vector 사용시 seed값을 주지 않으면 random한값이 seed로 사용되어 값이 계속 변경된다.
* 학습되지 않은 단어를 사용한 문서도 결과가 나온다.
model.random.seed(9999) doc_list = 'Rooms were clean'.split(' ') inferred_vector = model.infer_vector(doc_list) return_docs = model.docvecs.most_similar(positive=[inferred_vector],topn=5) for rd in return_docs: for des in df[df['User_ID'] == rd[0]]['Description']: print rd[0],rd[1],des
문서ID를 직접 입력할 수 도 있다.
return_docs = model.docvecs.most_similar('id39751',topn=5) for rd in return_docs: for des in df[df['User_ID'] == rd[0]]['Description']: print rd[0],rd[1],des
ref
https://radimrehurek.com/gensim/models/doc2vec.htm
https://www.kaggle.com/harmanpreet93/hotelreviews
댓글 없음:
댓글 쓰기