open-korean-text词形变化引擎深度解析:KoreanConjugation如何穷举全部活用形
【免费下载链接】open-korean-textOpen Korean Text Processor - An Open-source Korean Text Processor项目地址: https://gitcode.com/gh_mirrors/op/open-korean-text
韩语是一种活用形极其丰富的语言,一个动词可以衍生出几十种不同的形态,这让韩语分词(tokenization)和词性标注(POS tagging)变得格外棘手。open-korean-text作为一款开源韩语文本处理器,其核心秘密就藏在词形变化引擎 KoreanConjugation 中——它能在启动时把词典里的每个动词、形容词穷举成全部活用形,从而让分词器在真实文本中"认得"每一种写法。本文就带你深度拆解这个引擎的实现原理。
为什么韩语分词离不开活用形穷举
韩语谓词(动词、形容词)的词干(stem)几乎不会原样出现在句子中。"먹다"(吃)在实际文本里会变成"먹어요""먹었어""먹고"……如果词典里只存"먹다"这一个原型,分词器看到"먹었어"时就只能把它拆成一堆未知字符,词性标注自然全线崩溃。
open-korean-text 的解法很直接:在词典加载阶段就做活用形穷举,把"原型 + 全部活用形"一次性塞进内存词典。这样分词器在做最长匹配时,无论是"먹다"还是"먹었어",都能直接命中同一个词条。这正是 KoreanConjugation.scala 承担的核心职责。
KoreanConjugation核心机制:一个词如何变成几十种形态
词形变化引擎的入口是conjugatePredicated方法,它接收一个谓词集合和isAdjective标志(区分动词/形容词),返回穷举后的全部活用形集合。处理单个词时,引擎会走这样一条流水线:
- 拆解末字:用
decomposeHangul把最后一个音节拆成初声、中声、终声三部分(HangulChar(onset, vowel, coda)),据此判断该词属于哪一类变位规则。 - 匹配变位规则:代码里针对不同韵尾(coda)和元音组合写了十几条
case分支,例如无韵尾的"하다"类、"ㅗ"结尾的"쏘다"类、"ㅡ"结尾的"치르다"类,以及带韵尾的"만들다"类、"낫다"类等等。 - 拼接语尾:把预置的语尾序列(如"게겠고구기…"、"다더던도든…")逐一接到词干后面,再叠加"ㅂㅆㄹㄴㅁ"等常见韵尾变化。
- 补充不规则活用:最后单独处理"르"不规则等特殊情形。
以最简单的动词"가다"为例,引擎一次性生成了约50个活用形:가、가게、가겠、가고、가구、가기、가는、가다、가더、가도、가면、가서、가세、가시、가자、가죠、가지、간、갈、감、갔……几乎覆盖了日常韩语中能见到的所有写法。
活用形穷举的规则体系:从规则活用到不规则活用
词形变化引擎的精华在于它对韩语语法的系统化编码,主要规则可以归纳如下:
| 规则类别 | 典型词干 | 生成的关键活用形 |
|---|---|---|
| "하다"特殊处理 | 하다 | 합、해、했、하여、하니、하네 |
| 无韵尾+元音 | 쏘다、맞추다、마시다 | 쏴、쐈、맞춰、맞췄、마셔、마셨 |
| "ㅡ"元音结尾 | 치르다、구르다 | 치러、치렀、치른、치를、치름 |
| "ㄹ"韵尾 | 만들다、알다 | 만들어、만들었、만드니、만드는 |
| "ㅂ"不规则(形容词) | 가볍다、아름답다 | 가벼운、가벼워、아름다운 |
| "ㅎ"不规则(形容词) | 파랗다、어떻다 | 파래、파랬、파램、어때 |
| "ㄷ"不规则 | 묻다、붇다 | 물어、물으면、불어 |
| "르"不规则 | 고르다、구르다 | 골라、골랐、골라서 |
这里有个有趣的细节:词形变化引擎连网络用语都没放过。代码里专门为"ㅋㅋㅋ"这类拟声韵尾(CODAS_SLANG_CONSONANT)做了处理,比如"잨ㅋㅋㅋ"这种推特风格文本也能被正常识别——毕竟这个项目的前身就是 twitter-korean-text。
词形变化引擎如何驱动open-korean-text词典构建
词形变化引擎不是孤立存在的,它是整个 open-korean-text 词典体系的"发动机"。在 KoreanDictionaryProvider.scala 中可以看到它的两个关键用途:
正向:构建活用形词典。加载verb/verb.txt和adjective/adjective.txt两个基础词表后,调用conjugatePredicatesToCharArraySet把每个谓词展开成完整活用形集合,分别存入 Verb(动词)和 Adjective(形容词)词典:
map.put(Verb, conjugatePredicatesToCharArraySet(readWordsAsSet("verb/verb.txt"))) map.put(Adjective, conjugatePredicatesToCharArraySet(readWordsAsSet("adjective/adjective.txt"), isAdjective = true))反向:构建词干映射。引擎还生成了predicateStems反向索引,把每个活用形映射回它的原型(如"입니다 → 이다"),这正是 open-korean-text 词干还原(stemming)功能的底层支撑——分词后能轻松把"하는"归并回"하다"。
值得一提的还有词典的维护流程。词典文本文件来自多个来源,经过 CleanupDictionaries.scala 这类工具去重、排序、清洗后,再交给词形变化引擎展开。也就是说,引擎的质量上限,取决于词典数据的纯净度。
活用形穷举的正确性保障:黄金样本测试
穷举规则写得再好,也可能漏掉某些特殊词。open-korean-text 用一套"黄金样本"机制来兜底:测试资源里维护了两个对照文件verb_conjugate.txt(3242行)和adj_conjugate.txt(2518行),每行是"谓词 + 期望的全部活用形"。
KoreanConjugationTest.scala 会逐词调用引擎生成结果,再与黄金样本逐字比对,任何新增或遗漏的活用形都会在测试中暴露。而黄金样本本身也不是手写的——CreateConjugationExamples.scala 工具负责用引擎自动生成初版样本,再由人工校对固化,形成"引擎生成 → 人工校验 → 回归测试"的闭环。
这套机制保证了:只要你对引擎规则做了任何修改,mvn test就能立刻告诉你哪些词的活用形发生了变化,防止"修好一个词、弄坏一百个词"的回归事故。
结语:词形变化引擎的价值
对新手开发者来说,open-korean-text 的词形变化引擎是一个绝佳的学习样本:它用不到300行 Scala 代码,把韩语谓词的规则活用、不规则活用、敬语、时态、网络用语全部编码进了一个可穷举、可测试的系统。理解 KoreanConjugation 的运作方式,你就掌握了韩语分词的底层逻辑——下次遇到"가깝다"突然变成"가까운",你就能立刻明白,这正是词形变化引擎在背后默默完成了穷举。
【免费下载链接】open-korean-textOpen Korean Text Processor - An Open-source Korean Text Processor项目地址: https://gitcode.com/gh_mirrors/op/open-korean-text
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考