elasticsearch에 관해 학습했던 내용을 정리한 내용입니다. 혹시 잘못된 내용이 있으면 편하게 지적부탁드립니다.
https://porolog.tistory.com/68
이전편에서 elasticsearch에서 사용되는 한국어 형태소 분석기와 관련된 개략적인 내용과 배경을 살펴보았습니다.
이번에는 좀 더 나아가, mecab 엔진의 형태소 분석 과정을 좀 자세히 파헤쳐보겠습니다.
Mecab의 원리와 형태소 분석의 핵심
Mecab은 형태소 분석 과정에서 자연 언어의 복잡성과 규칙성을 기반으로 분석 후보 생성부터 적절한 후보 선택까지의 체계적인 과정을 거칩니다. 이러한 과정은 언어의 문맥과 의미를 최대한 반영하기 위해 설계되었으며, 아래와 같은 단계로 이루어집니다.
1. 분석 후보 생성
자연 언어의 제약 조건, 즉 문법 규칙을 기반으로 가능한 모든 분석 후보를 생성합니다.
예를 들어, 문장 “청개구리 작목반”을 분석할 경우, 아래와 같은 후보가 만들어질 수 있습니다.
1번 후보 : [청, 개구리, 작목, 반]
2번 후보 : [청개, 구리, 작목, 반]
여기에서, 후보 중에서 선택하기 위해서 추가적으로, 단어의 다양한 뜻이나 문맥적 의미를 고려한 분석이 필요합니다.
왜냐하면, 청개(靑芥)는 국어사전에서 십자화과 식물의 이름으로, 실제 존재하는 단어이기 때문에 특정 문맥에서 의미를 가질 수 있습니다. 그러나 1번 후보가 올바른 분석이라는 판단을 내리기 위해서는 청개라는 단어가 구리와 보통 같이 잘 안쓰인다는 경험적 지식이 필요합니다. 방금 말한 경험적 지식이란, 다음 단계인 적절한 분석 후보 선택에서 확률적으로 자주 등장하는 단어의 조합을 선택한다는 것과도 비슷합니다.
2. 적절한 분석 후보 선택
생성된 후보 중 가장 적합한 조합을 선택합니다. Mecab은 확률적 모델링을 통해 각 후보의 자연스러움을 평가하며, 최적의 분석 결과를 반환합니다.
예:
• [청개, 구리, 작목, 반]: 단어 간 조합이 어색하므로 적합하지 않음.
• [청, 개구리, 작목, 반]: 문맥과 단어의 조합이 자연스럽고 타당성이 높음.
방금 언급한 두 단계를 거쳐 Mecab은 형태소 분석에서 다양한 후보를 생성하고, 그중에서 최적의 해답을 선택하는 과정을 통해 높은 정확도를 유지합니다.
분석 후보 생성 단계는 솔루션 탐색 모델인 Viterbi 알고리즘을 통해 산출되며,
분석 후보 선택 단계는 Conditional Random Fields로 확률을 평가하여 최종 후보를 선택하게 됩니다.
각각 자세히 살펴보겠습니다.
솔루션 탐색 모델 - Viterbi
Mecab의 형태소 분석 과정에서 중요한 단계 중 하나는 각 노드(단어)에 도달할 수 있는 가장 높은 확률의 경로(Path)를 선택하는 것입니다. 이는 형태소 분석 결과의 정확성을 결정짓는 핵심적인 요소로, 아래와 같은 방식으로 동작합니다.
1. 노드와 경로의 정의
• 노드: 분석 후보로 생성된 형태소(단어) 단위입니다.
예: 청, 개구리, 청개, 구리
• 경로(Path): 각 노드를 연결하며, 이전 노드에서 현재 노드로 이어지는 자연스러움을 확률로 표현한 값입니다.
다음 그림처럼, Mecab은 문장에서 가능한 모든 경로를 탐색하고, 각 경로의 자연스러움을 평가해 최적의 경로를 선택합니다.
아래는 Elasticsearch 공식 블로그에 등장하는 viterbi lattice 탐색 경로의 한 예시입니다.
확률 평가 - Conditional Random Fields
경로를 탐색하는 방법은 Viterbi 알고리즘으로 탐색하지만, 인접한 단어가 확률이 높고 낮음은 어떻게 판단할까요?
Conditional Random Fields로 계산하게 되는데요, 특징은 다음과 같습니다.
1. 특징 함수(Feature Function)의 정의
CRF는 텍스트의 구조적 정보를 활용하여 특징 함수를 정의합니다.
특징 함수는 입력 데이터에서 관찰할 수 있는 특성과 정답 라벨 간의 관계를 나타냅니다.
• 예시:
• 단어가 -ly로 끝나면 부사일 가능성이 높음.
• 전치사 다음에는 전치사가 올 가능성이 높음.
이러한 특징 함수는 단순한 규칙뿐만 아니라 말뭉치 데이터를 기반으로 학습된 통계적 패턴을 반영할 수 있습니다.
2. 전역 최적화(Global Optimization)
CRF는 시퀀스 전체에서 가장 높은 확률을 가지는 라벨링 결과를 선택하며, 개별 단어의 로컬 최적화(Local Optimization)에 의존하지 않습니다. 이를 통해 문맥 정보를 최대한 활용할 수 있습니다.
3. 조건부 확률 모델
CRF는 입력 데이터(X)와 출력 라벨(Y) 간의 조건부 확률을 학습합니다.
이는 모든 가능한 라벨링 조합을 고려한 후, 가장 적합한 조합을 확률적으로 선택하는 방식입니다.
좀더 자세히 알고싶으신 분은, 이 영상을 추천합니다.
https://www.youtube.com/watch?v=rI3DQS0P2fk
그리고 한국어의 세종 말뭉치를 확률 모델로 학습시켜 만들어 놓은 것이 바로 mecab-ko-dic과 같은 비용 사전입니다.
Mecab-ko-dic은 한국어 형태소 분석을 위해 설계된 비용 사전으로, CRF(Conditional Random Fields)와 세종 말뭉치를 결합해 생성되었습니다. 이 사전은 형태소 분석 과정에서 단어의 품사, 연결 가능성, 비용 정보를 바탕으로 가장 적합한 분석 결과를 도출하는 데 사용됩니다.
mecab-ko-dic 산출물 살펴보기
mecab-ko-dic은 아래 링크에서 다운로드 받을 수 있습니다.
https://bitbucket.org/eunjeon/mecab-ko-dic/downloads/mecab-ko-dic-1.6.1-20140515.tar.gz
사전을 다운로드 받아서 열어보면 산출물은 다음과 같습니다.
품사별 정보
품사별 정보에는 좌문맥 ID, 우문맥 ID, 단어비용, 품사 기타 정보등이 포함되어있습니다.
1. 좌문맥 ID (LID)
• 해당 단어가 문장 내에서 왼쪽 문맥과 어떻게 연결되는지를 나타내는 ID입니다.
• 이 ID는 다음에 등장할 연접비용 matrix.def에서 연접 비용 계산 시 사용됩니다.
예:
• 단어 청의 좌문맥 ID = 1
• 단어 개구리의 좌문맥 ID = 2
2. 우문맥 ID (RID)
• 해당 단어가 문장 내에서 오른쪽 문맥과 어떻게 연결되는지를 나타내는 ID입니다.
• 마찬가지로, 연접 비용 계산에 활용됩니다.
예:
• 단어 청의 우문맥 ID = 1
• 단어 개구리의 우문맥 ID = 3
3. 단어 비용
• 해당 단어가 형태소로 선택될 확률에 영향을 미치는 비용 값입니다.
• 비용이 높을수록 해당 단어가 형태소 분석 결과로 선택될 가능성이 높아집니다.
예:
• 청의 단어 비용 = 200 (자주 등장하며 자연스러운 단어)
• 청개의 단어 비용 = 300 (덜 자주 사용되거나 특수한 단어)
명사에 대한 품사 정보인 NNG.csv를 열어보면 실제로 다음과 같이 구성되어있습니다.
연접 비용 정보
다음 중요한 역할을 하는 연접 비용 정보는 형태소 간의 연결 가능성과 그 자연스러움을 수치화한 데이터입니다. 이 정보는 형태소 분석 과정에서 최적의 조합을 선택하기 위해 사용됩니다. 연접 비용 정보는 matrix.def 파일에 저장되어 있으며, 형태소 간의 연결 비용을 정의합니다.
아래 그림에서는 차례로 LID(좌문맥 ID), RID(우문맥 ID), 연접비용입니다.
LID에 해당하는 품사가 왼쪽에, RID에 해당하는 품사가 오른쪽에 있다고 했을 때 나타날 것으로 예상되는 비용을 계산한 matrix 파일입니다.
예를 들면 다음과 같은 상황이 있을 수 있습니다..
• LID = 1, RID = 2, 연접비용 = 100
→ 품사 ID 1(예: “청”)과 품사 ID 2(예: “개구리”)가 연결될 때의 비용.
• LID = 3, RID = 5, 연접비용 = 320
→ 품사 ID 3(예: “청개”)와 품사 ID 5(예: “구리”)가 연결될 때의 비용.
연접 비용이 낮은 것을 채택하므로, 청 + 개구리가 최종 후보로 채택됩니다.
품사별 정보, 연접 비용 정보를 활용하여 최종적인 점수 계산은 다음과 같이 이루어집니다.
1. 후보의 형태소들에 대해 낱말 비용과 이전 형태소와의 연접비용을 각각 계산한다.
2. 이 비용들을 누적해서 합쳐서 최종 비용이 가장 낮은 후보를 채택한다.
위 과정을 mecab-ko를 직접 설치해서 테스트해볼수도 있는데요,
mecab-ko의 설치방법은 아래 참고자료의 은전한닢 프레젠테이션을 참고바랍니다.
설치 이후에 다음과 같은 명령어로 실제로 평가를 해보았습니다.
echo "청개구리 작목반" | mecab -d mecab-ko-dic -N3 -F"%m\t%f[0],%f[1],%phl,%phr,%pw,%pC,%pc\n"
결과는 다음과 같았는데요,
예시에서 Mecab은 품사별 정보와 연접 비용을 계산하여 (청개구리 작목 + 반)의 조합이 가장 낮은 점수를 가지는 최적의 후보로 선택했습니다.
(주의할 점)
실제 상황에서는 이러한 결과가 항상 문맥적으로 적합하다고 보장할 수는 없습니다.
형태소 분석기는 일반적인 말뭉치와 사전을 기반으로 학습되지만, 특정 도메인의 문맥이나 전문 용어를 충분히 반영하지 못할 수 있습니다.
예를 들어, “작목반”이 농업 도메인에서는 자연스러운 표현일 수 있지만, 일반적인 문맥에서는 생소하게 느껴질 수 있기 때문에 형태소 분석기가 원하는대로 분석해주지 않는 경우, 커스텀 사전을 등록해서 도메인에 맞게 활용하는게 중요하다고 생각합니다.
참고자료
은전한닢 프로젝트 – 형태소 분석기 프레젠테이션
https://docs.google.com/presentation/d/1qhuhi7A-4XF0X4DVJrSIjKbtMYO9Fh09czpL0mheGjg/edit#slide=id.p
Nori, a Korean analyzer based on mecab-ko-dic
https://issues.apache.org/jira/browse/LUCENE-8231
MeCab: Yet Another Part-of-Speech and Morphological Analyzer
https://taku910.github.io/mecab/
Introduction to Conditional Random Fields
https://blog.echen.me/2012/01/03/introduction-to-conditional-random-fields/
'Computer Science > DB' 카테고리의 다른 글
Elasticsearch 한국어 형태소 분석기의 원리 - 1 (2) | 2024.12.23 |
---|---|
Real MySQL 8.0 읽기 - 아키텍처 (0) | 2023.07.21 |
MySQL 쿼리 최적화 - Covering Index (0) | 2023.06.06 |
슬로우 쿼리 모니터링 - AWS CloudWatch (0) | 2023.06.06 |
DB Bulk Insert, Jmeter 부하테스트 (0) | 2023.06.06 |