2008년 11월 5일 수요일

hunspell 한글 검사 실험 - proof of concept

개요는 생략.

hunspell 프로그램이 한글 단어의 edit distance를 계산할 수 있으려면 내부 처리는 모두 첫가끝 코드로 바꿔야 한다. 프로그램을 바꾸기는 어려우니 첫가끝 코드로 변환하고 복원하는 간단한 필터 작성. 만만한게 파이썬에 들어 있는 unicodedata.normalize.

#!/usr/bin/env python
import unicodedata
import sys

while True:
    line = sys.stdin.readline()
    if not line:
        break
    line = unicodedata.normalize('NFC', line.decode("UTF-8")).encode("UTF-8")
    sys.stdout.write(line)
#!/usr/bin/env python
import unicodedata
import sys

while True:
    line = sys.stdin.readline()
    if not line:
        break
    line = unicodedata.normalize('NFD', line.decode("UTF-8")).encode("UTF-8")
    sys.stdout.write(line)

그리고 hunspell의 언어 추가에 필요한 두 가지 데이터, 사전과 affix 파일을 작성한다.

완전한 사전 데이터가 있을 리가 없고... 일단 마구 생각나는 단어 "가방", "발", "컴퓨터"를 입력해 본다. 이 파일은 hunspell에서 직접 읽어들이기 때문에 첫가끝으로 변환해야 하는데..  앞에서 작성한 필터로 변환한다.
3
가방/JS
발/JS
컴퓨터/JS

AFF 파일 작성, 욕심은 자제하고 조사 규칙만 입력한다. 원래는 용언의 어간과 어미를 넣어보려고 했으나.. proof of concept으로 명사 + 조사의 형태의 규칙만 만들어 본다. 받침이 있고 없고에 따라 달라지기 때문에 모음과 자음 목록을 첫가끝으로 입력해야 하는데, 좀 성가시므로 gucharmap을 이용했다.
SET UTF-8
LANG ko_KR
FLAG long

TRY ᄀᄁᄂᄃᄄᄅᄆᄇᄈᄉᄊᄋᄌᄍᄎᄏᄐᄑ하ᅢᅣᅤᅥᅦᅧᅨᅩᅪᅫᅬᅭᅮᅯᅰᅱᅲᅳᅴᅵᆨᆩᆪᆫᆬᆭᆮᆯᆰᆱᆲᆳᆴᆵᆶᆷᆸᆹᆺᆻᆼᆽᆾᆿᇀᇁᇂ
WORDCHARS ᄀᄁᄂᄃᄄᄅᄆᄇᄈᄉᄊᄋᄌᄍᄎᄏᄐᄑ하ᅢᅣᅤᅥᅦᅧᅨᅩᅪᅫᅬᅭᅮᅯᅰᅱᅲᅳᅴᅵᆨᆩᆪᆫᆬᆭᆮᆯᆰᆱᆲᆳᆴᆵᆶᆷᆸᆹᆺᆻᆼᆽᆾᆿᇀᇁᇂ

# 조사
SFX    JS    Y    9
SFX    JS    0    에    .
SFX    JS    0    가    [ᅡᅢᅣᅤᅥᅦᅧᅨᅩᅪᅫᅬᅭᅮᅯᅰᅱᅲᅳᅴᅵ]
SFX    JS    0    이    [ᆨᆩᆪᆫᆬᆭᆮᆯᆰᆱᆲᆳᆴᆵᆶᆷᆸᆹᆺᆻᆼᆽᆾᆿᇀᇁᇂ]
SFX    JS    0    를    [ᅡᅢᅣᅤᅥᅦᅧᅨᅩᅪᅫᅬᅭᅮᅯᅰᅱᅲᅳᅴᅵ]
SFX    JS    0    을    [ᆨᆩᆪᆫᆬᆭᆮᆯᆰᆱᆲᆳᆴᆵᆶᆷᆸᆹᆺᆻᆼᆽᆾᆿᇀᇁᇂ]
SFX    JS    0    는    [ᅡᅢᅣᅤᅥᅦᅧᅨᅩᅪᅫᅬᅭᅮᅯᅰᅱᅲᅳᅴᅵ]
SFX    JS    0    은    [ᆨᆩᆪᆫᆬᆭᆮᆯᆰᆱᆲᆳᆴᆵᆶᆷᆸᆹᆺᆻᆼᆽᆾᆿᇀᇁᇂ]
SFX    JS    0    로    [ᅡᅢᅣᅤᅥᅦᅧᅨᅩᅪᅫᅬᅭᅮᅯᅰᅱᅲᅳᅴᅵᆯ]
SFX    JS    0    으로    [ᆨᆩᆪᆫᆬᆭᆮᆰᆱᆲᆳᆴᆵᆶᆷᆸᆹᆺᆻᆼᆽᆾᆿᇀᇁᇂ]

그리고 테스트를 위해 커맨드라인을 첫가끝으로 변환해서 hunspell에 처리한 다음 다시 음절로 바꾸는 스크립트 작성.
#!/bin/sh
echo $* | ./syl2jamo.py | hunspell -d ko_KR | ./jamo2syl.py

몇 번의 시행착오 끝에 hunspell을 이용한 초보적인 한글 맞춤법 검사 동작!
duncan:~/hacks/hunspell$ ./test.sh 가방
Hunspell 1.2.6
*
duncan:~/hacks/hunspell$ ./test.sh 가방이
Hunspell 1.2.6
+ 가방
duncan:~/hacks/hunspell$ ./test.sh 가뱅
Hunspell 1.2.6
& 가뱅 1 0: 가방

