辞書ベースの日本語 Tokenizer - Kuromoji, Sudachi, Fugashi, Kagome, Lindera
辞書をベースに処理する日本語 Tokenizer のいくつかをコードを書いて実行してみました。
- (a) Lucene Kuromoji
- (b) atilika Kuromoji
- (c) Sudachi
- (d) Kuromoji.js
- (e) Fugashi
- (f) Kagome
- (g) Lindera
今回は以下の文を処理して分割された単語と品詞を出力します。
処理対象文
WebAssemblyがサーバーレス分野へ大きな影響を与えるだろうと答えた回答者は全体の56%だった。
システム辞書だけを使用し、分割モードを指定する場合は固有名詞などをそのままにする(細かく分割しない)モードを選ぶ事にします。
ソースコードは https://github.com/fits/try_samples/tree/master/blog/20220106/
(a) Lucene Kuromoji
Lucene に組み込まれた Kuromoji で Elasticsearch や Solr で使われます。
kuromoji.gradle を見ると、システム辞書は以下のどちらかを使うようになっているようです。
a1
lucene-analyzers-kuromoji の JapaneseTokenizer を使います。 辞書は IPADIC のようです。
lucene/a1.groovy
@Grab('org.apache.lucene:lucene-analyzers-kuromoji:8.11.1') import org.apache.lucene.analysis.ja.JapaneseTokenizer; import org.apache.lucene.analysis.ja.JapaneseTokenizer.Mode import org.apache.lucene.analysis.tokenattributes.CharTermAttribute import org.apache.lucene.analysis.ja.tokenattributes.PartOfSpeechAttribute def text = args[0] new JapaneseTokenizer(null, false, Mode.NORMAL).withCloseable { tokenizer -> def term = tokenizer.addAttribute(CharTermAttribute) def pos = tokenizer.addAttribute(PartOfSpeechAttribute) tokenizer.reader = new StringReader(text) tokenizer.reset() while(tokenizer.incrementToken()) { println "term=${term}, partOfSpeech=${pos.partOfSpeech}" } }
a1 結果
> groovy a1.groovy "WebAssemblyがサーバーレス分野へ大きな影響を与えるだろうと答えた回答者は全体の56%だった。" term=WebAssembly, partOfSpeech=名詞-固有名詞-組織 term=が, partOfSpeech=助詞-格助詞-一般 term=サーバー, partOfSpeech=名詞-一般 term=レス, partOfSpeech=名詞-サ変接続 term=分野, partOfSpeech=名詞-一般 term=へ, partOfSpeech=助詞-格助詞-一般 term=大きな, partOfSpeech=連体詞 term=影響, partOfSpeech=名詞-サ変接続 term=を, partOfSpeech=助詞-格助詞-一般 term=与える, partOfSpeech=動詞-自立 term=だろ, partOfSpeech=助動詞 term=う, partOfSpeech=助動詞 term=と, partOfSpeech=助詞-格助詞-引用 term=答え, partOfSpeech=動詞-自立 term=た, partOfSpeech=助動詞 term=回答, partOfSpeech=名詞-サ変接続 term=者, partOfSpeech=名詞-接尾-一般 term=は, partOfSpeech=助詞-係助詞 term=全体, partOfSpeech=名詞-副詞可能 term=の, partOfSpeech=助詞-連体化 term=5, partOfSpeech=名詞-数 term=6, partOfSpeech=名詞-数 term=%, partOfSpeech=名詞-接尾-助数詞 term=だっ, partOfSpeech=助動詞 term=た, partOfSpeech=助動詞 term=。, partOfSpeech=記号-句点
a2
org.codelibs が上記の ipadic-neologd 版を提供していたので、ついでに試してみました。
処理内容はそのままで、モジュールとパッケージ名を変えるだけです。
lucene/a2.groovy
@GrabResolver('https://maven.codelibs.org/') @Grab('org.codelibs:lucene-analyzers-kuromoji-ipadic-neologd:8.2.0-20200120') import org.apache.lucene.analysis.tokenattributes.CharTermAttribute import org.codelibs.neologd.ipadic.lucene.analysis.ja.JapaneseTokenizer import org.codelibs.neologd.ipadic.lucene.analysis.ja.JapaneseTokenizer.Mode import org.codelibs.neologd.ipadic.lucene.analysis.ja.tokenattributes.PartOfSpeechAttribute def text = args[0] new JapaneseTokenizer(null, false, Mode.NORMAL).withCloseable { tokenizer -> ・・・ }
a2 結果
> groovy a2.groovy "WebAssemblyがサーバーレス分野へ大きな影響を与えるだろうと答えた回答者は全体の56%だった。" term=WebAssembly, partOfSpeech=名詞-固有名詞-組織 term=が, partOfSpeech=助詞-格助詞-一般 term=サーバーレス, partOfSpeech=名詞-固有名詞-一般 term=分野, partOfSpeech=名詞-一般 term=へ, partOfSpeech=助詞-格助詞-一般 term=大きな, partOfSpeech=連体詞 term=影響, partOfSpeech=名詞-サ変接続 term=を, partOfSpeech=助詞-格助詞-一般 term=与える, partOfSpeech=動詞-自立 term=だろ, partOfSpeech=助動詞 term=う, partOfSpeech=助動詞 term=と, partOfSpeech=助詞-格助詞-引用 term=答え, partOfSpeech=動詞-自立 term=た, partOfSpeech=助動詞 term=回答者, partOfSpeech=名詞-固有名詞-一般 term=は, partOfSpeech=助詞-係助詞 term=全体, partOfSpeech=名詞-副詞可能 term=の, partOfSpeech=助詞-連体化 term=5, partOfSpeech=名詞-数 term=6, partOfSpeech=名詞-数 term=%, partOfSpeech=名詞-接尾-助数詞 term=だっ, partOfSpeech=助動詞 term=た, partOfSpeech=助動詞 term=。, partOfSpeech=記号-句点
a1 と違って "サーバーレス" や "回答者" となりました。
(b) atilika Kuromoji
https://github.com/atilika/kuromoji
Lucene Kuromoji のベースとなった Kuromoji。 更新は途絶えているようですが、色々な辞書に対応しています。
ここでは以下の 2種類の辞書を試してみました。
- UniDic(2.1.2)
- JUMAN(7.0-20130310)
b1
まずは、UniDic 版です。
kuromoji/b1.groovy
@Grab('com.atilika.kuromoji:kuromoji-unidic:0.9.0') import com.atilika.kuromoji.unidic.Tokenizer def text = args[0] def tokenizer = new Tokenizer() tokenizer.tokenize(args[0]).each { def pos = [ it.partOfSpeechLevel1, it.partOfSpeechLevel2, it.partOfSpeechLevel3, it.partOfSpeechLevel4 ] println "term=${it.surface}, partOfSpeech=${pos}" }
b1 結果
> groovy b1.groovy "WebAssemblyがサーバーレス分野へ大きな影響を与えるだろうと答えた回答者は全体の56%だ った。" term=WebAssembly, partOfSpeech=[名詞, 普通名詞, 一般, *] term=が, partOfSpeech=[助詞, 格助詞, *, *] term=サーバー, partOfSpeech=[名詞, 普通名詞, 一般, *] term=レス, partOfSpeech=[名詞, 普通名詞, 一般, *] term=分野, partOfSpeech=[名詞, 普通名詞, 一般, *] term=へ, partOfSpeech=[助詞, 格助詞, *, *] term=大きな, partOfSpeech=[連体詞, *, *, *] term=影響, partOfSpeech=[名詞, 普通名詞, サ変可能, *] term=を, partOfSpeech=[助詞, 格助詞, *, *] term=与える, partOfSpeech=[動詞, 一般, *, *] term=だろう, partOfSpeech=[助動詞, *, *, *] term=と, partOfSpeech=[助詞, 格助詞, *, *] term=答え, partOfSpeech=[動詞, 一般, *, *] term=た, partOfSpeech=[助動詞, *, *, *] term=回答, partOfSpeech=[名詞, 普通名詞, サ変可能, *] term=者, partOfSpeech=[接尾辞, 名詞的, 一般, *] term=は, partOfSpeech=[助詞, 係助詞, *, *] term=全体, partOfSpeech=[名詞, 普通名詞, 一般, *] term=の, partOfSpeech=[助詞, 格助詞, *, *] term=5, partOfSpeech=[名詞, 数詞, *, *] term=6, partOfSpeech=[名詞, 数詞, *, *] term=%, partOfSpeech=[名詞, 普通名詞, 助数詞可能, *] term=だっ, partOfSpeech=[助動詞, *, *, *] term=た, partOfSpeech=[助動詞, *, *, *] term=。, partOfSpeech=[補助記号, 句点, *, *]
"だろう" が分割されていないのが特徴。
b2
JUMAN 辞書版です。
kuromoji/b2.groovy
@Grab('com.atilika.kuromoji:kuromoji-jumandic:0.9.0') import com.atilika.kuromoji.jumandic.Tokenizer def text = args[0] def tokenizer = new Tokenizer() ・・・
b2 結果
> groovy b2.groovy "WebAssemblyがサーバーレス分野へ大きな影響を与えるだろうと答えた回答者は全体の56%だ った。" term=WebAssembly, partOfSpeech=[名詞, 組織名, *, *] term=が, partOfSpeech=[助詞, 格助詞, *, *] term=サーバーレス, partOfSpeech=[名詞, 人名, *, *] term=分野, partOfSpeech=[名詞, 普通名詞, *, *] term=へ, partOfSpeech=[助詞, 格助詞, *, *] term=大きな, partOfSpeech=[連体詞, *, *, *] term=影響, partOfSpeech=[名詞, サ変名詞, *, *] term=を, partOfSpeech=[助詞, 格助詞, *, *] term=与える, partOfSpeech=[動詞, *, 母音動詞, 基本形] term=だろう, partOfSpeech=[助動詞, *, 助動詞だろう型, 基本形] term=と, partOfSpeech=[助詞, 格助詞, *, *] term=答えた, partOfSpeech=[動詞, *, 母音動詞, タ形] term=回答, partOfSpeech=[名詞, サ変名詞, *, *] term=者, partOfSpeech=[接尾辞, 名詞性名詞接尾辞, *, *] term=は, partOfSpeech=[助詞, 副助詞, *, *] term=全体, partOfSpeech=[名詞, 普通名詞, *, *] term=の, partOfSpeech=[助詞, 接続助詞, *, *] term=56, partOfSpeech=[名詞, 数詞, *, *] term=%, partOfSpeech=[接尾辞, 名詞性名詞助数辞, *, *] term=だった, partOfSpeech=[判定詞, *, 判定詞, ダ列タ形] term=。, partOfSpeech=[特殊, 句点, *, *]
"サーバーレス"、"だろう"、"答えた"、"56"、"だった" が分割されていないのが特徴。 "サーバーレス" が人名となっているのは不思議。
(c) Sudachi
https://github.com/WorksApplications/Sudachi
辞書は UniDic と NEologd をベースに調整したものらしく、3種類(Small, Core, Full)用意されています。
辞書が継続的にメンテナンスされており最新のものを使えるのが魅力だと思います。
ここではデフォルトの Core 辞書を使いました。(system_core.dic ファイルをカレントディレクトリに配置して実行)
- Core 辞書(20211220 版)
また、Elasticsearch 用のプラグイン analysis-sudachi も用意されています。
sudachi/c1.groovy
@Grab('com.worksap.nlp:sudachi:0.5.3') import com.worksap.nlp.sudachi.DictionaryFactory import com.worksap.nlp.sudachi.Tokenizer def text = args[0] new DictionaryFactory().create().withCloseable { dic -> def tokenizer = dic.create() def ts = tokenizer.tokenize(Tokenizer.SplitMode.C, text) ts.each { t -> def pos = dic.getPartOfSpeechString(t.partOfSpeechId()) println "term=${t.surface()}, partOfSpeech=${pos}" } }
c1 結果
> groovy c1.groovy "WebAssemblyがサーバーレス分野へ大きな影響を与えるだろうと答えた回答者は全体の56%だっ た。" term=WebAssembly, partOfSpeech=[名詞, 普通名詞, 一般, *, *, *] term=が, partOfSpeech=[助詞, 格助詞, *, *, *, *] term=サーバーレス, partOfSpeech=[名詞, 普通名詞, 一般, *, *, *] term=分野, partOfSpeech=[名詞, 普通名詞, 一般, *, *, *] term=へ, partOfSpeech=[助詞, 格助詞, *, *, *, *] term=大きな, partOfSpeech=[連体詞, *, *, *, *, *] term=影響, partOfSpeech=[名詞, 普通名詞, サ変可能, *, *, *] term=を, partOfSpeech=[助詞, 格助詞, *, *, *, *] term=与える, partOfSpeech=[動詞, 一般, *, *, 下一段-ア行, 終止形-一般] term=だろう, partOfSpeech=[助動詞, *, *, *, 助動詞-ダ, 意志推量形] term=と, partOfSpeech=[助詞, 格助詞, *, *, *, *] term=答え, partOfSpeech=[動詞, 一般, *, *, 下一段-ア行, 連用形-一般] term=た, partOfSpeech=[助動詞, *, *, *, 助動詞-タ, 連体形-一般] term=回答者, partOfSpeech=[名詞, 普通名詞, 一般, *, *, *] term=は, partOfSpeech=[助詞, 係助詞, *, *, *, *] term=全体, partOfSpeech=[名詞, 普通名詞, 一般, *, *, *] term=の, partOfSpeech=[助詞, 格助詞, *, *, *, *] term=56, partOfSpeech=[名詞, 数詞, *, *, *, *] term=%, partOfSpeech=[名詞, 普通名詞, 助数詞可能, *, *, *] term=だっ, partOfSpeech=[助動詞, *, *, *, 助動詞-ダ, 連用形-促音便] term=た, partOfSpeech=[助動詞, *, *, *, 助動詞-タ, 終止形-一般] term=。, partOfSpeech=[補助記号, 句点, *, *, *, *]
"サーバーレス"、"だろう"、"回答者"、"56" となっているのが特徴。
(d) Kuromoji.js
https://github.com/takuyaa/kuromoji.js/
Kuromoji の JavaScript 実装。
kuromoji.js/d1.mjs
import kuromoji from 'kuromoji' const dicPath = 'node_modules/kuromoji/dict' const text = process.argv[2] kuromoji.builder({ dicPath }).build((err, tokenizer) => { if (err) { console.error(err) return } const ts = tokenizer.tokenize(text) for (const t of ts) { const pos = [t.pos, t.pos_detail_1, t.pos_detail_2, t.pos_detail_3] console.log(`term=${t.surface_form}, partOfSpeech=${pos}`) } })
d1 結果
> node d1.mjs "WebAssemblyがサーバーレス分野へ大きな影響を与えるだろうと答えた回答者は全体の56%だった。" term=WebAssembly, partOfSpeech=名詞,固有名詞,組織,* term=が, partOfSpeech=助詞,格助詞,一般,* term=サーバー, partOfSpeech=名詞,一般,*,* term=レス, partOfSpeech=名詞,サ変接続,*,* term=分野, partOfSpeech=名詞,一般,*,* term=へ, partOfSpeech=助詞,格助詞,一般,* term=大きな, partOfSpeech=連体詞,*,*,* term=影響, partOfSpeech=名詞,サ変接続,*,* term=を, partOfSpeech=助詞,格助詞,一般,* term=与える, partOfSpeech=動詞,自立,*,* term=だろ, partOfSpeech=助動詞,*,*,* term=う, partOfSpeech=助動詞,*,*,* term=と, partOfSpeech=助詞,格助詞,引用,* term=答え, partOfSpeech=動詞,自立,*,* term=た, partOfSpeech=助動詞,*,*,* term=回答, partOfSpeech=名詞,サ変接続,*,* term=者, partOfSpeech=名詞,接尾,一般,* term=は, partOfSpeech=助詞,係助詞,*,* term=全体, partOfSpeech=名詞,副詞可能,*,* term=の, partOfSpeech=助詞,連体化,*,* term=5, partOfSpeech=名詞,数,*,* term=6, partOfSpeech=名詞,数,*,* term=%, partOfSpeech=名詞,接尾,助数詞,* term=だっ, partOfSpeech=助動詞,*,*,* term=た, partOfSpeech=助動詞,*,*,* term=。, partOfSpeech=記号,句点,*,*
a1 と同じ結果になりました。
(e) Fugashi
https://github.com/polm/fugashi
辞書として unidic-lite と unidic のパッケージが用意されていましたが、 ここでは JUMAN 辞書を使いました。
- JUMAN
fugashi/e1.py
from fugashi import GenericTagger import sys text = sys.argv[1] tagger = GenericTagger() for t in tagger(text): pos = t.feature[0:4] print(f"term={t.surface}, partOfSpeech={pos}")
e1 結果
> python e1.py "WebAssemblyがサーバーレス分野へ大きな影響を与えるだろうと答えた回答者は全体の56%だった。" term=WebAssembly, partOfSpeech=('名詞', '組織名', '*', '*') term=が, partOfSpeech=('助詞', '格助詞', '*', '*') term=サーバーレス, partOfSpeech=('名詞', '人名', '*', '*') term=分野, partOfSpeech=('名詞', '普通名詞', '*', '*') term=へ, partOfSpeech=('助詞', '格助詞', '*', '*') term=大きな, partOfSpeech=('連体詞', '*', '*', '*') term=影響, partOfSpeech=('名詞', 'サ変名詞', '*', '*') term=を, partOfSpeech=('助詞', '格助詞', '*', '*') term=与える, partOfSpeech=('動詞', '*', '母音動詞', '基本形') term=だろう, partOfSpeech=('助動詞', '*', '助動詞だろう型', '基本形') term=と, partOfSpeech=('助詞', '格助詞', '*', '*') term=答えた, partOfSpeech=('動詞', '*', '母音動詞', 'タ形') term=回答, partOfSpeech=('名詞', 'サ変名詞', '*', '*') term=者, partOfSpeech=('接尾辞', '名詞性名詞接尾辞', '*', '*') term=は, partOfSpeech=('助詞', '副助詞', '*', '*') term=全体, partOfSpeech=('名詞', '普通名詞', '*', '*') term=の, partOfSpeech=('助詞', '接続助詞', '*', '*') term=56, partOfSpeech=('名詞', '数詞', '*', '*') term=%, partOfSpeech=('接尾辞', '名詞性名詞助数辞', '*', '*') term=だった, partOfSpeech=('判定詞', '*', '判定詞', 'ダ列タ形') term=。, partOfSpeech=('特殊', '句点', '*', '*')
同じ辞書を使っている b2 と同じ結果になりました。("サーバーレス" が人名なのも同じ)。
(f) Kagome
https://github.com/ikawaha/kagome
ここでは以下の辞書を使用します。
- IPADIC(mecab-ipadic-2.7.0-20070801)
- UniDic(2.1.2)
なお、Tokenize
を呼び出した場合は、分割モードとして Normal
が適用されるようです。
f1
IPADIC 版
kagome/f1.go
package main import ( "fmt" "os" "github.com/ikawaha/kagome-dict/ipa" "github.com/ikawaha/kagome/v2/tokenizer" ) func main() { text := os.Args[1] t, err := tokenizer.New(ipa.Dict(), tokenizer.OmitBosEos()) if err != nil { panic(err) } // 分割モード Normal ts := t.Tokenize(text) for _, t := range ts { fmt.Printf("term=%s, partOfSpeech=%v\n", t.Surface, t.POS()) } }
f1 結果
> go run f1.go "WebAssemblyがサーバーレス分野へ大きな影響を与えるだろうと答えた回答者は全体の56%だった。" term=WebAssembly, partOfSpeech=[名詞 固有名詞 組織 *] term=が, partOfSpeech=[助詞 格助詞 一般 *] term=サーバー, partOfSpeech=[名詞 一般 * *] term=レス, partOfSpeech=[名詞 サ変接続 * *] term=分野, partOfSpeech=[名詞 一般 * *] term=へ, partOfSpeech=[助詞 格助詞 一般 *] term=大きな, partOfSpeech=[連体詞 * * *] term=影響, partOfSpeech=[名詞 サ変接続 * *] term=を, partOfSpeech=[助詞 格助詞 一般 *] term=与える, partOfSpeech=[動詞 自立 * *] term=だろ, partOfSpeech=[助動詞 * * *] term=う, partOfSpeech=[助動詞 * * *] term=と, partOfSpeech=[助詞 格助詞 引用 *] term=答え, partOfSpeech=[動詞 自立 * *] term=た, partOfSpeech=[助動詞 * * *] term=回答, partOfSpeech=[名詞 サ変接続 * *] term=者, partOfSpeech=[名詞 接尾 一般 *] term=は, partOfSpeech=[助詞 係助詞 * *] term=全体, partOfSpeech=[名詞 副詞可能 * *] term=の, partOfSpeech=[助詞 連体化 * *] term=5, partOfSpeech=[名詞 数 * *] term=6, partOfSpeech=[名詞 数 * *] term=%, partOfSpeech=[名詞 接尾 助数詞 *] term=だっ, partOfSpeech=[助動詞 * * *] term=た, partOfSpeech=[助動詞 * * *] term=。, partOfSpeech=[記号 句点 * *]
同じ辞書を使っている a1 と同じ結果になりました。
f2
UniDic 版
kagome/f2.go
package main import ( "fmt" "os" "github.com/ikawaha/kagome-dict/uni" "github.com/ikawaha/kagome/v2/tokenizer" ) func main() { text := os.Args[1] t, err := tokenizer.New(uni.Dict(), tokenizer.OmitBosEos()) ・・・ }
f2 結果
> go run f2.go "WebAssemblyがサーバーレス分野へ大きな影響を与えるだろうと答えた回答者は全体の56%だった。" term=WebAssembly, partOfSpeech=[名詞 普通名詞 一般 *] term=が, partOfSpeech=[助詞 格助詞 * *] term=サーバー, partOfSpeech=[名詞 普通名詞 一般 *] term=レス, partOfSpeech=[名詞 普通名詞 一般 *] term=分野, partOfSpeech=[名詞 普通名詞 一般 *] term=へ, partOfSpeech=[助詞 格助詞 * *] term=大きな, partOfSpeech=[連体詞 * * *] term=影響, partOfSpeech=[名詞 普通名詞 サ変可能 *] term=を, partOfSpeech=[助詞 格助詞 * *] term=与える, partOfSpeech=[動詞 一般 * *] term=だろう, partOfSpeech=[助動詞 * * *] term=と, partOfSpeech=[助詞 格助詞 * *] term=答え, partOfSpeech=[動詞 一般 * *] term=た, partOfSpeech=[助動詞 * * *] term=回答, partOfSpeech=[名詞 普通名詞 サ変可能 *] term=者, partOfSpeech=[接尾辞 名詞的 一般 *] term=は, partOfSpeech=[助詞 係助詞 * *] term=全体, partOfSpeech=[名詞 普通名詞 一般 *] term=の, partOfSpeech=[助詞 格助詞 * *] term=5, partOfSpeech=[名詞 数詞 * *] term=6, partOfSpeech=[名詞 数詞 * *] term=%, partOfSpeech=[名詞 普通名詞 助数詞可能 *] term=だっ, partOfSpeech=[助動詞 * * *] term=た, partOfSpeech=[助動詞 * * *] term=。, partOfSpeech=[補助記号 句点 * *]
同じ辞書を使っている b1 と同じ結果になりました。
(g) Lindera
https://github.com/lindera-morphology/lindera
kuromoji-rs のフォークのようで、辞書は IPADIC です。
- IPADIC(mecab-ipadic-2.7.0-20070801)
lindera/src/main.rs
use lindera::tokenizer::Tokenizer; use lindera_core::LinderaResult; use std::env; fn main() -> LinderaResult<()> { let text = env::args().nth(1).unwrap_or("".to_string()); let mut tokenizer = Tokenizer::new()?; let ts = tokenizer.tokenize(&text)?; for t in ts { let pos = t.detail.get(0..4).unwrap_or(&t.detail); println!("text={}, partOfSpeech={:?}", t.text, pos); } Ok(()) }
結果
> cargo run "WebAssemblyがサーバーレス分野へ大きな影響を与えるだろうと答えた回答者は全体の56%だった。" ・・・ text=WebAssembly, partOfSpeech=["UNK"] text=が, partOfSpeech=["助詞", "格助詞", "一般", "*"] text=サーバー, partOfSpeech=["名詞", "一般", "*", "*"] text=レス, partOfSpeech=["名詞", "サ変接続", "*", "*"] text=分野, partOfSpeech=["名詞", "一般", "*", "*"] text=へ, partOfSpeech=["助詞", "格助詞", "一般", "*"] text=大きな, partOfSpeech=["連体詞", "*", "*", "*"] text=影響, partOfSpeech=["名詞", "サ変接続", "*", "*"] text=を, partOfSpeech=["助詞", "格助詞", "一般", "*"] text=与える, partOfSpeech=["動詞", "自立", "*", "*"] text=だろ, partOfSpeech=["助動詞", "*", "*", "*"] text=う, partOfSpeech=["助動詞", "*", "*", "*"] text=と, partOfSpeech=["助詞", "格助詞", "引用", "*"] text=答え, partOfSpeech=["動詞", "自立", "*", "*"] text=た, partOfSpeech=["助動詞", "*", "*", "*"] text=回答, partOfSpeech=["名詞", "サ変接続", "*", "*"] text=者, partOfSpeech=["名詞", "接尾", "一般", "*"] text=は, partOfSpeech=["助詞", "係助詞", "*", "*"] text=全体, partOfSpeech=["名詞", "副詞可能", "*", "*"] text=の, partOfSpeech=["助詞", "連体化", "*", "*"] text=5, partOfSpeech=["名詞", "数", "*", "*"] text=6, partOfSpeech=["名詞", "数", "*", "*"] text=%, partOfSpeech=["名詞", "接尾", "助数詞", "*"] text=だっ, partOfSpeech=["助動詞", "*", "*", "*"] text=た, partOfSpeech=["助動詞", "*", "*", "*"] text=。, partOfSpeech=["記号", "句点", "*", "*"]
a1 と概ね同じ結果となりましたが、"WebAssembly" が名詞になっていないのが特徴。