- ナイーブベイズ( Naive Bayes)とは何か
- 確率に基づいて予測を行う計算方法
- pythonでのナイーブベイズの実装
ナイーブベイズ( Naive Bayes)とは?
ナイーブベイズは確率に基づいて予測を行うモデルで、ベイズの定理の考え方をもとにしたアルゴリズムとなっています。
ナイーブベイズは分類に問題にも利用することができます。
スパムメールのフィルタなど、自然言語の分類問題に利用されることが多くなっています。
例として、野球とサッカーの新聞記事の見出しを分類する例を以下に示します。
項番 | 学習データ | カテゴリ |
文章1 | 順調な調整 紅白戦で3回1安打無失点 | 野球 |
文章2 | 8回無失点の好投でトップタイの3勝目 | 野球 |
文章3 | シート打撃で一発!攻守で高いレベル見せる | 野球 |
文章4 | 「人生で最も美しいゴール」自賛弾でVへ前進 | サッカー |
文章5 | 前半だけで4失点…ディフェンス崩壊で大量リード許す | サッカー |
文章6 | ハットトリック達成、攻守切り替え素早くカウンターさえる | サッカー |
検証データ | カテゴリ |
5回1安打無失点 完封リレーで接戦を制し白星スタート | 野球 |
学習データ6件から検証データのカテゴリを推定する方法は、
学習データには野球のデータが3件、サッカーのデータ3件があり、単純に考えると検証データのカテゴリが「野球」である確率は50%(3/6)です。
この方法だと、検証データの内容によらずカテゴリに分類される確率は変わらないので、ナイーブベイズでは文章中に含まれる単語をもとにカテゴリの推定をします。
検証データに含まれる「失点」という単語に着目すると、野球のデータの中に「失点」という単語が含まれる確率は66%(2/3)で、サッカーのデータの中に「失点」という単語が含まれる確率は33%(1/3)です。
項番 | 学習データ | カテゴリ |
文章1 | 順調な調整 紅白戦で3回1安打無失点 | 野球 |
文章2 | 8回無失点の好投でトップタイの3勝目 | 野球 |
文章3 | シート打撃で一発!攻守で高いレベル見せる | 野球 |
文章4 | 「人生で最も美しいゴール」自賛弾でVへ前進 | サッカー |
文章5 | 前半だけで4失点…ディフェンス崩壊で大量リード許す | サッカー |
文章6 | ハットトリック達成、攻守切り替え素早くカウンターさえる | サッカー |
「失点」という単語だけでナイーブベイズを使った場合、検証データの分類は野球であると判断されます。
「失点」という単語が使われていたら、野球カテゴリの確率が66%だから野球に分類されるよ。
上記の例では「失点」という単語のみで判断していましたが、実際は様々な単語を使って推定します。
ナイーブベイズでは文章の出現割合と文章に使われている単語ごとの出現確率を用いて分類の精度を上げています。
ナイーブベイズのアルゴリズム
ナイーブベイズで自然言語の分類を行う場合は3ステップの処理が必要となります。
- データ形式をBoW(Bag of Words)に変換する
- 単語ごとの出現確率を計算する
- 検証データを分類する
データ形式をBoW(Bag of Words)に変換する
BoW(Bag of Words)とは文章中の単語の出現回数を数えて整理したものです。
学習データをBoWの一覧表(一部省略)のイメージを作ってみます。
単語 | 文章1 | 文章2 | 文章3 | 文章4 | 文章5 | 文章6 |
順調 | 1 | 0 | 0 | 0 | 0 | 0 |
調整 | 1 | 0 | 0 | 0 | 0 | 0 |
紅白戦 | 1 | 0 | 0 | 0 | 0 | 0 |
回 | 1 | 1 | 0 | 0 | 0 | 0 |
安打 | 1 | 0 | 0 | 0 | 0 | 0 |
失点 | 1 | 1 | 0 | 0 | 1 | 0 |
好投 | 0 | 1 | 0 | 0 | 0 | 0 |
トップタイ | 0 | 1 | 0 | 0 | 0 | 0 |
打撃 | 0 | 0 | 1 | 0 | 0 | 0 |
一発 | 0 | 0 | 1 | 0 | 0 | 0 |
攻守 | 0 | 0 | 1 | 0 | 0 | 1 |
ゴール | 0 | 0 | 0 | 1 | 0 | 0 |
前進 | 0 | 0 | 0 | 1 | 0 | 0 |
前半 | 0 | 0 | 0 | 0 | 1 | 0 |
ディフェンス | 0 | 0 | 0 | 0 | 1 | 0 |
カウンター | 0 | 0 | 0 | 0 | 0 | 1 |
この例の場合、文章1(順調な調整 紅白戦で3回1安打無失点)をBoWの形で変換すると、[1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0]となります。
この形式にすることで自然言語をプログラムで解析できるようになりました。
単語ごとの出現確率を計算する
ナイーブベイズの確率計算ではまず、単語ごとの出現確率を求めます。
単語 | 野球の確率 (文章1,2,3) | サッカーの確率 (文章4,5,6) |
順調 | 1/3 | 0.01 |
調整 | 1/3 | 0.01 |
紅白戦 | 1/3 | 0.01 |
回 | 2/3 | 0.01 |
安打 | 1/3 | 0.01 |
失点 | 2/3 | 1/3 |
好投 | 1/3 | 0.01 |
トップタイ | 1/3 | 0.01 |
打撃 | 1/3 | 0.01 |
一発 | 1/3 | 0.01 |
攻守 | 1/3 | 1/3 |
ゴール | 0.01 | 1/3 |
前進 | 0.01 | 1/3 |
前半 | 0.01 | 1/3 |
ディフェンス | 0.01 | 1/3 |
カウンター | 0.01 | 1/3 |
テストデータに出てこなかった単語でも、スムージングという処理をして確率は0.01のような小さな値を入れておきます。
スムージングは、学習データ数が少なくて0になってしまった可能性を考慮して、単語が出現しなかった箇所にも低確率を割り振ります。
検証データを分類する
出現確率が求められたら、分類したい文章(検証用データ)に出現している単語から結果を判断します。
ナイーブベイズを使った確率は、
$$確率 = カテゴリの出現確率 × 各単語ごとの条件付き確率の積$$で算出されます。
単語 | 野球の確率 (文章1,2,3) | サッカーの確率 (文章4,5,6) | 検証データのBoW |
順調 | 1/3 | 0.01 | 0 |
調整 | 1/3 | 0.01 | 0 |
紅白戦 | 1/3 | 0.01 | 0 |
回 | 2/3 | 0.01 | 1 |
安打 | 1/3 | 0.01 | 1 |
失点 | 2/3 | 1/3 | 1 |
好投 | 1/3 | 0.01 | 0 |
トップタイ | 1/3 | 0.01 | 0 |
打撃 | 1/3 | 0.01 | 0 |
一発 | 1/3 | 0.01 | 0 |
攻守 | 1/3 | 1/3 | 0 |
ゴール | 0.01 | 1/3 | 0 |
前進 | 0.01 | 1/3 | 0 |
前半 | 0.01 | 1/3 | 0 |
ディフェンス | 0.01 | 1/3 | 0 |
カウンター | 0.01 | 1/3 | 0 |
検証データで試しに計算してみましょう。
野球に分類される時の確率を求める例です。
$$野球カテゴリの出現確率 = \frac{野球カテゴリのデータ数}{学習データ数(野球カテゴリ)} = \frac{3}{6} $$$$単語(順調)の条件付き確率 = 1 – \frac{1}{3} = \frac{2}{3} $$
※検証データに含まれていないので、「順調」という単語がない時に野球カテゴリになる確率を求めています。
$$単語(回)の条件付き確率 = \frac{2}{3} $$ $$単語(ゴール)の条件付き確率 = 1-0.99 $$上記のように各確率を求めて、全ての積を計算すれば野球カテゴリに分類される確率を求めることができます。
$$確率(野球) = \frac{3}{6} × \frac{2}{3} × \frac{2}{3} × ・・・ × 0.99 $$
ここで求めた確率(野球)と確率(サッカー)を比べ、高い確率の方に分類されます。
ナイーブベイズはシンプルなアルゴリズムだから、高速で計算できて大規模なデータにも有効な手法だよ。
ナイーブベイズをpythonで実装
必要ライブラリのインポート
from sklearn.naive_bayes import MultinomialNB
データの生成
#データ生成 X_train = [[1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0], [0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]] y_train = [1, 1, 1, 0, 0, 0]#1:野球、0:サッカー
サポートベクターマシンのモデルで学習する
#ナイーブベイズで分類する model = MultinomialNB() model.fit(X_train, y_train)#学習 model.predict([[0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]])#推定結果
結果はarray([1])となり、野球カテゴリに分類されました。
まとめ
ナイーブベイズとは何かをまとめると以下の3つの特徴を持つモデルです。
- 確率に基づいて予測を行うモデル
- 自然言語の分類問題に用いられるモデル
- 高速で処理でき、大規模なデータにも有効
コメント