Google Cloud で金融サービスの傾向モデルを構築する

このチュートリアルでは、Google Cloud でデータを探索して scikit-learn 機械学習(ML)モデルを構築する方法について説明します。このチュートリアルでは、ユースケースとして金融サービスの予測(購入傾向)モデルを使用します。

傾向モデルは、金融業界で見込み顧客の購入傾向を分析するために広く使用されています。企業では多くの場合に、柔軟性が低くスケーリングが困難なオンプレミス ソリューションが使用されています。このチュートリアルでは、Google Cloud の柔軟でサーバーレスの ML モデルについて説明します。このモデルは、ビジネス ワークフローの一部としてデプロイできます。

このチュートリアルで説明するベスト プラクティスは、金融サービスに限らず、幅広い ML ユースケースに適用できます。

この記事は、次のテクノロジーについて理解していることを前提としています。

目標

  • BigQuery、AI Platform Notebooks、AI Platform を使用して、Google Cloud でデータを探索し、サーバーレス ML scikit-learn モデルを構築するためのベスト プラクティスを学習する。
  • pandas プロファイリングLime などのオープンソース コンポーネントを使用して、データとモデルを詳しく分析する方法について理解する。
  • モデルを比較して最適なモデルを選択する方法を学習する。
  • scikit-learn のハイパーパラメータ調整の使用方法を学習する。
  • scikit-learn モデルをマネージド API として Google Cloud にデプロイする。

アーキテクチャ

このチュートリアルの ML モデルでは、次の Google Cloud コンポーネントを使用します。

  • BigQuery にトレーニング データを格納します。
  • Notebooks のノートブックを使用して、プロファイリングとトレーニングを実行します。
  • AI Platform でスケーラブルなトレーニングと予測を行います。

次の図に、このモデルのアーキテクチャを示します。

このチュートリアルで使用する機械学習モデルのアーキテクチャを表す図。

このアーキテクチャでは、次のような機能を実行します。

  • 保存。BigQuery にトレーニング データを保存します。
  • プロファイリング。BigQuery を使用してデータを取得し、そのデータを pandas データフレームとして AI Platform Notebook に読み込みます。その後、pandas で基本的な前処理を行います。
  • モデリング。scikit-learn を使用して複数のモデルをテストし、最もパフォーマンスの高いモデルを選択します。次に、Lime を使用して、選択した予測器を記述します。
  • トレーニング。AI Platform を使用してトレーニングと予測のモデルをパッケージ化します。

このチュートリアルでは、他のアプローチよりも導入が容易であることから、pandasscikit-learn を使用しています。このアプローチには次のような利点があります。

  • スケーラビリティ。Google Cloud では、トレーニングと予測のスケーリングを容易に行うことができます。
  • 透明性。Lime と pandas のプロファイリングにより、データとモデルに関する分析情報が得られます。
  • 柔軟性。オープンソース モデルを移植して再利用できます。
  • シンプル。pandas と scikit-learn を使用すると、すぐに結果を得ることができます。

このチュートリアルのトレーニング データはメモリに収まるように設計されています。大規模なデータセットを処理できる ML モデルを構築する場合や、アクセラレータを使用して分散トレーニングを行う場合は、TensorFlow と AI Platform による分散トレーニングデータの前処理に関する Dataflow のドキュメントの記事をご覧ください。

費用

このチュートリアルでは、課金対象である次の Google Cloud コンポーネントを使用します。

料金計算ツールを使うと、予想使用量に基づいて費用の見積もりを生成できます。新しい Google Cloud ユーザーは無料トライアルをご利用いただけます。

このチュートリアルを終了した後、作成したリソースを削除すると、それ以上の請求は発生しません。詳しくは、クリーンアップをご覧ください。

始める前に

  1. Cloud プロジェクトを選択または作成します。

    [プロジェクトの選択] ページに移動

  2. Cloud プロジェクトに対する課金を有効にします。

    課金を有効にする方法について

  3. プロジェクトでBigQuery, AI Platform, and Compute Engine API を有効にします。

    API を有効にする

Notebooks の開始

