Oracle Database Cloud Service上で機械学習を試してみた

[前回の記事](http://qiita.com/ogamiki/items/130b40a8ea72fddc432d)でOracle Database Cloud Service上に機械学習環境を構築するところまでを書かせていただきました。今回は構築した環境で実際に、Oracle Database Cloud Service上で機械学習を行ってみたいと思います。

#機械学習で行える分析とは?#
機械学習環境でどんな分析ができるかは、その環境がサポートしているアルゴリズムの種類に依存します。Oracle Database Cloud Serviceで機械学習を行う際には、Oracle DatabaseのOracle Data Miningの機能を活用しますので、Oracle Data Miningでサポートされるアルゴリズムが重要となります。

Oracle Data Miningでは、行いたい分析によって、使用されるアルゴリズムが自動的に選択されるため、アルゴリズムの特性をゼロから学ばなくても簡単に分析を始めることができます。

以下の種類の分析がOracle Database Cloud Service上の機械学習環境で可能です。
1. 回帰
2. 分類
3. 異常検出
4. クラスタリング
5. 相関
6. 属性評価
7. 特徴抽出

##1. 回帰##
利益や売上などのように予測する値が連続的な量的データのときに使用します。
一般化線形モデル(GLM)とサポート・ベクター・マシン(SVM)がサポートされます。

##2. 分類##
性別や婚姻ステータスのように予測する値が質的データのときに使用します。
ディシジョン・ツリー(DT),Naive Bayes(NV),GLMとSVMがサポートされます。
ただし、GLMは2クラス・分類という質的値が二種類のものだけをサポートします。

##3. 異常検出##
機器の故障のような稀に起こった異常値を検出するときに使用します。
1クラス・分類という分類の一種で実装されており、SVMがサポートされています。

##4. クラスタリング##
どんな顧客セグメントが存在するかなど、とりあえず持っているデータに対してグルーピングをするときに使用します。
k-Means,O-Cluster,EMアルゴリズムがサポートされます。

##5. 相関##
トランザクションデータの中から、何かと何かがどれくらい関連して発生しているかを検出するときに使用します。
Aprioriがサポートされます。

##6. 属性評価##
人が離職した際にどんなことが要因だったのかなど、属性の影響度を評価するときに使用します。
Minimum Description Length(MDL)がサポートされます。

##7. 特徴抽出##
身長、体重、筋肉量など様々な属性を体格と一つに絞るなど、データの可視化の前の次元削減を行う時に使用します。
Non-Negative Matrix Factorization (NMF), Singular Value Decomposition(SVD)とPrincipal Component Analysis(PCA)がサポートされます。

#Oracle Database Cloud Service上で機械学習を試してみる#
今回も前置きが長くなりましたが、Oracle Database Cloud Service上で機械学習を試してみます。環境は[前回](http://qiita.com/ogamiki/items/130b40a8ea72fddc432d)構築済みなので、Oracle SQL Developerを立ち上げて接続まで完了したところから始めます。
今回はOracle Data Minerのリポジトリをインストールした際に入るデモ・データでクラスタリングと分類を試していきます。

1. プロジェクトとワークフローを作成する
2. 元データを選択する
3. 元データに対してクラスタリングを行う
4. クラスタリングの結果を見る
5. 分類モデルを構築する
6. 分類モデルを比較する
7. 分類モデルを見る
8. 予測分析を行う

##1．プロジェクトとワークフローを作成する##
Oracle Data Minerにおいては、プロジェクトとワークフローという単位で分析フローを管理することができます。一つ一つの機械学習のフローはワークフローに設計し、複数のワークフローはプロジェクトとして管理することができます。
ワークフローで、ノードと呼ばれるOracle Data Minerのアイコンをつないで機械学習フローを設計していきます。

![projectworkflow.png](https://qiita-image-store.s3.amazonaws.com/0/108610/810e6d73-f324-4eb3-7647-98f1352bc9f5.png)


ワークフローはxml形式でエクスポート、インポートが可能です。チームで分析を行って、一部の処理、例えば学習用データ準備のためのETL処理などをチーム内で簡単に共有可能です。

プロジェクトを作成するには、**Data Minerの接続タブ**から作成された接続名を右クリックして、**新規プロジェクト**を選択します。

![createproject.png](https://qiita-image-store.s3.amazonaws.com/0/108610/19d4de2b-3e5e-b3a7-e8d1-d4b66bba825b.png)

プロジェクト名と必要であれば、コメントを入力して**OK**を押せば無事にプロジェクトが接続の下に表示されます。
![projectname.png](https://qiita-image-store.s3.amazonaws.com/0/108610/521642e0-28bb-5f7c-a7ed-6beacdf3a434.png)

ワークフローは一つのプロジェクトに紐づくため、プロジェクトを右クリックして、**新規ワークフロー**を選択することによって、選択したプロジェクトに紐づいたワークフローを作成できます。

![createworkflow.png](https://qiita-image-store.s3.amazonaws.com/0/108610/72e65074-7f77-369a-60f2-0b5eeb86f4b1.png)

ワークフロー名を入力して**OK**を押せばワークフロー名がプロジェクトの下に表示され、中心に白い画面が表示されます。

![workflowname.png](https://qiita-image-store.s3.amazonaws.com/0/108610/2ed1c464-6954-d22b-ff85-beded9b65b5f.png)

![workflowimage.png](https://qiita-image-store.s3.amazonaws.com/0/108610/7650c768-09b9-e5a7-27cc-693a8ed4f14b.png)


##2. 元データを選択する##
デフォルトだと画面右側に表示されているOracle Data Minerの**ワークフロー・エディタ**から**データソース**ノードを選択して、中心の白い画面にドラッグ&ドロップしていきます。

![workflowediter.png](https://qiita-image-store.s3.amazonaws.com/0/108610/3240820a-b4b0-3d53-390a-6c12dab776e3.png)

ドロップすると、データソースとして使用可能な表一覧が表示されるため、対象の表を選択します。今回はINSUR_CUST_LTV_SAMPLE表を選択します。

![datasource.png](https://qiita-image-store.s3.amazonaws.com/0/108610/95d98fee-365f-f22a-9a2f-745e3c9d58d5.png)

**次**を選択すると使用する列を指定することもできますが、今回はすべての列を使うため、**終了**を押します。終了を押すと、中心の白い画面に表名の記されたデータソースノードが表示されます。

![datasource1.png](https://qiita-image-store.s3.amazonaws.com/0/108610/a38ede18-8ddb-1bd0-86fb-478da4b29c02.png)

##3. 元データに対してクラスタリングを行う##
データソースに対してクラスタリングを実行するには、ワークフロー・エディタから**クラスタリング**ノードをドラッグ&ドロップしてきます。

![setclustering.png](https://qiita-image-store.s3.amazonaws.com/0/108610/8d72cab2-b21a-228a-84d8-2446fc293730.png)

ドロップすると**クラスタリング構築**というノードが作成されます。この時点では右上にWarningのマークが出ており、実行することはできません。データソースノードを右クリックし、**接続**を選択します。接続を選択すると線が出てくるため、クラスタリング構築のノードに合わせてクリックします。

![join.png](https://qiita-image-store.s3.amazonaws.com/0/108610/7ef7f1ee-639f-2b9b-2731-f985ce29dfe6.png)

そうするとデータソースノードとクラスタリング構築のノードが矢印で結ばれます。

![joinedwclustering.png](https://qiita-image-store.s3.amazonaws.com/0/108610/8136d942-a185-9880-1c5a-675901d89776.png)

ここまでで実行する準備が整ったため、クラスタリング構築のノードを右クリックし、**実行**を選択します。

![runclustering.png](https://qiita-image-store.s3.amazonaws.com/0/108610/9518a859-6233-30ee-d8a9-2fa171afaaad.png)

実行が完了すれば、ノードの右上に緑色のチェックマークがつきます。これでクラスタリングは完了です。データソースとクラスタリング構築のノードを二つ持ってきて、矢印で結んで実行するだけでクラスタリング分析ができます。

##4. クラスタリングの結果を見る##
せっかくクラスタリングを行ったので、その結果についてみていきたいと思います。クラスタリング構築では、三つのアルゴリズム(k-Means,O-Cluster,EMアルゴリズム)がデフォルトだと同時に実行されて構築されます。今回は、k-Meansの結果についてみていきたいと思います。
クラスタリング構築ノードを右クリックして、モデルの表示から**CLUS_KM_x_x**を選択します。xとした部分は、クラスタリングモデルを構築した際に、名前が重複しないように数字が入って来ますので、それぞれの環境や実行した回数によって違う数字が入るかと思います。

![checkcluster.png](https://qiita-image-store.s3.amazonaws.com/0/108610/9f58fff3-4348-4317-b9ee-ddff75f8e992.png)

選択すると新たにタブが開き、クラスタリングモデルの結果を確認することができます。Oracle Database Cloud Serviceで提供されているk-Meansは正確には拡張k-meansとなっており、階層型のクラスタリングを構築します。デフォルトだと、末端のクラスタの数が10になるようにクラスタリングを行います。ツリー構造をGUIで確認でき、特定のクラスタを選択すると、重心やそのクラスタに入るための条件を確認することができます。

<img width="582" alt="treeofcluster.png" src="https://qiita-image-store.s3.amazonaws.com/0/108610/2e3774b9-969f-f4bc-f684-5abfdd8bc447.png">

ツリータブの横の**クラスタ**タブを選択すると、クラスタごとの属性別のヒストグラムを確認することができます。そのクラスタの各属性がどのような分布を持つかを確認することによって、機械が自動的にふるい分けたクラスタの特徴を見つけ出すことができます。

<img width="801" alt="histofcluster.png" src="https://qiita-image-store.s3.amazonaws.com/0/108610/9fb428ba-1be3-6b9d-68e6-203f475d6392.png">

他にも比較というタブからはクラスタ同士の相違点をチェックすることなど、自動的に分けられたクラスターを人間が理解できるように直感的にわかりやすい形で表示する機能を持っています。

##5. 分類モデルを構築する##

データソースに対して分類モデルを構築するには、ワークフロー・エディタから**分類**ノードをドラッグ&ドロップしてきます。
ドロップすると**分類構築**というノードが作成されます。クラスタリング分析のときと同じように、データソースノードを右クリックし、**接続**を選択し、分類ノードに合わせてクリックします。

分類ノードをクリックすると、ウィンドウが立ち上がります。分類はクラスタリングと違い、教師あり学習という種類の機械学習を行うため、正解データ(ラベル)がどれかを機械に教える必要があります。ウィンドウの中の**ターゲット**と書かれている箇所にラベルとなる列名を選択します。ケースIDは一意なキーがどの列かを機械に教えることによってパフォーマンスが向上します[^1]。
[^1]: 影響するのはパフォーマンスだけの為、指定しなくとも問題なく、分類モデルを構築できます。仮に一意でない列をケースIDとして指定すると、この後の実行でエラーが出て分類モデル構築が完了しません。

![settargetofprediction.png](https://qiita-image-store.s3.amazonaws.com/0/108610/147d7a62-85b1-ed0e-745c-e6ab37b6829d.png)

ターゲットとケースIDの選択が終われば、あとは**OK**を押します。OKを押すと、データソースノードと分類ノードが矢印で結ばれます。

![joinedwprediction.png](https://qiita-image-store.s3.amazonaws.com/0/108610/fdb24747-e8f7-e3d4-7e7c-a7846354a92f.png)

実行する準備が整ったため、分類ノードを右クリックし、**実行**を選択します。実行が完了すれば、ノードの右上に緑色のチェックマークがつきます。分類もクラスタリングと同じような手順で行うことができます。

##6. 分類モデルを比較する##
それでは作成した分類モデルを見ていきたいと思います。分類では、四つのアルゴリズム(DT,NV,GLMとSVM)がデフォルトだと同時に実行されます。クラスタリングは教師なし学習という種類の機械学習だったため、正解を求めるものではなく、モデルの精度などを考える必要はありませんでした。分類は教師あり学習のため、作成したモデルがどれくらいの精度を持つものかを把握する必要があります。

テスト結果を比較するには、分類構築ノードを右クリックして、**テスト結果の比較**を選択します。

![predictioncompare.png](https://qiita-image-store.s3.amazonaws.com/0/108610/758335d3-cda8-d20f-c518-cb336e8d16ee.png)

テスト結果の比較を選択するとタブが開き、実行したアルゴリズム全てをグラフィカルに比較することができます。

![predictionperformance.png](https://qiita-image-store.s3.amazonaws.com/0/108610/8c44d2b8-75b8-f2eb-4ab7-f4a710a14ec9.png)

**パフォーマンス**からは各モデルの予測信頼度や全体精度、平均精度等をアルゴリズムごとに棒グラフで比較して見れます。基本的には一番棒グラフが高いアルゴリズムがいいことになります。画面ショットの例だとディシジョン・ツリーが一番良さそうに見えます。ただ、これだけだと正しくターゲットを当てられた割合(真陽性:True Positive)、ターゲットであったのに当てられなかった割合(偽陽性:False Positive)、ターゲットでないのに間違ってターゲットとしたもの(偽陰性:False Negative)、ターゲットでないものを正しく当てられた割合(真陰性:True Negative)がわかりません。**パフォーマンス・マトリックス**タブを選択すると、各モデルの詳細精度を見ることができます。

![predictionperformancematrix.png](https://qiita-image-store.s3.amazonaws.com/0/108610/12d043ea-b00f-4574-118f-9a1204d61836.png)

パフォーマンス・マトリックスより、行を実際の値、列を予測として確認できます。スクリーンショットの例では、ディシジョン・ツリーのモデル(CLAS_DT_x_x)におけるTrue Positiveが83、False Positiveが23、False Negativeが56、True Negativeが242となっていることが確認できます。

この値を閾値を変えて全て見比べていくのも大変なので、True Positive Rateを縦軸に、False Positive Rate横軸にしたROC曲線(受信者動作特性曲線:Receiver Operatorating Characteristic curve)というものがあります。ROCタブから全モデルのROC曲線を確認できます。

![predictionroc.png](https://qiita-image-store.s3.amazonaws.com/0/108610/cf719e11-b20b-1616-8df4-d632002b10ba.png)

True PositiveとFalse Positiveの組み合わせなので、曲線が左上に近いところでカーブしているほど、ターゲットを正しく当てながら、漏れが少ないモデルとなります。曲線を一つの変数として評価する値はAUC(Area Under Curve)と呼ばれますが、ここでは**曲線の下の領域**として表示されています。この値が高いほど良いモデルといえます。

DM顧客の抽出、チャーン顧客分析などで、ターゲットの何割にアプローチしたらどれだけのTrue Positiveになるかだけを知りたいことも多くあります。そのような場合にはリフトチャートを使います。**リフト**タブを選択すると全モデルのリフトチャートを確認できます。

![predictionlift.png](https://qiita-image-store.s3.amazonaws.com/0/108610/3c6c4ebe-54a3-e8ff-3bc6-614f615758a6.png)

リフトチャートはTrue Positive Rateを縦軸に、アプローチした数を横軸としています。左上に急に立ち上がっているグラフほど、より少ない数のアプローチでターゲットに当たることができるため、効率の良いモデルとなります。今回のスクリーンショットの例だと、アプローチの数が少ない場合には、一般化線形モデルの精度がいいですが、アプローチの数がある程度増えてくるとディシジョン・ツリーがよりターゲットに当たる割合が多くなることがわかります。

リフトチャートまで、考えていくとターゲットに当たった際の収益とアプローチごとにかかるコストから、どれだけの利益が出るかを見たい場合があります。その場合には、**利益**タブを選択することによって、全モデルの最大利益を比較することができます。

![predictionbenefit.png](https://qiita-image-store.s3.amazonaws.com/0/108610/dcaa89ba-dbb6-dd7b-6521-44c5981e3013.png)

デフォルトでは、利益設定が開始コスト、増分収益、増分コスト、予算がすべて1で母集団が100と設定されています。実際のビジネスにあった値に更新し、**OK**を選択することによって、値を反映したグラフに書き換わります。

![predictionbenefit2.png](https://qiita-image-store.s3.amazonaws.com/0/108610/0d9520e7-02ec-873b-5616-2a4ce409fe7c.png)

増分収益を5、予算を30に更新した場合の状態を下に載せます。

![predictionbenefit.png](https://qiita-image-store.s3.amazonaws.com/0/108610/1649102d-469d-61b3-b7e2-ea680fb31208.png)

モデルを作るの方法はシンプル化されていますが、モデルを見る方法は様々な方法が提供されています。用途に合ったモデルの精度の確認方法が一通り提供されていることを確認できるかと思います。

##7. 分類モデルを見る##
四つのアルゴリズム(DT,NV,GLMとSVM)で分類モデルを構築し、モデルの精度に関してみてきましたが、ディシジョン・ツリーの中身をもう少し見ていきたいと思います。ワークフローの画面に戻り、分類構築のノードを右クリックし、**モデルの表示**から、ディシジョン・ツリーに該当するモデルを選択します。今回の例だと**CLAS_DT_x_x**がディシジョン・ツリーに該当するので、こちらを選択します。

![predictioncheckdt.png](https://qiita-image-store.s3.amazonaws.com/0/108610/7d5461e6-463f-ff6c-57f1-d8faf17fae35.png)

タブが開いて、ディシジョン・ツリーがどのような条件を元に分類しているかを確認できます。各ノードごとにラベルとして設定した列の値の割合を表示しながら、どの列を元に条件分岐しているかが表示されています。特定のノード[^2]を選択すると、そのノードに入るための条件式、信頼度とサポート(出現頻度)が確認できます。
[^2]: ここでいうノードはディシジョン・ツリーにおいて作成されるノードを意味しているため、データフローを設計する際のノードとは無関係です。


<img width="402" alt="dt.png" src="https://qiita-image-store.s3.amazonaws.com/0/108610/70818e7e-f122-711e-ff44-853808f5bcf3.png">

モデルによって見える内容が違いますが、人の感覚でモデルのロジックをとらえやすいものはディシジョン・ツリーと一般化線形モデルになると思います。同じ手順で一般化線形モデルのモデルを選択すると各列がどれくらい影響があるのかがわかります。

<img width="404" alt="glm.png" src="https://qiita-image-store.s3.amazonaws.com/0/108610/1d9eaad2-af7a-1ac3-d986-b9684a7d220f.png">

##8. 予測分析を行う##
モデルも無事に作成できているので、新しいデータに対して予測を行って行きます。ワークフロー・エディタから**適用**ノードとデータソースノードをドラッグ&ドロップしてきます。データソースノードは本来は予測するテーブルを選択しますが、今回はデモデータを使用しているため、学習用で使用したINSUR_CUST_LTV_SAMPLE表を再度選択します。内部的には同じ列名でスコアリングして動作する仕組みなので、列名さえ同じであれば問題ありません。わかりやすくするために、データソースのアイコンの名前だけ(INSUR_CUST_LTV_SAMPLE->INSUR_CUST_LTV_APPLY)変えています。

![apply.png](https://qiita-image-store.s3.amazonaws.com/0/108610/1ac742e5-9ca9-3df9-b42c-afcefb30618e.png)

分類構築とINSUR_CUST_LTV_APPLYをそれぞれ右クリックして**適用**ノードと結びます。これまでは、一つのノードを一つのノードと接続していましたが、適用ノードはどのモデルをどのデータに反映させるかを表すために二つのノードと結ぶ必要があります。このまま実行しても結果が出力されますが、出力結果をわかりやすくするために、出力結果を編集します。適用ノードを右クリックして**編集**を選択します。

![edit.png](https://qiita-image-store.s3.amazonaws.com/0/108610/2bc40289-ca72-5f10-4f5e-7a9672c0c138.png)

ウィンドウが開かれるとこのまま出力される予定の列がすべて表示されます。このまま実行すると全モデルでの予測値などが表示されることになるので、今回はディシジョン・ツリー以外の出力はなくすことにします。**自動設定**のチェックボックスがチェックされていると編集できないため、チェックを外して不要な列を削除していきます。

![edit1.png](https://qiita-image-store.s3.amazonaws.com/0/108610/020d74a6-f09d-d492-a6ab-b026fbf1cd68.png)

また、このままでは予測値しか出力されないため、**追加出力**タブから追加したい列名を選択します。今回は、CUSTOMER_ID列を追加します。

![edit2.png](https://qiita-image-store.s3.amazonaws.com/0/108610/c5232177-cbf4-9c1c-ec5c-3d887aaca0f2.png)

あとは、これまでと同様に、適用ノードを実行すれば完了です。実行が完了したら、適用ノードを右クリックして**データの表示**を選択します。

![dataview.png](https://qiita-image-store.s3.amazonaws.com/0/108610/448b922b-b2fa-5cf9-ee01-3ec9b1849587.png)

CUSTOMER_IDごとに予測値となるyes,noが出力されているのを確認できるかと思います。

![dataview2.png](https://qiita-image-store.s3.amazonaws.com/0/108610/58e42714-cf9d-98b9-f5a2-e4c9e1a33298.png)

Oracle Database Cloud Service上で機械学習を試してみたはこれで終了となります。
次回はこの環境で実際にデータをロードして分析を行い、特定の分析に深く焦点を当てていきたいと思います。

#注釈#