次の方法で共有


チュートリアル: チャーン予測モデルを作成、評価、スコア付けする

このチュートリアルでは、Microsoft Fabric の Synapse Data Science ワークフローのエンド ツー エンドの例について説明します。 このシナリオでは、銀行の顧客が離反するかどうかを予測するモデルを構築します。 チャーン レートまたは解約率には、銀行の顧客が銀行との取引を終了するレートが含まれます。

このチュートリアルに含まれる手順は次のとおりです:

  • カスタム ライブラリをインストールする
  • データの読み込み
  • 探索的データ分析を通じてデータを理解して処理し、Fabric Data Wrangler 機能の使用方法を示します
  • Scikit-Learn、LightGBM、MLflow を使って機械学習モデルをトレーニングし、MLflow および Fabric 自動ログ機能を使用して実験を追跡します
  • 最終的な機械学習モデルを評価して保存する
  • Power BI の視覚化を使用してモデルのパフォーマンスを表示します

前提条件

ノートブックで作業を進めます

ノートブックでこれらの後続のオプションのうちのいずれかを選択できます

  • Data Science 環境のビルトイン ノートブックを開いて実行します
  • GitHub から Data Science 環境にノートブックをアップロードする

ビルトインのノートブックを開きます

例の [顧客離反] のノートブックは、このチュートリアルに付属しています。

チュートリアルのビルトインのサンプル ノートブックを Synapse Data Science 環境で開くには:

  1. Synapse Data Science のホーム ページに移動します。

  2. [サンプルの使用] を選択してください。

  3. 対応するサンプルを選択してください。

    • サンプルが Python チュートリアル用の場合は、既定の [エンド ツー エンド ワークフロー (Python)] タブから。
    • サンプルが R チュートリアル用の場合は、[エンド ツー エンド ワークフロー (R)] タブから。
    • サンプルがクイック チュートリアル用の場合は、[クイック チュートリアル] タブから。
  4. コードの実行を開始する前に、[レイクハウスをノートブックにアタッチします]

GitHub からノートブックをインポートします

[AIsample - Bank Customer Churn.ipynb] ノートブックは、このチュートリアルに付属しています。

このチュートリアルが付属するノートブックを開く場合は、「データ サイエンス チュートリアル用にシステムを準備する」内の指示に従い、ノートブックを、お使いのワークスペースにインポートします。

このページからコードをコピーして貼り付ける場合は、[新しいノートブックを作成する] ことができます。

コードの実行を開始する前に、必ずレイクハウスをノートブックにアタッチしてください。

手順 1: カスタム ライブラリをインストールする

機械学習モデルの開発またはアドホックなデータ分析には、Apache Spark セッション用のカスタム ライブラリをすばやくインストールすることが必要な場合があります。 ライブラリをインストールするには、2 つのオプションがあります。

  • ノートブックのインライン インストール機能 (%pip または %conda) を使って、現在のノートブックにのみライブラリをインストールします
  • または、Fabric 環境を作成し、パブリック ソースからライブラリをインストールするか、あるいはカスタム ライブラリをそこにアップロードすると、ワークスペース管理者はその環境をワークスペースの既定としてアタッチできます。 その後、環境内のすべてのライブラリが、ワークスペース内のすべてのノートブックと Spark ジョブ定義で使用できるようになります。 環境の詳細については、「Microsoft Fabric で環境を作成、構成、および使用する」を参照してください。

このチュートリアルでは、%pip install を使用して、ノートブックに imblearn ライブラリをインストールします。

Note

PySpark カーネルは、%pip install の実行後に再起動します。 他のセルを実行する前に必要なライブラリをインストールします。

# Use pip to install libraries
%pip install imblearn

手順 2: データを読み込む

churn.csvのデータセットには、10,000 人の顧客のチャーン状態と、次を含む 14 個の属性が含まれています:

  • クレジット スコア
  • 地理的な場所 (ドイツ、フランス、スペイン)
  • 性別 (男性、女性)
  • Age
  • 加入期間 (その人がその銀行の顧客であった年数)
  • 口座残高
  • 推定給与
  • 銀行を通じて顧客が購入した商品の数
  • クレジット カードの状況 (顧客がクレジット カードを所有しているかどうか)
  • アクティブ メンバーの状況 (銀行のアクティブな顧客であるかどうか)

