elasticsearch 및 nori 설치는 이전 글을 참고 부탁드립니다.
https://sooyeol86.blogspot.com/2019/12/elasticsearch-with-nori-feat-docker.html
Elasticsearch에 nori를 설치 하면 기본적인 형태소 분석기 및 사전을 사용할 수 있습니다.
하지만, 때때로 사용자 정의 사전이나 유의어가 필요할 수도 있겠습니다.
하지만, 때때로 사용자 정의 사전이나 유의어가 필요할 수도 있겠습니다.
예를 들면 "삼성전자" 라는 단어는 사전에 없는 단어이기 때문에 아래 이미지와 같이 "삼성" / "전자" 로 단어를 분리합니다.
이 단어를 한 단어로 사용을 하고 싶다면 사용자 정의 사전에 추가를 해야합니다.
그리고 "삼성전자" = "삼전" 이라고 표현을 할 수도 있겠는데, 따로 유의어를 등록하지 않으면 "삼전" 이라고 했을 때 "삼성전자" 에 대해서 검색을 해오지 못합니다.
유의어 사전에 "삼성전자,삼전" 이라고 등록을 해두면 "삼전" 검색 시 "삼성전자"도 같이 검색이 되겠지요.
그럼 간략하게 진행을 해보도록 하겠습니다.
- 사용자 사전 파일 생성
docker-elk/elasticsearch/config/ 폴더에 user_dic.txt 파일을 생성 하고 첫번째 Line에 "삼성전자" 라고 등록을 합니다.
- 유의어 사전 파일 생성
docker-elk/elasticsearch/config/ 폴더에 synonyms.txt 파일을 생성하고 첫번째 Line에 "삼성전자,삼전" 이라고 등록을 합니다.
- docker 설정 파일에서 user_dic.txt / synoyms.txt 파일 복사하도록 설정
docker-elk/elasticsearch/Dockerfile 을 열어서 아래 내용을 추가 합니다.
COPY config/user_dic.txt config/user_dic.txt
COPY config/synonyms.txt config/synonyms.txt
- docker 재실행
ctrl + c 혹은 docker-compose down -v 를 통하여 docker 를 전부 종료 합니다.
docker-compose up --build -d 를 통하여 docker 를 실행합니다. (-d 옵션은 background 에서 돌리는 옵션)
- 파일 추가 여부 확인
docker ps 를 하고 docker-elk_elasticsearch 에 대한 container_id 를 획득하여
docer exec -it [container_id] bash 를 수행합니다. (container 내부로 접속하는 명령어)
그런다음 config 폴더를 확인해보면 아래와 같이 user_dic.txt 과 synonyms.txt 파일이 추가 된 것을 확인할 수 있습니다.
- 인덱스 생성 및 테스트
아래와 같이 인덱스를 생성합니다.
아래 filter 내용을 참고하여 nori_part_of_speech 에 대한 조정이 필요한 경우 조정해야 합니다.
인터넷에 돌아다니는 예제 들의 경우 이것저것 품사들을 제거해서 실제로 원하는 analyzer를 했을 때 결과물이 안나올 가능성도 큽니다.
구축하고자 하는 사이트에 맞게 해당 필터를 사용하시기 바랍니다.
PUT test2
{
"settings": {
"analysis": {
"tokenizer": {
"nori_user_dict": {
"type": "nori_tokenizer",
"decompound_mode": "mixed",
"user_dictionary": "user_dic.txt"
}
},
"analyzer": {
"korean_analyzer": {
"filter": [
"pos_filter_speech", "nori_readingform",
"lowercase", "synonym", "remove_duplicates"
],
"tokenizer": "nori_user_dict"
}
},
"filter": {
"synonym" : {
"type" : "synonym_graph",
"synonyms_path" : "synonyms.txt"
},
"pos_filter_speech": {
"type": "nori_part_of_speech",
"stoptags": [
"E", "J", "SC", "SE", "SF", "SP", "SSC", "SSO", "SY", "VCN", "VCP",
"VSV", "VX", "XPN", "XSA", "XSN", "XSV"
]
}
}
}
}
}
아래와 같이 analyze를 실행하면 "삼전" / "삼성전자" 가 나오는 것을 확인할 수 있습니다.
POST test2/_analyze
{
"analyzer":"korean_analyzer",
"text":"삼성전자"
}
- 생성한 인덱스 필터에 대한 설명
자세한 설명 및 추가 사용가능한 필터는 elasticsearch 사이트 참고
nori_part_of_speech : 품사 제거 필터
nori_readingform : 한자 to 한글 필터
lowercase : 소문자로 변경해주는 필터https://www.elastic.co/guide/en/elasticsearch/reference/current/analysis-lowercase-tokenfilter.html
synonym_graph : 유의어 필터
remove_duplicates : 중복 토큰 제거 필터https://www.elastic.co/guide/en/elasticsearch/reference/current/analysis-remove-duplicates-tokenfilter.html
- nori_part_of_speech 필터 사용을 위한 간략한 품사 정리
nori 의 경우 lucense/mecab 기반으로 만들어졌기 때문에, mecab 사전을 참고하면 조금 도움이 될 수 있습니다.
(Tag의 경우 lucene 을 참고 하고 사전은 mecab gitgub 참고)
간략하게 예제와 품사에 대한 설명을 적긴 했지만 헷갈릴수 있으니 헷갈리면 직접 찾아보시길 권장..
E
: 어미 [Verbal
endings]
어간 뒤에 놓이는 굴절 접사
ex) 하고,다,습니다,있,었
IC
: 감탄사
[Interjection]
말하는 이의 본능적인 놀람이나 느낌, 부름, 응답 따위를 나타내는 말의 부류
ex) 만세,맙소사,아이고
J
: 조사 [Ending
Particle]
주로 체언에 붙어 뒤에 오는 다른 단어에 대하여 가지는 문법적 관계를 표시하거나 그
말의 뜻을 도와주는 품사
ex) ~보다,~까지
MAG
: 부사 [General
Adverb]
동사, 형용사, 동사구, 문장 전체를 수식하는 역할을 맡는 품사
ex) 힘껏,즉시,번쩍
MAJ
: 접속부사
[Conjunctive adverb]
문장과 문장 사이를 접속해(연이어) 주는 부사
ex) 그러나,왜냐하면,그리고
MM
: 관형사
[Determiner]
체언 앞에 놓여서, 그 체언의 내용을 자세히 꾸며 주는 품사
ex) 저,갓,그딴,수천수만
NNB
: 의존명사
[Dependent noun(following nouns)]
의미가 형식적이어서 다른 말 아래에 기대어 쓰이는 명사
ex) 것,따름,동안,무렵,이상
NNBC
: 분류사
[Dependent noun]
단위를 나타내는 명사
ex) 퍼센트,군단
NNG
: 보통명사 [General
Noun]
일반 개념을 표시하는 명사. 여러 가지
사물의 공통된 특성을 나타낸다
NNP
: 고유명사 [Proper
Noun]
특정한 대상이나 유일한 대상을 가리키는 명사의 일종.
NP
: 대명사 [Pronoun]
사람이나 사물, 장소를 직접 가리키는 기능을
하는 품사
ex) 이것저것,귀하,그거
NR
: 수사 [Numeral]
사물의 수량이나 순서를 나타내는 단어의 한 부류
ex) 경,십,예닐곱,오륙백
VA
: 형용사
[Adjective]
품사의 하나로 사람이나 사물의 성질과 상태 또는 존재를 나타내는 말
ex) 가녀린,잔망스럽,올바른
VCN
: 부정 지정사
[Negative designator]
지정사 : 어떤 대상을 지정할 때 사용하는 ‘이다’와 ‘아니다’를 가리키는 품사
ex) 아니,아닌
VCP
: 긍정 지정사
[Positive designator]
ex) 이,보이,사이
VV
: 동사 [Verb]
사람이나 사물의 움직임 또는 작용을 나타내는 말
VX
: 보조용언
[Auxiliary Verb or Adjective]
조적 기능을 수행하는 동사의 부류. 즉
뒤에 있는 동사구가 앞의 동사에 어떤 보조의 의미를 첨가하는 기능을 한다
ex) 헷갈리,잡수
XPN
: 체언접두사
[Prefix]
체언 : 조사의 도움을 받아 문장에서 주체의
구실을 하는 단어
ex) 새 (새 것, 새 날)
XR
: 어근 [Root]
단어의 실질적 의미를 나타내는 중심 부분
ex) 불그스름,희뿌염,일목요염
XSA
: 형용사 파생 접미사
[Adjective Suffix]
접미사 : 접사의 하나로 낱말의 끝에 붙어
의미를 첨가하여 다른 낱말을 이루는 말
ex) 못마땅하,스럽
XSN
: 명사 파생 접미사
[Noun Suffix]
ex) 치레,투성이
XSV
: 동사 파생 접미사
[Verb Suffix]
ex) 되잖,시키
NA,
UNA, Unknown, VSV : 알수없는 [unknown]
SC
: 구분기호
[Separator (· / :)]
SE
: 생략 [Ellipsis]
SF
: 물음표,느낌표,마침표 [Terminal punctuation (? ! .)]
SH
: 한자 [Chinese
character]
SL
: 외국어 [Foreign
language]
SN
: 숫자 [Number]
SP
: 공백 [Space]
SSC
닫는 괄호 [Closing
brackets]
SSO
: 여는 괄호
[Opening brackets]
SY
: 기타 기호 [Other
symbol]
추가적으로 아래 사이트를 참고 하면 도움이 될듯 합니다.
글 내용이 아주 큰 도움이 되었습니다 잘 보고 가요
답글삭제도움이 되셨다니 기분이 좋네요! 감사합니다.
삭제굳굳.. 좋은글 감사합니다.
답글삭제감사합니다. ^^
삭제실제 운영하고 있는 인스턴스에서 user_dic과 synonyms가 업데이트가 필요한 경우엔 어떻게 하시는지 궁금합니다 :)
답글삭제안녕하세요..
답글삭제저는 따로 배우고 했거나.. 심도 깊게 연구를 하고 사용한 것은 아니고, 소규모 검색엔진이 필요한 곳에서 사용을 했었습니다.
저 같은 경우는 es 올려둔 서버에 파일을 업데이트 하고 es 재기동을 통하여 업데이트를 진행했습니다.
그렇게 했던 이유는 색인을 할 때는 user_dic 도 사용을 하여 색인을 했지만.. synonyms 의 경우는 별도 색인 없이 검색 시 검색 쿼리를 사용할 때 사용을 했던 것으로 기억합니다.
user_dic 의 경우 이미 색인이 된 데이터의 경우 재색인을 해주지 않을 경우 매칭이 안될 것 같기는 하나, 그 정도까지 타이트하게 관리할 필요는 없었어서 해당 방법으로 했습니다.
전문적으로 심도 깊게 사용하시는 분들은 어떻게 하시는지 저도 궁금하네요..
다른 분들의 경우도 어떻게 하는지 알게 되시면 댓글로 링크라도 부탁드립니다!
좋은 하루 되세요 :)
감사합니다. 덕분에 실습하는 환경 잘 구축했습니다.!
답글삭제안녕하세요. 오래전 글인데도 도움이 되었다니 기분이 좋네요! 좋은 하루 되세요 :)
삭제