为文言文设计的 NLP 工具包。
项目描述
甲言嘉彦
简介
甲言,取「甲骨文」之意,是词专注于古汉语处理的 NLP 工具包。
目前通用的 NLP 以现代汉语为核心分料,对古代汉语的看言处理均效果很差( ) 帮助古汉语的信息真心,是辅助古汉语处理的初代文化矿工。帮助本项目有志于藏藏的古汉语爱好者、志同道合的人有志于利用文言资料,从“作品”中出“文化新言” ”。目前词库制作、自动分词
支持、词标标点、文言版本句读和五项功能,更多功能正在开发中。
功能
- 词库制造
- 无使用的双树搜索、点互信息以及左右邻接的熵进行监督文词库制造。
- 分词
- 词性标注
- 断句
- 根据时况条件场的标注插入点信息及插入点,测试值特征,对文句段落进行自动断断续续。
- 标点
- 基于的基础上标式点对场,在断句的文字段落上自动进行的顺序标。
- 文白翻译
- 注意:受语料影响,目前不支持繁体。如需处理繁体,可先用OpenCC将输入转换为简体,再将结果转换为相应繁体(如港澳台等)。
安装
$ pip install jiayan
$ pip install https://github.com/kpu/kenlm/archive/master.zip
使用
下面各模块的使用方法均来自examples.py。
-
下载模型并解压:百度网盘,提取码:
p0sc
- jiayan.klm:语言模型,主要使用分词,以及读标点任务中的特征提取;
- pos_model:CRF词标注性模型;
- cut_model:CRF句读模型;
- punc_model:CRF标点模型;
- 庄子txt:使用全文测试词库制造的庄子。
-
词库制造
from jiayan import PMIEntropyLexiconConstructor constructor = PMIEntropyLexiconConstructor() lexicon = constructor.construct_lexicon('庄子.txt') constructor.save(lexicon, '庄子词库.csv')
结果:
Word,Frequency,PMI,R_Entropy,L_Entropy 之,2999,80,7.944909328101839,8.279435615456894 而,2089,80,7.354575005231323,8.615211168836439 不,1941,80,7.244331150611089,6.362131306822925 ... 天下,280,195.23602384978196,5.158574399464853,5.24731990592901 圣人,111,150.0620531154239,4.622606551534004,4.6853474419338585 万物,94,377.59805590304126,4.5959107835319895,4.538837960294887 天地,92,186.73504238078462,3.1492586603863617,4.894533538722486 孔子,80,176.2550051738876,4.284638190120882,2.4056390622295662 庄子,76,169.26227942514097,2.328252899085616,2.1920058354921066 仁义,58,882.3468468468468,3.501609497059026,4.96900162987599 老聃,45,2281.2228260869565,2.384853500510039,2.4331958387289765 ...
-
分词
-
字符级隐马尔可夫模型分词,效果符合语感,建议使用,需加载语言模型
jiayan.klm
from jiayan import load_lm from jiayan import CharHMMTokenizer text = '是故内圣外王之道,暗而不明,郁而不发,天下之人各为其所欲焉以自为方。' lm = load_lm('jiayan.klm') tokenizer = CharHMMTokenizer(lm) print(list(tokenizer.tokenize(text)))
结果:
['是', '故', '内圣外王', '之', '道', ',', '暗', '而', '不', '明', ',', '郁', '而', '不', '发', ',', '天下', '之', '人', '各', '为', '其', '所', '欲', '焉', '以', '自', '为', '方', '。']
古汉语的不同处理结果,我们无法通过不同的NLP工具对不同的处理结果来展示本项目的优势:
试比较LTP (3.4.0) 模型分词结果:
['是', '故内', '圣外王', '之', '道', ',', '暗而不明', ',', '郁', '而', '不', '发', ',', '天下', '之', '人', '各', '为', '其', '所', '欲', '焉以自为方', '。']
再试比较HanLP分词结果:
['是故', '内', '圣', '外', '王之道', ',', '暗', '而', '不明', ',', '郁', '而', '不', '发', ',', '天下', '之', '人', '各为其所欲焉', '以', '自为', '方', '。']
可见本工具对汉语的分词效果明确通用通用汉语 NLP 工具。
-
基本字词最大路径为粗分词,以颗粒度为较粗的单位
from jiayan import WordNgramTokenizer text = '是故内圣外王之道,暗而不明,郁而不发,天下之人各为其所欲焉以自为方。' tokenizer = WordNgramTokenizer() print(list(tokenizer.tokenize(text)))
结果:
['是', '故', '内', '圣', '外', '王', '之', '道', ',', '暗', '而', '不', '明', ',', '郁', '而', '不', '发', ',', '天下', '之', '人', '各', '为', '其', '所', '欲', '焉', '以', '自', '为', '方', '。']
-
-
词性标注
from jiayan import CRFPOSTagger words = ['天下', '大乱', ',', '贤圣', '不', '明', ',', '道德', '不', '一', ',', '天下', '多', '得', '一', '察', '焉', '以', '自', '好', '。'] postagger = CRFPOSTagger() postagger.load('pos_model') print(postagger.postag(words))
结果:
['n', 'a', 'wp', 'n', 'd', 'a', 'wp', 'n', 'd', 'm', 'wp', 'n', 'a', 'u', 'm', 'v', 'r', 'p', 'r', 'a', 'wp']
-
断句
from jiayan import load_lm from jiayan import CRFSentencizer text = '天下大乱贤圣不明道德不一天下多得一察焉以自好譬如耳目皆有所明不能相通犹百家众技也皆有所长时有所用虽然不该不遍一之士也判天地之美析万物之理察古人之全寡能备于天地之美称神之容是故内圣外王之道暗而不明郁而不发天下之人各为其所欲焉以自为方悲夫百家往而不反必不合矣后世之学者不幸不见天地之纯古之大体道术将为天下裂' lm = load_lm('jiayan.klm') sentencizer = CRFSentencizer(lm) sentencizer.load('cut_model') print(sentencizer.sentencize(text))
结果:
['天下大乱', '贤圣不明', '道德不一', '天下多得一察焉以自好', '譬如耳目', '皆有所明', '不能相通', '犹百家众技也', '皆有所长', '时有所用', '虽然', '不该不遍', '一之士也', '判天地之美', '析万物之理', '察古人之全', '寡能备于天地之美', '称神之容', '是故内圣外王之道', '暗而不明', '郁而不发', '天下之人各为其所欲焉以自为方', '悲夫', '百家往而不反', '必不合矣', '后世之学者', '不幸不见天地之纯', '古之大体', '道术将为天下裂']
-
标点
from jiayan import load_lm from jiayan import CRFPunctuator text = '天下大乱贤圣不明道德不一天下多得一察焉以自好譬如耳目皆有所明不能相通犹百家众技也皆有所长时有所用虽然不该不遍一之士也判天地之美析万物之理察古人之全寡能备于天地之美称神之容是故内圣外王之道暗而不明郁而不发天下之人各为其所欲焉以自为方悲夫百家往而不反必不合矣后世之学者不幸不见天地之纯古之大体道术将为天下裂' lm = load_lm('jiayan.klm') punctuator = CRFPunctuator(lm, 'cut_model') punctuator.load('punc_model') print(punctuator.punctuate(text))
结果:
天下大乱,贤圣不明,道德不一,天下多得一察焉以自好,譬如耳目,皆有所明,不能相通,犹百家众技也,皆有所长,时有所用,虽然,不该不遍,一之士也,判天地之美,析万物之理,察古人之全,寡能备于天地之美,称神之容,是故内圣外王之道,暗而不明,郁而不发,天下之人各为其所欲焉以自为方,悲夫!百家往而不反,必不合矣,后世之学者,不幸不见天地之纯,古之大体,道术将为天下裂。
版本
- v0.0.21
- 将安装过程分为两步,确保得到最新的kenlm版本。
- v0.0.2
- 增加词性标注功能。
- v0.0.1
- 词库制造、自动分词、文句读、标点功能开放。
介绍
甲骨,即刻在甲骨上的汉字,是一款专业的文言文 Python NLP 工具。
流行的中文 NLP 工具主要针对现代中文数据进行训练,这导致在文言文上表现不佳(参见Tokenizing)。本项目的目的是协助文言文信息处理。
当前版本支持词典构建、分词、词性标注、分句和自动标点,更多功能正在开发中。
特征
- 词典建设
- 使用无监督方法,使用Trie树、PMI(逐点互信息)和左右字符的相邻熵构建词典。
- 标记化
- 使用无监督、无字典的方法使用N-gram语言模型和HMM(隐马尔可夫模型)对古典汉语句子进行标记。
- 使用词典构建产生的词典,用有向无环词图、最大概率路径和动态规划对一个古典汉语句子进行标记。
- 词性标注
- 句子分割
- 使用 CRF 进行字符级序列标记,引入 PMI 和T 检验值作为特征。
- 标点
- 使用分层 CRF 的字符级序列标记,基于句子切分结果为给定的文言文文本加标点。
- 注意:由于我们使用的数据,我们暂时不支持繁体中文。如果需要处理繁体,请使用OpenCC将繁体输入转换为简体,然后再将结果转换回来。
安装
$ pip install jiayan
$ pip install https://github.com/kpu/kenlm/archive/master.zip
用法
以下使用代码均来自examples.py。
-
下载模型并解压:Google Drive
- jiayan.klm:用于分句和标点符号化和特征提取的语言模型;
- pos_model:词性标注的CRF模型;
- cut_model:分句的CRF模型;
- punc_model:标点符号的CRF模型;
- 庄子.txt:《庄子》全文,用于测试词库构建。
-
词典建设
from jiayan import PMIEntropyLexiconConstructor constructor = PMIEntropyLexiconConstructor() lexicon = constructor.construct_lexicon('庄子.txt') constructor.save(lexicon, 'Zhuangzi_Lexicon.csv')
结果:
Word,Frequency,PMI,R_Entropy,L_Entropy 之,2999,80,7.944909328101839,8.279435615456894 而,2089,80,7.354575005231323,8.615211168836439 不,1941,80,7.244331150611089,6.362131306822925 ... 天下,280,195.23602384978196,5.158574399464853,5.24731990592901 圣人,111,150.0620531154239,4.622606551534004,4.6853474419338585 万物,94,377.59805590304126,4.5959107835319895,4.538837960294887 天地,92,186.73504238078462,3.1492586603863617,4.894533538722486 孔子,80,176.2550051738876,4.284638190120882,2.4056390622295662 庄子,76,169.26227942514097,2.328252899085616,2.1920058354921066 仁义,58,882.3468468468468,3.501609497059026,4.96900162987599 老聃,45,2281.2228260869565,2.384853500510039,2.4331958387289765 ...
-
标记化
-
推荐的基于字符的 HMM 需要语言模型:
jiayan.klm
from jiayan import load_lm from jiayan import CharHMMTokenizer text = '是故内圣外王之道,暗而不明,郁而不发,天下之人各为其所欲焉以自为方。' lm = load_lm('jiayan.klm') tokenizer = CharHMMTokenizer(lm) print(list(tokenizer.tokenize(text)))
结果:
['是', '故', '内圣外王', '之', '道', ',', '暗', '而', '不', '明', ',', '郁', '而', '不', '发', ',', '天下', '之', '人', '各', '为', '其', '所', '欲', '焉', '以', '自', '为', '方', '。']
由于文言文没有公开的分词数据,因此很难直接进行性能评估;但是,我们可以将结果与其他流行的现代中文 NLP 工具进行比较来检查性能:
比较LTP (3.4.0) 的分词结果:
['是', '故内', '圣外王', '之', '道', ',', '暗而不明', ',', '郁', '而', '不', '发', ',', '天下', '之', '人', '各', '为', '其', '所', '欲', '焉以自为方', '。']
另外,比较HanLP的分词结果:
['是故', '内', '圣', '外', '王之道', ',', '暗', '而', '不明', ',', '郁', '而', '不', '发', ',', '天下', '之', '人', '各为其所欲焉', '以', '自为', '方', '。']
很明显,佳言比一般的中文 NLP 工具具有更好的标记性能。
-
基于单词的最大概率路径方法标记化
from jiayan import WordNgramTokenizer text = '是故内圣外王之道,暗而不明,郁而不发,天下之人各为其所欲焉以自为方。' tokenizer = WordNgramTokenizer() print(list(tokenizer.tokenize(text)))
结果:
['是', '故', '内', '圣', '外', '王', '之', '道', ',', '暗', '而', '不', '明', ',', '郁', '而', '不', '发', ',', '天下', '之', '人', '各', '为', '其', '所', '欲', '焉', '以', '自', '为', '方', '。']
-
-
词性标注
from jiayan import CRFPOSTagger words = ['天下', '大乱', ',', '贤圣', '不', '明', ',', '道德', '不', '一', ',', '天下', '多', '得', '一', '察', '焉', '以', '自', '好', '。'] postagger = CRFPOSTagger() postagger.load('pos_model') print(postagger.postag(words))
结果:
['n', 'a', 'wp', 'n', 'd', 'a', 'wp', 'n', 'd', 'm', 'wp', 'n', 'a', 'u', 'm', 'v', 'r', 'p', 'r', 'a', 'wp']
-
句子分割
from jiayan import load_lm from jiayan import CRFSentencizer text = '天下大乱贤圣不明道德不一天下多得一察焉以自好譬如耳目皆有所明不能相通犹百家众技也皆有所长时有所用虽然不该不遍一之士也判天地之美析万物之理察古人之全寡能备于天地之美称神之容是故内圣外王之道暗而不明郁而不发天下之人各为其所欲焉以自为方悲夫百家往而不反必不合矣后世之学者不幸不见天地之纯古之大体道术将为天下裂' lm = load_lm('jiayan.klm') sentencizer = CRFSentencizer(lm) sentencizer.load('cut_model') print(sentencizer.sentencize(text))
结果:
['天下大乱', '贤圣不明', '道德不一', '天下多得一察焉以自好', '譬如耳目', '皆有所明', '不能相通', '犹百家众技也', '皆有所长', '时有所用', '虽然', '不该不遍', '一之士也', '判天地之美', '析万物之理', '察古人之全', '寡能备于天地之美', '称神之容', '是故内圣外王之道', '暗而不明', '郁而不发', '天下之人各为其所欲焉以自为方', '悲夫', '百家往而不反', '必不合矣', '后世之学者', '不幸不见天地之纯', '古之大体', '道术将为天下裂']
-
标点
from jiayan import load_lm from jiayan import CRFPunctuator text = '天下大乱贤圣不明道德不一天下多得一察焉以自好譬如耳目皆有所明不能相通犹百家众技也皆有所长时有所用虽然不该不遍一之士也判天地之美析万物之理察古人之全寡能备于天地之美称神之容是故内圣外王之道暗而不明郁而不发天下之人各为其所欲焉以自为方悲夫百家往而不反必不合矣后世之学者不幸不见天地之纯古之大体道术将为天下裂' lm = load_lm('jiayan.klm') punctuator = CRFPunctuator(lm, 'cut_model') punctuator.load('punc_model') print(punctuator.punctuate(text))
结果:
天下大乱,贤圣不明,道德不一,天下多得一察焉以自好,譬如耳目,皆有所明,不能相通,犹百家众技也,皆有所长,时有所用,虽然,不该不遍,一之士也,判天地之美,析万物之理,察古人之全,寡能备于天地之美,称神之容,是故内圣外王之道,暗而不明,郁而不发,天下之人各为其所欲焉以自为方,悲夫!百家往而不反,必不合矣,后世之学者,不幸不见天地之纯,古之大体,道术将为天下裂。
版本
- v0.0.21
- 将安装分为两步,确保获得最新版本的kenlm。
- v0.0.2
- POS标记功能已打开。
- v0.0.1
- 添加词典构建、标记化、句子分割和自动标点符号的功能。