duncan:~/hacks/hunspell$ ./test.sh 따방
Hunspell 1.2.6
& 따방 1 0: 가방

duncan:~/hacks/hunspell$ ./test.sh 컴퓨터가
Hunspell 1.2.6
+ 컴퓨터

duncan:~/hacks/hunspell$ ./test.sh 컴퓨터이
Hunspell 1.2.6
& 컴퓨터이 2 0: 컴퓨터에, 컴퓨터

duncan:~/hacks/hunspell$ ./test.sh 컴퓨방
Hunspell 1.2.6
& 컴퓨방 2 0: 컴퓨터, 가방

duncan:~/hacks/hunspell$ ./test.sh 발로
Hunspell 1.2.6
+ 발

duncan:~/hacks/hunspell$ ./test.sh 발으로
Hunspell 1.2.6
& 발으로 3 0: 가방으로, 발로, 발


실제 활용할 수 있을 정도로 끌어올리기에는 할 일이 많다. 다른 프로그램과 연동을 고려하면 첫가끝 변환 코드는 실행 파일에 내장해야 한다. 또 우리말 형태론에 맞게 주의깊게 접두어/접미어 규칙이 작성되어야 한다. (복잡한 용어 어미 변화도 가능해 보인다.) 단어별로 특성이 기술된 단어 사전을 축적하는 게 가장 시간이 오래 걸리는 일이다.

하지만 hunspell로 처리할 수 있다는 건 확인할 수 있었다. 오픈오피스와 파이어폭스 사용자의 피드백을 이용할 수도 있다는 점에서 별도의 프로그램을 작성하는 것보다는 더 가능성 있는 방향으로 보인다.

댓글 6개:

  1. 우왓!!!

    오픈소스 스팰러로 한국어를 -첫가끝 풀어쓰기로!- 이렇게 지원할 수 있군요!!

    감탄, 또 감탄하고 있습니다.

    답글삭제
  2. 와 정말 굉장합니다.

    공개/오픈 맞춤법 검사기가 없어서 굉장히 아쉬워하고 있는데 이렇게 개발을 하고 계시다니..

    너무 감사드립니다. 특히 말씀하신 오픈오피스와 파이어폭스의 확장으로 사용할 수 있게 된다면 굉장한 일이 될 것입니다. :)

    답글삭제
  3. @Mr.Dust - 2008/11/12 17:04
    개발은 안 하고 있구요.. 제목 그대로 된다는 것만 확인한 겁니다.



    확장만으로는 못 사용하고, 파이어폭스나 오픈오피스 다음 개발 사이클에서 hunspell에 코드 변환이라도 구현되어야 가능한 일이죠.

    답글삭제
  4. 사실 처음 이 포스트를 보았을때, 왜 저렇게 어렵게 하실까.. 뭘 위한 것일까? 그런 생각을 했었습니다.

    오늘 직접 해보니 필요한 것 같긴 한데, 도통 이해는 안되네요. ^^;



    일단 Hunspell 을 이용한 아주 기초적인 단어 매칭은 성공을 했습니다. 그냥 dic 파일에 단어 주루룩 넣고, 일치하지 않으면 맞춤법이 틀리다고 표시되는 정도죠. 즉, affix 를 무시한 설정. 여기에 affix 규칙을 적용하려면 결국 첫가끝으로 분해하는 방식으로 돌아가야 하는건가요? 바로 다이렉트로 적용이 안되려나..

    이에 대한 설명 좀 부탁드려도 되련지요?

    답글삭제
  5. @Mr.Dust - 2008/11/23 09:36
    어떤 단어가 맞냐 틀리냐 여부를 판가름하는 용도라면 인코딩을 안 바꿔도 되는데, 맞춤법을 검사한 다음에 틀린 단어에 대해서 맞는 단어가 뭐일것 같다고 고칠 단어를 추천하는 기능이 문제입니다.



    이런 맞춤법 검사는 전통적으로 "edit distance"를 계산해서 그 거리가 가까운 단어중에서 사전에 있는 단어를 추천하게 되는데요. 음절로 사용하면 "갖"/"같"처럼 비슷한 말이나 "랄"/"히" 처럼 이렇게 틀리기 어려운 글자나 똑같이 1글자 다른 걸로 취급하게 되서 적당한 후보를 찾지 못하겠죠.



    한글은 실제 키보드 입력도 자모 단위로 하고 발음도 자모 단위로 하기 때문에 자모로 분해하면 서양 언어와 똑같은 알고리즘을 써도 무리가 없습니다. (조사, 용언 활용 등의 문제는 별개이고 이게 aff 규칙과 관계있는 것.)

    답글삭제
  6. @cwryu - 2008/11/23 12:52
    아 그렇군요. 창우님 글을 보면서 'edit distance' 가 뭐고 그게 왜 필요할까에 대해 고민을 많이 했습니다. 한글로 된 자료도 적고, 영어는 확실히 컨샙 이해에는 별로 도움이 안되고.. 그런데 추천 기능 때문에 필요한 것이었군요.

    답글삭제

뜬금없이 문법 따위를 지적하거나, 오래된 글에 링크가 깨진 걸 지적하는 등의 의미 없는 댓글은 자제해 주시기 바랍니다. 그러한 경우 답 없이 삭제합니다. 또한 이해 당사자이신 경우 숨어서 옹호하지 마시고 당사자임을 밝히시길 바랍니다.

참고: 블로그의 회원만 댓글을 작성할 수 있습니다.