Skip to content

기분석 사전

krikit edited this page Jul 23, 2020 · 7 revisions

기분석 사전은 단일 어절에 대해 문맥에 상관없이 일괄적인 분석 결과를 갖는 경우 사용합니다.

사전 엔트리의 종류

기분석 사전의 엔트리는 아래와 같은 두 가지 종류가 있습니다.

  • 완전 일치: 전체 어절이 완전히 일치하는 경우에 적용되는 엔트리
  • 전방 매칭: 어절의 앞부분부터 부분적으로 일치할 경우에도 적용되는 엔트리

다음은 기분석 사전 엔트리의 예시들입니다.

번호 입력 어절 분석 결과
1 이더리움* 이더리움/NNP
2 이러쿵저러쿵 이러쿵저러쿵/MAG
3 고통스러워하* 고통/NNG + 스럽/XSA + 어/EC + 하/VX
4 고통스러웠* 고통/NNG + 스럽/XSA + 었/EP
5 고통스러웠다. 고통/NNG + 스럽/XSA + 었/EP + 다/EF + ./SF

입력 어절의 끝에 "*"가 있는 1, 3, 4번 엔트리는 전방 매칭 패턴입니다. 가령 1번 엔트리 이더리움*의 경우는 "이더리움이", "이더리움을" 등과 같은 여러 어절에 적용됩니다.

반변 2, 5번 엔트리는 완전 일치 어절입니다. 이러한 엔트리들은 입력 어절도 처음부터 끝까지 완전히 일치할 경우에만 적용됩니다. 가령 5번 엔트리 고통스러웠다.의 경우 "고통스러웠다"와 같이 마지막 구두점 "."이 하나만 없어도 적용되지 않습니다.

자세히 보면 4번과 5번 엔트리는 서로 포함관계에 있습니다. 가령 "고통스러웠다."라는 어절은 4번과 5번 엔트리 모두에 해당됩니다. 이러한 경우 긴 엔트리를 우선적으로 적용합니다. 그래서 "고통스러웠다."의 모든 7개의 음절들은 기분석 사전의 결과로 채워집니다.

반면에 "고통스러웠다"와 같이 마지막 구두점 "."이 없는 어절은 4번 엔트리에 적용됩니다. 그래서 "고통스러웠"까지 5개의 음절은 기분석 사전의 결과로 채워지고, 마지막 "다" 음절은 기계학습 분류기의 판단에 맡깁니다.

사전 파일

rsc/src 디렉터리 아래에는 두 개의 파일이 존재합니다.

  • preanal.auto: 코퍼스로부터 자동으로 추출한 엔트리가 있는 파일
  • preanal.manual: 사용자가 직접 추가할 엔트리를 넣을 파일

필요할 경우 preanal.my와 같은 새로운 파일을 추가해도 됩니다. 사전을 빌드하는 프로그램이 preanal.로 시작하는 모든 파일을 이용하여 사전을 빌드합니다.

사전에 엔트리를 추가하여 변경된 경우 반드시 make resource 명령을 통해 사전을 다시 빌드해 줘야 합니다. 마치 소스 코드를 빌드하여 실행 프로그램을 생성하듯이, rsc/src 디렉터리 아래의 사전 소스를 빌드하여 build/share/khaiii 아래에 프로그램에서 사용할 수 있도록 구조화된 바이너리 사전(리소스)이 생성됩니다.

사전 포맷

기분석 사전의 포맷은 <어절(패턴)> <탭> <분석 결과>입니다. 아래는 사전 내용 예시입니다.

이더리움*	이더리움/NNP
이러쿵저러쿵	이러쿵저러쿵/MAG
# 아래 엔트리들은 비슷비슷하네요~
고통스러워하*	고통/NNG + 스럽/XSA + 어/EC + 하/VX
고통스러웠*	고통/NNG + 스럽/XSA + 었/EP
고통스러웠다.	고통/NNG + 스럽/XSA + 었/EP + 다/EF + ./SF

맨 처음에 "#"으로 시작하는 줄은 무시됩니다. 코드에서 주석과 같습니다만, 가운데에 나타난 "#" 이후로 주석이 되지는 않으므로 반드시 맨 앞에만 사용하시기 바랍니다.

사전 빌드

build 디렉터리에서 make resource 명령으로 전체 리소스를 빌드할 수 있지만, 기분석 사전만 별도로 빌드가 가능합니다. 아래 명령을 통해 기분석 사전만 빌드합니다.

cd rsc
mkdir -p ../build/share/khaiii
PYTHONPATH=$(pwd)/lib ./bin/compile_preanal.py --rsc-src=./src --rsc-dir=../build/share/khaiii

--rsc-src 옵션은 rsc/src 디렉터리, 즉 preanal.autopreanal.manual 파일이 있는 디렉터리입니다. --rsc-dir 옵션은 ../build/share/khaiii 디렉터리로 바이너리 사전을 출력할 곳입니다. 빌드가 성공하면 아래 두 파일이 생성됩니다.

preanal.tri
preanal.val

사전 로딩

