2019년 3월 24일 일요일

Python: doc2vec 모델을 사용해 문서간 유사도 계산

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

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

댓글 없음:

댓글 쓰기

추천 게시물

python: SVD(Singular Value Decomposition)로 간단한 추천시스템 만들기( feat. surprise )

svd_example In [15]: # !pip install surprise In [21]: from...