boostcampaitech2 / mrc-level2-nlp-06

KLUE-MRC - Machine Reading Comprehension
6 stars 2 forks source link

Elastic Search로 Retrieval 대체 가능? #41

Open HongCu opened 2 years ago

HongCu commented 2 years ago

https://colab.research.google.com/github/fastforwardlabs/ff14_blog/blob/master/_notebooks/2020-06-30-Evaluating_the_Retriever_&_End_to_End_System.ipynb#scrollTo=KxL9yAI1lTri

좋은 참고자료 Get!

BaekTree commented 2 years ago

ES로 우리를 구해주세요...!!

HongCu commented 2 years ago

es.indices.delete(index='squad-standard-index', ignore=[400, 404])로 shard문제는 해결했으나 여전히 unable to load document 문제 발생.. 근본적인 문제를 다시 찾아야겠다.

HongCu commented 2 years ago

[Elastic Search 가이드북] https://esbook.kimjmin.net/

[elastic search 오피스아워 자료] (재형님이 알려주심) https://github.com/thejungwon/search-engine-tutorial/blob/main/02_elastic_search.ipynb

HongCu commented 2 years ago

image

일단 index를 populate할 때 3분, query하나를 찾는데는 2 mileseconds밖에 걸리지 않았다. 속도에서는 확실히 강점이 있다는 것을 눈으로 확인했다.

하지만 index setting을 제대로 하지 않고, query를 줬을 때, 당연하게도 답변이 제대로 나오지 않았다.

elastic search를 사용하지 않고 BM25를 통해 Top 5를 뽑았을 때, 답변이 일반적으로 잘 나왔었던 문제였다.

index_settings의 문제가 클 것으로 예측된다.

그러면 이를 해결하기 위해 무엇을 해야할까?

HongCu commented 2 years ago

`def elastic_search(topk, es, dataset) : print(f'start {topk} document')

    dataset = dataset['validation']
    dataset_context = []
    dataset_question = dataset['question']
    dataset_id = dataset['id']

    for question in tqdm(dataset_question) :
        query = {
            'query': {
                'match': {
                    'document_text': question
                    }
                }
            }

        # topk만큼 score 높은 순위로 뽑아주고 그 context tokenization
        topk_docs = es.search(index='test2', body=query, size=topk)['hits']['hits']
        document_list = []
        for doc in topk_docs :
            temp_doc = doc['_source']['document_text']
            tokenized_doc = pororo_tokenizer(temp_doc)
            # tokenized_doc = Mecab().morphs(temp_doc)
            modified_doc = ''.join([word for word in tokenized_doc])
            # pororo는 _로 tokenized 된다. 그래서 pororo 사용할 때는 밑에를 켜야 함
            modified_doc = modified_doc.replace('▁', ' ')

            document_list.append(modified_doc)
        modified_context = '\n'.join(document_list)
        dataset_context.append(modified_context)

    df = pd.DataFrame({'id' : dataset_id, 'question' : dataset_question, 'context' : dataset_context})

    f = Features(
        {
            "context": Value(dtype="string", id=None),
            "id": Value(dtype="string", id=None),
            "question": Value(dtype="string", id=None),
        }
    )
    datasets = DatasetDict({'validation': Dataset.from_pandas(df, features=f)})
    return datasets`

elastic search로 prediction하기 위해 dataset pd형태로 만든 코드