Verticaでは、新バージョンの8.1から機械学習への対応が強化されました。この記事では、サポートベクターマシン(Support Vector Machine:以降はSVMと表記します)アルゴリズムへの対応についてご紹介します。
目次
SVMとは
SVMは、機械学習における教師あり学習のパターン認識アルゴリズムの一つで、二値分類に利用されます。以降では、サンプルデータを例にVerticaでSVMを利用する手順をご紹介します。
VerticaでSVMを利用する手順
サンプルスキーマ、データのダウンロード
以下URLよりサンプルファイルをダウンロードします。https://github.com/vertica/Machine-Learning-Examples
画面右上にある「Clone or Download」をクリックします。
展開される画面の右下にある「Download ZIP」をクリックしてファイルを保存します。
サンプルスキーマの作成、データのロード
ダウンロードしたファイルをVerticaサーバ上の任意のディレクトリに転送します。転送後、以下コマンドでファイルを解凍します。
1 2 |
$ cd $ unzip Machine-Learning-Examples-master.zip |
解凍後に以下コマンドでサンプルスキーマとテーブルの作成、データロードを実行します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 |
$ cd Machine-Learning-Examples-master/data $ /opt/vertica/bin/vsql -d <データベース名> -w <パスワード> -f load_ml_data.sql DROP TABLE DROP TABLE DROP TABLE CREATE TABLE ~途中、省略~ COMMIT CREATE TABLE CREATE TABLE 以下のようなテーブルが作成されます。 dbadmin=> \d List of tables Schema | Name | Kind | Owner | Comment --------+-------------------+-------+---------+--------- public | agar_dish | table | dbadmin | public | agar_dish_1 | table | dbadmin | public | agar_dish_2 | table | dbadmin | public | baseball | table | dbadmin | public | dem_votes | table | dbadmin | public | faithful | table | dbadmin | public | faithful_testing | table | dbadmin | public | faithful_training | table | dbadmin | public | house84 | table | dbadmin | public | house84_clean | table | dbadmin | public | house84_test | table | dbadmin | public | house84_train | table | dbadmin | public | iris | table | dbadmin | public | iris1 | table | dbadmin | public | iris2 | table | dbadmin | public | mtcars | table | dbadmin | public | mtcars_test | table | dbadmin | public | mtcars_train | table | dbadmin | public | rep_votes | table | dbadmin | public | salary_data | table | dbadmin | public | transaction_data | table | dbadmin | (21 rows) |
本記事で使用するmtcarsテーブルは教師データ(mtcars_train)とテストデータ(mtcars_test)しかありません。後述手順の「実装」で未知のデータを予測するため、テストデータの一部を未知のデータとして別テーブル(mtcars_predict)に移動します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
dbadmin=> create table mtcars_predict as select * from mtcars_test order by 1 desc limit 3; CREATE TABLE dbadmin=> select * from mtcars_predict; car_model | mpg | cyl | disp | hp | drat | wt | qsec | vs | am | gear | carb | tf ---------------+------+-----+-------+-----+------+-------+-------+----+----+------+------+------ Volvo 142E | 21.4 | 4 | 121 | 109 | 4.11 | 2.78 | 18.6 | 1 | 1 | 4 | 2 | test Valiant | 18.1 | 6 | 225 | 105 | 2.76 | 3.46 | 20.22 | 1 | 0 | 3 | 1 | test Toyota Corona | 21.5 | 4 | 120.1 | 97 | 3.7 | 2.465 | 20.01 | 1 | 0 | 3 | 1 | test (3 rows) dbadmin=> delete from mtcars_test where car_model in ('Toyota Corona','Valiant','Volvo 142E'); OUTPUT -------- 3 (1 row) dbadmin=> select * from mtcars_test; car_model | mpg | cyl | disp | hp | drat | wt | qsec | vs | am | gear | carb | tf ----------------+------+-----+-------+-----+------+-------+-------+----+----+------+------+------ AMC Javelin | 15.2 | 8 | 304 | 150 | 3.15 | 3.435 | 17.3 | 0 | 0 | 3 | 2 | test Camaro Z28 | 13.3 | 8 | 350 | 245 | 3.73 | 3.84 | 15.41 | 0 | 0 | 3 | 4 | test Datsun 710 | 22.8 | 4 | 108 | 93 | 3.85 | 2.32 | 18.61 | 1 | 1 | 4 | 1 | test Honda Civic | 30.4 | 4 | 75.7 | 52 | 4.93 | 1.615 | 18.52 | 1 | 1 | 4 | 2 | test Hornet 4 Drive | 21.4 | 6 | 258 | 110 | 3.08 | 3.215 | 19.44 | 1 | 0 | 3 | 1 | test Maserati Bora | 15 | 8 | 301 | 335 | 3.54 | 3.57 | 14.6 | 0 | 1 | 5 | 8 | test Merc 280 | 19.2 | 6 | 167.6 | 123 | 3.92 | 3.44 | 18.3 | 1 | 0 | 4 | 4 | test Merc 450SL | 17.3 | 8 | 275.8 | 180 | 3.07 | 3.73 | 17.6 | 0 | 0 | 3 | 3 | test Porsche 914-2 | 26 | 4 | 120.3 | 91 | 4.43 | 2.14 | 16.7 | 0 | 1 | 5 | 2 | test (9 rows) |
SVMモデルの作成
今回の例では、mtcarsというサンプルデータを利用します。このデータは、1974年のMotor Trend US誌から抽出されたもので、燃料消費量と32の自動車(1973-74モデル)の自動車設計と性能の10の側面から構成されています。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
■テーブルレイアウト dbadmin=> \d mtcars List of Fields by Tables Schema | Table | Column | Type | Size | Default | Not Null | Primary Key | Foreign Key --------+--------+-----------+-------------+------+---------+----------+-------------+------------- public | mtcars | car_model | varchar(30) | 30 | | f | f | public | mtcars | mpg | float | 8 | | f | f | public | mtcars | cyl | int | 8 | | f | f | public | mtcars | disp | float | 8 | | f | f | public | mtcars | hp | int | 8 | | f | f | public | mtcars | drat | float | 8 | | f | f | public | mtcars | wt | float | 8 | | f | f | public | mtcars | qsec | float | 8 | | f | f | public | mtcars | vs | float | 8 | | f | f | public | mtcars | am | float | 8 | | f | f | public | mtcars | gear | int | 8 | | f | f | public | mtcars | carb | int | 8 | | f | f | public | mtcars | tf | varchar(5) | 5 | | f | f | (13 rows) |
mtcarsテーブルの列名と内容
列名 | 内容 |
---|---|
car_model | 車種 |
mpg | マイル/(米)ガロン |
cyl | シリンダ数 |
disp | ディスプレースメント(cu.in.) |
hp | 総馬力 |
drat | リアアクスル比 |
wt | 重量(1000ポンド) |
qsec | 1/4マイルタイム |
vs | V / S |
am | トランスミッション(0=オートマ、1=マニュアル) |
gear | 前進ギアの数 |
carb | 気化器の数 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
■データの例(※5件のみ表示) dbadmin=> select * from mtcars limit 5; car_model | mpg | cyl | disp | hp | drat | wt | qsec | vs | am | gear | carb | tf --------------------+------+-----+------+-----+------+-------+-------+----+----+------+------+------- AMC Javelin | 15.2 | 8 | 304 | 150 | 3.15 | 3.435 | 17.3 | 0 | 0 | 3 | 2 | test Cadillac Fleetwood | 10.4 | 8 | 472 | 205 | 2.93 | 5.25 | 17.98 | 0 | 0 | 3 | 4 | train Camaro Z28 | 13.3 | 8 | 350 | 245 | 3.73 | 3.84 | 15.41 | 0 | 0 | 3 | 4 | test Chrysler Imperial | 14.7 | 8 | 440 | 230 | 3.23 | 5.345 | 17.42 | 0 | 0 | 3 | 4 | train Datsun 710 | 22.8 | 4 | 108 | 93 | 3.85 | 2.32 | 18.61 | 1 | 1 | 4 | 1 | test (5 rows) dbadmin=> select count(*) from mtcars; count ------- 32 (1 row) |
初めに、mtcars_trainテーブルにロード済みのデータを利用して、svm_classという名前のSVMモデルを作成します。今回の例では、am(伝送タイプ、0=オートマ、1=マニュアル)の値を予測するモデルを作成します。
1 2 3 4 5 6 7 |
dbadmin=> SELECT SVM_CLASSIFIER('svm_class', 'mtcars_train', 'am', 'cyl, mpg, wt,hp' dbadmin(> USING PARAMETERS exclude_columns='hp'); SVM_CLASSIFIER --------------------------------------------------------------- Finished in 7 iterations. Accepted Rows: 20 Rejected Rows: 0 (1 row) |
【参考】パラメータの意味
パラメータ名 | 意味 |
---|---|
svm_class | モデル名 |
mtcars_train | 教師データとして利用するテーブル |
am | 目的変数(予測したい列) |
cyl, mpg, wt,hp | 説明変数(予測に利用する列) |
exclude_columns='hp' | 入力カラムとしては省略するカラム |
サマリを出力
svm_viewとしてモデルのサマリ情報を出力します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
dbadmin=> SELECT SUMMARIZE_MODEL('svm_class'); SUMMARIZE_MODEL ---------------------------------------------- =========================== Predictors and Coefficients =========================== |Coefficients ---------+------------ Intercept| 0.18716 cyl | 0.42349 mpg | 0.12485 wt | -1.73971 ===== Notes ===== Call string: SELECT svm_classifier('svm_class', 'mtcars_train', '"am"', 'cyl, mpg, wt,hp' USING PARAMETERS exclude_columns='hp', C=1, max_iterations=100, epsilon=0.001); Number of rows accepted: 20 Number of rows rejected: 0 Training finished in 7 iterations. (1 row) |
テストデータを使用した予測結果を格納するテーブルを作成
出力した予測値を格納するsvm_mtcars_predictテーブルを作成します。この表に、テスト・データに対してPREDICT_SVM_CLASSIFIER関数を実行して得られた予測出力を格納します。
1 2 3 4 5 |
dbadmin=> CREATE TABLE svm_mtcars_predict AS dbadmin-> (SELECT car_model, am, PREDICT_SVM_CLASSIFIER(cyl, mpg, wt dbadmin(> USING PARAMETERS model_name='svm_class') dbadmin(> AS Prediction FROM mtcars_test); CREATE TABLE |
予測結果を確認
am列とPrediction列の値が異なっていると、予測と一致していない結果であることを表します。
1 2 3 4 5 6 7 8 9 10 11 12 13 |
dbadmin=> SELECT * FROM svm_mtcars_predict; car_model | am | Prediction ----------------+----+------------ AMC Javelin | 0 | 0 Camaro Z28 | 0 | 0 Datsun 710 | 1 | 1 Honda Civic | 1 | 1 Hornet 4 Drive | 0 | 0 Maserati Bora | 1 | 0 ★予測と一致していない Merc 280 | 0 | 0 Merc 450SL | 0 | 0 Porsche 914-2 | 1 | 1 (9 rows) |
svm_mtcars_predictテーブルの列の意味
列名 | 内容 |
---|---|
car_model | 車種 |
am | 目的変数(予測したい列) |
Prediction | 予測値 |
PREDICT_SVM_CLASSIFIER関数の精度を評価
CONFUSION_MATRIX関数を使ってPREDICT_SVM_CLASSIFIER関数の精度を評価します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
dbadmin=> SELECT CONFUSION_MATRIX(obs::int, pred::int USING PARAMETERS num_classes=2) OVER() dbadmin-> FROM (SELECT am AS obs,Prediction AS pred FROM svm_mtcars_predict) as prediction_output; class | 0 | 1 | comment -------+---+---+------------------------------------------- 0 | 5 | 0 | 1 | 1 | 3 | Of 9 rows, 9 were used and 0 were ignored ★1 ↑ ↑ ↑ 予測と一致 ↑ 予測と一致していない (2 rows) ★1(2行目) am列の値が1である4台の自動車のうち3台が1の値を持つと正しく予測しました。 1台の車が誤って値0を持つと分類されました。 |
実装
作成したモデルを使用して予測結果を求めます。
1 2 3 4 5 6 7 8 9 10 |
dbadmin=> SELECT car_model AS 車種, dbadmin-> PREDICT_SVM_CLASSIFIER (cyl,mpg,wt dbadmin(> USING PARAMETERS model_name='svm_class') AS 予測 dbadmin-> FROM mtcars_predict; 車種 | 予測 ---------------+------ Toyota Corona | 1 Valiant | 0 Volvo 142E | 0 (3 rows) |
PREDICT_SVM_CLASSIFIER関数を利用することで、作成したSVMのモデルを呼び出すことができます。これにより未知のデータ(mtcars_predict)を機械学習で分類することができます。上記例の場合は「予測」列が、各行のcyl,mpg,wt列の内容から導き出したam列の予測結果です。
参考情報
SVM (Support Vector Machine)https://my.vertica.com/docs/8.1.x/HTML/index.htm#Authoring/AnalyzingData/MachineLearning/SVM/SVM.htm
検証バージョンについて
この記事の内容はVertica 8.1で確認しています。- 投稿タグ
- 機械学習, SVM, サポートベクターマシン