프로그래밍

초보자도 쉽게 이해하는 doc2vec으로 문서 임베딩과 유사도 검색 방법

푸른강아지 2025. 3. 10. 17:59
반응형

요즘 자연어 처리 분야에서는 단순히 단어만 벡터로 표현하는 게 아니라, 문서 전체의 의미를 벡터로 나타내는 문서 임베딩 기법이 주목받고 있어요. 특히 doc2vec은 word2vec의 개념을 발전시켜서, 문서의 전체적인 의미를 잘 표현할 수 있도록 도와주죠. 문서 분류나 추천 시스템, 유사한 문서를 찾는 검색 시스템 등 다양한 분야에서 유용하게 쓰이고 있어요.

이 글에서는 doc2vec의 기본 개념과 원리부터 시작해서, 새로운 문서를 추가적으로 학습시키는 방법과 유사한 문서를 쉽게 찾을 수 있는 검색 방법까지 차근차근 살펴볼게요.

 

doc2vec은 문서의 의미를 어떻게 표현하는지 알아봐요

doc2vec은 word2vec에서 더 발전된 개념이에요. word2vec이 단어 하나하나의 의미를 벡터로 표현했다면, doc2vec은 단어뿐 아니라 문서 전체의 의미를 고려한 문서 벡터를 만듭니다. 이를 통해 각 문서가 어떤 맥락을 가지고 있는지 효과적으로 표현할 수 있어요.

doc2vec이 문서의 의미를 배우는 방식은 크게 두 가지인데요. 첫 번째는 DM(Distributed Memory) 방식으로, 문서 벡터와 주변 단어의 벡터를 함께 사용해서 특정 단어를 예측하는 방식이에요. 두 번째는 DBOW(Distributed Bag of Words) 방식인데, 이 방식은 문서 벡터만을 이용해 문서 내의 단어들을 예측합니다. 두 방식 모두 문서마다 고유한 태그를 붙여서 각 문서의 개성을 반영하는 벡터를 생성합니다.

 

doc2vec 모델 전체 학습은 어떻게 할까요?

처음부터 doc2vec 모델을 학습할 때의 과정도 간단히 소개해 드릴게요.

from gensim.models.doc2vec import Doc2Vec, TaggedDocument

# 학습할 문서 준비
documents = ["첫 번째 문서의 내용입니다.", "두 번째 문서의 내용입니다."]
tagged_documents = [TaggedDocument(words=doc.split(), tags=[str(i)]) for i, doc in enumerate(documents)]

# 모델 초기화 및 학습
model = Doc2Vec(vector_size=100, window=5, min_count=1, workers=4, epochs=20)
model.build_vocab(tagged_documents)
model.train(tagged_documents, total_examples=model.corpus_count, epochs=model.epochs)

# 모델 저장
model.save('your_doc2vec_model')

 

새로운 문서가 생겼다면 doc2vec 모델을 어떻게 추가로 학습시킬까요?

doc2vec 모델을 처음부터 다시 학습시키지 않고도 새로운 문서를 추가할 수 있어요. 추가 학습은 생각보다 간단한데요, 우선 새 문서를 기존과 같은 방식으로 토큰화하고 문서마다 고유한 태그를 부여합니다.

그 다음 기존 모델의 어휘를 새로운 문서의 단어들로 업데이트 해줘야 합니다. gensim 라이브러리에서는 이를 위해 model.build_vocab(new_docs, update=True)라는 명령어를 제공해요.

마지막으로 추가된 단어들을 반영해서 모델을 추가로 학습시키면 되는데요, model.train(new_docs, total_examples=..., epochs=...)를 통해서 간단히 가능합니다. 이때, 새로운 데이터가 기존 데이터와 매우 다르면 전체 모델을 다시 학습하는 것도 고려해야 합니다.

 

# 기존 모델 로드
model = Doc2Vec.load('your_doc2vec_model')

# 새로운 문서 준비
new_docs = ["새로운 문서의 내용입니다.", "추가할 또 다른 문서입니다."]
tagged_new_docs = [TaggedDocument(words=doc.split(), tags=[str(i)]) for i, doc in enumerate(new_docs)]

# 어휘 업데이트 및 추가 학습
model.build_vocab(tagged_new_docs, update=True)
model.train(tagged_new_docs, total_examples=len(tagged_new_docs), epochs=10)

 

학습한 doc2vec 모델로 유사한 문서를 빠르게 찾아봐요

doc2vec 모델을 사용하면 문서가 하나의 벡터로 표현되기 때문에, 비슷한 문서를 찾는 작업도 간편하게 할 수 있어요. 방법도 어렵지 않은데요.

먼저, 검색하고 싶은 문장이나 쿼리를 토큰화해서 모델에 넣으면 쿼리 벡터가 생성됩니다. 이 벡터를 가지고 gensim의 model.dv.most_similar() 기능을 이용하면 쿼리와 가장 비슷한 문서들을 바로 찾을 수 있죠. 데이터를 아주 많이 가지고 있다면, Faiss나 Annoy와 같은 도구를 사용하면 검색 속도를 더욱 빠르게 높일 수 있어요.

 

query = "찾고 싶은 문장의 내용을 입력해요"
query_tokens = your_tokenizer(query)  # 예: 형태소 분석기 사용
query_vector = model.infer_vector(query_tokens)

similar_docs = model.dv.most_similar([query_vector], topn=10)
for doc_tag, similarity in similar_docs:
    print(f"문서 태그: {doc_tag}, 유사도: {similarity:.3f}")

 

doc2vec을 잘 활용하면 다양한 문서 분석이 쉬워져요

doc2vec은 단어만 표현하는 방법의 한계를 극복하고 문서 전체의 의미를 효과적으로 벡터로 표현할 수 있는 강력한 방법이에요. 새롭게 들어오는 데이터를 쉽게 추가로 학습시키고, 문서 간 유사도를 빠르게 계산할 수 있어서 검색 시스템이나 문서 추천 시스템 구축에 아주 유용합니다.

이제 여러분도 doc2vec으로 자신만의 문서 분석 및 추천 시스템을 만들어 보세요!

반응형