[In - DB Analytics] Oracle Database で Data Mining

# はじめに
この記事では、Oracle Data Mining の機能を活用した Data Mining 手順例を記載します。Oracle Data Mining は Oracle Database Enterprise Edition の Advanced Analytics Option に含まれているコンポーネントの一つです。

※2019年12月にAdvanced Analytics Option は Oracle Machine Learning としてOracle Database に包含され、Edition に関係なく活用できることになりました。 
　参考：https://www.oracle.com/database/technologies/oaa-osg-licensing-change-faq.html

# Oracle Data Mining とその活用メリット
Oracle Data Mining の特徴として以下が挙げられます。

- 主なマイニング機能は DBMS_DATA_MINING パッケージとしてDBにビルトイン済み
- インターフェースとしてPL/SQL, SQLが用意されているためインプリが容易

Oracle Data Mining等による In - Database Analytics の特徴として以下が挙げられます。

- DBのセキュリティ・メカニズムで保護
- データの移動や準備にかかるマイニングプロセスを簡略化可能
- DBサーバーのリソースを活用可能

Oracle Data Mining には代表的なマイニング機能が含まれています。以下は主なマイニング機能とアルゴリズムです。

* 教師あり機能、アルゴリズム
    * 分類：ディシジョン・ツリー、明示的セマンティック分析、Naive Bayes、ランダム・フォレスト
    * 時系列：指数平滑法
    * 分類と回帰：一般化線形モデル、ニューラル・ネットワーク、サポート・ベクター・マシン
    * 属性評価：最小記述長

* 教師なし機能、アルゴリズム
    * 相関：Apriori
    * 属性評価:CUR行列分解
    * クラスタリング：期待値最大化、k-Means、直交パーティショニング・クラスタリング
    * 特徴抽出：明示的セマンティック分析、Non-Negative Matrix Factorization、特異値分解および主成分分析  
    * 異常検出：1クラス・サポート・ベクター・マシン

# Oracle Data Mining 実行手順
例としてランダム・フォレストを活用した分類を実行してみます。

### ランダム・フォレストとは
ディシジョン・ツリーを応用した手法。ディシジョン・ツリーは多変量の教師データから条件式を作り、予測の際には root nodeから順番に条件を辿り、leaf nodeに到達すると予測結果を返すアルゴリズム。
ランダム・フォレストはディシジョン・ツリーの集団学習を行い、性能の良い複数学習器の予測結果を多数決で結合する（アンサンブル学習） 。データに前提条件を設けず高精度なクラス分類が可能。
用途としては、無料会員・有料会員の混在するテストデータでモデルを作成し、スコアリング用データで有料会員になる可能性の高い顧客の分類や、機器のセンサーデータから正常・異常の分類等に利用可能です。

### 手順の試行環境

- Oracle Database 18.3 Enterprise Edition - Advanced Analytics Option

### ユーザー準備

```
-- ユーザー作成
CREATE USER dmuser IDENTIFIED BY dmuser
       DEFAULT TABLESPACE users
       TEMPORARY TABLESPACE temp
       QUOTA UNLIMITED ON users;

-- データ・マイニングの権限付与
GRANT CREATE MINING MODEL TO dmuser;
GRANT CREATE SESSION TO dmuser;
GRANT CREATE TABLE TO dmuser;
GRANT CREATE VIEW TO dmuser;
GRANT EXECUTE ON CTXSYS.CTX_DDL TO dmuser;

-- トレーニング用テーブル（またはビュー）へのアクセス権限付与
GRANT SELECT ON yimaaa.customer_train TO dmuser;
-- 精度評価用テーブル（またはビュー、列はトレーニング用と同一）へのアクセス権限付与
GRANT SELECT ON yimaaa.customer_test TO dmuser;
-- スコアリング用テーブル（またはビュー）へのアクセス権限付与
GRANT SELECT ON yimaaa.customer_apply TO dmuser;

-- データ・マイニングのシステム権限
GRANT CREATE MINING MODEL TO dmuser;
GRANT SELECT ANY MINING MODEL TO dmuser;
```