次の手順で、Notebooks インスタンスを作成します。

  1. Cloud Console で、AI Platform の [ノートブック インスタンス] ページに移動します。

    [ノートブック インスタンス] ページに移動

  2. メニューバーで [新しいインスタンス] をクリックして、[TensorFlow 1.x] フレームワークを選択します。

  3. [Without GPUs] を選択します。

  4. [新しいノートブック インスタンス] ダイアログで、次のオプションを確認します。

    • デフォルトのインスタンス名をそのまま使用することも、編集することもできます。
    • [カスタマイズ] をクリックすると、リージョン、ゾーン、機械学習フレームワーク、マシンタイプ、GPU のタイプ、GPU の数、ブートディスクのタイプ、サイズを選択できます。GPU を追加する場合は、[NVIDIA GPU ドライバを自動的にインストールする] チェックボックスをオンにします。
  5. [作成] をクリックします。

    Notebooks で新しいインスタンスが作成されるまでには数分かかります。

GitHub からノートブックのクローンを作成して設定する

Notebooks インスタンスが作成されたので、このチュートリアル用のノートブック ファイルをダウンロードできます。このノートブックのすべてのセルには、値が事前に設定されています。これらのセルを使用してデータセットを分析し、ML モデルを構築します。

  1. Cloud Console で、AI Platform の [ノートブック インスタンス] ページに移動します。

    [ノートブック インスタンス] ページに移動

  2. 作成したインスタンスで [JupyterLab を開く] をクリックします。

  3. [ランチャー] ページで [ターミナル] をクリックします。

    ノートブック インスタンスの [ターミナル] ボタンのスクリーンショット

  4. ターミナル ウィンドウに次のコマンドを貼り付け、[実行] をクリックします。

    git clone https://github.com/GoogleCloudPlatform/professional-services.git
    

    出力は次のようになります。

    Cloning into 'professional-services'...
    remote: Enumerating objects: 24, done.
    remote: Counting objects: 100% (24/24), done.
    remote: Compressing objects: 100% (20/20), done.
    remote: Total 5085 (delta 8), reused 13 (delta 4), pack-reused 5061
    Receiving objects: 100% (5085/5085), 50.50 MiB | 19.47 MiB/s, done.
    Resolving deltas: 100% (2672/2672), done.
    

    クローンの作成が完了すると、隣接するペインに professional-services という新しいフォルダが表示されます。

  5. ノートブックのファイル リソースで [professional-services] > [examples] > [cloudml-bank-marketing] の順に選択して、[bank_marketing_classification_model.ipynb] をダブルクリックします。

  6. ノートブックでセル 1 のコードを実行し、Lime パッケージがインストールされていることを確認します。

    Python パッケージが存在しないことを示すエラーが表示された場合は、セル 1 のコードの 1 行目を削除します。このセルにはコマンド install pandas-profiling が含まれています。

  7. インストール後、[Kernel] タブをクリックして [Restart Kernel] をクリックします。

  8. Colab で実行している場合を除き、セル 2 はスキップします。

  9. ターミナル ウィンドウでセル 3 を実行します。ここには [2] が含まれています。

  10. 次のコマンドでセルを実行します。PROJECT_ID は実際の Cloud プロジェクト ID に置き換えます。

    %env GOOGLE_CLOUD_PROJECT=PROJECT_ID
    
  11. セル 7 までスキップしてコードを更新します。

    import os
    your_dataset = 'your_dataset'
    your_table = 'your_table'
    project_id = os.environ["GOOGLE_CLOUD_PROJECT"]
    

    your_datasetyour_table は任意の名前に置き換えます。

    データセットの命名について詳しくは、BigQuery の命名規則をご覧ください。

  12. セル 7 のコードを更新したら、環境変数を設定して、BigQuery のデータセットとテーブルを作成します。

    !bq mk -d {project_id}:{your_dataset}
    !bq mk -t {your_dataset}.{your_table}
    

    出力は次のようになります。

    Dataset 'your_project.your_dataset' successfully created
    Table 'your_project.your_dataset.your_table' successfully created
    
  13. 次のセルを実行して CSV ファイルをダウンロードし、data.csv としてローカルに保存します。このチュートリアルでは、UCI Bank Marketing Dataset を使用します。

    !curl https://storage.googleapis.com/erwinh-public-data/bankingdata/bank-full.csv --output data.csv
    
  14. セルを実行して data.csv ファイルを BigQuery テーブルにアップロードします。

    !bq load --autodetect --source_format=CSV --field_delimiter ';' --skip_leading_rows=1 --replace {your_dataset}.{your_table} data.csv
    

    出力は次のようになります。

    Upload complete.
    Waiting on job … (2s) Current status: DONE
    

BigQuery からデータを取得して pandas データフレームを作成する

