为Elasticsearch开发的新型中文形态分析器” Sudachi”
太长不看(简称TL;DR)
-
- Kuromojiに代わる新しい形態素解析器「Sudachi」
-
- なにが良いの?
最新の辞書
企業(ワークスアプリケーションズ)による継続的な更新
複数の分割単位 → 検索用途での再現率と適合率の向上
プラグインによる拡張
省メモリ
Elasticsearchで使いたい
プラグイン: WorksApplications/elasticsearch-sudachi
使い方は当記事の後半をご覧ください
请注意:本文的作者参与了Sudachi的开发。
各种各样的形态素分析器
形態素解析是自然语言处理(Natural Language Processing, NLP)中的基础技术。世界上存在着各种形態素解析器,有些是可供购买的,但也有一些是公开的。举例来说,JUMAN++是利用JUMAN和RNNLM开发的,还有ChaSen(也叫Champion-Segmenter)和它的后继者MeCab,目前是最著名的形態素解析器。还有可以通过点估计从部分注释数据中进行学习的KyTea,kuromoji在Elasticsearch中有官方支持,还有使用纯Go/JavaScript/Python实现并带有词典的kagome/kuromoji.js/Janome等解析器。除了软件形式,还有通过Web API提供的形態素解析器(例如Yahoo! JAPAN文本分析Web API)。因为有各种不同的解析器,所以也有一些库(如JapaneseTokenizers)可以集合多个解析器一起使用。
除此之外还有其他一些跟所谓的分词解析的定义稍有出入的工具,比如基于JavaScript实现的Rakuten MA(分词+词性标注)、同样由JavaScript开发的简洁分词工具TinySegmenter,以及最近基于神经网络方法的自然语言处理分词工具SentencePiece等。此外,还有一个特别值得一提的项目是雪だるま,它致力于根本改进以往的分词解析,可以说是一个高度理念驱动的日本语言解析系统项目。
大多数情况下,形态素解析都需要使用字典以及经过注释的训练数据或已训练的模型。作为语言资源,Unidic辞典/BCCWJ语料库、IPA辞典/语料库、Juman辞典/京都语料库、NAIST JDic等是主要的资源。由于这些资源不经常更新,因此许多人也会同时使用从网络文本中收集和记录新词的NEologd。
2018年3月,将在举办第24届年度自然语言处理学会(NLP2018)年会,其中有一个题为“形态分析的现在与未来”的研讨会将于近期举行,预计会有热烈的讨论。此外,据悉近日将出版一本由工藤拓先生撰写的完全关于形态分析的疯狂之作,他也是MeCab和SentencePiece的作者。可以说,形态分析如今为何如此火热。
…还有一种叫做「Sudachi」的形态素解析器。
在这些中,2017年诞生了一个名为”Sudachi”的全新解析器。在已经存在各种工具的情况下,它宣称是一个适用于商业用途、更高品质和使用便利的词法分析器。
開発活動主要在株式会社ワークスアプリケーションズ旗下的ワークス徳島人工智能NLP研究所进行。在企业的支持下,将代码和语言资源作为开源软件对外公开。许可证为Apache-2.0。
首先,Sudachi的特點之一是提供最新的詞典。現有的形態素解析器詞典已經停止更新超過10年,新詞和專有名詞也不足。然而,Sudachi則是基於UniDic和NEologd進行調整,提供了由專家調整的高品質且大規模的資源,並計劃在未來10年持續進行更新。
在其他方面,Sudachi还具有以多个分割单元输出的功能。通常情况下,形态分析器只能以一个单元进行输出,但是Sudachi可以以A、B、C三个单元进行输出。这是通过向Sudachi的系统词典添加分割信息来实现的。
当输入为“医药品安全管理负责人”时,可能有以下3种输出选项。
A: 医薬 / 品 / 安全 / 管理 / 責任 / 者
B: 医薬品 / 安全 / 管理 / 責任者
C: 医薬品安全管理責任者
在传统的形态素分析器中,只能按照A或B这样的单位进行分割,但是Sudachi还可以将特定表达作为具有意义的语言单位进行判别,比如C。
通过同时使用短单位和长单位,可以提高在搜索用途中的召回率和精确率(在后面提到的Elasticseach插件的搜索模式中,将使用A单位和C单位同时)。
除了分割信息外,Sudachi的系统词典还包括以下拼写规范化。
-
- 送り違い
打込む → 打ち込む
字種
かつ丼 → カツ丼
異体字
附属 → 付属
誤用
シュミレーション → シミュレーション
縮約
ちゃあ → ては
这是一个高品质的系统词典,用户可以自行准备多个用户词典来进行扩展。
此外,您还可以通过插件进行功能扩展。您可以将通常在解析器外进行的正规化和校正等常见处理过程包含进来。以下是一些插件的类型,其中一些已经作为系统提供的插件存在,并且其他插件目前也正在开发中。
-
- 入力テキスト: 異体字統制、長音記号正規化、など
-
- 未知語: 1文字未知語ノードの作成、MeCab互換処理、など
-
- 単語の連接: 品詞接続禁制、コスト値の書き換え、など
- 出力解補正: 敬称や前後関係から人名部を推定、漢数詞や位取りの正規化、など
当然,您也可以自己编写插件并插入。例如,您可以进行自定义的未知词处理,或根据目标数据提取产品编号和型号等。
此外,通过使用内存映射来实现多个JVM之间的字典共享,从而实现了内存的节省。有关实现细节,请参阅《JJUG CCC 2017秋季大会》上的演讲。
和MeCab、Kuromoji相比,可以得出以下结论。
-
- ^1: n-best解による近似
- ^2: Lucene フィルター併用
尽管发布时间还不久,但SyncThought先生已经有一些应用实例了。
从这里开始,我们将在各个方面加强形态分析器,包括创建各种插件、提高速度和分析精度、与同义词词典的协作、扩展分割信息和规范化表示、改善阅读信息,提升用户词典的易用性等等。同时,我们还在开发Python实现(名为SudachiPy),它将简单易用,方便数据分析等用途。我们计划使其能够轻松安装和使用。
请参阅以下资料,以了解有关Sudachi的说明。
形態素解析の話 by 高岡一馬 @ NLPエンジニアによる自然言語処理の実用化にむけた勉強会, 2017/6/22
Javaでつくる本格形態素解析器 by 高岡一馬 @ JJUG CCC 2017 Fall, 2017/11/18
请从这里获取各种源代码。
WorksApplications/Sudachi – 本家Java版
WorksApplications/elasticsearch-sudachi – Elasticsearch用プラグイン
WorksApplications/SudachiPy – Python版(開発中)
Elasticsearch 的切分工具:Sudachi
让我们实际操作一下,在Elasticsearch中运行Sudachi!
以下是此次验证环境的简述。
-
- Elasticsearch 5.6.1
-
- Ubuntu 17.10
- Java 1.8.0_151
由于环境和代码的整备,以前在Qiita上写的关于在Elasticsearch中使用Sudachi的步骤#1已经发生了重大变化。
获取和构建插件
Sudachi插件适用于Elasticsearch,可以在WorksApplications/elasticsearch-sudachi中找到。
这个插件的pom.xml文件中指定了Elasticsearch的版本为5.6.1,本次验证中我们也匹配了相同的版本。如果是5.6.x版本,只需要把这部分修改一致即可正常运行。针对6.x版本的支持目前正在进行中,请稍等片刻。
2018-01-09 补充:@matsuda_vla 先生已经写了在6系上运行的步骤。
在Elasticsearch6.1.1上使用Sudachi的步骤(非官方)- Qiita
首先,拿出源代码,进行构建。
$ git clone https://github.com/WorksApplications/elasticsearch-sudachi.git
$ cd elasticsearch-sudachi
$ mvn package
当构建成功后,将在elasticsearch-sudachi/target/releases/目录下生成一个名为analysis-sudachi-1.0.0-SNAPSHOT.zip的文件。
自己构建的替代方案是从快照版本库中下载(2017-12-19注:感谢Kengo Toda指出)。
安装插件
然后,你需要安装已经构建好的文件。你可以使用Elasticsearch提供的elasticsearch-plugin脚本来完成。在install命令中,请指定刚刚构建的文件路径。
安装完成后,如果list命令的结果包含了analysis-sudachi,那就表示成功。
$ sudo /usr/share/elasticsearch/bin/elasticsearch-plugin install file:///path/to/builded/file/analysis-sudachi-1.0.0-SNAPSHOT.zip
$ /usr/share/elasticsearch/bin/elasticsearch-plugin list
analysis-sudachi
获取和安装字典
除了安装之外,还需要做另外一项准备工作,即将字典文件放置在适当的位置。您可以从以下网址下载字典文件。
索引 /repositories/snapshots/com/worksap/nlp/sudachi/0.1.1-SNAPSHOT
请从这里获取最新版本的dictionary_core或dictionary_full。
dictionary_core: 専門家による語彙の追加や調整がなされた高品質な辞書。UniDicをベースに、会社名、住所、駅名、人名などが追加されている。語彙数150万程度
dictionary_full: dictionary_coreへ語彙をさらに追加した上位集合。語彙数300万弱程度
$ wget https://oss.sonatype.org/content/repositories/snapshots/com/worksap/nlp/sudachi/0.1.1-SNAPSHOT/sudachi-0.1.1-20171208.130044-8-dictionary-core.tar.bz2
$ tar xf sudachi-0.1.1-20171208.130044-8-dictionary-core.tar.bz2
$ ls
system_core.dic
通常,词典文件放置在$ES_HOME/sudachi/目录下。您可以通过修改后续的配置文件来将其放置在其他位置,并更改文件名称。
$ sudo mkdir /etc/elasticsearch/sudachi
$ sudo mv system_core.dic /etc/elasticsearch/sudachi
确认插件
最后,重新启动Elasticsearch,并验证插件是否已加载,如果在plugins中存在analysis-sudachi,则表示成功。
$ sudo /etc/init.d/elasticsearch restart
$ curl -X GET 'http://localhost:9200/_nodes/plugins?pretty'
...
"plugins" : [
{
"name" : "analysis-sudachi",
"version" : "1.0.0-SNAPSHOT",
"description" : "The Japanese (Sudachi) Analysis plugin integrates Lucene Sudachi analysis module into elasticsearch.",
"classname" : "com.worksap.nlp.elasticsearch.sudachi.plugin.AnalysisSudachiPlugin",
"has_native_controller" : false
}
]
...
设置用于索引的配置
现在,我们已经准备好在Elasticsearch中使用Sudachi了。接下来,我们将创建索引并实际查看解析结果。
首先,我们准备了用于创建索引的设置。在这里,我们将以下内容写入了一个名为analysis_sudachi_settings.json的文件中。
tokenizer
sudachi_tokenizer を指定
mode
normal, search, extended から指定。デフォルトはsearch
normal: 通常の分割
search: A単位とC単位
extended: searchに加えて未知語のユニグラム
discard_punctuation
句読点を除くか。デフォルトはtrue
settings_path: Sudachiの設定ファイルのパス
指定がなければ、Sudachiに同梱されている sudachi.json を利用
この設定ファイルで辞書ファイル名などを指定
デフォルトでは辞書ファイル名(systemDict)はsystem_core.dicとなっている
system_full.dicを利用したり、異なる名前の辞書ファイルを利用する際には、上のsudachi.jsonを書き換えたような設定ファイルを用意し、このsettings_pathで指定
相対パスの場合、後述のresources_pathからの相対
基本的に$ES_HOME以下でないとNG
resources_path: 辞書ファイルのあるディレクトリのパス
指定がなければ、$ES_HOME/sudachi/
基本的に$ES_HOME以下でないとNG
{
"settings": {
"index": {
"analysis": {
"tokenizer": {
"sudachi_tokenizer": {
"type": "sudachi_tokenizer",
"mode": "search",
"discard_punctuation": true,
"resources_path": "/etc/elasticsearch/sudachi",
"settings_path": "/etc/elasticsearch/sudachi/sudachi.json"
}
},
"analyzer": {
"sudachi_analyzer": {
"filter": [
],
"tokenizer": "sudachi_tokenizer",
"type": "custom"
}
}
}
}
}
}
创建索引
我们将使用写有此设置的analysis_sudachi_settings.json来创建索引。让我们用名称sudachi_test创建它。
$ curl -X PUT 'http://localhost:9200/sudachi_test/' -d @analysis_sudachi_settings.json
{"acknowledged":true,"shards_acknowledged":true,"index":"sudachi_test"}
让我们来检查一下所创建的索引是否设置正确。
$ curl -X GET 'http://localhost:9200/sudachi_test/?pretty'
{
"sudachi_test" : {
"aliases" : { },
"mappings" : { },
"settings" : {
"index" : {
"number_of_shards" : "5",
"provided_name" : "sudachi_test",
"creation_date" : "1512992783788",
"analysis" : {
"analyzer" : {
"sudachi_analyzer" : {
"type" : "custom",
"tokenizer" : "sudachi_tokenizer"
}
},
"tokenizer" : {
"sudachi_tokenizer" : {
"mode" : "search",
"resources_path" : "/etc/elasticsearch",
"type" : "sudachi_tokenizer",
"discard_punctuation" : "true"
}
}
},
"number_of_replicas" : "1",
"uuid" : "DBqj21t7STS8ZE2gM32MXw",
"version" : {
"created" : "5060199"
}
}
}
}
}
使用Sudachi插件进行分析。
我们已经完成了Sudachi插件的安装。让我们看看它实际上是如何被分析的。
在以下的例子中,我们传入了文本“东京都知事选举”,可以确认输出了多个分割单元(一个是“东京都知事选举”这个整体,一个是“东京/都/知事/选举”这几个部分)。这是使用search模式和system_full词典得出的结果。通过更改分割模式、更改词典或添加下述的过滤器,结果也会有所不同。
$ curl -X GET 'http://localhost:9200/sudachi_test/_analyze?analyzer=sudachi_analyzer&pretty' -d "東京都知事選挙"
{
"tokens" : [
{
"token" : "東京都知事選挙",
"start_offset" : 0,
"end_offset" : 7,
"type" : "word",
"position" : 0,
"positionLength" : 4
},
{
"token" : "東京",
"start_offset" : 0,
"end_offset" : 2,
"type" : "word",
"position" : 0
},
{
"token" : "都",
"start_offset" : 2,
"end_offset" : 3,
"type" : "word",
"position" : 1
},
{
"token" : "知事",
"start_offset" : 3,
"end_offset" : 5,
"type" : "word",
"position" : 2
},
{
"token" : "選挙",
"start_offset" : 5,
"end_offset" : 7,
"type" : "word",
"position" : 3
}
]
}
各种不同的过滤器
除了使用新鮮的Sudachi上述之外,還可以根據使用情境應用各種不同的濾鏡。以下是提供的濾鏡選項。
sudachi_part_of_speech
設定に書かれた品詞のトークンを除外
デフォルト設定は stoptags.txt
sudachi_ja_stop
日本語のストップワードを除外
stopwords.txt でストップワードの一覧を確認可能
sudachi_baseform
動詞と形容詞の終止形化
例: 飲み → 飲む
sudachi_readingform
カタカナ、もしくはローマ字の読みに変換
例1: 寿司 → スシ
例2: 寿司 → sushi
这些过滤器基本上是以与Kuromoji几乎兼容的方式创建的。在许多情况下,仅需将kuromoji替换为sudachi即可正常运行。有关更详细的设置方法和用法示例,请参阅README中的“对应过滤器”部分。
结尾处
我们介绍了分词器”Sudachi”以及其在Elasticsearch中的使用。
我认为Sudachi的各种特点,如精心设计的短单位和长单位、语义和文字的表达控制,以及通过插件可以灵活扩展等,可以为Elasticsearch的应用提供重要的优势。
我们将进一步加强Sudachi,但仍然缺乏知识、使用例和文档。如果您在使用过程中有任何疑问、意见或可疑行为,请务必提交GitHub的Issue,我们将不胜感激!
顺便说一下,我明天也会从德岛赶到东京参加 Elastic{ON} Tokyo 2017。我会穿着德岛县的吉祥物“酸橙君”的衬衫,带着名产“酸橙派”,如果看到我,请务必和我打声招呼!
明天12/14的《Elastic stack Advent Calendar 2017》是由ZooBonta先生撰写的有关Logstash的文章!
(补充)Sudachi 官方 Slack
我们为开发人员和用户准备了一个Slack工作空间,以便他们可以进行提问和讨论。请不要犹豫,将您的问题和需求发送到这里来!