【自然言語処理シリーズ】形態素解析についてわかりやすく解説!実践編

形態素解析実践編

キカガク機械学習講師の船蔵です!

本記事では、形態素解析の実践編として、MeCab や HuggingFace Tokenizer など、よく利用されている解析器の基本的な使用法をご説明します。また、記事の最後に、知っておくと便利なアライメントという処理についてもご説明します。

形態素解析を試してみる

本節では、形態素解析の入出力イメージを掴むために、具体的な解析を実施してみます。ここでは、とても広く利用されている MeCab と、比較的新しい Nagisa の二つを試します。実行環境は Google Colaboratory を想定しています。

まずは MeCab による解析を試します。以下では基本的な使用感をお伝えするにとどめますので、詳細は MeCab 公式ページ などをご確認ください。

今回は、辞書として IPAdic を使用します。まずは MeCab、IPAdic それぞれの Python ラッパーをインストールします。

Python
!pip install mecab-python3==1.0.6
!pip install ipadic==1.0.0

それでは、形態素解析を実行します。以下のコードで非常に簡単に解析できます。

Python
import MeCab
import ipadic

tagger = MeCab.Tagger(ipadic.MECAB_ARGS) # ipadic を辞書に指定してインスタンス生成

text = "いま、自然言語処理が熱い。" # 解析対象のテキストを定義

parsed_text = tagger.parse(text) # 解析を実行
print(parsed_text) # 解析結果を表示

コードを実行すると、結果が次のように表示されます。

実行結果
いま	名詞,副詞可能,*,*,*,*,いま,イマ,イマ
、	記号,読点,*,*,*,*,、,、,、
自然	名詞,形容動詞語幹,*,*,*,*,自然,シゼン,シゼン
言語	名詞,一般,*,*,*,*,言語,ゲンゴ,ゲンゴ
処理	名詞,サ変接続,*,*,*,*,処理,ショリ,ショリ
が	助詞,格助詞,一般,*,*,*,が,ガ,ガ
熱い	形容詞,自立,*,*,形容詞・アウオ段,基本形,熱い,アツイ,アツイ
。	記号,句点,*,*,*,*,。,。,。
EOS

このように、各形態素についての解析結果が、行ごとに出力されます。出力のフォーマットは下記のようになっています(MeCab 公式ページ より引用)。

表層形\t品詞,品詞細分類1,品詞細分類2,品詞細分類3,活用型,活用形,原形,読み,発音

解析結果は、自然言語データの詳細な分析や、自然言語処理モデルへの入力として利用することがよくあります(詳しくは理論編を参照ください)。

出力の形式は解析器によって異なるので、使用する前に確認しておく必要があります。他の解析器の出力例として、比較的新しい解析器である Nagisa の出力結果を確認してみましょう。はじめに、pip でインストールします。

Python
!pip install nagisa==0.2.9

解析してみます。Nagisa の解析結果は、単語/品詞 の形式で出力されます。

Python
import nagisa

text = 'いま、自然言語処理が熱い'

words = nagisa.tagging(text)
print(words)
実行結果
いま/名詞 、/補助記号 自然/名詞 言語/名詞 処理/名詞 が/助詞 熱い/形容詞

出力形式の他にも、デフォルトの辞書として何が使用されるか、未知語に対してどのような処理が行われているかなど、さまざまな観点から、事前に公式ドキュメントを確認しておくことが重要です。この一手間が、予期せぬバグを防ぐことに繋がります。

深層学習向けトークナイザ

近年の自然言語処理には、BERT や GPT などの Transformer モデルが広く利用されています。理論編でお伝えしたように、これらのモデルはサブワードによる分かち書きを想定している場合がほとんどです。本節では、サブワードトークナイザの基本的な利用方法をご紹介します。

利用シーン

BERT や GPT などの事前学習済みモデルを、自分の目的に合わせてファインチューニングする場合、ファインチューニング用のデータを、事前学習時に使用したトークナイザで分割処理する必要があります。そうしなかった場合、事前学習とファインチューニングとでモデルへの入力形式が変わってしまい、適切に学習できなくなってしまいます。

そのため、ファインチューニング用データを作成する際には、事前学習済みモデルとセットで公開されているトークナイザを使用する必要があります。

HuggingFace Tokenizer を試す

ここでは、Transformer モデルの事前学習やファインチューニングでよく利用されるライブラリ HuggingFace Transformers を使用します。

BERT モデルのトークナイザを試してみましょう。BERT モデルといっても様々なモデルが HuggingFace Models に公開されていますが、ここではよく利用される東北大のモデル cl-tohoku/bert-base-japanese-v3 を使用します。

まずは HuggingFace Transformers ライブラリをインストールします。

Python
!pip install transformers==4.33.1

次のコードでトークナイザを読み込みます。BertTokenizer.from_pretrained の引数にモデル名 cl-tohoku/bert-base-japanese-v3 を与えることで、トークナイザを読み込むことができます。

Python
from transformers import BertTokenizer

tokenizer = BertTokenizer.from_pretrained("cl-tohoku/bert-base-japanese-v3")

では、分かち書きを行なってみましょう。

Python
tokenizer.tokenize("いま、自然言語処理が熱い")
実行結果
['いま', '、', '自', '然', '言', '語', '処', '理', 'が', '熱', 'い']

「いま」がひとつのサブワードとなり、その他は一文字のサブワードに分割されています。

このサブワードたちを実際に BERT モデルへ入力するには、上記のようなテキストではなく、各サブワードに対応する id の列を作る必要があります。入力に必要な値は次のコードで簡単に用意できます。

