OpenText Analytics Database 旧Vertica

技術情報サイト

Analytics Database

Verticaで始める機械学習~ナイーブベイズを使った分類~

公開日:
更新日:
基本操作
機械学習
#機械学習

Verticaでは、機械学習の分類アルゴリズムとしてナイーブベイズを利用できます。

ナイーブベイズとは

ナイーブベイズは、機械学習における教師あり学習のアルゴリズムであり、分類を行う際に利用できます。

ナイーブベイズの利用例は以下の通りです。
・スパムメールの判定
・ある病気になる確率の予測

以降では、サンプルデータを例にVerticaでナイーブベイズを利用する手順をご紹介します。

Verticaでナイーブベイズを利用する手順

サンプルスキーマ、データのダウンロード

以下URLよりサンプルファイルをダウンロードします。
https://github.com/vertica/Machine-Learning-Examples

画面右上にある「Clone or Download」をクリックします。

展開される画面の右下にある「Download ZIP」をクリックしてファイルを保存します。

サンプルスキーマの作成、データのロード

ダウンロードしたファイルをVerticaサーバ上の任意のディレクトリに転送します。
転送後、以下コマンドでファイルを解凍します。

$ cd 
$ unzip Machine-Learning-Examples-master.zip

解凍後に以下コマンドでサンプルスキーマとテーブルの作成、データロードを実行します。

$ cd Machine-Learning-Examples-master
$ /opt/vertica/bin/vsql -d <データベース名> -w <パスワード> -f load_ml_data.sql

DROP TABLE
DROP TABLE
DROP TABLE
CREATE TABLE

~途中、省略~

COMMIT
CREATE TABLE
CREATE TABLE

ナイーブベイズモデルの作成

本記事では機械学習のサンプルデータとしてよく用いられるhouse84データを使用します。
本データには、米国議会の1984年に実施された16の投票について下院議員が賛成票を投じたか否かが記録されています。

dbadmin=> SELECT * FROM house84 LIMIT 10;
 id |   party    | vote1 | vote2 | vote3 | vote4 | vote5 | vote6 | vote7 | vote8 | vote9 | vote10 | vote11 | vote12 | vote13 | vote14 | vote15 | vote16
----+------------+-------+-------+-------+-------+-------+-------+-------+-------+-------+--------+--------+--------+--------+--------+--------+--------
  1 | republican | n     | y     | n     | y     | y     | y     | n     | n     | n     | y      | ?      | y      | y      | y      | n      | y
  2 | republican | n     | y     | n     | y     | y     | y     | n     | n     | n     | n      | n      | y      | y      | y      | n      | ?
  3 | democrat   | ?     | y     | y     | ?     | y     | y     | n     | n     | n     | n      | y      | n      | y      | y      | n      | n
  4 | democrat   | n     | y     | y     | n     | ?     | y     | n     | n     | n     | n      | y      | n      | y      | n      | n      | y
  5 | democrat   | y     | y     | y     | n     | y     | y     | n     | n     | n     | n      | y      | ?      | y      | y      | y      | y
  6 | democrat   | n     | y     | y     | n     | y     | y     | n     | n     | n     | n      | n      | n      | y      | y      | y      | y
  7 | democrat   | n     | y     | n     | y     | y     | y     | n     | n     | n     | n      | n      | n      | ?      | y      | y      | y
  8 | republican | n     | y     | n     | y     | y     | y     | n     | n     | n     | n      | n      | n      | y      | y      | ?      | y
  9 | republican | n     | y     | n     | y     | y     | y     | n     | n     | n     | n      | n      | y      | y      | y      | n      | y
 10 | democrat   | y     | y     | y     | n     | n     | n     | y     | y     | y     | n      | n      | n      | n      | n      | ?      | ?
(10 rows)

本データは学習に適切な状態になっていないため、はじめにクリーニングを行います。クリーニング用のスクリプトはサンプルデータセットに含まれています。

$ cd Machine-Learning-Examples-master
$ /opt/vertica/bin/vsql -d <データベース名> -w <パスワード> -f naive_bayes_data_preparation.sql

ナイーブベイズによる機械学習を行うには、LOGISTIC_REG関数を利用します。

NAIVE_BAYES ( 'model‑name', 'input‑relation', 'response‑column', 'predictor‑columns'
	      [ USING PARAMETERS[exclude_columns='excluded‑columns']
	                        [, alpha=alpha-value] ] )

パラメータ名

内容

model‑name

任意のモデル名

input‑relation

学習データのテーブル名

response‑column

予測したい列(目的変数)

