[OCI]Autonomous Database：Database ActionsとAutoMLを使って弁当の需要予測

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1930162/aee0e5eb-de2c-5fa0-99f6-c285e55c286a.png)
# はじめに
Database ActionsはAutonomous Databaseに同梱されているGUIツールです。データのロードや管理、監視を行うことのできるWebベースのインタフェースです。

AutoMLはDatabase Actionsと同様に、Autonomous Databaseに同梱されている、機械学習モデルの作成を自動で行ってくれるツールです。

今回は<a href="https://signate.jp/competitions/24" target="_blank" rel="noopener noreferrer">SIGNATEのお弁当の需要予測チュートリアル</a>を題材に、Database Actionsでデータ分析→データ加工→モデル作成という流れで精度を高めてみようと思います。

# 前提条件
Autonomous Data Warehouseを作成済みであること

参考：<a href="https://oracle-japan.github.io/ocitutorials/database/adb101-provisioning/" target="_blank" rel="noopener noreferrer">101: ADBインスタンスを作成してみよう</a>


# 生データでの精度
まずは、SIGNATEのサイトからダウンロードしたtrain.csvをデータ・ソースにAutoMLでモデル作成をしてみます。
1. Oracle Machine Learning(OML) ユーザーを作成
    Database Actionsのデータベース・ユーザーをクリックします。
    ![create_user1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1930162/bc1492b6-791f-8ab8-9565-d5359888822e.png)
    **+ユーザーの作成**をクリックします。
    ![create_user2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1930162/ec15a9d0-4971-53c0-bcff-87d4530dcded.png)
    以下の項目を入力し、**ユーザーの作成**をクリックします。
    + ユーザー名：**OMLUSER**
    + パスワード：*********
    + 表領域の割当て制限 DATA：**UNLIMITED**
    + OMLのトグルボタンを**ON**
    + Webアクセスのトグルボタンを**ON**
    ![create_user3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1930162/c443c7f2-94d4-1580-fbf2-6eff2ad15202.png)

1. データのロード
    OMLUSERでDatabase Actionsにログインし、**データ・ロード**をクリックします。
    ![data_load1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1930162/aacb3af1-6187-8d2b-cfe9-e52f36e2c30e.png)
    デフォルトのローカル・ファイルをチェックしたまま、**次**をクリックします。
    ![data_load2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1930162/48325e1e-edc5-6e7c-7668-7b8f54cb07e4.png)
    **train.csv**をドラッグ&ドロップし、ロードを開始します。特に編集はしません。
    ![data_load3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1930162/707fdfd0-c145-0b46-35cc-360be3830407.png)
    「207行をロードしました」と表示されます。
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1930162/970872a8-9445-6fe0-9c55-82fe077e0139.png)

1. データの確認
    ロードしたデータの確認をします。起動パッドに戻り、**SQL**をクリックします。
    ![data_check1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1930162/9fab49ed-1a56-12a0-ea5e-a839dda5b738.png)
    TRAIN表をSELECTします。
    ```sql
    SELECT * FROM TRAIN;
    ```
    ![data_check2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1930162/a65dce18-4b12-f472-930b-98c6b7d37092.png)
    2列目の**Y**が目的変数、つまりお弁当の売れた個数です。その他、DATETIMEやSOLDOUT(売り切れたかどうか)、nullを含むREMARKS列などがあります。

1. モデルの作成
    TRAIN表から需要予測を行うモデルを作成します。起動パッドから**ORACLE MACHINE LEARNING**をクリックします。
    ![create_model1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1930162/0e0d113c-1d26-bc79-8a71-d6a185251b55.png)
    ユーザー名：OMLUSERとパスワードを入力し、**サインイン**します。
    ![create_model2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1930162/b31be089-afc4-946f-8898-cf0a8945d40b.png)
    クイック・アクションの**AutoML**をクリックします。
    ![create_model3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1930162/3e102530-58d7-39ed-46e6-d3b441a067e2.png)
    AutoML実験というページに遷移するので、**+作成**をクリックします。
    ![create_model4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1930162/2dd78791-97a3-55a4-2f3d-cfe979f63354.png)
    以下のように項目を入力していきます。
    名前：**bento_pred1**
    データ・ソース：**OMLUSER.TRAIN**
    予測：**Y**
    予測タイプ：**回帰**
    ![create_model5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1930162/d74ffae8-01f6-c798-b16e-91c182ed0a47.png)
   追加設定は以下です。
    最大上位モデル(指定した数のアルゴリズムでそれぞれモデル作成を行う)：**2**
    最大実行期間(時間)：8(デフォルト)
    データベース・サービス・レベル(データベースのリソース配分)：**高**
    モデル・メトリック：**R2**
    ![create_model6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1930162/0a25247e-d71b-2235-fe44-9832402acd38.png)
    こちらで**開始**をクリックします。今回は**より良い精度**を選択します。
    ![create_model7.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1930162/58a7fe77-fc88-21e8-32f5-d7fafd4953ef.png)
    モデルの作成が完了しました。Support Vector Machine(ガウス)のR2は**0.6160**となりました。
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1930162/d6f840f9-4a36-cd60-89cb-37d167dbfd00.png)
    0.6160は現実的な数値ではありますが精度が高いとは言えません。
    Database Actionsの各種機能を使って特徴量エンジニアリングを行うことで、この精度を上げてみようと思います。

