OpenText Analytics Database 旧Vertica

技術情報サイト

Analytics Database

Verticaで始める機械学習~k-meansを使ったクラスタリング~

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

Verticaでは、機械学習のクラスタリングアルゴリズムとしてk-means(k平均法)を利用できます。

k-meansとは

k-meansは、機械学習における教師なし学習で、クラスタリングを行う際に利用されます。

k-meansの利用例は以下の通りです。
・特性に基づいた類似顧客のグルーピング
・スパム検出
・サイバーセキュリティ(不正検知等)

以降では、サンプルデータを例にVerticaでk-meansを利用する手順をご紹介します。

Verticaでk-meansを利用する手順

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

以下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/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)

k-meansモデルの作成

本記事ではk-meansのサンプルデータとしてよく用いられるirisデータを使用します。
irisデータには「あやめ」の3品種「setosa」、「versicolor」、「virginica」のSepal(がく片)の長さと幅、及びPetal(花びら)の長さと幅の情報が含まれています。

dbadmin=> SELECT * FROM iris WHERE id=1 OR id=51 OR id=101;
 id  | Sepal_Length | Sepal_Width | Petal_Length | Petal_Width |  Species
-----+--------------+-------------+--------------+-------------+------------
   1 |          5.1 |         3.5 |          1.4 |         0.2 | setosa
  51 |            7 |         3.2 |          4.7 |         1.4 | versicolor
 101 |          6.3 |         3.3 |            6 |         2.5 | virginica
(3 rows)

Sepal(がく片)の長さと幅、及びPetal(花びら)の長さと幅の情報を用いて機械学習を行い、学習データから花の品種を予測するクラスタリングを行います。

サンプルデータセットでは、すでにirisデータを分割した学習データ(iris1)とテストデータ(iris2)が用意されています。そのため、iris1テーブルを用いてk-meansによる機械学習を行います。
※k-meansはランダム要素があるため、本記事と同じようにSQLを実行しても同様の結果にならない場合があります。

k-meansによる機械学習を行うには、KMEANS関数を利用します。

SELECT KMEANS('myKmeansModel', 'iris1', '*', 3
                  USING PARAMETERS max_iterations=20, output_view='myKmeansView', key_columns='id',
exclude_columns='Species, id');
          KMEANS
---------------------------
 Finished in 4 iterations

(1 row)

【参考】パラメータの意味

パラメータ名

意味

myKmeansModel

任意のモデル名

iris1

学習データのテーブル名

*

予測に使用する説明変数(*の場合は全ての列)

3

作成したいクラスタの数、花の品種は3種類なので3を指定

max_iterations

(オプション) アルゴリズムが実行する最大反復回数

output_view

(オプション) 学習データのクラスタリング結果を保存するビュー名

key_columns

(オプション) output_viewオプションを利用する場合の主キーとなる列 

exclude_columns

(オプション) 予測列を*(全列)と指定した場合に、予測列から除外する列

サマリを出力

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

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

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


=======
centers
=======
sepal_length|sepal_width|petal_length|petal_width
------------+-----------+------------+-----------
   5.03667  |  3.44000  |   1.45333  |  0.25333
   6.72333  |  3.00667  |   5.57000  |  1.91667
   5.77333  |  2.71000  |   4.19000  |  1.34333


=======
metrics
=======
Evaluation metrics:
     Total Sum of Squares: 402.52322
     Within-Cluster Sum of Squares:
         Cluster 0: 7.071
         Cluster 1: 20.217
         Cluster 2: 18.006333
     Total Within-Cluster Sum of Squares: 45.294333
     Between-Cluster Sum of Squares: 357.22889
     Between-Cluster SS / Total SS: 88.75%
 Number of iterations performed: 4
 Converged: True
 Call:
kmeans('public.myKmeansModel', 'iris1', '*', 3
USING PARAMETERS exclude_columns='Species, id', max_iterations=20, epsilon=0.0001, init_method='kmeanspp', distance_method='euclidean', output_view='myKmeansView', key_columns='id')
(1 row)

作成したモデルの評価

学習データ(iris1)がどのようにクラスタリングされたかを確認します。

dbadmin=> SELECT a.id,a.cluster_id,b.Species FROM myKmeansView AS a 
                                             INNER JOIN iris1 AS b ON a.id=b.id 
          ORDER BY cluster_id;

 id  | cluster_id |  Species