predictor‑columns

予測に使用する説明変数

exclude_columns

(オプション) input‑columnsで*(全列)と指定した場合に、対象列から除外する列

alpha

(オプション) モデルがカテゴリカル、多項分類、ベルヌーイの場合に、ラプラススムージングの使用を指定する値。デフォルトは1.0

本例ではvote1~vote16(投票結果)を説明変数として機械学習を行い、閣議員が所属する政党(party列(republican=共和党、democrat=民主党))を予測します。

クリーニングスクリプトを実行することで、house84データを分割した訓練データ(house84_train)とテストデータ(house84_test)が用意されています。そのため、house84_trainテーブルを用いてナイーブベイズによる機械学習を行います。

dbadmin=> SELECT NAIVE_BAYES('naive_house84_model', 'house84_train', 'party',
dbadmin(>                       '*' USING PARAMETERS exclude_columns='party, id');
                  NAIVE_BAYES
------------------------------------------------
 Finished. Accepted Rows: 325  Rejected Rows: 0
(1 row)

サマリを出力

作成したnaive_house84_modelモデルのサマリ情報を確認します。

dbadmin=> SELECT GET_MODEL_SUMMARY(USING PARAMETERS model_name='naive_house84_model');

GET_MODEL_SUMMARY
-----------------------------------------------------

=======
details
=======
index|predictor|   type
-----+---------+-----------
  0  |  party  | ResponseC
  1  |  vote1  |Categorical
  2  |  vote2  |Categorical
  3  |  vote3  |Categorical
  4  |  vote4  |Categorical
  5  |  vote5  |Categorical
  6  |  vote6  |Categorical
  7  |  vote7  |Categorical
  8  |  vote8  |Categorical
  9  |  vote9  |Categorical
 10  | vote10  |Categorical
 11  | vote11  |Categorical
 12  | vote12  |Categorical
 13  | vote13  |Categorical
 14  | vote14  |Categorical
 15  | vote15  |Categorical
 16  | vote16  |Categorical


=====
prior
=====
  class   |probability
----------+-----------
 democrat |  0.62462
republican|  0.37538


===========
call_string
===========
naive_bayes('public.naive_house84_model', 'house84_train', '"party"', '*' USING PARAMETERS exclude_columns='party, id', alpha=1)

=================
categorical.vote1
=================
category|democrat|republican
--------+--------+----------
   n    | 0.40000|  0.80645
   y    | 0.60000|  0.19355


=================
categorical.vote2
=================
category|democrat|republican
--------+--------+----------
   n    | 0.45366|  0.39516
   y    | 0.54634|  0.60484


=================
categorical.vote3
=================
category|democrat|republican
--------+--------+----------
   n    | 0.11707|  0.87903
   y    | 0.88293|  0.12097
 ・
 ・
 ・
===============
Additional Info
===============
       Name       | Value
------------------+--------
      alpha       | 1.00000
accepted_row_count|  325
rejected_row_count|   0

(1 row)

作成したモデルの評価

学習時に利用していないテストデータ(house84_test)を利用して、作成したモデルの精度を評価します。
作成したモデルによる評価(予測)を行うにはPREDICT_NAIVE_BAYES関数を使用します。

PREDICT_NAIVE_BAYES ( input‑columns
                        USING PARAMETERS model_name='model‑name'
                                         [, type=' return‑type ']
                                         [, class='user‑input‑class'] 
                                         [, match_by_pos=match‑by‑position] )

パラメータ名

意味

input‑columns

予測に使用する説明変数列をカンマ区切りで指定

model_name

予測に使用するモデル名

type

(オプション) 以下のいずれかを指定
response:予測結果を0 or 1で出力(デフォルト)
probability: 予測結果が1になる確率を出力

classes

typeをresponseに指定した場合に、予測確率を出力したいクラスを指定。省略した場合は最も高い予測確率のクラスが出力される。

match_by_pos

(オプション) 入力列と特徴量の紐付けのルール。以下のいずれかを指定。
false:入力した列名と特徴量の名前で紐付(デフォルト)
true:列名は無視し、入力した列の順番通りに紐づけ

本例ではnaive_house84_modelモデルを用いて、house84_testのparty列を予測します。

dbadmin=> SELECT id,party,
dbadmin->        PREDICT_NAIVE_BAYES (vote1, vote2, vote3, vote4, vote5,
dbadmin(>                             vote6, vote7, vote8, vote9, vote10,
dbadmin(>                             vote11, vote12, vote13, vote14,
dbadmin(>                             vote15, vote16
dbadmin(>                               USING PARAMETERS model_name = 'naive_house84_model') AS Predicted_Party
dbadmin-> FROM house84_test;

 id  |   party    | Predicted_Party
-----+------------+-----------------
   1 | republican | republican
   5 | democrat   | democrat
   8 | republican | republican
   9 | republican | republican
  12 | republican | republican
  20 | democrat   | democrat
  21 | democrat   | democrat
  24 | democrat   | democrat
 ・
 ・
 376 | democrat   | republican ★
 ・
 ・

★のデータについては、間違った分類を行っていますが、それ以外は期待した分類が行われていることが確認できます。

また、PREDICT_NAIVE_BAYES_CLASSES関数を使用すると、各クラス毎の確率を出力できます。

PREDICT_NAIVE_BAYES_CLASSES ( predictor‑columns
                USING PARAMETERS model_name='model‑name'
                                 [, key_columns='key‑columns']
                                 [, exclude_columns='excluded‑columns] 
                                 [, classes='classes'] 
                                 [, match_by_pos=match‑by‑position] )
                 OVER( [window-partition-clause] ) 

パラメータ名

意味

predictor‑columns

予測に使用する説明変数列をカンマ区切りで指定

model_name

予測に使用するモデル名

key_columns

(オプション) 出力結果を識別するための一意の値が格納された列を指定

exclude_columns

(オプション) predictor‑columnsで*(全列)と指定した場合に、対象列から除外する列

classes

予測確率を出力したいクラスをカンマ区切りで指定。クラス名は大文字、小文字が区別されます。

match_by_pos

(オプション) 入力列と特徴量の紐付けのルール。以下のいずれかを指定。
false:入力した列名と特徴量の名前で紐付(デフォルト)
true:列名は無視し、入力した列の順番通りに紐づけ

本例ではdemocrat、republicanそれぞれの確率を出力しています。

dbadmin=> SELECT PREDICT_NAIVE_BAYES_CLASSES (id, vote1, vote2, vote3, vote4, vote5,
dbadmin(>                                        vote6, vote7, vote8, vote9, vote10,
dbadmin(>                                        vote11, vote12, vote13, vote14,
dbadmin(>                                        vote15, vote16
dbadmin(>                                        USING PARAMETERS model_name = 'naive_house84_model',
dbadmin(>                                                         key_columns = 'id', exclude_columns = 'id',
dbadmin(>                                                         classes = 'democrat, republican')
dbadmin->         OVER() FROM house84_test;
 id  | Predicted  |    Probability    |       democrat       |      republican
-----+------------+-------------------+----------------------+----------------------
   1 | republican | 0.999999960776576 | 3.92234240121355e-08 |    0.999999960776576
   5 | democrat   |  0.99380385631155 |     0.99380385631155 |  0.00619614368844963
   8 | republican |  0.99999740954849 | 2.59045150953901e-06 |     0.99999740954849
   9 | republican | 0.999999949990135 | 5.00098650760445e-08 |    0.999999949990135
  12 | republican | 0.999999515168995 | 4.84831005174758e-07 |    0.999999515168995
  20 | democrat   | 0.999999999999531 |    0.999999999999531 | 4.68820039378911e-13
  21 | democrat   | 0.999999999982497 |    0.999999999982497 | 1.75026148031812e-11
  24 | democrat   | 0.999999999995455 |    0.999999999995455 | 4.54507504521018e-12
 ・
 ・
 376 | republican | 0.999999137425226 | 8.62574774571355e-07 |    0.999999137425226
 ・
 ・
 ・

実装

作成したナイーブベイズのモデルを実装する場合も、評価時に利用したPREDICT_NAIVE_BAYES、またはPREDICT_NAIVE_BAYES_CLASSES関数を利用できます。

PREDICT_NAIVE_BAYES関数を利用する場合の例

SELECT id,party,
       PREDICT_NAIVE_BAYES (vote1, vote2, vote3, vote4, vote5,
                            vote6, vote7, vote8, vote9, vote10,
                            vote11, vote12, vote13, vote14,
                            vote15, vote16
                              USING PARAMETERS model_name = 'naive_house84_model') AS Predicted_Party
FROM <予測したいデータがあるテーブル>;

参考情報

Classifying Data Using Naive Bayes
https://www.vertica.com/docs/9.1.x/HTML/index.htm#Authoring/AnalyzingData/MachineLearning/NaiveBayes/ClassifyingDataUsingNaiveBayes.htm

検証バージョンについて

この記事の内容はVertica 9.1で確認しています。