聖刻の里

遊戯王、NLP、アニメ、語学とか

【自然言語処理】文章の特徴量とBag of Words

どうもLibraです。

 

今回は趣味のお話です(いつも通りですが(^^;))。自然言語処理の分野についてお勉強しているのでメモ代わりとして残しておきます。

 

 

 

文章の特徴量とは

自然言語処理とはそもそも人間が使っている自然言語(英語や日本語など)をコンピュータに扱わせる(処理させる)ことを目的としています。自然言語(以下日本語としましょう)をコンピュータで扱う場合、そのままの形では処理(計算)しにくいため、文章を扱いやすい形に変換する必要があります。

具体的に何をするかというと、文章をベクトルで表します。このベクトルのこと特徴量(feature)特徴ベクトル(feature vector)と呼びます。自然言語から特徴量を抽出することを特徴量抽出(feature extraction)特徴ベクトル化すると言います。また、特徴量抽出の手法を実装した関数やオブジェクトのことを特徴量抽出器(feature extractor)と呼びます。

 

文章の特徴量を抽出するには

特徴量抽出の手法にも様々なものが今回はその一つであるBag of Wordsについて解説します。

環境はMacOS Catalina 10.15.3、使用言語はPython 3.7.2、分かち書きにはMeCabを使用しています。ここでは自然言語処理の理論に焦点を当てていきたいので、PythonMeCabの実装方法についてはスキップします。

 

Bag of Words

とても基本的かつ広く使われている手法です。略してBoWとも呼ばれます。

処理の内容としてはシンプルで、読み込んだ文章の単語の登場回数を数えるだけです。プログラム的にいうと、文章中に登場する単語にユニークな番号(インデックス)を割り当て、各単語の登場回数を並べてリストとして返します。なんのこっちゃと思われるかもしれないので例を踏まえて解説します。

入力する文は「二色の眼の龍よ、その黒き逆鱗を震わせ刃向かう敵を殲滅せよ」とします。この文章を特徴ベクトルに変換してみましょう。

f:id:scarlet09Libra:20200315164402p:plain

 

こんな感じになります。 

この結果が何を表しているかというと、まず入力された文章を分かち書きし、それぞれの単語にインデックスを割り当てます(分かち書きとは文を単語ごとに分けること)。今回の例文を分かち書きすると、

二色 の 眼 の 龍 よ 、 その 黒き 逆鱗 を 震わせ 刃向かう 敵 を 殲滅 せよ

 

となります。先頭の単語から順番にインデックスを割り当てていくと、"二色"は0、"の"は1、"眼"は2...となり、すなわち上記の図のvocabulary:となるワケです。

単語とインデックスの対応のことを語彙(vocabulary)辞書(dictionary)と呼びます。また、辞書とインデックスの内容はユニーク(一意)でなければならないため、文中に同じ単語が登場した場合はインデックスを割り当てる必要はありません。(例文のインデックス:1で既に"の"がセットされているため、"眼"の次に登場する"の"に新たにインデックスを割り当てる必要はない)

 

ここまで理解できれば図中のBoW:が何を示しているか分かると思います。

このリストはインデックス番号0から順にそれぞれの単語が何回登場したかを示しています。図中のベクトルの左からインデックス番号0、すなわち"二色"の登場回数は1回、インデックス番号1、すなわち"の"の登場回数は2回...といった具合です。

 

BoWが例文に対しての特徴ベクトルとなります。自然言語(日本語)のままではコンピュータにとって不規則なbyte列で扱いにくいデータでしたが、文章を特徴ベクトル化することでコンピュータにとって扱いやすい数値の配列に変換することができます。

特徴量抽出の手法はBag of Wordsだけでなく他にも様々な手法があります。ここでは参考程度に名前と概略だけ紹介しておきます。

 

TF-IDF

一言でいうとBoWの発展系です。TF(Term Frequency:単語の登場頻度)、IDF(Inverse Document Frequency:ある単語を含む文書の頻度DFに対数をとった値)という意味です。

ある文書の中で、特に出現頻度の高い単語はその文を特徴付けるために重要な単語である」、または「様々な文書で広く出現する単語は個々の文を特徴付けるために重要な単語でない」といった考え方から、BoWと比較してより正確に文の特徴をベクトルとして表現することができます。

 

example.

Text1:「1ターンに1度、もう片方の自分のPゾーンにカードが存在しない場合に発動できる。デッキからPモンスター1体を選び、自分のPゾーンに置く。」

 

Text1の文章とTF-IDFの文章を比較すると、Text1では「Pゾーン」、上の文章では「単語」という単語がそれぞれ多く登場しています。したがって「Pゾーン」や「単語」はそれぞれの文書を特徴付けるための値(重み)が高く評価されます。

それに対し、「できる」はどちらの文書にも幅広く登場するため文書の特徴付けの重みは低く評価されます。

 

<TF-IDFの計算方法>

TF-IDF(t, d) = TF(t, d)・IDF(t)

 

TF(t, d) = 文書dに登場する単語tの数

IDF(t) = ln(1 / (DF(t))) = ln(文書の総数 / 単語tを含む文書の数)

 

DF(t) = (単語t を含む文書の数) / (文書の総数)

 

BM25

TF-IDFの発展系です。基本的な考え方や目的はTF-IDFと同じです。TF-IDFでは文書の長さ(文書の含まれる総単語数)による影響が出やすいという欠点があり、それを補う手法がBM25です。

一言でいうと、TF-IDFの計算に文の長さを考慮するよう修正したものです。計算方法の式を書きたいところですが非常にややこしく書くことすら面倒なので割愛します。

 

 

 特徴量抽出について自分なりに解説してみました。自分はIT系のエンジニアとして飯を食っている人間なんですが、昔は海外に住んでいて2か国語使えたりもするので、自然言語の解析やそのしくみについては非常に興味をそそられますね。今後もこのような話をできればいいなと思います。それでは( ^_^)/~~~

f:id:scarlet09Libra:20200322001148j:plain