-----+------------+------------
  50 |          0 | setosa
  49 |          0 | setosa
  44 |          0 | setosa
  41 |          0 | setosa
  40 |          0 | setosa
  37 |          0 | setosa
  36 |          0 | setosa
  31 |          0 | setosa
  30 |          0 | setosa
  29 |          0 | setosa
  28 |          0 | setosa
  27 |          0 | setosa
  26 |          0 | setosa
  23 |          0 | setosa
  20 |          0 | setosa
  19 |          0 | setosa
  18 |          0 | setosa
  17 |          0 | setosa
  16 |          0 | setosa
  13 |          0 | setosa
  12 |          0 | setosa
  11 |          0 | setosa
   9 |          0 | setosa
   8 |          0 | setosa
   7 |          0 | setosa
   6 |          0 | setosa
   4 |          0 | setosa
   3 |          0 | setosa
   2 |          0 | setosa
   1 |          0 | setosa
 150 |          1 | virginica
 149 |          1 | virginica
 147 |          1 | virginica
 144 |          1 | virginica
 140 |          1 | virginica
 138 |          1 | virginica
 137 |          1 | virginica
 135 |          1 | virginica
 132 |          1 | virginica
 131 |          1 | virginica
 130 |          1 | virginica
 128 |          1 | virginica
 126 |          1 | virginica
 125 |          1 | virginica
 124 |          1 | virginica
 123 |          1 | virginica
 121 |          1 | virginica
 117 |          1 | virginica
 116 |          1 | virginica
 112 |          1 | virginica
 111 |          1 | virginica
 109 |          1 | virginica
 108 |          1 | virginica
 106 |          1 | virginica
 105 |          1 | virginica
 103 |          1 | virginica
  84 |          1 | versicolor ★
  78 |          1 | versicolor ★
  77 |          1 | versicolor ★
  53 |          1 | versicolor ★
 139 |          2 | virginica ★
 122 |          2 | virginica ★
 114 |          2 | virginica ★
 100 |          2 | versicolor
  99 |          2 | versicolor
  98 |          2 | versicolor
  95 |          2 | versicolor
  94 |          2 | versicolor
  93 |          2 | versicolor
  92 |          2 | versicolor
  88 |          2 | versicolor
  86 |          2 | versicolor
  85 |          2 | versicolor
  83 |          2 | versicolor
  81 |          2 | versicolor
  80 |          2 | versicolor
  79 |          2 | versicolor
  76 |          2 | versicolor
  74 |          2 | versicolor
  72 |          2 | versicolor
  70 |          2 | versicolor
  69 |          2 | versicolor
  68 |          2 | versicolor
  67 |          2 | versicolor
  61 |          2 | versicolor
  60 |          2 | versicolor
  58 |          2 | versicolor
  56 |          2 | versicolor
  55 |          2 | versicolor
  52 |          2 | versicolor
(90 rows)

★のデータについては、間違ったクラスタリングを行っていますが、それ以外は期待したクラスタリングが行われていることが確認できます。今回は以下のようにクラスタリングされました。

品種

0

setosa

1

virginica

2

versicolor

次に、学習時に利用していないテストデータ(iris2)を利用して、作成したモデルの精度を評価します。
モデルの評価はAPPLY_KMEANS関数を利用します。

dbadmin=> SELECT id,
dbadmin->        APPLY_KMEANS(sepal_length,sepal_width,petal_length,petal_width
dbadmin(>                     USING PARAMETERS
dbadmin(>                     MODEL_NAME='myKmeansModel') AS cluster_id,
dbadmin->        Species AS 品種
dbadmin-> FROM iris2 ORDER BY cluster_id;
 id  | cluster_id |    品種
-----+------------+------------
  48 |          0 | setosa
  47 |          0 | setosa
  46 |          0 | setosa
  45 |          0 | setosa
  43 |          0 | setosa
  42 |          0 | setosa
  39 |          0 | setosa
  38 |          0 | setosa
  35 |          0 | setosa
  34 |          0 | setosa
  33 |          0 | setosa
  32 |          0 | setosa
  25 |          0 | setosa
  24 |          0 | setosa
  22 |          0 | setosa
  21 |          0 | setosa
  15 |          0 | setosa
  14 |          0 | setosa
  10 |          0 | setosa
   5 |          0 | setosa
 148 |          1 | virginica
 146 |          1 | virginica
 145 |          1 | virginica
 142 |          1 | virginica
 141 |          1 | virginica
 136 |          1 | virginica
 134 |          1 | virginica
 133 |          1 | virginica
 129 |          1 | virginica
 119 |          1 | virginica
 118 |          1 | virginica
 115 |          1 | virginica
 113 |          1 | virginica
 110 |          1 | virginica
 104 |          1 | virginica
 101 |          1 | virginica
  87 |          1 | versicolor ★
  51 |          1 | versicolor ★
 143 |          2 | virginica ★
 127 |          2 | virginica ★
 120 |          2 | virginica ★
 107 |          2 | virginica ★
 102 |          2 | virginica ★
  97 |          2 | versicolor
  96 |          2 | versicolor
  91 |          2 | versicolor
  90 |          2 | versicolor
  89 |          2 | versicolor
  82 |          2 | versicolor
  75 |          2 | versicolor
  73 |          2 | versicolor
  71 |          2 | versicolor
  66 |          2 | versicolor
  65 |          2 | versicolor
  64 |          2 | versicolor
  63 |          2 | versicolor
  62 |          2 | versicolor
  59 |          2 | versicolor
  57 |          2 | versicolor
  54 |          2 | versicolor
(60 rows)

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

【参考】APPLY_KMEANS関数のパラメータの意味

パラメータ名

意味

sepal_length,sepal_width,petal_length,petal_width

予測に使用する列(モデル作成時に指定した説明変数)

MODEL_NAME

予測に使用するモデル名

実装

作成したk-meansモデルを実装する場合も、評価時に利用したAPPLY_KMEANS関数を利用できます。

SELECT id,
       APPLY_KMEANS(sepal_length,sepal_width,petal_length,petal_width
                    USING PARAMETERS 
                    MODEL_NAME='myKmeansModel') AS cluster_id,
       Species AS 品種
FROM <予測したいデータがあるテーブル> ORDER BY cluster_id;

参考情報

Clustering Data Using k-means
https://my.vertica.com/docs/9.0.x/HTML/index.htm#Authoring/AnalyzingData/MachineLearning/Kmeans/ClusteringDataUsingkmeans.htm

検証バージョンについて

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