Python
tokenizer("いま、自然言語処理が熱い")
実行結果
{'input_ids': [2, 17968, 384, 4949, 3622, 5568, 5630, 993, 3822, 430, 3656, 422, 3],
'token_type_ids': [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
'attention_mask': [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]}

この出力結果のうち、input_ids がサブワード列を id 列化したものです。id 列以外にも、token_type_idsattention_mask が出力されています。以下でそれぞれについてご説明します。

token_type_ids は、入力として複数の文が与えられたときに、各文をモデルが区別するために必要です。次の処理例を見てみましょう。

Python
tokenizer("いま、自然言語処理が熱い", "最近の夏は特に暑い")
実行結果
{'input_ids': [2, 17968, 384, 4949, 3622, 5568, 5630, 993, 3822, 430, 3656, 422, 3, 2803, 5985, 464, 1578, 465, 3720, 461, 2761, 422, 3],
'token_type_ids': [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
'attention_mask': [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]}

二文目のトークンが始まったところから、token_type_ids の値が 1 になっていることがわかります。このような区別が必要になるタスクとしては、二文間の論理的関係を識別する含意関係認識が代表的です。

attention_mask は、注意機構が無視するべきトークンを明示するという役割を担います。次の処理例を見てみましょう。処理する文は先ほどと同じですが、出力系列の長さを 16 に指定し、足りない分はパディングトークンという特殊なトークンで埋めるよう指定します。

Python
tokenizer("いま、自然言語処理が熱い",
          max_length=16,
          padding="max_length")
実行結果
{'input_ids': [2, 17968, 384, 4949, 3622, 5568, 5630, 993, 3822, 430, 3656, 422, 3, 0, 0, 0],
'token_type_ids': [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
'attention_mask': [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0]}

input_idsattention_mask の末尾 3 つの要素に注目してください。input_ids に含まれる 0 は、パディングトークン [PAD] に対応する id です。

パディングトークンは、トークナイズ結果の長さを 16 に揃えるためのトークンです。注意機構にはこのトークンを無視して欲しいので、attention_mask の値のうち、パディングトークンと同じ位置の値は 0 になっています。

attention_mask の値が 0 になっているトークンには注意機構が働かず、意味のないトークンを無視することができます。

ところで、そもそもなぜパディングトークンで埋める必要があるのでしょうか?パディングによって長さを揃える処理には、ミニバッチ学習を行う際、入力される系列たちの長さが全て同じでなければならないという背景があります。

以上、サブワードトークナイザの例として HuggingFace Transformers のトークナイザを取り上げ、出力として得られる以下三つの要素についてご説明しました。

  • input_ids
  • token_type_ids
  • attention_mask

最後に、サブワードトークナイザを使用する際に利用場面の多い、アライメントという処理についてご説明します。

発展:サブワードと単語のアライメント

アライメントとは、各サブワードがどの単語に属するかを特定する処理のことです。この処理は、サブワード分かち書きを使用しつつ、単語ごとに予測を行う必要がある、という場面で使用することが多いです。アライメントが必要になる場面の主な例として、固有表現抽出や品詞タグ付けなどの、各単語にラベルを付与するタスクが挙げられます。

例として、「秋風の涼しさ」というフレーズに対してサブワード分割を行い、アライメントを求めてみます。このフレーズを単語レベルで分割すると以下のようになります。

[“秋風”, “の”, “涼し”, “さ”]

一方で、サブワードトークナイザは以下のように解析したとします。

[“秋”, “風”, “の”, “涼し”, さ”]

アライメントによって、各サブワードがどの単語に属するかを求めましょう。アライメントには、spacy-alignments が便利です。以下のコードでインストールします。

Python
!pip install spacy-alignments==0.9.1

では、以下のコードでアライメントを実施します。

Python
import spacy_alignments

words = ["秋風", "の", "涼し", "さ"]
subwords = ["秋", "風", "の", "涼し", "さ"]

alignment = spacy_alignments.get_alignments(subwords, words)

alignment の中身は以下のようになっています。

([[0], [0], [1], [2], [3]], [[0, 1], [2], [3], [4]])

各要素が何を表しているかを以下にご説明します。

  • [[0], [0], [1], [2], [3]]: 各サブワードがどの単語に属しているか
  • [[0, 1], [2], [3], [4]]: 各単語がどのサブワードから構成されているか

以上、アライメントを実演しました。サブワードレベルで処理を行うモデルによって、単語レベルでの出力が欲しい場合にとても役立つので、ぜひ心に留めておいてください!

まとめ

本記事では、形態素解析や分かち書きの実践的な内容をご説明しました。本記事でご紹介しきれなかった解析器も多くあり、それぞれの特長を持っています。様々な技術に触れるための下地として、本記事が活きることを願っています。

こちらの記事もオススメ

まずは無料で学びたい方・最速で学びたい方へ

まずは無料で学びたい方: Python&機械学習入門コースがおすすめ

Python&機械学習入門コース

AI・機械学習を学び始めるならまずはここから!経産省の Web サイトでも紹介されているわかりやすいと評判の Python&機械学習入門コースが無料で受けられます!
さらにステップアップした脱ブラックボックスコースや、IT パスポートをはじめとした資格取得を目指すコースもなんと無料です!

無料で学ぶ

最速で学びたい方:キカガクの長期コースがおすすめ

一生学び放題

続々と転職・キャリアアップに成功中!受講生ファーストのサポートが人気のポイントです!

AI・機械学習・データサイエンスといえばキカガク!
非常に需要が高まっている最先端スキルを「今のうちに」習得しませんか?

無料説明会を週 2 開催しています。毎月受講生の定員がございますので確認はお早めに!

説明会ではこんなことをお話します!
  • 国も企業も育成に力を入れている先端 IT 人材とは
  • キカガクの研修実績
  • 長期コースでの学び方、できるようになること
  • 料金・給付金について
  • 質疑応答