pandas データフレームを作成するには、Google Cloud クライアント ライブラリを使用して BigQuery からデータを取得し、pandas データフレームに読み込みます。このライブラリの組み込み機能を使用すると、追加のコードを記述することなく、BigQuery から pandas データフレームにデータを簡単に取り込むことができます。

  • このコードが含まれているセルを実行します。

    client = bq.Client(project=project_id)
    df = client.query('''
      SELECT *
      FROM `%s.%s`
    ''' % (your_dataset, your_table)).to_dataframe()
    

上記の SQL ステートメントは、pandas データフレームの作成に使用されるデータを返します。SQL ステートメントを使用するメリットは、SQL ステートメントを変更して BigQuery から別のデータサンプルを取得できることです。

pandas プロファイリングを使用してデータを探索する

  • このコードが含まれているセルを実行します。

    import pandas_profiling as pp
    pp.ProfileReport(df)
    

pandas データフレームが読み込まれたら、pandas プロファイリングを使用してデータを探索できます。pandas プロファイリングは、説明的分析用のレポートを生成します。pandas プロファイルによって、通常 df.describe() 関数で生成される情報よりも多くの統計情報が得られます。各列に関連する統計情報の概要が入り、インタラクティブな HTML 形式で表示されます。

ここでは、y 列がラベルになり、他の列は特徴列として使用できます。これらの列を分析することで、使用する特徴を選択し、モデル トレーニングの前に前処理が必要かどうかを指定できます。

次の図は、pandas プロファイリングのサンプル レポートを示しています。

pandas プロファイリング レポートの概要のスクリーンショット。

pandas プロファイリングのサンプル レポートには、previous 列のデータが偏っていることを通知する警告が表示されます。プロファイリング レポートは、y 列には約 5,000 個の True のサンプルと、約 40,000 個の Missing、すなわち「False」のサンプルが含まれていることも示しています。

pandas プロファイリング レポートのデータのスクリーンショット

データセットの偏りが大きいため、データをトレーニング セットとテストセットに分割すると、すべての True サンプルがテストセットまたはトレーニング セットに含まれなくなります。

偏ったデータセットの処理

偏りのあるデータへの対処方法は次の 2 つです。

  • データセットをシャッフルして、前順序を回避します。
  • テストとトレーニングの両方のデータセットで y の分布が類似した状態を保持するように、層化サンプルを使用します。各データセットのサンプルの約 12% は True で、残りは False であることが必要です。

次のコードでは、シャッフルと層化サンプルの両方を使用しています。

  • このコードが含まれているセルを実行します。

    from sklearn.model_selection import StratifiedShuffleSplit
    
    #Here we apply a shuffle and stratified split to create a train and test set.
    split = StratifiedShuffleSplit(n_splits=1, test_size=0.2, random_state=40)
    for train_index, test_index in split.split(df, df["y"]):
        strat_train_set = df.loc[train_index]
        strat_test_set = df.loc[test_index]
    

データの前処理

ML モデルを作成する前に、モデルで処理可能な形式にデータをフォーマットする必要があります(これを前処理といいます)。

データを前処理する方法は次のとおりです。

  1. 数値列の場合、すべての値が 01 の範囲内にあることを確認します。1 つの列に非常に大きな値が含まれている場合、その値が原因で結果が偏らないように、列の正規化を行います。
  2. 列の一意の値を整数に置き換えて、カテゴリ値を数値に変換します。たとえば、列 Color に一意の 3 つの文字列(redyellowblue)がある場合、それぞれの値を 012 に置き換えます。
  3. True / False 値をそれぞれ 1 / 0 整数に変換します。

次のコードは、この 3 つのアプローチをすべて実装しています。

  • このコードが含まれているセルを実行します。

      def data_pipeline(df):
        """Normalizes and converts data and returns dataframe """
    
        num_cols = df.select_dtypes(include=np.number).columns
        cat_cols = list(set(df.columns) - set(num_cols))
        # Normalize Numeric Data
        df[num_cols] = StandardScaler().fit_transform(df[num_cols])
        # Convert categorical variables to integers
        df[cat_cols] = df[cat_cols].apply(LabelEncoder().fit_transform)
        return df
    

もう 1 つの重要な前処理は特徴の選択です。多くの場合にデータセットは、ラベルを予測するうえで有用ではないと考えられる特徴を備えています。これらの特徴を削除すると、モデルの精度が向上するだけでなく、計算時間も大幅に節約できます。

次のいずれかの方法で特徴を選択します。

  • SelectKBest メソッド。このメソッドは、スコア関数(このチュートリアルでは f_classif)を使用して、上位 K 個の特徴を選択します。
  • ツリー分類器。このオプションでも上位 K 個の特徴が決まります。