このデータセットには、行番号、顧客 ID、顧客の姓の列が含まれます。 これらの列の値は、銀行を解約するという顧客の判断に影響を与えるべきではありません。

その顧客にとっての解約を定義するイベントとは、顧客の銀行口座の閉鎖です。 データセットの Exited 列は、顧客の放棄を意味します。 これらの属性に関するコンテキストがほとんどないため、データセットに関する背景情報を必要としません。 これらの属性が Exited 状態にどのように影響するかを理解することを望んでいます。

その 10,000 人の顧客のうち、銀行を解約した顧客は 2037 人 (約 20%) に過ぎません。 そのクラスの不均衡の比率により、合成データを生成することをお勧めします。 混同行列の精度は、不均衡な分類に関連しない可能性があります。 精度再現率曲線 (AUPRC) の下の領域を使用して精度を測定したい場合があります。

  • この表に、churn.csv データのプレビューを示します。
CustomerID CreditScore 地理的な場所 Gender Age 在職期間 残高 NumOfProducts HasCrCard IsActiveMember EstimatedSalary 退職済
15634602 Hargrave 619 フランス 女性 42 2 0.00 1 1 1 101348.88 1
15647311 Hill 608 スペイン 女性 41 1 83807.86 1 0 1 112542.58 0

データセットをダウンロードしてレイクハウスにアップロードする

さまざまなデータセットでこのノートブックを使用できるように、これらのパラメーターを定義します:

IS_CUSTOM_DATA = False  # If TRUE, the dataset has to be uploaded manually

IS_SAMPLE = False  # If TRUE, use only SAMPLE_ROWS of data for training; otherwise, use all data
SAMPLE_ROWS = 5000  # If IS_SAMPLE is True, use only this number of rows for training

DATA_ROOT = "/lakehouse/default"
DATA_FOLDER = "Files/churn"  # Folder with data files
DATA_FILE = "churn.csv"  # Data file name

このコードは、公開されているバージョンのデータセットをダウンロードし、Fabric レイクハウスに格納します:

重要

実行する前に、ノートブックに [レイクハウスを追加する]。 間違ってインストールすると、エラーが発生します。

import os, requests
if not IS_CUSTOM_DATA:
# With an Azure Synapse Analytics blob, this can be done in one line

# Download demo data files into the lakehouse if they don't exist
    remote_url = "https://synapseaisolutionsa.blob.core.windows.net/public/bankcustomerchurn"
    file_list = ["churn.csv"]
    download_path = "/lakehouse/default/Files/churn/raw"

    if not os.path.exists("/lakehouse/default"):
        raise FileNotFoundError(
            "Default lakehouse not found, please add a lakehouse and restart the session."
        )
    os.makedirs(download_path, exist_ok=True)
    for fname in file_list:
        if not os.path.exists(f"{download_path}/{fname}"):
            r = requests.get(f"{remote_url}/{fname}", timeout=30)
            with open(f"{download_path}/{fname}", "wb") as f:
                f.write(r.content)
    print("Downloaded demo data files into lakehouse.")

ノートブックの実行にかかる時間の記録を開始します:

# Record the notebook running time
import time

ts = time.time()

レイクハウスから生データを読み取る

レイクハウスの [ファイル] セクションから生データを読み取り、異なる日付要素ごとに列を追加します。 パーティション分割されたデルタ テーブルの作成では、この情報が使用されます。

df = (
    spark.read.option("header", True)
    .option("inferSchema", True)
    .csv("Files/churn/raw/churn.csv")
    .cache()
)

データセットから pandas データフレームを作成する

このコードは、処理と視覚化を容易にするために、spark DataFrame を pandas DataFrame に変換します:

df = df.toPandas()

手順 3: 探索的データ分析を実行する

生データを表示する

display を使用して生データを探索し、一部の基本的な統計の実行およびグラフ ビューの表示を行います。 まず、データの視覚化に必要なライブラリ (例 seaborn) をインポートする必要があります。 Seaborn は Python データ視覚化ライブラリであり、データフレームと配列でビジュアルを構築するための高度なインターフェイスを提供します。

