ちょっと話題の記事

Python用の自然言語処理ライブラリ”StanfordNLP”を試す

2019.02.15

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

StanfordNLPとは

StanfordNLPとは、スタンフォード大学の自然言語処理(Natural Language Processing, NLP)グループが提供するPythonのNLPライブラリです。 同じくスタンフォード大学のNLPグループが提供するStanford CoreNLPというJavaで書かれたNLPツールのサーバーにアクセスする為のパッケージが含まれています。

GitHub - StanfordNLP

GitHub - Stanford CoreNLP

ライセンス

基となるStanford CoreNLPはGNU GPL(v3以降)ですが、StanfordNLPはApache License Version 2.0となっています。

特徴

StanfordNLPは、Python3.6以降をサポートしており、トークナイザー、形態素解析、依存関係パーサー等の機能を有します。

また、かなり広範囲な多言語対応がなされており、日本語もサポートされています。ただし、StanfordNLPで用いられている理論の基となる論文に書かれている"完全なニューラルパイプライン"に比べると、StandardNLPの実装では少なくとも1%は精度が悪いモデルになっているようです。

Human Languages Supported by StanfordNLP

インストール

StanfordNLPはpipコマンドで簡単にインストールすることができます。

pip install stanfordnlp

ニューラルパイプラインを実行する

公式のGetting Startedでは、以下の様に

>>> import stanfordnlp
>>> stanfordnlp.download('en') # This downloads the English models for the neural pipeline
>>> nlp = stanfordnlp.Pipeline() # This sets up a default neural pipeline in English
>>> doc = nlp("Barack Obama was born in Hawaii. He was elected president in 2008.")
>>> doc.sentences[0].print_dependencies()

インタラクティブ環境で、英文に対してパイプラインを実行する例が掲載されていますが、せっかくなので日本語の文章に対して実行してみましょう。

import stanfordnlp

stanfordnlp.download('ja') # モデルのダウンロード(一回実行すれば、以降は不要)

# lang(仕様言語)とtreebank(ツリーバンク=コーパスの一種)を指定
nlp = stanfordnlp.Pipeline(lang="ja", treebank="ja_gsd")
doc = nlp("昨日の夜、私は大学時代の友人と食事に行きました。")
doc.sentences[0].print_dependencies()

print('----------')

words = doc.sentences[0].words
word = ''

for w in words:
word += w.text + ' '

print(word)

stanfordnlp.download('ja')でローカルに日本語用の言語モデルをダウンロードします。現在実行中のローカル環境で過去に一回でも実行されていれば以降はダウンロード済みのモデルを使用するので実行は不要です。

※ 気軽にダウンロード実行したらファイルサイズが2GB弱あったのでご注意ください

stanfordnlp.Pipelineの引数"lang"と"treebank"に対しては、上述の「Human Languages Supported by StanfordNLP」のページにある一覧から、使用する言語に応じた規定のコードを探して渡すようにします。

また、公式のサンプルに加えて分かち書きの処理も記載しています(doc.sentences[0].wordsからtextを抽出することで分割された形態素を取り出すことができるので、それを半角スペースで繋いで出力しています)

出力結果は以下の様になります。

(前略)
---
('昨日', '3', 'nmod')
('の', '1', 'case')
('夜', '14', 'obl')
('、', '3', 'punct')
('私', '14', 'nsubj')
('は', '5', 'case')
('大学', '8', 'compound')
('時代', '10', 'nmod')
('の', '8', 'case')
('友人', '12', 'nmod')
('と', '10', 'case')
('食事', '14', 'iobj')
('に', '12', 'case')
('行き', '0', 'root')
('まし', '14', 'aux')
('た', '14', 'aux')
('。', '14', 'punct')
----------
昨日 の 夜 、 私 は 大学 時代 の 友人 と 食事 に 行き まし た 。

形態素解析や依存関係パースされた結果(1番目が形態素、2番目が係り受け元のindex、3番目が係り受けタグになっています。係り受けタグについては、こちらの記事を参考にしてください。)と分かち書きの結果が出力されました。

※ 結果の出力の前にStandard CoreNLPサーバーの各機能の呼び出しに関する出力がありますが、そこは省略しました。

ニューラルパイプラインの学習

StandardNLPでは、利用者が独自にニューラルパイプラインを再学習できる仕組みを持っていますが、実行の為に膨大な計算リソースと計算時間を要する為、これについては検証を断念しました。あしからず。

まとめ

Python用のNLPライブラリであるStanfordNLPについて実際にパイプライン実行までを検証してみました。 昨今、日本語の形態素解析ツール・ライブラリも多く登場していますが、StanfordNLPは導入の簡単で形態素間の依存関係の解析が出来るなど、有用な点も幾つか見られたので今後の展開に注目です。