このチュートリアルでは、どちらのオプションでも上位 5 個の特徴を選択することにします。

  • SelectKBest メソッドを使用するには、次のコードを含むセルを実行します。

    from sklearn.feature_selection import SelectKBest, f_classif
    
    predictors = train_features_prepared.columns
    
    # Perform feature selection where `k` (5 in this case) indicates the number of features we wish to select
    selector = SelectKBest(f_classif, k=5)
    selector.fit(train_features_prepared[predictors], train_label)
    
  • ツリー分類器を使用するには、次のコードを含むセルを実行します。

    from sklearn.ensemble import ExtraTreesClassifier
    from sklearn.feature_selection import SelectFromModel
    
    predictors_tree = train_features_prepared.columns
    
    selector_clf = ExtraTreesClassifier(n_estimators=50, random_state=0)
    selector_clf.fit(train_features_prepared[predictors], train_label)
    

さまざまな機械学習モデルの比較と評価

ユースケースに最適なモデルと最適なハイパーパラメータが何かを特定するのが容易ではない場合も考えられます。

最適なモデルとハイパーパラメータを選択するため、次のように create_classifiers 関数を定義します。

  • create_classifiers 関数を作成するには、このコードを含むセルを実行します。

    def create_classifiers():
        """Create classifiers and specify hyper parameters"""
    
        log_params = [{'penalty': ['l1', 'l2'], 'C': np.logspace(0, 4, 10)}]
    
        knn_params = [{'n_neighbors': [3, 4, 5]}]
    
        svc_params = [{'kernel': ['linear', 'rbf'], 'probability': [True]}]
    
        tree_params = [{'criterion': ['gini', 'entropy']}]
    
        forest_params = {'n_estimators': [1, 5, 10]}
    
        mlp_params = {'activation': [
                        'identity', 'logistic', 'tanh', 'relu'
                      ]}
    
        ada_params = {'n_estimators': [1, 5, 10]}
    
        classifiers = [
            ['LogisticRegression', LogisticRegression(random_state=42),
             log_params],
            ['KNeighborsClassifier', KNeighborsClassifier(), knn_params],
            ['SVC', SVC(random_state=42), svc_params],
            ['DecisionTreeClassifier',
             DecisionTreeClassifier(random_state=42), tree_params],
            ['RandomForestClassifier',
             RandomForestClassifier(random_state=42), forest_params],
            ['MLPClassifier', MLPClassifier(random_state=42), mlp_params],
            ['AdaBoostClassifier', AdaBoostClassifier(random_state=42),
             ada_params],
            ]
    
        return classifiers
    

create_classifiers 関数は最大 7 個の分類器とハイパーパラメータを入力パラメータとして使用します。ノートブックのこのセクションにある次のいくつかのセルでは、この関数を使用して各分類器に最適な構成(ハイパーパラメータ)を選択します。

このチュートリアルでは、最適な分類器を選択する 2 つの方法を説明します。

  • 1 つ目の方法は、分類器ごとにいくつかの指標を含むテーブルを作成するというものです。このアプローチでは、ユースケースに応じてさまざまな指標を検討できます。たとえば、実際のケースで Accuracy 指標は最適でない場合があります。

    分類器テーブルのスクリーンショット

  • 2 つ目の方法は、次の図に示すように受信者動作特性(ROC)グラフを生成して、各分類器を詳しく分析するというものです。

    分類器グラフのスクリーンショット

両方のデータセットを見ると、曲線の下の面積(AUC)が最も大きいため、モデルとしてロジスティック回帰を選択できます。最適なモデルはユースケースによって異なります。

モデルの説明

モデルを選択したら、予測のパフォーマンスを詳しく把握する必要があります。そのために、このチュートリアルでは Python パッケージの Lime を使用します。Lime を使用すると、説明インスタンスを作成して結果を表示できます。

  • ノートブックの次のセルにあるコードを実行します。

    i = 106
    exp = explainer.explain_instance(train[i], predict_fn)
    pprint.pprint(exp.as_list())
    fig = exp.as_pyplot_figure()
    

Lime では次の図に示すように、上位の特徴が Y 軸に、各特徴の値が X 軸に表示されます。

Lime の説明のスクリーンショット。

AI Platform でのトレーニングと予測

チュートリアルでは、ここまでのモデルのトレーニングと予測はローカルで行いました。トレーニング時間を短縮する場合や大規模な予測を行う場合は、AI Platform を使用できます。AI Platform には、多数のノード間でトレーニングをスケーリングでき、デプロイされたモデル用に API エンドポイントを備えたマネージド サービスが用意されています。

