(4강) Passage Retrieval - Sparse Embedding
1. Introduction to Passage Retrieval
Passage Retrieval
우리 대회에서는 위키피디아가 해당되겠지만 일반적인 경우는 웹 사이트가 해당될 것이다.
이런 시스템이 왜 필요할까? 1~3강에서 배웠던 MRC 시스템과 연동하면 Open Domain System이 될 수 있기 때문이다.
Passage Retrieval with MRC
이 때 모델은 주어진 질문에 관한 도메인을 데이터베이스에서 찾는 것을 학습해야 하며 이를 위해 질문을 던져주는 모델도 존재해야한다. 이러한 전체 과정이 2-stage 방식으로 이루어진다.
Overview of Passage Retrieval
이 때 Passage Embedding같은 경우는 질문이 들어왔을 때 하는 것이 아니라 미리 해놓아서 효율성을 도모할 수 있도록 한다.
이후, 질문과 지문의 임베딩의 유사도를 측정하게 된다. 이 경우 여러가지 측정 방법이 있으며 주로 고차원에서의 두 점의 거리 또는 내적과 같은 연산으로 유사도를 얻게된다.
2. Passage Embedding and Sparse Embedding
Passage Embedding Space
지문을 숫자로 매핑하고자 하는 것이고 이런 과정에서 고차원의 벡터공간이 필요하다. 이러한 차원을 3차원으로 축소했을 때 저렇게 시각화할 수 있다.
Sparse Embedding 소개
만약 우리가 30만개의 단어를 가지고 있다면 모든 문서가 30만 벡터 공간으로 매핑을 하게된다. 그리고 차원은 하나의 단어에 해당하게 된다.
기본적으로 unigram을 사용하게 되면 vocab의 크기가 문서의 단어 개수와 동일하게 된다. 반면 bigram을 사용하게 되면 vocab의 크기가 문서의 단어의 제곱이 되며, 이 n-gram에서 n이 늘어날수록 vocab의 크기가 기하급수적으로 늘어나게 된다. 따라서 n을 무조건 높이는 것은 적절하지는 않지만 보통 bigram까지 하는편이며 가끔은 trigram까지 하기도 한다.
또한 Term을 결정할 수 있는데, 등장하냐 하지않느냐에 따른 이진 분류도 가능하지만 몇번 등장하는지에 대한 빈도수를 가지고 측정할 수 있다.
Sparse Embedding 특징
검색을 할 때 겹치는 단어를 찾아서 쉽게 매칭할 수 있지만, 의미론적인 개념은 활용하지 못한다는 단점이 있다.
3. TF-IDF
TF-IDF (Term Frequency – Inverse Document Frequency) 소개
어떤 문서에 단어가 많이 등장했는데, 전체 문서에서는 잘 등장하지 않았다면 이 단어는 이 문서에서는 매우 중요한 단어라고 할 수 있다. 이럴 때 좀 더 점수를 주는 방식이 TF-IDF이다. 반면 현재 문서에서 많이 등장했는데 전체 문서에서도 많이 등장했다면 중요도를 낮게보아서 비교적 낮은 점수를 부여한다.
Term Frequency (TF)
이 때 값을 정규화하게 되며 비율로 값을 가지게된다.
Inverse Document Frequency (IDF)
The나 is의 경우 TF가 매우 높을 것이다. 100개의 문서에 모두 등장한다면 DF Score는 100이 된다. 반면 IDF는 위와같이 전체 문서의 개수에 대한 어떤 단어가 등장한 문서의 개수의 log를 취한 값으로 나타내지며, 만약 전체 문장에서 어떤 단어가 등장했다면 log 1의 값으로 수렴해서 IDF값은 0이 된다.
중요한 점은 TF와 다르게 IDF의 경우에는 각 Term에 특정되고 문서에는 무관하다는 점이다. 아래에 바로 등장하는 식을 보자
Combine TF & IDF
TF는 단어와 문서까지 표시를 해줘야 하지만 IDF는 단어마다 유니크하고 문서마다 다르지 않게 된다. TF-IDF는 이 두 수치를 곱한 수치가 된다.
TF-IDF 계산하기
유니그램만을 사용했다고 가정한다.
TF-IDF를 이용해 유사도 구해보기
TF-IDF는 주로 Cosine Distance를 구하는 방법으로 유사도를 측정하며, 이 때 각 벡터를 Inner Product 하면 Cosin Distance를 구할 수 있다.
BM25란?
문서가 짧을 수록 해당 단어의 등장에 대한 희귀성을 인정해주는 방법
실습
Requirements
!pip install datasets
!pip install transformers
데이터셋 준비
from datasets import load_dataset
dataset = load_dataset("squad_kor_v1")
corpus = list(set([example['context'] for example in dataset['train']]))
len(corpus)
>>> 500
!pip install datasets
!pip install transformers
from datasets import load_dataset
dataset = load_dataset("squad_kor_v1")
corpus = list(set([example['context'] for example in dataset['train']]))
len(corpus)
>>> 500
중복된 corpus가 있다보니 set으로 했다가 다시 list로 캐스팅 해주는 모습.
corpus[0]
자크 시라크 대통령과 우호적인 관계에 추가로 슈뢰더는 러시아와 독일 사이에 발트해에 가스 파이프라인을 개장한 것을 포함한 베를린과 모스크바 사이의 전략 협력을 강화하는 시도에서 러시아의 블라디미르 푸틴 대통령과 가까운 관계를 깊게 하였다. ...
토크나이저 준비
tokenizer_func = lambda x: x.split(' ')
tokenizer_func(corpus[0])[:10]
>>>'자크', '시라크', '대통령과', '우호적인', '관계에', '추가로', '슈뢰더는', '러시아와', '독일', '사이에']
TF-IDF embedding 만들기
from sklearn.feature_extraction.text import TfidfVectorizer
vectorizer = TfidfVectorizer(tokenizer=tokenizer_func, ngram_range=(1,2))
(1, 2)에서 2는 포함되는 값이다. 보통 python의 range에서 end값은 포함되지 않지만 여기서는 포함되는 포맷을 사용한다. 따라서 unigram과 bigram을 사용하는 것으로 하는 것이다.
벡터라이저를 사용할 때 IDF의 경우 문서 전체를 보고 전체 등장하는 Term들을 모두 Vocaburary로 만들어줘야 한다. 이 때 fit
을 사용해서 학습하지만 NN을 사용해서 학습하는 방식과는 조금 다르다.
vectorizer.fit(corpus)
sp_matrix = vectorizer.transform(corpus)
sp_matrix.shape
>>> (9606, 1272768)
sparse matrix는 각 문서에 해당하는 sparse vector를 가지고 있는 하나의 큰 matrix이다. 9,606
은 전체 문서의 개수이며 1,272,768
는 문서내에 등장하는 sparse vector의 개수이다. 문서 내에는 사실 이렇게 많은 vector가 존재할 리 없지만 unigram뿐만 아니라 bigram까지 셌기 때문에 이렇게 큰 수가 등장했다.
import pandas as pd
df = pd.DataFrame(sp_matrix[0].T.todense(), index=vectorizer.get_feature_names(), columns=["TF-IDF"])
df = df.sort_values('TF-IDF', ascending=False)
print(df.head(10))
TF-IDF
슈뢰더는 0.262591
자신의 0.102764
며칠 0.101019
대통령과 0.096607
동안에 빅토르 0.072674
비율에 올 0.072674
회고록 《결정들:정치에서 0.072674
의하여 비난을 0.072674
민주적 개발의 0.072674
나의 인생》에서 0.072674
테이블을 잘 활용하기 위해 판다스를 사용했다. 간단히 시각화를 위한 용도이다.
TF-IDF embedding을 활용하여 passage retrieval 실습해보기
import random
import numpy as np
random.seed(1)
sample_idx = random.choice(range(len(dataset['train'])))
query = dataset['train'][sample_idx]['question']
ground_truth = dataset['train'][sample_idx]['context']
랜덤하게 지문과 질문을 선택했다.
query_vec = vectorizer.transform([query])
query_vec.shape
>>> (1, 1272768)
1
이라는 숫자는 matrix로 표현하기 위함이고 실제로는 벡터이며 이를 배치사이즈로 간주해도 된다.
result = query_vec * sp_matrix.T
result.shape
>>> (1, 9606)
결과는 간단하게 inner product를 계산하면 된다. 각각의 지문과 현재의 질문의 유사도를 9606개의 수로 나타낸 것이다. 여기서 가장 높은 값을 가지는 질문을 찾으면 된다.
sorted_result = np.argsort(-result.data)
doc_scores = result.data[sorted_result]
doc_ids = result.indices[sorted_result]
유사도가 큰 값을 찾기 위해 -
를 붙여서 내림차순으로 정렬을 한다. 그리고 정렬 기준은 data이지만 정렬한 값은 index이다. 따라서 이 순서대로 data가 정렬된 것을 doc_scores
로 선언한다. doc_ids
는 indices
함수를 통해 (data를 기준으로 정렬된) 인덱스 값을 가지도록 한다.
k = 3
doc_scores[:k], doc_ids[:k]
>>> (array([0.18985967, 0.03625019, 0.03371167]),
array([8132, 3206, 4891], dtype=int32))
TOP-3의 결과를 출력해본 결과.
print("[Search query]\n", query, "\n")
print("[Ground truth passage]")
print(ground_truth, "\n")
for i in range(k):
print("Top-%d passage with score %.4f" % (i + 1, doc_scores[i]))
doc_id = doc_ids[i]
print(corpus[doc_id], "\n")
[Search query]
호메로스 찬가를 신통기에 비해 간결한 서사로 간주한 사람은 누구인가?
[Ground truth passage]
고전 시대 신화에서는 티탄들의 패배 이후, 신들의 새로운 판테온이 세워졌다고 설명한다. 주요한 그리스 신들 중에서 올림피안은 올림포스 산 정상에서 제우스의 통치 아래 살아가는 신들을 말한다. 이들의 인원이 열두 명으로 제한된 것은 비교적 최근에 도입된 개념으로 보인다. 올림피안 이외에도 그리스인들은 염소 신 판, 강의 정령 님프, 샘에 사는 나이아드, 나무의 정령 드라이어드, 바다에 사는 네레이드, 강의 신, 사티로스를 비롯한 그 지역의 다양한 신들을 숭배하였다. 여기에는 에리니에스(또는 푸리아이)처럼 혈연 관계에게 범죄를 저지른 죄인을 뒤쫓는 저승의 암흑 세력도 있었다. 시인들은 그리스 판테온의 영광을 기리고자 호메로스 찬가를 지었다.(33편의 노래). 그레고리 나지는 호메로스 찬가를 "각 노래마다 신에 대한 기원을 노래하는(《신통기》에 비해) 간결한 서가"로 간주하였다.
Top-1 passage with score 0.1899
고전 시대 신화에서는 티탄들의 패배 이후, 신들의 새로운 판테온이 세워졌다고 설명한다. 주요한 그리스 신들 중에서 올림피안은 올림포스 산 정상에서 제우스의 통치 아래 살아가는 신들을 말한다. 이들의 인원이 열두 명으로 제한된 것은 비교적 최근에 도입된 개념으로 보인다. 올림피안 이외에도 그리스인들은 염소 신 판, 강의 정령 님프, 샘에 사는 나이아드, 나무의 정령 드라이어드, 바다에 사는 네레이드, 강의 신, 사티로스를 비롯한 그 지역의 다양한 신들을 숭배하였다. 여기에는 에리니에스(또는 푸리아이)처럼 혈연 관계에게 범죄를 저지른 죄인을 뒤쫓는 저승의 암흑 세력도 있었다. 시인들은 그리스 판테온의 영광을 기리고자 호메로스 찬가를 지었다.(33편의 노래). 그레고리 나지는 호메로스 찬가를 "각 노래마다 신에 대한 기원을 노래하는(《신통기》에 비해) 간결한 서가"로 간주하였다.
Top-2 passage with score 0.0363
두 사람은 낙담하고, 밴 하우튼의 집을 떠난다. 리더비히는 대신 사과하며 두 사람과 같이 여행을 한다. 세 사람은 안네 프랑크의 집을 방문한다. 집에 계단이 많기 때문에 헤이즐은 힘들게 올라간다. 안네 프랑크의 집 꼭대기에서 헤이즐은 사랑을 느끼고 어거스터스와 로맨틱한 키스를 한다. 두 사람은 호텔로 돌아와 처음으로 밤을 같이 보낸다. 다음날, 어거스터스는 헤이즐에게 자신의 암이 재발했다고 말한다. 인디애나폴리스에 돌아와서 어거스터스의 상태가 더욱 악화되어 갔다. 어거스터스는 중환자실로 보내지며 죽음이 가까운 것을 깨달았다. 어거스터스는 자신의 생전 장례식에 눈 먼 친구 아이작과 헤이즐을 불러 두 사람은 사전에 적은 추도사를 낭독한다. 헤이즐은 밴 하우튼의 소설을 인용하며, 어거스터스와 함께하는 짧은 시간은 무엇과도 바꿀 수 없는 것이라고 말한다.
Top-3 passage with score 0.0337
고대 그리스에서 신화는 일상의 중심이었다. 그리스인들은 신화를 그들의 역사의 일부로 보았다. 그들은 자연 현상과 문화적 변화, 인습적인 증오와 친교를 설명하는데 신화를 사용하였다. 한 지도자가 신화적 영웅, 또는 신의 후손이라는 증거로 사용할 수 있는 자부심의 원천이기도 했다. 《일리아스》와 《오디세이아》에서 설명하는 트로이아 전쟁의 진실에 대해서 의문을 갖는 사람은 거의 없었다. 군사 역사가, 칼럼니스트, 정치 수필가이자 전 고전학 교수인 빅터 데이비스 핸슨과 고전학 부교수 존 히스에 따르면, 그리스인들에게 호메로스 서사시의 심오한 지식은 그들의 문화 변용의 기저로 간주되었다. 호메로스는 "그리스의 학문"(Ἑλλάδος παίδευσις)이었고, 그의 시는 한 권의 "책"이었다.
정확히 retrieve 했음을 알 수 있다.
Author And Source
이 문제에 관하여((4강) Passage Retrieval - Sparse Embedding), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@sangmandu/4강-Passage-Retrieval-Sparse-Embedding저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)