### モデル設定表の作成
表名は任意ですが、列名とデータタイプは固定です。

```
CREATE TABLE RF_SETTING(setting_name varchar2(30), setting_value varchar2(4000));
INSERT INTO RF_SETTING VALUES ('ALGO_NAME', 'ALGO_RANDOM_FOREST');
commit;
```

アルゴリズム名は以下を参照
https://docs.oracle.com/cd/E96517_01/arpls/DBMS_DATA_MINING.html#GUID-409BAB5C-3D02-4495-A68C-F117033C555B

アルゴリズムの設定は以下を参照。適宜設定してください。
https://docs.oracle.com/cd/E96517_01/arpls/DBMS_DATA_MINING.html#GUID-24047A09-0542-4870-91D8-329F28B0ED75

### マイニング・モデルの作成

```
BEGIN
  DBMS_DATA_MINING.CREATE_MODEL(
  model_name          => 'RF_MODEL',
  mining_function     => dbms_data_mining.classification,
  data_table_name     => 'CUSTOMER_TRAIN', -- 学習用テーブル名（以下id, status列の他、学習させるための説明変数をそれぞれ列として保持）
  case_id_column_name => 'ID',             -- テーブルのケースID
  target_column_name  => 'STATUS',         -- 学習用テーブルのターゲット列（ここでは0 or 1）
  settings_table_name => 'RF_SETTING',     -- モデル設定表
  data_schema_name    => 'YIMAAA'          -- 学習用テーブルの保持スキーマ
  );
END;
/
```

### 精度評価用データを適用して正解率を算出
`PREDICTION`ファンクションを用いてstatusを予測し予測と実績が一致する件数をカウントすることで正解率を算出します。
```
SQL> SELECT
         ROUND(SUM(correct)/COUNT(*),4) AS accuracy
     FROM (SELECT DECODE(status,
                         PREDICTION(RF_MODEL USING *),
                         1,
                         0) AS correct
             FROM customer_test);

    ACCURACY
------------
      0.8255

```
以下のコマンドで混同行列も出力しておきます。
```
SQL> SELECT
         class                        AS actual_target_value, 
         PREDICTION(RF_MODEL USING *) AS predicted_target_value,
         COUNT(*)                     AS value
     FROM
         customer_test
     GROUP BY
         class,
         PREDICTION(RF_MODEL USING *)
    ORDER BY 1,2;

ACTUAL_TARGET_VALUE,PREDICTED_TARGET_VALUE,      VALUE
-------------------,----------------------,-----------
                  0,                     0,        447
                  0,                     1,         53
                  1,                     0,         81
                  1,                     1,        187

```


### マイニング・モデルにスコアリング用データを適用

```
BEGIN
  DBMS_DATA_MINING.APPLY (
  model_name          => 'RF_MODEL',       -- 適用するモデル名
  data_table_name     => 'CUSTOMER_APPLY', -- スコアリング用テーブル、またはビュー
  case_id_column_name => 'ID',
  result_table_name   => 'RF_MODEL_RESULT', -- 結果が保存される表
  data_schema_name    => 'YIMAAA' -- スコアリング用テーブルの保持スキーマ 
  );
END;
/
```

CUSTOMER_APPLYテーブルはスコアリング用のためSTATUS列は不要です。

### 適用結果確認
DBMS_DATA_MINING.APPLYプロシージャの"result_table_name"オプションにて指定したテーブルに結果があります
IDごとにPREDICTION（予測）とそのPROBABILITY（確率）が算出されています。
このケースでは、学習用テーブルのターゲット列"STATUS"には"1"か"0"が指定されていたため、PREDICTIONは"1", "0"それぞれの確率となっています。