기분석 사전에 새로운 엔트리를 추가하여 빌드한 경우 기존에 배포한 경로, 예를 들여 /usr/local/share/khaiii 혹은 python site-packages 경로에 전체 사전을 다시 복사해 줘야 합니다. 사전의 설치 경로에 관해서는 설치 위치에 관하여 문서를 참고하시기 바랍니다.

아니면, 아래와 같이 사전의 경로를 직접 API의 인자로 전달하여 로딩하여야 합니다.

from khaiii import KhaiiiApi

api = KhaiiiApi(rsc_dir='/path/to/custom/khaiii/dictionary')

음절 단위 정렬

사전을 빌드하는 과정에서 CNN 모델 문서에서 설명한 것처럼 어절과 분석 결과를 정렬하여 어절 내 각 음절에 대한 출력 태그를 생성합니다. 이 정렬 과정에서 오류가 발생할 경우 아래와 같은 에러를 보게 될 것입니다.

INFO:root:preanal.manual
INFO:root:preanal.auto
ERROR:root:{M:N} [이더] [리움] []
{M:N} [이/I-NNP 더/I-NNP] [륨/I-NNP] []

ERROR:root:preanal.manual:2: fail to align: "이더리움	이더륨/NNP"
ERROR:root:1 errors

위 예제는 어절에 "이더리움"을 넣은 데 반해 분석 결과에 "이더륨"이라고 일부러 넣은 것입니다. 이로써 어절의 "리움" 부분과 분석 결과의 "륨" 부분이 정렬이 되지 않고 남아 결국 정렬에 실패하여 빌드 에러를 발생하게 됩니다. 이러한 경우는 보통 분석 결과 부분의 입력에 실수한 경우가 많으므로 바르게 수정하면 문제없이 빌드되는 경우가 많습니다.

반면에 아래와 같은 경우는 양쪽이 바른 분석 결과임에도 불구하고 정렬에 실패하는 경우입니다.

INFO:root:preanal.manual
INFO:root:preanal.auto
ERROR:root:{M:N} [] [해야] [겠습니다.]
{M:N} [] [하/I-VV 여/I-EC 야/I-EC] [하/I-VX 겠/I-EP 습/I-EF 니/I-EF 다/I-EF ./I-SF]

ERROR:root:preanal.auto:79823: fail to align: "해야겠습니다.	하/VV + 여야/EC + 하/VX + 겠/EP + 습니다/EF + ./SF"
ERROR:root:1 errors

이것은 어절의 "해야" 부분이 분석 결과 "하/I-VV 여/I-EC 야/I-EC" 부분과 정렬이 이뤄지지 않아서 발생하는 문제입니다. 만약, 해당 부분이 정렬되는 것이 맞다면 rsc/src/char_align.map 파일에 아래와 같이 규칙을 추가해 주면 정렬이 되고 빌드가 성공합니다.

해야	하/I-VV 여/I-EC 야/I-EC	21

포맷은 <음절들> <탭> <분석 결과 음절과 태그> <탭> <정렬 정보> 형태입니다. 앞에 두 칼럼은 위에서 설명한 정렬이 되지 않는 두 부분을 뜻하지만 마지막 "21" 부분은 첫 번째 칼럼의 한 음절이 두 번째 칼럼의 몇 음절과 정렬이 이뤄지느냐 하는 정보입니다.

음절들 분석 결과 음절과 태그 정렬 정보
하/I-VV, 여/I-EC 2
야/I-EC 1

위에서 보는 것처럼 "해"라는 음절은 분석 결과 음절 2개와 정렬이 되고, "야" 음절은 1개와 정렬이 됩니다. 따라서 세 번째 칼럼의 정렬 정보는 "21"이며, 이는 항상 첫 번째 칼럼의 음절 길이만큼 아라비아 숫자로 표기합니다.

이렇게 정렬이 되고 나면 "해"는 원형 복원이 필요한 "I-VV:I-EC:1"과 같은 복합 태그를 갖게 되므로, 만약 원형복원 사전에 존재하지 않는다면 rsc/src/restore.dic 파일에 자동으로 원형복원 정보를 추가합니다. 또한 새로운 복합 태그인 경우 rsc/src/vocab.out.more 파일에 자동으로 출력 태그 정보를 추가합니다.

사전 입력 가이드라인

CNN 모델의 경우 좌우 문맥을 3개씩 이용하여 음절의 출력 태그를 판단하므로, 길이가 4를 넘어가는 경우 분석 결과를 예측하기 어려운 단점이 있습니다. 기분석 사전은 이를 손쉽게 보완할 수 있는 기능이 아닐까 생각합니다. 따라서 긴 고유명사와 같은 오분석에 대응하기 위해 사용하는 것을 추천드립니다.

기분석 사전은 하나의 어절만을 보고 적용되므로, 좌우에 어떤 어절이 오느냐에 따라 분석 결과가 달라지는 모호성이 있는 경우 사용하면 부작용이 발생하게 되니 주의하시기 바랍니다.

어절과 분석 결과의 음절이 변형되는 경우 정렬이 안 되는 경우가 있는데, rsc/src/char_align.map에 무조건 넣으면 이 또한 다른 엔트리들의 정렬에 영향을 미칠 가능성이 있으므로, 음절 단위 정렬에 대한 깊은 이해와 확신을 갖고 신중히 추가하시기 바랍니다.