동형이의어 구분 원리 (베타)
동형이의어 구분 원리 — 품사 너머의 의미 (베타)
형태소 분석은 다리가 명사(NNG)라는 것까지 알려 줍니다. 그런데 그 다리가 건너는 다리(橋)인지
몸의 다리(脚)인지는 품사로 갈리지 않습니다. 바른은 문맥으로 뜻을 고르는 층을 형태소 분석 위에
얹어, 형태소마다 사전 의미 번호(어깨번호)를 붙일 수 있습니다.
이 문서는 그 원리와 학습 데이터, 그리고 현재 수준을 설명합니다. 사용 방법은 동형이의어 의미 구분 API를 참고하세요.
베타 기능입니다
동형이의어 의미 구분은 베타이며, 정식 기능으로는 바른 3.1.0 릴리스에 포함됩니다. 아래 설명은 베타 시점의 구조와 실측 결과입니다.
왜 어려운 문제인가
한국어 동형이의어 판별에는 세 가지 벽이 있습니다.
1. 후보가 많고, 대부분 같은 품사입니다.
배는 배(腹)·배(船)·배(梨)·배(倍)·배(杯)… 사전 항목이 열 개 가까이 되고 상당수가 NNG 입니다.
품사 태깅은 이 구분에 아무 도움을 주지 못합니다.
2. 의미의 분포가 극단적으로 치우쳐 있습니다.
실제 글에서 어떤 뜻은 수천 번 쓰이고, 어떤 뜻은 몇 번 쓰이고 끝납니다. 그래서 "그 단어에서 가장 흔한 뜻"을 늘 고르는 단순 규칙이 이미 상당히 높은 정확도를 냅니다. 모델이 의미가 있으려면 이 최빈 의미 규칙보다 확실히 나아야 합니다.
3. 정답 데이터가 부족합니다.
의미 번호가 사람 손으로 붙어 있는 한국어 말뭉치는 제한적이고, 사전마다 의미를 나누는 기준도 달라 그대로 합칠 수 없습니다.
graph TD
A["'다리' / NNG"] --> B{"문맥"};
B -->|"…를 건넜다"| C["다리 5 — 시설물"];
B -->|"…가 저리다"| D["다리 1 — 신체"];
B -->|"안경 …"| E["다리 3 — 물체의 지지 부분"];
의미는 전용 모델이 판정합니다
바른의 의미 판정은 형태소 분석과 분리된 전용 모델이 맡습니다. 형태소 분석기가 문장을 형태소로 나누고 품사를 붙이면, 의미 모델이 그 결과를 받아 각 형태소가 어느 뜻으로 쓰였는지 고릅니다.
graph LR
S["문장"] --> M["형태소 분석<br/>(분절 + 품사)"];
M --> W["의미 판정<br/>(전용 문맥 모델)"];
W --> R["형태소 + 어깨번호<br/>+ 뜻풀이 + 확률"];
처음에는 품사와 의미를 한 모델이 함께 내도록 만들었습니다. 문맥 표현을 두 번 만들지 않아 비용이 적다는 장점이 있었지만, 실제 문장에서 재 보니 의미 판별력이 최빈 의미 규칙과 거의 차이가 없었습니다. 그래서 의미 판정만 떼어내 문맥 표현을 더 깊이 읽는 전용 모델로 다시 만들었습니다. 3.1.0 에서는 그 전용 모델이 후보를 번호가 아니라 뜻풀이 문장으로 받아 문맥과 직접 대조하도록 한 번 더 바꿨습니다(아래 "현재 수준과 한계" 참고).
- 품사 정확도에 영향을 주지 않습니다. 의미 모델은 형태소 분석 결과를 바꾸지 않고, 어깨번호와 뜻풀이만 덧붙입니다. 의미를 요청하지 않은 호출은 이 모델을 아예 실행하지 않습니다.
- 의미를 요청하면 계산이 늘어납니다. 전용 모델이므로 문장마다 판정이 한 번 더 돌아갑니다. 응답 시간이 중요한 경로라면 필요한 요청에만 켜서 쓰시는 것을 권합니다.
형태소 분석 쪽 문맥 인코더 구조는 트랜스포머 모델 아키텍처를 참고하세요.
핵심 장치 — 후보를 그 단어의 사전 항목으로 제한합니다
의미 판정에서 가장 중요한 설계는 "고를 수 있는 답을 미리 좁히는 것" 입니다.
한국어 전체 의미 목록은 수만 개(현재 약 5만 8천 항목)입니다. 이 전부를 놓고 하나를 고르게 하면, 흔한 의미에 쏠리고 드문 의미는 사실상 선택되지 않습니다. 그래서 바른은 판정 순간에
- 그 형태소의 표제어와 품사로 사전 후보를 찾고,
- 그 후보들 사이에서만 확률을 계산해 가장 높은 것을 고릅니다.
이 제한이 만드는 차이는 큽니다.
| 판정 방식 | 성질 |
|---|---|
| 전체 의미에서 고르기 | 흔한 의미로 쏠리고, 드문 의미는 거의 선택되지 않습니다. |
| 그 단어의 후보에서 고르기 | 사전에 없는 엉뚱한 의미가 원천적으로 나오지 않고, 드문 의미도 겨룰 수 있습니다. |
부수 효과도 두 가지 있습니다.
- 표제어가 어긋난 뜻이 붙지 않습니다. 후보 자체가 그 표제어·품사의 사전 항목이라, 다른 단어의 뜻풀이가 실릴 구조적 여지가 없습니다.
- 응답의 확률이 뜻을 가집니다.
sense.probability는 이 후보 집합 안에서 고른 정도에, 그 의미가 실제로 얼마나 흔히 쓰이는지를 함께 반영한 값입니다. 두 가지를 같이 보기 때문에 후보를 모두 더해도 1이 되지 않습니다. 후보가 하나뿐이면 항상 1.0 인데, 이는 확신이 아니라 "고를 것이 하나뿐"이라는 뜻입니다. - 믿을 만하지 않으면 비웁니다. 어느 후보도 충분히 믿을 만하지 않은 자리에는 틀린 뜻을
붙이는 대신
sense를 싣지 않습니다.
어깨번호 체계를 우리말샘으로 통일했습니다
의미 번호는 사전마다 다릅니다. 바른의 학습 자료도 원래는 기준이 섞여 있었습니다.
| 자료 | 원래 의미 번호 기준 |
|---|---|
| 세종 말뭉치(문어·구어) | 표준국어대사전 |
| 모두의 말뭉치(뉴스) | 의미 번호 표기 없음 |
| 국립국어원 어휘 의미 분석 자료 | 우리말샘 |
바른은 전부를 우리말샘 기준으로 옮겨 하나의 번호 공간으로 통일했습니다. 우리말샘을 택한 이유는 표제어·의미 수가 가장 많아 실제 글에 나오는 단어를 담아내고, 갱신이 계속되며, 공개된 자료로 뜻풀이까지 연결할 수 있기 때문입니다.
통일의 효과는 정확도로도 확인됐습니다. 표준국어대사전 기준(약 6,600 의미)에서 우리말샘 기준(3만 이상)으로 옮기면 구분해야 할 의미가 5배 이상 촘촘해져 절대 정확도는 내려가지만, 최빈 의미 규칙 대비 모델이 만들어 내는 이득은 오히려 커졌습니다. 과제가 어려워졌는데도 모델의 기여가 늘었다는 뜻입니다. (이 비교는 번호 체계를 옮기던 시점의 측정이며, 현재 수준은 아래 "현재 수준과 한계"의 독립 테스트셋 수치를 보세요.)
뜻풀이는 결과에 미리 넣어 둡니다
응답의 meaning(뜻풀이)은 서버가 요청 시점에 사전을 조회해 채우는 값이 아닙니다.
의미 목록을 만들 때 표제어·어깨번호로 우리말샘과 맞춰 두어, 형태소 분석기만 설치한
환경에서도 뜻풀이가 함께 나옵니다. 맞춤법 검사기 여부와 무관합니다.
용언은 어간이 아니라 기본형('먹' → '먹다') 으로 맞추고, 품사 부류가 어긋나는 연결은 버립니다. 어간만으로 맞추면 같은 표기의 명사 뜻이 조용히 붙는 일이 생기기 때문입니다. 이 처리로 뜻풀이 연결률은 99.4%가 되었습니다(남은 0.6%는 우리말샘에 표제어가 없는 항목).
학습 데이터 — 사람이 붙인 정답을 먼저 씁니다
의미 판별은 정답 데이터의 품질이 성능을 거의 결정합니다. 바른은 우선순위를 이렇게 두었습니다.
- 사람이 붙인 의미 주석을 최우선으로 씁니다. 세종 말뭉치의 의미 주석과 국립국어원의 어휘 의미 분석 자료(뉴스 문장 약 146만 형태소)가 기준선입니다.
- 없는 곳은 자동으로 채우되, 검증을 거칩니다. 의미 번호가 없는 문장에는 대규모 언어모델로 후보를 붙인 뒤, 같은 의미로 묶인 예문들을 서로 비교해 어긋나는 것을 걸러 냅니다. 사람 정답과 겹치는 구간에서 자동 부착의 오류가 대량으로 드러났고, 그 교훈으로 사람 정답이 있는 곳에서는 자동 부착을 쓰지 않습니다.
- 드문 의미는 기존 말뭉치에서 찾아 보강합니다. 문장을 새로 만들기보다, 이미 있는 문장에서 그 의미로 쓰인 용례를 찾아 라벨을 붙이는 방식을 먼저 씁니다. 실제 글의 문체가 유지됩니다.
- 원본 말뭉치는 건드리지 않습니다. 의미 번호가 붙은 자료는 원본과 별도로 관리해, 품사·분절 학습에 쓰이는 기준 자료가 오염되지 않게 합니다.
정리 과정에서 배운 것 — '표기가 같으면 같은 의미'가 아닙니다
자동으로 붙인 의미를 검증할 때, 처음에는 "같은 어깨번호면 같은 뜻이어야 한다"는 기준으로 걸렀습니다. 그런데 어깨번호는 동형이의어 단위이고 그 아래 여러 갈래(다의)가 또 있어서, 이 기준으로는 정상 데이터의 대부분이 불일치로 잡혔습니다. 기준을 "같은 사전 항목에 속하는 쓰임인가"로 바꾸자 걸러 낼 대상이 제대로 좁혀졌습니다.
현재 수준과 한계
어떤 자료로 쟀는지가 수치보다 중요합니다. 학습에 쓴 말뭉치와 같은 성격의 문장으로 재면 값이 높게 나오지만, 실제 서비스 문장에서 기대할 수 있는 수준은 그보다 낮습니다. 그래서 바른은 학습에 전혀 쓰지 않은 독립 테스트셋(국립국어원 웹 말뭉치에서 새로 채취한 문장)과 사람이 검수한 정답 문장을 따로 두고, 그것으로 품질을 판단합니다.
현재 수준은 문맥을 읽지 않고 그 단어에서 가장 흔한 뜻으로 찍는 방식보다 낫습니다. 특히 가장 흔한 뜻이 정답이 아닌 자리, 그리고 학습에서 드물게 본 의미에서 차이가 납니다. 다만 그 차이를 더 벌리는 것이 지금의 과제이고, 완성했다고 보지 않기 때문에 베타로 제공합니다.
품사 판정에는 영향이 없습니다. 의미 모델은 형태소 분석 결과를 바꾸지 않고 어깨번호와 뜻풀이만 덧붙입니다.
의미 판정을 형태소 분석에서 떼어내 전용 모델로 만들면서 한 차례 올랐고, 3.1.0 에서는 후보를 뜻풀이 문장으로 받아 문맥과 대조하는 방식으로 다시 바꿨습니다. 사전에 뜻풀이가 있는 의미라면 학습에서 드물게 본 의미도 근거를 갖고 고를 수 있습니다.
그럼에도 실제 문장에서는 아직 눈에 띄는 약점이 있습니다. 베타로 공개하는 이유입니다.
| 약점 | 실측 예 |
|---|---|
| 한 문장에 같은 표기가 여러 번 나오면 같은 의미로 몰립니다. | 밤에 밤을 구웠다. → 두 밤 모두 '야간' |
| 문맥 단서가 짧으면 흔한 의미로 떨어집니다. | 배를 먹었다. → 배 를 '복부'로 판정 |
| 학습에서 거의 못 본 의미는 여전히 어렵습니다. | 사전에는 있으나 실제 글에 드물게 쓰이는 뜻 |
원인은 대체로 데이터 쪽입니다. 자동으로 붙인 의미 주석에 오차가 적지 않고, 지금 모델의 정확도는 그 주석을 만든 판정기와 이미 비슷한 수준까지 왔습니다. 즉 같은 방식으로 자동 주석을 더 만들어서는 크게 오르지 않습니다. 이어지는 작업은 성격이 다른 여러 판정기의 합의를 쓰거나 사람이 직접 정답을 붙이는 쪽으로, 그리고 드문 의미의 용례를 실제 말뭉치에서 찾아 보강하는 방향입니다.
정리
- 의미 판정은 형태소 분석과 분리된 전용 모델이 맡습니다. 요청하지 않으면 실행되지 않고, 형태소 분석 결과 자체를 바꾸지 않습니다.
- 판정은 그 표제어·품사의 사전 후보 안에서만 이뤄집니다. 그래서 엉뚱한 뜻이 붙지 않고, 응답 확률이 해석 가능한 값이 됩니다.
- 의미 번호는 우리말샘 기준으로 통일했고, 뜻풀이는 미리 결과에 담겨 있습니다.
- 사람 정답을 최우선으로 쓰고, 자동 부착은 검증을 거쳐 보조로만 씁니다.
- 품질은 학습에 쓰지 않은 독립 테스트셋과 사람이 검수한 정답 문장으로 판단하며, 반복 출현·짧은 문장·드문 의미가 남은 과제입니다.
다른 도구·자원과의 비교는 한국어 동형이의어 분석 자원 비교에서 다룹니다.
자주 묻는 질문
Q. 의미 구분을 위해 별도의 모델을 더 돌리는 건가요?
A. 네. 의미 판정은 형태소 분석과 분리된 전용 모델이 맡습니다. with_sense 를 켜지 않은 호출은
이 모델을 아예 실행하지 않아 기존과 완전히 같은 비용으로 동작하고, 켜면 문장마다 판정이 한 번 더
돌아갑니다.
Q. 사전에 없는 의미가 나올 수도 있나요?
A. 없습니다. 판정 후보 자체가 그 표제어·품사의 사전 항목으로 제한되므로, 사전에 없는 번호나 다른 단어의 뜻이 실리지 않습니다.
Q. 어깨번호 기준은 왜 우리말샘인가요?
A. 표제어·의미 수가 가장 많아 실제 글의 단어를 담아내고, 공개 자료로 뜻풀이까지 연결할 수 있습니다. 학습 자료마다 달랐던 번호 기준도 우리말샘 하나로 통일했습니다.
Q. 최빈 의미를 고르는 것과 무엇이 다른가요?
A. 학습에 쓰지 않은 독립 테스트셋에서 바른의 모델이 최빈 의미 규칙보다 낫습니다. 차이가 가장 크게 나는 곳은 가장 흔한 뜻이 정답이 아닌 자리입니다. 최빈 의미 규칙은 그 자리를 정의상 하나도 맞히지 못하지만, 문맥을 읽는 모델은 상당수를 맞힙니다. 다만 문맥 단서가 부족한 짧은 문장에서는 결과가 최빈 의미에 가까워지는 경향이 남아 있습니다.
도움이 되었나요?