【係り受け解析の主なライブラリとデータセット編】文の構造を理解する最強ツール群
形態素解析でテキストを単語に分割できるようになりました。でも、それだけじゃ文の意味は理解できない。「誰が」「何を」「どうした」のか――そこを理解するのが係り受け解析です。
今回は実際に使える係り受け解析ツールを、コード例とともに徹底解説していきます。最後まで読めば、あなたも文の構造を可視化できるようになりますよ!
1. CaboCha - 日本語係り受け解析のスタンダード
CaboChaとは?
CaboChaは、Support Vector Machines (SVMs)に基づく日本語係り受け解析器です。SVMの分類アルゴリズムの高速化手法であるPKE(ACL 2003にて発表)を適用しています。
一言で言えば、日本語係り受け解析の定番ツール。MeCabの作者である工藤拓さんが開発したこともあり、MeCabとの連携が抜群です。
CaboChaの特徴
主な特徴:
- Support Vector Machines (SVMs)に基づく高性能な係り受け解析器
- IREX の定義による固有表現解析が可能
- 柔軟な入力形式。生文はもちろん、形態素解析済みデータ、文節区切り済みデータ、部分的に係り関係が付与されたデータからの解析が可能
- 係り受けの同定に使用する素性をユーザ側で再定義可能
- データを用意すれば、ユーザ側で学習を行うことが可能
CaboChaのインストール
CaboChaを動かすには、事前準備が必要です。
必要なもの
- MeCab (形態素解析器)
- CRF++ (条件付き確率場のライブラリ)
- CaboCha本体
インストール手順(Linux/macOS)
# 1. MeCabのインストール(形態素解析編を参照)
# 2. CRF++のインストール
wget https://taku910.github.io/crfpp/CRF++-0.58.tar.gz
tar xvzf CRF++-0.58.tar.gz
cd CRF++-0.58
./configure
make
sudo make install
# 3. CaboChaのインストール
wget https://taku910.github.io/cabocha/cabocha-0.69.tar.bz2
tar xvjf cabocha-0.69.tar.bz2
cd cabocha-0.69
./configure --with-mecab-config=`which mecab-config` --with-charset=UTF8
make
sudo make install
sudo ldconfig
# 4. Python用ラッパー
pip install cabocha-python
インストールに必要な設定で、makefileが作成される際、MeCabの文字セットと合わせるため、オプションで--with-charset=UTF8を指定します。
CaboChaの基本的な使い方
コマンドラインで試す
$ echo "太郎は花子が読んでいる本を次郎に渡した" | cabocha
太郎は---------D
花子が-D |
読んでいる-D
本を---D
次郎に-D
渡した
EOS
この出力から、各文節がどの文節にかかっているかが矢印で表示されています。例えば「太郎は」→「渡した」、「花子が」→「読んでいる」という係り受け関係が読み取れます。
Pythonから使う
import CaboCha
# CaboChaのパーサーを初期化
cabocha = CaboCha.Parser()
# 解析対象の文
text = "形態素解析の次は構文解析に挑戦!"
# 解析実行
tree = cabocha.parse(text)
# 結果を出力
print(tree.toString(CaboCha.FORMAT_TREE))
出力:
形態素解析の-D
次は-------D
構文解析に-D
挑戦!
EOS
係り受け関係を抽出する
係り受け解析された要素を係り先IDを使って関係先を出力することができます。実用的なコード例:
import CaboCha
cabocha = CaboCha.Parser()
sentence = '形態素解析の次は構文解析に挑戦しているが、苦戦を強いられている。'
tree = cabocha.parse(sentence)
chunks = [] # 解析結果格納用
text = ""
for i in range(tree.size()):
token = tree.token(i)
if token.chunk:
chunk_id = token.chunk.link # 係り先ID
text = token.surface
else:
text += token.surface
# ID内の最後の要素のタイミングで解析結果とIDを辞書に格納
if i == tree.size() - 1 or tree.token(i+1).chunk:
chunks.append({'c': text, 'to': chunk_id})
# IDが0以上だった場合係り元と係り先を出力
for chunk in chunks:
if chunk['to'] >= 0:
print(f"{chunk['c']} → {chunks[chunk['to']]['c']}")
出力:
形態素解析の → 次は
次は → 挑戦しているが、
構文解析に → 挑戦しているが、
苦戦を → 強いられている。
挑戦しているが、 → 強いられている。
これで文の構造が一目瞭然!「形態素解析の」が「次は」を修飾している、といった関係が明確になります。
CaboChaの出力フォーマット
CaboChaは複数の出力フォーマットに対応しています:
主な出力形式:
- -f 0 (tree): ツリー形式(デフォルト)
- -f 1 (lattice): 詳細情報付き形式
- -f 3 (xml): XML形式
# ラティス形式で出力
$ cabocha -f1 "太郎は花子に本を渡した"
# XML形式で出力
$ cabocha -f3 "太郎は花子に本を渡した"
用途に応じて使い分けましょう。プログラムから扱う場合はXML形式が便利です。
CaboChaのライセンスと注意点
CaboChaはフリーソフトウェアです。LGPL(Lesser GNU General Public License)、またはnew BSDライセンスに従って本ソフトウェアを使用、再配布することができます。
ただし、付属モデルには制限があります:
付属のモデルファイルは、株式会社毎日新聞社の御厚意により配布されている毎日新聞記事CD-ROM版を基に学習、作成されたものです。付属のモデルファイルは、毎日新聞データ使用許諾に関する覚書に記載の利用条件内でその使用及び、複製、改変、頒布が認められます。そのため配布しているモデルをそのままの形で使うことは、研究目的、個人利用に限られます。ご自身で用意なさったコーパスを基に、独自にモデルを学習、作成した場合は研究目的以外の利用が可能です。
商用利用する場合は、独自にモデルを学習する必要があります。
2. GiNZA - spaCyベースの最新NLPライブラリ
GiNZAとは?
GiNZAは、spaCyで使用できる日本語用の解析モデルを提供します。リクルートと国立国語研究所の共同研究成果の学習モデルです。
spaCyは、Explosion AI社が開発しているオープンソースの自然言語処理ライブラリで、製品への本格活用を想定して開発されています。2019年4月にGiNZAが登場し、spaCyを日本語で利用できるようになりました。
つまり、世界標準のNLPフレームワークspaCyで日本語が使えるようになった、ということ。これは革命的です。
GiNZAの特徴
主な特徴:
- 高度な自然言語処理をワンステップで導入完了: これまで複雑な導入作業が必要でしたが、GiNZAはワンステップでモジュールとモデルファイルの導入を完了できます
- 高速・高精度な解析処理と依存構造解析レベルの国際化に対応
- 国立国語研究所との共同研究成果の学習モデルを提供
spaCyでは訓練済みのモデルを読み込むことで多言語の自然言語処理に対応します。GiNZAを使うことで、複数の欧米言語と日本語の言語リソースを切り替えて使用することが可能となり、エンジニアは複数言語の解析を単一のライブラリで行うことができます。
GiNZAのインストール
# GiNZAと従来型モデルのインストール
pip install -U ginza ja_ginza
# Transformersベースの高精度モデル(オプション)
pip install ja_ginza_electra
# Apple Silicon (M1/M2)環境での高速化
pip install torch thinc-apple-ops
M1やM2などのMPSに対応したApple Silicon環境では、thinc-apple-opsを導入することで解析速度が向上します。
めちゃくちゃ簡単!MeCabやCaboChaのような複雑なインストール手順は不要です。
GiNZAの基本的な使い方
コマンドラインで試す
$ ginza
銀座でランチをご一緒しましょう。
このコマンドを実行すると、日本語の形態素解析が実行されます。品詞タグと依存関係ラベリングが表示されます。
出力:
# text = 銀座でランチをご一緒しましょう。
1 銀座 銀座 PROPN 名詞-固有名詞-地名-一般 _ 7 obl _ SpaceAfter=No
2 で で ADP 助詞-格助詞 _ 1 case _ SpaceAfter=No
3 ランチ ランチ NOUN 名詞-普通名詞-一般 _ 7 obj _ SpaceAfter=No
...
Pythonから使う
import spacy
# GiNZAモデルをロード
nlp = spacy.load('ja_ginza')
# 解析対象のテキスト
text = "自然言語処理は面白い技術です"
# 解析実行
doc = nlp(text)
# トークンごとに情報を表示
for token in doc:
print(f"{token.text}\t{token.pos_}\t{token.dep_}\t{token.head.text}")
出力:
自然 NOUN compound 言語
言語 NOUN compound 処理
処理 NOUN nsubj です
は ADP case 処理
面白い ADJ acl 技術
技術 NOUN ROOT 技術
です AUX cop 技術
spaCyではまずLanguageクラスを生成します。Languageクラスはテキスト文をDocクラスに変換する責務を持ちます。
GiNZAで係り受けを可視化する
spaCyには強力な可視化ツールdisplacyが付属しています:
import spacy
from spacy import displacy
nlp = spacy.load('ja_ginza')
text = "私は自然言語を勉強する"
doc = nlp(text)
# 係り受けを可視化
displacy.render(doc, style="dep", options={"compact": True}, jupyter=True)
この可視化により以下が行われていることがわかります:
- 形態素解析によりトークン(最小単位の単語)に分解し品詞タグを割り当て
- 構文解析によりトークン間の依存関係を分析し係り受けタグを割り当て
ブラウザで見ると、矢印付きの美しい図が表示されます。プレゼンや説明資料に最適!
GiNZAのモデル比較
GiNZAには複数のモデルがあります:
| モデル | 特徴 | 用途 |
|---|---|---|
| ja_ginza | 従来型CNN、高速 | 通常用途、大量テキスト処理 |
| ja_ginza_electra | Transformerベース、高精度 | 精度重視、少量テキスト |
ja_ginza_electraは、関根の拡張固有表現階層を用いた拡張固有表現抽出精度(ENE)において大幅な精度向上が得られています。
精度が必要ならelectra、速度が必要なら無印を選びましょう。
GiNZAとSudachiの連携
GiNZAは形態素解析のために内部でSudachiPy(SudachiのPython版)を使用しています。Sudachi辞書のmode(A/B/C)を切り替えることができます。
import spacy
import ginza
nlp = spacy.load("ja_ginza")
# Sudachi辞書modeをCにする(長い単位)
ginza.set_split_mode(nlp, "C")
text = "NCDC株式会社では、内製化支援も行っています。"
doc = nlp(text)
for token in doc:
print(token.text)
形態素解析のモードをAにした場合、「内製」と「化」で分割されることになりますが、モードをCにしているため、「内製化」として分割してくれます。
Universal Dependenciesとは?
spaCyで使われる品詞タグと係り受けタグは、Universal Dependencies (UD)に基づきます。UDは異なる言語間で共通化したツリーバンクを作成するプロジェクトで品詞や係り受けの関係について一貫したタグをつけるためのフレームワークになります。
「Universal Dependencies」の取組みが、2014年から全世界で始まっています。日本においても当初からUDの日本語への適用に関する研究と日本語版UDコーパス(データ)構築が同時に進められてきました。
つまり、GiNZAで学んだ知識は英語やフランス語のNLPにも応用できるということ。これは大きなメリットです。
3. KNP - 京大黒橋研の高機能解析器
KNPとは?
KNPはJUMAN辞書を使いたいとき、依存構造などを(ほどほどの速度と精度で)解析したいときに使用します。KNPは単なる係り受けだけでなく、依存関係の種類、述語項構造や照応関係まで分析してくれます。最強。
京都大学黒橋研究室で開発されている、最も高機能な日本語構文解析システムです。
KNPの特徴
- 形態素解析器JUMANと連携
- 係り受け解析
- 格解析
- 照応解析
- 述語項構造解析
CaboChaやGiNZAよりも深い解析が可能ですが、その分計算コストも高め。研究用途に最適です。
公式サイト: http://nlp.ist.i.kyoto-u.ac.jp/index.php?KNP
ライブラリ比較 - 総合評価
| 項目 | CaboCha | GiNZA | KNP |
|---|---|---|---|
| インストール難易度 | ⭐⭐ | ⭐⭐⭐⭐⭐ | ⭐⭐ |
| 処理速度 | ⭐⭐⭐⭐ | ⭐⭐⭐⭐⭐ | ⭐⭐⭐ |
| 解析精度 | ⭐⭐⭐⭐ | ⭐⭐⭐⭐ | ⭐⭐⭐⭐⭐ |
| 可視化機能 | ⭐⭐ | ⭐⭐⭐⭐⭐ | ⭐⭐ |
| 多言語対応 | ✗ | ⭐(spaCy経由) | ✗ |
| 商用利用 | △(要注意) | ⭐ | △ |
| 開発の活発さ | ⭐ | ⭐⭐⭐⭐⭐ | ⭐⭐⭐ |
| 学習曲線 | やや急 | 緩やか | 急 |
使い分けガイド
CaboChaを選ぶべき場合:
- MeCabと連携して使いたい
- SVMベースの解析が必要
- 既存のCaboChaベースのシステムがある
GiNZAを選ぶべき場合:
- 簡単にインストールしたい
- 可視化機能が欲しい
- 多言語対応したい
- モダンなPythonコードで書きたい
- 商用プロダクトに組み込みたい
KNPを選ぶべき場合:
- 最高精度が必要
- 述語項構造や照応解析が必要
- 研究用途
私のおすすめ
2025年時点では、GiNZA一択だと思います。
理由:
- インストールが圧倒的に簡単
- 商用利用に制限がない
- 開発が活発
- spaCyのエコシステムが使える
- ドキュメントが充実
CaboChaは歴史的に重要ですが、環境構築の難しさと商用利用の制約がネック。KNPは研究用途には最強ですが、プロダクションには少しオーバースペック。
データセット・コーパス
係り受け解析を学習させるためのデータセットも紹介します。
京都大学テキストコーパス
京都大学テキストコーパスをCaboCha形式の学習データに変換するツールが用意されています(tools/kc2juman.pl、tools/kcs2cabocha.pl)。
日本語係り受け解析の標準的なコーパス。新聞記事を中心に係り受け関係が人手でアノテーションされています。
UD Japanese BCCWJ
GiNZA v5の解析モデルは、UD Japanese BCCWJ r2.8の一部を使用して学習されています。これは国立国語研究所とMegagon Labsが共同開発したものです。
Universal Dependencies形式の日本語コーパス。GiNZAはこれをベースに学習されています。
実践Tips - プロダクション投入のための知識
1. パフォーマンスチューニング
GiNZAで大量テキストを処理する場合:
import spacy
nlp = spacy.load('ja_ginza')
# バッチ処理で高速化
texts = ["文章1", "文章2", "文章3", ...]
docs = nlp.pipe(texts, batch_size=50, n_process=4)
for doc in docs:
# 処理
pass
GiNZA v3.0から-p NUM_PROCESSオプションが追加されました。処理するプロセス数を指定してください。全CPUコアを使用したい場合は、ginza -p 0を実行してください。
2. カスタム辞書の追加
固有名詞を正しく認識させたい場合:
import spacy
nlp = spacy.load("ja_ginza_electra")
# ルールベースのエンティティ抽出を追加
patterns = [
{"label": "PERSON", "pattern": "おじいさん"},
{"label": "PERSON", "pattern": "おばあさん"}
]
ruler = nlp.add_pipe('entity_ruler')
ruler.add_patterns(patterns)
doc = nlp(text)
辞書登録により、システムが認識できなかった固有表現を適切に抽出できるようになります。
3. 依存関係のフィルタリング
特定の係り受け関係だけを抽出したい場合:
import spacy
nlp = spacy.load('ja_ginza')
doc = nlp("太郎は本を読んだ")
# 特定の依存関係タイプだけを抽出
for token in doc:
if token.dep_ in ['nsubj', 'obj']: # 主語と目的語のみ
print(f"{token.text} -> {token.head.text} ({token.dep_})")
まとめ - NLP連載を終えて
全4回にわたってNLPの基礎から実践まで解説してきました。
概念編で自然言語処理の全体像を掴み、形態素解析・係り受け解析のちがい編で基本的な処理の違いを理解しました。そして形態素解析編と係り受け解析編で、実際に手を動かせる実践的な知識を身につけました。
これからNLPを学ぶあなたへ
-
まずはGiNZAから始めよう
- インストールが簡単
- spaCyのエコシステムが強力
- ドキュメントが充実
-
小さなプロジェクトで経験を積もう
- Twitterの感情分析
- ブログ記事のキーワード抽出
- 質問応答システムのプロトタイプ
-
コーパスを活用しよう
- BCCWJで大規模データに触れる
- 自分の分野のデータで学習する
NLPの未来
ChatGPTやClaude、Geminiなどの大規模言語モデルが注目を集めていますが、その基礎となるのは今回学んだ形態素解析や係り受け解析です。
基礎をしっかり理解しておけば、最新の技術もすんなり理解できるようになります。
さらに学びたい方へ
- 言語処理学会: https://www.anlp.jp/
- 国立国語研究所: https://www.ninjal.ac.jp/
- spaCy公式ドキュメント: https://spacy.io/
- GiNZA公式サイト: https://megagonlabs.github.io/ginza/
この連載が、あなたのNLP学習の第一歩になれば嬉しいです。
それでは、Happy NLP Hacking!