import seaborn as sns
sns.set_theme(style="whitegrid", palette="tab10", rc = {'figure.figsize':(9,6)})
import matplotlib.pyplot as plt
import matplotlib.ticker as mticker
from matplotlib import rc, rcParams
import numpy as np
import pandas as pd
import itertools
display(df, summary=True)

Data Wrangler を使って最初のデータ クリーニングを実行する

ノートブックから直接 Data Wrangler を起動して、pandas DataFrameを探索して変換します。 ノートブック リボンの [データ] タブで、Data Wrangler ドロップダウン プロンプトを使用して、編集に使用できるアクティブな Pandas DataFrames を参照します。 Data Wrangler で開くデータフレームを選びます。

Note

ノートブック カーネルがビジー状態の間は、Data Wrangler を開くことができません。 Data Wrangler を起動する前に、セルの実行を完了する必要があります。 Data Wrangler の詳細について確認してください

Screenshot that shows where to access Data Wrangler.

Data Wrangler が起動したら、次の図に示すように、表示されるデータ パネルの説明的な概要が生成されます。 この概要には、DataFrame の分析コード、欠損値などに関する情報が含まれています。Data Wrangler を使用して、欠損値を持つ行、重複する行、特定の名前の列を削除するためのスクリプトを生成し、スクリプトをセルにコピーできます。 その後、スクリプトをセルにコピーできます。 次のセルに、コピーしたスクリプトが表示されます。

Screenshot that shows the Data Wrangler menu.

Screenshot that shows missing data in Data Wrangler.

def clean_data(df):
    # Drop rows with missing data across all columns
    df.dropna(inplace=True)
    # Drop duplicate rows in columns: 'RowNumber', 'CustomerId'
    df.drop_duplicates(subset=['RowNumber', 'CustomerId'], inplace=True)
    # Drop columns: 'RowNumber', 'CustomerId', 'Surname'
    df.drop(columns=['RowNumber', 'CustomerId', 'Surname'], inplace=True)
    return df

df_clean = clean_data(df.copy())

属性を決定する

このコードは、カテゴリ、数値、ターゲットの属性を決定します:

# Determine the dependent (target) attribute
dependent_variable_name = "Exited"
print(dependent_variable_name)
# Determine the categorical attributes
categorical_variables = [col for col in df_clean.columns if col in "O"
                        or df_clean[col].nunique() <=5
                        and col not in "Exited"]
print(categorical_variables)
# Determine the numerical attributes
numeric_variables = [col for col in df_clean.columns if df_clean[col].dtype != "object"
                        and df_clean[col].nunique() >5]
print(numeric_variables)

5 つの数値の概要を表示します

ボックス プロットを使用して 5 つの数値の概要を表示する

  • 最小スコア
  • 第 1 四分位数
  • 中央値 (median)
  • 3 番目の四分位数
  • 最大スコア

数値属性の場合。

df_num_cols = df_clean[numeric_variables]
sns.set(font_scale = 0.7) 
fig, axes = plt.subplots(nrows = 2, ncols = 3, gridspec_kw =  dict(hspace=0.3), figsize = (17,8))
fig.tight_layout()
for ax,col in zip(axes.flatten(), df_num_cols.columns):
    sns.boxplot(x = df_num_cols[col], color='green', ax = ax)
# fig.suptitle('visualize and compare the distribution and central tendency of numerical attributes', color = 'k', fontsize = 12)
fig.delaxes(axes[1,2])

Screenshot that shows a notebook display of the box plot for numerical attributes.

解約した顧客と解約していない顧客の分布を表示する

カテゴリ属性全体にわたる、解約した顧客対解約していない顧客の分布を表示します:

