버튼 수집상

[Elastic Search] 한글 문장 벡터화해서 유사한 문장 찾기 알고리즘 구현 - 1 본문

TIL - Elastic Search

[Elastic Search] 한글 문장 벡터화해서 유사한 문장 찾기 알고리즘 구현 - 1

cocokaribou 2023. 10. 17. 20:35

순서

1. 데이터셋 준비

2. 형태소 분석 (Tokenization)

    - 한글 형태소 분석기 nori, konlpy

    - Elasticsearch 의 REST api 사용하거나 파이썬 모듈 사용
    - Elasticsearch 콘솔 홈 > Dev Tools 에서 REST api 테스트 가능

3. 단어장 (Vocabulary)

    - 빈 단어장 생성

    - 형태소 분석이 완료된 텍스트 데이터를 단어장에 업데이트

    - 중복 제거하고 각 토큰마다 식별ID 부여

4. 단어 임베딩 (Embedding)

    - 모델: Word2Vec, FastText, gensim 등

    - 토큰화된 텍스트를 위 모델들에게 학습시켜서 벡터 얻기

 

Elasticsearch

용어집

SQL Elasticsearch
Database Index
Table x
Row Document

Elasticsearch는 데이터베이스가 곧 테이블, 즉 join이 없다.

 

Elasticsearch CRUD 명령어 -> HTTP 메소드 형태

POST movie
{
    "mappings": {
        "properties" : {
        "movieCd" : {"type" : "integer"},
        "movieNm" : {"type":"text", "analyzer": "nori"},
        "prdtYear" : {"type":"integer"},
        "regGenreNm" : {"type" : "keyword"}
      }
    }
}

POST 메소드 (/패스가 없음.)

movie 인덱스 생성.

 

인덱스 생성시 settings, mappings 키 값을 설정할 수 있다.

POST movie/_doc
{ 
    "movieCd" : 10,
    "movieNm" : "Titanic",
    "prdtYear": 1998,
    "regGenreNm" : "Drama"
}

POST 메소드/_doc 패스.

movie 인덱스에 document 추가.

 

HTTP 메소드 뒤에 붙는 패스로 API에 접근한다.

예를 들어 /_doc은 Document API 을 호출한다.

POST 뿐만 아니라 DELETE, UPDATE, BULK 등의 메소드에서 사용할 수 있다.

 

Document APIs | Elasticsearch Guide [8.10] | Elastic

 

www.elastic.co

 

색인, 인덱싱이란? (출처)

원본 문서를 검색어 토큰들으로 변환하여 저장하는 일련의 과정.
데이터를 검색하기 쉬운 형태로 변경하는 것.

 

인덱싱 비용 줄이기 (출처)

1. _bulk 리퀘스트를 사용하라
2. 데이터 전송시 멀티스레딩을 하라
3. 자동생성 id를 사용하라
4. index.number_of_replicas 를 0으로 설정해서 복사본 생성을 막는다

 

Elasticsearch 메소드

POST : index 생성 가능, SQL의 INSERT와 유사, 유니크한 식별자 필요 x
PUT : 유니크한 식별자 필요, 기존에 있던 데이터면 UPDATE, 없으면 INSERT

_bulk : 여러 데이터를 한번의 리퀘스트로 처리

 

gensim

gensim doc2vec 이용해서 파일 읽고 처리하는 함수 작성하기 (출처)

1. train/test 파일을 연다 (인코딩 돼있어야함)
2. 파일을 line-by-line으로 읽어들인다
3. 각 라인을 전처리한다 : 텍스트를 단어 낱개로 토큰화tokenize, 마침표 지우기, 소문자 변환 등

 

gensim doc2vec 훈련시키기

import gensim

model = gensim.models.doc2vec.Doc2Vec(vector_size=256, min_count=2, epochs=40)
# 벡터 사이즈 256, 칼럼이 256개

model.build_vocab(train_corpus)
# 전처리된 텍스트 뭉치로 단어장 만들기

model.train(train_corpus, total_examples=model.corpus_count, epochs=model.epochs)
# 모델 훈련시키기

 

Google Colab에서 실습

Colab에서 Elasticsearch에 접속하기

import numpy as np
from elasticsearch import Elasticsearch
es = Elasticsearch(hosts = [{'host': 'HOST', 'port': 8888, 'scheme' : "https"}],
    request_timeout=300, max_retries=10, retry_on_timeout=True,
    basic_auth=('USER', 'PW')
)

# 테스트로 데이터 가져오기
query_dsl = {
    "term": {
        "regGenreNm": "SF"
    }
}

res = es.search(index="movie", query = query_dsl , size=3)

# GET movie/_search
# {
#     "query" : {
#         "term" : {
#             "reGenreNm" : "SF"
#         }
#     }
#     "size" : 3
# }

print("Got %d Hits:" % res['hits']['total']['value'])
for hit in res['hits']['hits']:
    print( hit["_source"]["movieCd"], ":" , hit["_source"]["movieNm"])

Colab에서 구글 드라이브의 파일에 접근

from google.colab import drive
drive.mount('/content/drive')
file_path = "/content/drive/My Drive/test.json"

with open(file_path, 'r') as file_data:
    first_line = file_data.readline()  # 테스트로 첫 줄만 출력

print(first_line)

 

중요한 것

한번 학습시킨 모델은 저장해서 쓴다.

 

* 계속 수정될 예정

 

728x90