ナイーブベイズについて勉強したのでざっくりまとめ — pythonでやってみた

概要

こんにちは、データインテグレーション部のyoshimです。この記事は機械学習アドベントカレンダー7日目のものとなります。 本日は、先日ご紹介した「ナイーブベイズ」を実際に計算するところまでをPythonの「scikit-learnのチュートリアル」に沿って実際にやってみたので、ご紹介します。

目次

やること

今回のエントリでやることは、「ナイーブベイズの処理をpythonでとりあえずやってみる」というものです。 目的は、アドベントカレンダー6日目にてご紹介した「ナイーブベイズの理論への理解」をより深める、です。

また、今回Pythonでナイーブベイズの計算を行うにあたり、「scikit-learnのチュートリアル」に沿って実装しています。 また、使うデータについては機械学習アドベントカレンダー5日目に行った「tf-idfについて勉強したのでざっくりまとめ_pythonでやってみた」で計算したtf-idfの値を利用します。
なので、今回のナイーブベイズの実装を自分でもやる方は、機械学習アドベントカレンダー5日目の記事からコードをコピペして実行しておいてください。

作業環境

  • macOS High Sierra 10.13.1
  • python 3.6.3
  • sklearn 0.19.1

手順概要

この後、ソースコードをご紹介するのですが、その前にざっくりと「今回の処理の概要」についてご説明します。 今回、「ナイーブベイズ」を計算するまでを4つの段階に分けて処理させています。 コード自体はそこまで難しいものではありません。

  • 1.データの準備 機械学習アドベントカレンダー5日目に行った「tf-idfについて勉強したのでざっくりまとめ_pythonでやってみた」で計算したtf-idfの値を利用します。
    なので、この記事からコードをコピペして実行しておいてください。

  • 2.ナイーブベイズ分析を実行(コード中では「7」で表示しています) sklearnに用意されているモジュールを使ってナイーブベイズを実行します。
    具体的には、「用意したデータからモデルを作成」、「新しいデータセット作成」、「新しいデータセットをモデルに入れて予測結果を確認」の3手順を踏みます また、ナイーブベイズについて今回は「多項分布」に基づいたナイーブベイズを実行しています。sklearnでは他にも「ガウス分布」、「ベルヌーイ分布」でのモジュールも用意されています。

  • 3.実装をシンプルにする(コード中では「8」で表示しています) 今回、「単語単位に分割し、出現頻度をカウント」、「tf-idfを計算」、「ナイーブベイズモデルを作成」といった工程を踏んでいるのですが、新しく分析をするたびにそれらを一個づつ書くのは面倒臭いので1つにまとめます。 Pythonでは「pipeline」というモジュールを使う事で、このような機能を1まとめにすることが可能です。

  • 4.モデルの評価(コード中では「9」で表示しています) 今回作成したナイーブベイズモデルの精度を評価します。もし、ここで期待した精度が出ていないようならアルゴリズム変更等、何らかの対応が必要となります。
    ナイーブベイズは仮定をシンプルにしているため精度はあまり期待できないはずなのですが、思ったよりはいい数字が出ているのではないでしょうか?

コード

実際のコードは下記の通りです。一応、コード中にコメントを入れています。 実際のコードや、より詳細な解説については、scikit-learnのチュートリアルをご参照ください。

#  7.ナイーブベイズ分析を実行
print("=====7.ナイーブベイズ分析を実行=====")
from sklearn.naive_bayes import MultinomialNB # 7-1.多項分布のNB(ナイーブベイズ)
clf = MultinomialNB().fit(X_train_tfidf, twenty_train.target) # 7-2.学習

docs_new = ['God is love', 'OpenGL on the GPU is fast'] # 7-3.新しいデータセット作成(2つ作成)
X_new_counts = count_vect.transform(docs_new) # 7-4.単純にカウント(BoW計算)
X_new_tfidf = tfidf_transformer.transform(X_new_counts) # 7-5.tf-idfを計算(すでに作成しているモデルと同じ基準で計算)

predicted = clf.predict(X_new_tfidf) # 7-6.上記で作成したモデルを使って、新しいデータセットのカテゴリを予測

for doc, category in zip(docs_new, predicted): # 7-7.各カテゴリのデータの中身と予測結果を表示
    print('%r => %s' % (doc, twenty_train.target_names[category]))

# 8.実装をシンプルにするために
print("=====8.実装をシンプルにするために=====")
from sklearn.pipeline import Pipeline # 8-1.pipelineの機能を使うことで、「BoW、tf-idf、ナイーブベイズ」といった3つの処理を1まとめに記述できます。
text_clf = Pipeline([('vect', CountVectorizer()),
                         ('tfidf', TfidfTransformer()),
                         ('clf', MultinomialNB()),
                        ])

text_clf = text_clf.fit(twenty_train.data, twenty_train.target) # 8-2.1度パイプラインを作ってしまえば、次からこんなにシンプルに記述できます。


# 9.モデルの評価
print("=====9.モデルの評価=====")

twenty_test = fetch_20newsgroups(subset='test',
                                 categories=categories, shuffle=True, random_state=42)  # 9-1.検証用データセットを取得
docs_test = twenty_test.data # 9-2.検証用データセットの「データの部分のみ(カテゴリーは取得しない)」を取得
predicted = text_clf.predict(docs_test) # 9-3.モデルに入れて分析(パイプラインを使う)

import numpy as np # 9-4.モジュールのインポート
print(np.mean(predicted == twenty_test.target)) # 9-5.精度を確認 (予測した結果ともともと保有していたカテゴリーが一致していたら「1」が表示され、その平均値を計算するので結果的に精度が求まる。)

まとめ

「ナイーブベイズ」について、実際にPythonで実装してみた内容のご説明でした。 ここまででモデルが作成できているので、適当にデータをモデルに入れてどのように判別されるのかを試してみると面白いかもしれません。

明日は統計的言語モデル(n-gram, スムージングなど)についてのご紹介です。