attr_list = ['Geography', 'Gender', 'HasCrCard', 'IsActiveMember', 'NumOfProducts', 'Tenure']
fig, axarr = plt.subplots(2, 3, figsize=(15, 4))
for ind, item in enumerate (attr_list):
    sns.countplot(x = item, hue = 'Exited', data = df_clean, ax = axarr[ind%2][ind//2])
fig.subplots_adjust(hspace=0.7)

Screenshot that shows a notebook display of the distribution of exited versus non-exited customers.

数値属性の分布を表示します

ヒストグラムを使用して数値属性の頻度分布を表示します:

columns = df_num_cols.columns[: len(df_num_cols.columns)]
fig = plt.figure()
fig.set_size_inches(18, 8)
length = len(columns)
for i,j in itertools.zip_longest(columns, range(length)):
    plt.subplot((length // 2), 3, j+1)
    plt.subplots_adjust(wspace = 0.2, hspace = 0.5)
    df_num_cols[i].hist(bins = 20, edgecolor = 'black')
    plt.title(i)
# fig = fig.suptitle('distribution of numerical attributes', color = 'r' ,fontsize = 14)
plt.show()

Screenshot that shows a notebook display of numerical attributes.

特徴エンジニアリングを実行する

この特徴エンジニアリングにより、現在の属性に基づいて新しい属性を生成します:

df_clean["NewTenure"] = df_clean["Tenure"]/df_clean["Age"]
df_clean["NewCreditsScore"] = pd.qcut(df_clean['CreditScore'], 6, labels = [1, 2, 3, 4, 5, 6])
df_clean["NewAgeScore"] = pd.qcut(df_clean['Age'], 8, labels = [1, 2, 3, 4, 5, 6, 7, 8])
df_clean["NewBalanceScore"] = pd.qcut(df_clean['Balance'].rank(method="first"), 5, labels = [1, 2, 3, 4, 5])
df_clean["NewEstSalaryScore"] = pd.qcut(df_clean['EstimatedSalary'], 10, labels = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10])

Data Wrangler を使用してワンホット エンコードを実行する

前に説明したように、Data Wrangler を起動するのと同じ手順で、Data Wrangler を使用してワンホット エンコードを実行します。 このセルには、コピーされた、ワンホット エンコード用に生成されたスクリプトが表示されます:

Screenshot that shows one-hot encoding in Data Wrangler.

Screenshot that shows the selection of columns in Data Wrangler.

df_clean = pd.get_dummies(df_clean, columns=['Geography', 'Gender'])

デルタ テーブルを作成して Power BI レポートを生成する

table_name = "df_clean"
# Create a PySpark DataFrame from pandas
sparkDF=spark.createDataFrame(df_clean) 
sparkDF.write.mode("overwrite").format("delta").save(f"Tables/{table_name}")
print(f"Spark DataFrame saved to delta table: {table_name}")

探索的データ分析からの観測の概要

  • ほとんどの顧客はフランス出身です。 スペインは、フランスとドイツに比べてチャーン レートが最も低い。
  • ほとんどの顧客はクレジット カードを持っています
  • 一部の顧客は 60 歳以上で、クレジット スコアが 400 未満です。 ただし、その顧客を外れ値と見なすことはできません
  • 銀行の商品を 2 つ以上持っている顧客はごくわずかです
  • 非アクティブな顧客の解約率が高くなります
  • 性別と加入期間年数 は、銀行口座を閉じるという顧客の決定には影響を与えません

手順 4: モデルのトレーニングと追跡を実行します

データを配置したので、モデルを定義できるようになりました。 このノートブックでは、ランダム フォレストと LightGBM のモデルを適用します。

scikit-learn ライブラリと LightGBM ライブラリを使用して、数行のコードでモデルを実装します。 さらに、MLfLow と Fabric の自動ログ記録を使用して実験を追跡します。

このコード サンプルでは、レイクハウスからデルタ テーブルを読み込みます。 レイクハウスをソースとして使用する他のデルタ テーブルを使用できます。

SEED = 12345
df_clean = spark.read.format("delta").load("Tables/df_clean").toPandas()

MLflow を使用することでモデルの追跡とログ記録のための実験を生成します

このセクションでは、実験を生成する方法を示し、モデルとトレーニングのパラメーターとスコア付けメトリックを指定します。 さらに、後で使用するために、モデルをトレーニングし、ログに記録し、トレーニング済みのモデルを保存する方法も示します。

import mlflow

# Set up the experiment name
EXPERIMENT_NAME = "sample-bank-churn-experiment"  # MLflow experiment name

自動ログ記録は、モデルがトレーニングされている際、機械学習モデルの入力パラメータ、出力メトリック、出力項目の両方を自動的にキャプチャします。 その後、この情報はワークスペースに記録され、そこでは MLflow API またはワークスペース内の対応する実験によりアクセスおよび視覚化できます。

完了すると、実験はこちらの画像のようになります:

Screenshot that shows the experiment page for the bank churn experiment.

それぞれの名前が付いたすべての実験がログに記録され、そのパラメーターとパフォーマンス メトリックを追跡できます。 自動ログ機能の詳細については、「Microsoft Fabric での自動ログ記録」を参照してください。

実験と自動ログ機能の仕様を設定する

mlflow.set_experiment(EXPERIMENT_NAME) # Use a date stamp to append to the experiment
mlflow.autolog(exclusive=False)

scikit-learn と LightGBM をインポートする

# Import the required libraries for model training
from sklearn.model_selection import train_test_split
from lightgbm import LGBMClassifier
from sklearn.ensemble import RandomForestClassifier
from sklearn.metrics import accuracy_score, f1_score, precision_score, confusion_matrix, recall_score, roc_auc_score, classification_report

トレーニング用およびテスト用のデータセットを準備する

y = df_clean["Exited"]
X = df_clean.drop("Exited",axis=1)
# Train/test separation
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.20, random_state=SEED)

SMOTE をトレーニング データに適用します

不均衡な分類には、モデルが決定境界を効果的に学習するには、少数派クラスの例が少なすぎるために、問題があります。 これに対処するために、Synthetic Minority Oversampling Technique (SMOTE) は、少数派クラスの新しいサンプルを合成するために最も広く使用されている技術です。 手順 1 でインストールした imblearn ライブラリを使用して SMOTE にアクセスします。

SMOTE をトレーニング データセットにのみ適用します。 元のデータに対するモデルのパフォーマンスの有効な近似を得るには、テスト データセットをその元の不均衡な分布のままにしておく必要があります。 この実験は、運用環境の状況を表します。

from collections import Counter
from imblearn.over_sampling import SMOTE

sm = SMOTE(random_state=SEED)
X_res, y_res = sm.fit_resample(X_train, y_train)
new_train = pd.concat([X_res, y_res], axis=1)

詳細については、「SMOTE」および「ランダム オーバーサンプリングから SMOTE と ADASYN へ」を参照してください。 不均衡な学習 Web サイトは、これらのリソースをホストします。

モデルのトレーニング

4 つの特徴量を持つ最大深度が 4 のランダム フォレストを使用してモデルをトレーニングします:

mlflow.sklearn.autolog(registered_model_name='rfc1_sm')  # Register the trained model with autologging
rfc1_sm = RandomForestClassifier(max_depth=4, max_features=4, min_samples_split=3, random_state=1) # Pass hyperparameters
with mlflow.start_run(run_name="rfc1_sm") as run:
    rfc1_sm_run_id = run.info.run_id # Capture run_id for model prediction later
    print("run_id: {}; status: {}".format(rfc1_sm_run_id, run.info.status))
    # rfc1.fit(X_train,y_train) # Imbalanced training data
    rfc1_sm.fit(X_res, y_res.ravel()) # Balanced training data
    rfc1_sm.score(X_test, y_test)
    y_pred = rfc1_sm.predict(X_test)
    cr_rfc1_sm = classification_report(y_test, y_pred)
    cm_rfc1_sm = confusion_matrix(y_test, y_pred)
    roc_auc_rfc1_sm = roc_auc_score(y_res, rfc1_sm.predict_proba(X_res)[:, 1])

6 つの特徴量を持つ最大深度が 8 のランダム フォレストを使用してモデルをトレーニングします:

mlflow.sklearn.autolog(registered_model_name='rfc2_sm')  # Register the trained model with autologging
rfc2_sm = RandomForestClassifier(max_depth=8, max_features=6, min_samples_split=3, random_state=1) # Pass hyperparameters
with mlflow.start_run(run_name="rfc2_sm") as run:
    rfc2_sm_run_id = run.info.run_id # Capture run_id for model prediction later
    print("run_id: {}; status: {}".format(rfc2_sm_run_id, run.info.status))
    # rfc2.fit(X_train,y_train) # Imbalanced training data
    rfc2_sm.fit(X_res, y_res.ravel()) # Balanced training data
    rfc2_sm.score(X_test, y_test)
    y_pred = rfc2_sm.predict(X_test)
    cr_rfc2_sm = classification_report(y_test, y_pred)
    cm_rfc2_sm = confusion_matrix(y_test, y_pred)
    roc_auc_rfc2_sm = roc_auc_score(y_res, rfc2_sm.predict_proba(X_res)[:, 1])

LightGBM を使用したモデルのトレーニングをする:

# lgbm_model
mlflow.lightgbm.autolog(registered_model_name='lgbm_sm')  # Register the trained model with autologging
lgbm_sm_model = LGBMClassifier(learning_rate = 0.07, 
                        max_delta_step = 2, 
                        n_estimators = 100,
                        max_depth = 10, 
                        eval_metric = "logloss", 
                        objective='binary', 
                        random_state=42)

with mlflow.start_run(run_name="lgbm_sm") as run:
    lgbm1_sm_run_id = run.info.run_id # Capture run_id for model prediction later
    # lgbm_sm_model.fit(X_train,y_train) # Imbalanced training data
    lgbm_sm_model.fit(X_res, y_res.ravel()) # Balanced training data
    y_pred = lgbm_sm_model.predict(X_test)
    accuracy = accuracy_score(y_test, y_pred)
    cr_lgbm_sm = classification_report(y_test, y_pred)
    cm_lgbm_sm = confusion_matrix(y_test, y_pred)
    roc_auc_lgbm_sm = roc_auc_score(y_res, lgbm_sm_model.predict_proba(X_res)[:, 1])

モデルのパフォーマンスを追跡するための実験アーティファクトを確認します

実験の実行は、実験アーティファクトに自動的に保存されます。 ワークスペースでそのアーティファクトを見つけることができます。 アーティファクト名は、実験の設定に使用される名前に基づいています。 トレーニングされたすべてのモデル、それらの実行、パフォーマンス メトリック、およびモデル パラメーターが実験ページのログに記録されます。

実験を表示するには:

  1. 左側のパネルで、ワークスペースを選択します。
  2. 実験名 (この場合は、sample-bank-churn-experiment) を見つけて選択します。

Screenshot that shows logged values for one of the models.

手順 5: 最終的な機械学習モデルを評価して保存する

保存した実験をワークスペースから開き、最適なモデルを選択して保存します:

# Define run_uri to fetch the model
# MLflow client: mlflow.model.url, list model
load_model_rfc1_sm = mlflow.sklearn.load_model(f"runs:/{rfc1_sm_run_id}/model")
load_model_rfc2_sm = mlflow.sklearn.load_model(f"runs:/{rfc2_sm_run_id}/model")
load_model_lgbm1_sm = mlflow.lightgbm.load_model(f"runs:/{lgbm1_sm_run_id}/model")

テスト データセット上で保存されたモデルのパフォーマンスを評価します

ypred_rfc1_sm = load_model_rfc1_sm.predict(X_test) # Random forest with maximum depth of 4 and 4 features
ypred_rfc2_sm = load_model_rfc2_sm.predict(X_test) # Random forest with maximum depth of 8 and 6 features
ypred_lgbm1_sm = load_model_lgbm1_sm.predict(X_test) # LightGBM

混同行列を使用して、真陽性、真陰性、偽陽性、偽陰性を表示します

分類の精度を評価するために、混同行列をプロットするスクリプトを作成します。 「不正検出サンプル」に示されているように、SynapseML ツールを使用して混同行列をプロットすることもできます。

def plot_confusion_matrix(cm, classes,
                          normalize=False,
                          title='Confusion matrix',
                          cmap=plt.cm.Blues):
    print(cm)
    plt.figure(figsize=(4,4))
    plt.rcParams.update({'font.size': 10})
    plt.imshow(cm, interpolation='nearest', cmap=cmap)
    plt.title(title)
    plt.colorbar()
    tick_marks = np.arange(len(classes))
    plt.xticks(tick_marks, classes, rotation=45, color="blue")
    plt.yticks(tick_marks, classes, color="blue")

    fmt = '.2f' if normalize else 'd'
    thresh = cm.max() / 2.
    for i, j in itertools.product(range(cm.shape[0]), range(cm.shape[1])):
        plt.text(j, i, format(cm[i, j], fmt),
                 horizontalalignment="center",
                 color="red" if cm[i, j] > thresh else "black")

    plt.tight_layout()
    plt.ylabel('True label')
    plt.xlabel('Predicted label')

最大深度が 4 で、4 つの特徴量を持つランダム フォレスト分類子の混同行列を作成します:

cfm = confusion_matrix(y_test, y_pred=ypred_rfc1_sm)
plot_confusion_matrix(cfm, classes=['Non Churn','Churn'],
                      title='Random Forest with max depth of 4')
tn, fp, fn, tp = cfm.ravel()

Screenshot that shows a notebook display of a confusion matrix for random forest with a maximum depth of four.

最大深度が 8 で、6 つの特徴量を持つランダム フォレスト分類子の混同行列を作成します:

cfm = confusion_matrix(y_test, y_pred=ypred_rfc2_sm)
plot_confusion_matrix(cfm, classes=['Non Churn','Churn'],
                      title='Random Forest with max depth of 8')
tn, fp, fn, tp = cfm.ravel()

Screenshot that shows a notebook display of a confusion matrix for random forest with a maximum depth of eight.

LightGBM の混同行列の作成:

cfm = confusion_matrix(y_test, y_pred=ypred_lgbm1_sm)
plot_confusion_matrix(cfm, classes=['Non Churn','Churn'],
                      title='LightGBM')
tn, fp, fn, tp = cfm.ravel()

Screenshot that shows a notebook display of a confusion matrix for LightGBM.

Power BI の結果を保存する

デルタ フレームをレイクハウスに保存して、モデル予測結果を Power BI の視覚化に移動します。

df_pred = X_test.copy()
df_pred['y_test'] = y_test
df_pred['ypred_rfc1_sm'] = ypred_rfc1_sm
df_pred['ypred_rfc2_sm'] =ypred_rfc2_sm
df_pred['ypred_lgbm1_sm'] = ypred_lgbm1_sm
table_name = "df_pred_results"
sparkDF=spark.createDataFrame(df_pred)
sparkDF.write.mode("overwrite").format("delta").option("overwriteSchema", "true").save(f"Tables/{table_name}")
print(f"Spark DataFrame saved to delta table: {table_name}")

手順 6: Power BI で視覚化にアクセスする

Power BI で保存したテーブルにアクセスします:

  1. 左側で、[OneLake データ ハブ] を選択します
  2. このノートブックに追加したレイクハウスを選択します
  3. [このレイクハウスを開く] セクションで、[開く] を選択します
  4. リボンで、[新しいセマンティック モデル] を選択します。 [df_pred_results] を選択してから、[続行] を選択して、予測にリンクされた新しい Power BI セマンティック モデルを作成します
  5. セマンティック モデルのページの上部にあるツールから [新しいレポート] を選択して Power BI レポートの作成ページを開きます

次のスクリーンショットは、視覚化の例をいくつか示しています。 データ パネルには、デルタ テーブルとテーブルから選択する列が表示されます。 適切なカテゴリ (x) と値 (y) 軸を選択すると、テーブル列の合計や平均などのフィルターと関数を選択できます。

Note

このスクリーンショットでは、図示した例は、Power BI で保存された予測結果の分析を説明します:

Screenshot that shows a Power BI dashboard example.

ただし、実際の顧客離反のユース ケースの場合、プラットフォーム ユーザーは、特定分野の専門知識と、どのようなものを会社とビジネス分析チームがメトリックとして標準化しているかに基づいて、作成する視覚化のより徹底的な一連の要求を行う必要がある場合があります。

Power BI レポートでは、2 つ以上の銀行の商品を使用している顧客のチャーン率が高いことが示されています。 ただし、2 つ以上の商品を持っていた顧客はほとんどいませんでした。 (左下のパネルのプロットを参照。)銀行はより多くのデータを収集する必要がありますが、商品数の多さと相関関係のある他の特徴量も調査する必要があります。

ドイツの銀行の顧客は、フランスとスペインの顧客に比べて解約率が高いです。 (右下のパネルのプロットを参照してください)。 レポートの結果に基づいて、顧客の退会を促した要因の調査が役立つ可能性があります。

中高年の顧客が増えています (25 歳から 45 歳)。 45 歳から 60 歳の顧客は、より多く退会する傾向があります。

最後に、クレジット スコアが低い顧客は、他の金融機関のために銀行を解約する可能性が最も高くなります。 銀行は、クレジット スコアと口座残高が低い顧客がその銀行と契約し続けるよう促す方法を調査する必要があります。

# Determine the entire runtime
print(f"Full run cost {int(time.time() - ts)} seconds.")