以降のステップでは、モデルを AI Platform にデプロイし、AI Platform を使用して将来の予測に使用するモデルをデプロイします。

AI Platform を使用してモデルをトレーニングし、予測をリクエストするには、次の 2 つのステップが必要です。

  1. AI Platform にトレーニング ジョブを送信する。
  2. AI Platform でモデルを作成する。

トレーニング ジョブを送信する

  1. 次の環境変数を設定します。gcs_bucket は実際の Cloud Storage バケットの名前に置き換えます。

    %env GCS_BUCKET=gcs_bucket
    %env REGION=us-central1
    %env LOCAL_DIRECTORY=./trainer/data
    %env TRAINER_PACKAGE_PATH=./trainer
    
  2. 次のコマンドを含むセルを実行して、トレーニング ジョブを送信します。

    %%bash
    
    JOBNAME=banking_$(date -u +%y%m%d_%H%M%S)
    
    echo $JOBNAME
    
    gcloud ai-platform jobs submit training model_training_$JOBNAME \
            --job-dir $GCS_BUCKET/$JOBNAME/output \
            --package-path trainer \
            --module-name trainer.task \
            --region $REGION \
            --runtime-version=1.9 \
            --python-version=3.5 \
            --scale-tier BASIC
    

    これらのコマンドにより、トレーニング データセットが Cloud Storage バケットに格納され、Python ファイル用のディレクトリが作成されます。

    ジョブのステータスを確認するには、サイドバーの AI Platform に移動し、[ジョブ] を選択します。トレーニングは 8 分ほどで完了します。

AI Platform でモデルを作成する

モデルのトレーニングが完了したら、モデルから予測をリクエストできます。

構成と環境変数を設定する

  1. 次のコードを含むセルで、環境変数を gcs_bucket に置き換えて前のトレーニング手順で使用した Cloud Storage バケットを指定します。

    gcs_bucket
    

    この Cloud Storage バケットは、中間出力のステージングと結果の格納に使用されます。

  2. モデルのディレクトリを探し、その名前をコピーします。

    前のトレーニング ステップでモデルのディレクトリは Cloud Storage バケットに保存されています。ディレクトリの形式は model_YYYYMMDD_HHMMSS です。

  3. 次のコードを含むセルで、model_directory を先ほどコピーしたモデルのディレクトリの値に置き換えます。

    model_directory
    

モデルを作成する

  • ノートブックで、次のコードを含むセルを実行します。

    ! gcloud ai-platform models create $MODEL_NAME --regions=us-central1
    
    ! gcloud ai-platform versions create $VERSION_NAME \
            --model $MODEL_NAME --origin $MODEL_DIR \
            --runtime-version 1.9 --framework $FRAMEWORK \
            --python-version 3.5
    

    これらのコマンドが実行されると、cmle_model という名前のモデルと v1 というバージョンが生成されます。バージョンとは、構築するモデルに固有の構成を指します。1 つのモデルに多数の異なるバージョンが存在する場合があります。

モデルを使用する

モデルとそのバージョンを作成したら、AI Platform の Prediction API で予測をリクエストできます。コマンドラインまたは Python クライアント ライブラリを使用して予測を行うことができます。結果はノートブックの最後のいくつかのセルに表示されます。

デプロイされたモデルをビジネス プロセスの一部として本番環境で使用する場合、本番環境に合わせて実装するために、いくつかの追加作業を行うことができます。このチュートリアルの範囲外ではありますが、これらの手順には次のような作業が含まれます。

  • データを評価して匿名化する。詳しくは、機械学習データセット内の機密データに関する考慮事項をご覧ください。
  • 繰り返し実行されるデータ変換を構築し、トレーニングと予測のパイプラインを処理する。トレーニングと予測は同じデータ変換を通じて行われます。
  • 繰り返し実行されるデプロイ プロセスを構築し、モデルの再トレーニングを処理する。
  • データアクセス、データ パイプライン、デプロイされた AI Platform リソースに適切な Identity and Access Management(IAM)権限を設定する

クリーンアップ

このチュートリアルで使用したリソースについて、Google Cloud アカウントに課金されないようにするには、このチュートリアルで作成した Google Cloud プロジェクトを削除します。

  1. Cloud Console で [リソースの管理] ページに移動します。

    [リソースの管理] に移動

  2. プロジェクト リストで、削除するプロジェクトを選択し、[削除] をクリックします。
  3. ダイアログでプロジェクト ID を入力し、[シャットダウン] をクリックしてプロジェクトを削除します。

次のステップ