# Database Actions でデータ分析
TRAIN表の各カラムは以下になっています。
+ DATETIME：日付
+ WEEK：曜日（月～金）
+ SOLDOUT：完売フラグ（0：完売せず, 1：完売）
+ NAME：メインメニュー
+ KCAL：おかずのカロリー
+ REMARKS：特記事項
+ EVENT：お弁当持ち込み可の社内イベント
+ PAYDAY：給料日フラグ（1:給料日）
+ WEATHER：天気
+ PRECIPITATION：降水量。ない場合は"-"
+ TEMPERATURE：気温
+ Y：販売数（目的変数）

まずはDATETIMEとYに関係がないか調べてみます。
Database Actionsの**データ分析**をクリックします。
![data_analytics1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1930162/d000cb0f-e81f-2153-6084-7c67df1e3916.png)
**分析ビューの作成**をクリックします。
![data_analytics2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1930162/4536355e-c285-3372-1f0f-ccd28302adc4.png)
**階層およびメジャーの作成**をクリックします。
![data_analytics3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1930162/585beae5-a543-eac9-9926-d2bc51c31493.png)
**階層**をクリックし、DATETIMEを追加します。
![data_analytics4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1930162/2c0bc246-502c-4706-71de-eae2ba84570e.png)
分析ビューの作成が完了したら、DATETIMEとYの折れ線グラフを表示してみます。
![data_analytics6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1930162/a53c0ece-a0f8-7060-01fd-bb5b096379ee.png)
所々スパイクがあるものの、月日が経つにつれYが減少していっていることが分かります。
経過日数がYに影響を与えている可能性が高そうです。
ということで、経過日数を表すDAYS列を追加します。
```sql
ALTER TABLE TRAIN ADD (DAYS NUMBER); 
UPDATE TRAIN T1
SET DAYS = (SELECT COUNT(*) FROM TRAIN T2 WHERE T2.DATETIME <= T1.DATETIME);
COMMIT;
```
他の特徴量についても見てみます。
分析ビューの編集で、**階層の追加**で**REMARKS**を追加し、更新します。
![data_analytics7.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1930162/2f36ac81-560d-89f0-07cd-3309f5d25393.png)

X軸をRemarks、Y軸をYとする棒グラフのレポートを作成します。
![data_analytics8.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1930162/cedac486-05d4-0d0d-ffa7-1748af322df2.png)
Remarks列が**お楽しみメニュー**のときに売上数(Y)が増えていることが分かりました。
ということでRemarks列がお楽しみニューかどうか判別するFUN列を追加します。（特徴量をあまり増やさないようにRemarks列は削除しています。）
```sql
ALTER TABLE TRAIN ADD (FUN NUMBER);
UPDATE TRAIN
SET TRAIN.FUN = CASE TRAIN.REMARKS WHEN 'お楽しみメニュー' THEN 1 ELSE 0 END;
COMMIT;
ALTER TABLE TRAIN DROP COLUMN REMARKS;
```

**Weather列**についても同様に見てみます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1930162/d80b4332-cdef-fea6-1acd-4983839d550b.png)
Weatherが快晴、晴れ、曇の日と、それ以外の天気の日で売上数(Y)に大きな差があります。
ということで、Weather列が快晴、晴れ、曇の日は0、それ以外の日は1とする**RAIN列**を新たに追加します。
```sql
ALTER TABLE TRAIN ADD (RAIN NUMBER);
UPDATE TRAIN
SET RAIN = 
    CASE WHEN WEATHER IN ('快晴', '晴れ', '曇') THEN 0 ELSE 1 END;
COMMIT;
ALTER TABLE TRAIN DROP COLUMN WEATHER;
```

また、日付列であるDATETIME列は、2023/5現在AutoMLでは扱えないDATE型であるため、DATETIME列はNUMBER型のYEAR列とMONTH列に分割します。
```sql
ALTER TABLE TRAIN ADD (YEAR NUMBER, MONTH NUMBER);
UPDATE TRAIN SET YEAR = EXTRACT(YEAR FROM DATETIME), MONTH = EXTRACT(MONTH FROM DATETIME);
ALTER TABLE TRAIN DROP COLUMN DATETIME;
```

最後に、いくつかの列で欠損値があるので、SQLで補完しておきます。
```sql
-- KCAL列がNULLの場合、平均値で補完
UPDATE TRAIN
SET KCAL = (SELECT TRUNC(AVG(KCAL), 0) FROM TRAIN)
WHERE KCAL IS NULL;

-- PAYDAY列がNULLの場合、0で補完
UPDATE TRAIN
SET PAYDAY = 0
WHERE PAYDAY IS NULL;

-- EVENT列がNULLの場合、'なし'で補完
UPDATE TRAIN
SET EVENT = 'なし'
WHERE EVENT IS NULL;

COMMIT;
```

# モデル作成
特徴量エンジニアリング後、再度AutoMLでモデル作成を行ってみます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1930162/4f24016e-292b-b0d5-68bb-05b693899659.png)
結果は以下のようになりました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1930162/511f5e5c-bfc5-af13-37f2-6b7efa597f82.png)
80%には満たないですが、生データと比べると16%精度が上がりました。
より細かいデータ分析をしていけば、さらに精度は上げることができます。

# まとめ
今回、作業としては、Database Actionsでデータロード→データ分析でデータの傾向把握→SQLで特徴量追加→モデル作成で完結しています。
Autonomous Databaseに付随しているDatabase Actionsは、データのロード・分析・データ変換などデータ活用に役立つ機能が一つにまとめられています。
さらに、同じく付属ツールであるOracle APEXでは今回のモデルを使った需要予測を行うWebアプリまで作成できます。
簡単すぐにデータベース運用、およびアプリ開発ができるのでぜひ試してみてください。

[Autonomous DatabaseはAlways Freeでも利用可能です！]
https://www.oracle.com/jp/cloud/free/