```
SQL> SELECT
         id,
         prediction
         probability
    FROM
        dmuser.rf_model_result
    WHERE prediction = 1;

         ID, PREDICTION        ,PROBABILITY
------------,------------------,-----------
       151  ,1                 ,  2.15E-001
       152  ,1                 , 1.985E-001
       153  ,1                 , 1.985E-001
       154  ,1                 , 2.131E-001
　　　　・
　　　　・
　　　　・
```
以下のようにSQL文でモデルにデータを適用することもできます。
STATUSが0である確率を算出しています。
`USING *`は全列をモデルに適用することを示します。
列情報は学習させている表の列と正解ラベルを保持する列以外が同じである必要があります。
```
SQL> SELECT
         PREDICTION(RF_MODEL USING *)                         AS predict_class,
         ROUND(PREDICTION_PROBABILITY(RF_MODEL, 0 USING *), 2) AS probability
     FROM (
         SELECT
             0    AS col1,
  　         101  AS col2,
            ...
         FROM DUAL
     )
     ;

"REDICT_CLASS","PROBABILITY"
"0",.65
```

結果の判定にあたり、影響度の大きいカラムは"dm$va＜モデル名＞"で確認ができます。

```
SQL> col attribute_name for a10
SQL> SELECT attribute_name, attribute_importance FROM dm$varf_model ORDER BY attribute_importance;

ATTRIBUTE_,ATTRIBUTE_IMPORTANCE
----------,--------------------
COL9      ,          5.425E-001
COL2      ,          3.431E-001
  ・
  ・
  ・
```

### その他ディクショナリ・ビュー
作成されたモデルの確認

```
col model_name for a15
col mining_function for a15
col algorithm for a15
col ALGORITHM_TYPE for a15
col creation_date for a22
SELECT model_name, mining_function, algorithm ,algorithm_type, creation_date FROM user_mining_models WHERE model_name = 'RF_MODEL';

MODEL_NAME     ,MINING_FUNCTION,ALGORITHM      ,ALGORITHM_TYPE ,CREATION_DATE
---------------,---------------,---------------,---------------,----------------------
RF_MODEL       ,CLASSIFICATION ,RANDOM_FOREST  ,NATIVE         ,2019/05/11 00:47:34
```

モデルの作成により作成されるビューの確認

```
SQL> SELECT * FROM user_mining_model_views WHERE model_name = 'RF_MODEL';

MODEL_NAME     ,VIEW_NAME      ,VIEW_TYPE
----------------------------------------------------------
RF_MODEL       ,DM$VARF_MODEL  ,Variable Importance
RF_MODEL       ,DM$VCRF_MODEL  ,Scoring Cost Matrix
RF_MODEL       ,DM$VTRF_MODEL  ,Classification Targets
RF_MODEL       ,DM$VGRF_MODEL  ,Global Name-Value Pairs
RF_MODEL       ,DM$VSRF_MODEL  ,Computed Settings
RF_MODEL       ,DM$VWRF_MODEL  ,Model Build Alerts
```

モデルの設定内容

```
SQL> col setting_value for a30
SQL> col setting_name for a30
SQL> SELECT * FROM  user_mining_model_settings WHERE model_name = 'RF_MODEL';

MODEL_NAME     ,SETTING_NAME                  ,SETTING_VALUE             ,SETTING_TYPE
---------------,------------------------------,--------------------------,---------------------
RF_MODEL       ,ALGO_NAME                     ,ALGO_RANDOM_FOREST        ,INPUT
RF_MODEL       ,PREP_AUTO                     ,ON                        ,DEFAULT
RF_MODEL       ,TREE_TERM_MINPCT_NODE         ,.05                       ,DEFAULT
RF_MODEL       ,TREE_TERM_MINREC_SPLIT        ,20                        ,DEFAULT
RF_MODEL       ,ODMS_RANDOM_SEED              ,0                         ,DEFAULT
RF_MODEL       ,TREE_IMPURITY_METRIC          ,TREE_IMPURITY_GIN         ,DEFAULT
RF_MODEL       ,CLAS_MAX_SUP_BINS             ,32                        ,DEFAULT
RF_MODEL       ,CLAS_WEIGHTS_BALANCED         ,OFF                       ,DEFAULT
　・
　・
　・
```

以上です。