DNN(ディープニューラルネットワーク:Deep Neural Network)とは、人間の脳の神経回路を模した人工ニューラルネットワークを多層化し、複雑なデータから高精度な特徴を自動で学習する深層学習(ディープラーニング)の中心的な技術である。

今回は、Kaggleのテーブルデータセット「Bank Customer Churn Dataset」でDNNを利用してみたので、その手順を共有する。

なお、DNNについては、以下のサイトを参照のこと。
https://biz.kddi.com/content/column/smartwork/what-is-dnn/

前提条件

下記記事のKaggleのアカウント登録が完了していること。

Kaggleのアカウント登録を行ってみたKaggleは、約 100 万人以上の方が利用している世界最大のデータサイエンスコンペティションプラットフォームで、企業や政府等がコンペ...

また、Kaggleの下記「Bank Customer Churn Dataset」でコード実行できる状態になっていること。
前提条件

やってみたこと

  1. データの読み込みと確認
  2. データの前処理
  3. DNNモデルの構築と検証

データの読み込みと確認

「Bank Customer Churn Dataset」で、訓練データを読み込みデータを確認する実装例は、以下の通り。

1) 以下のようにライブラリを読み込み、inputファイル名を確認する。

# ライブラリを読み込む
import numpy as np
import pandas as pd
import os
# ファイル名を一覧表示する
for dirname, _, filenames in os.walk('/kaggle/input'):
    for filename in filenames:
        print(os.path.join(dirname, filename))
データの読み込みと確認_1_1

実際、以下のように、インプットファイルが配置されているのが確認できる。
データの読み込みと確認_1_2

2) インプットファイル「Bank Customer Churn Prediction.csv」を読み込む。

# ファイルを読み込む
df = pd.read_csv('/kaggle/input/datasets/gauravtopre/bank-customer-churn-dataset/Bank Customer Churn Prediction.csv')
print(df.shape)
df
データの読み込みと確認_2

3) 2)で読み込んだファイルの統計情報・データ型を確認する。

# ファイルの統計指標を確認する
df.describe()
データの読み込みと確認_3_1
# ファイルのデータ型を確認する
df.info()
データの読み込みと確認_3_2 エンジニアファーストバナー

データの前処理

「Bank Customer Churn Dataset」で、データの前処理を行う実装例は、以下の通り。

1) 読み込んだファイルから、不要な列を削除する。

# 判定に使わないcustomer_idを除外する
df = df.drop('customer_id', axis=1)
print(df.shape)
df
データの前処理_1

2) 読み込んだファイルから正解値(ラベル)を取得する。

# 読み込んだファイルから正解値(ラベル)を取得する
label = df["churn"]
print(label.shape)
label
データの前処理_2

3) 読み込んだファイルから正解値(ラベル)を除去した値を、dataに設定する。

# 読み込んだファイルから正解値(ラベル)を除去した値をdataに格納する
data = df.drop("churn", axis=1)
print(data.shape)
data
データの前処理_3

4) 読み込んだファイルのカテゴリカルデータ(文字や分類のデータ)をOne-hot encoding(「0」と「1」の並び(数値のベクトル)に変換する)を行う。

# dataの文字列(country, gender)に対し、One-hot encoding(「0」と「1」の並び(数値のベクトル)に変換する)を行う
data = pd.get_dummies(data, columns=['country', 'gender'], dtype=int)
print(data.shape)
data
データの前処理_4

5) 読み込んだファイルの数値データを標準化する。

from sklearn.preprocessing import StandardScaler

# dataの数値行に対し、標準化(平均0, 分散1)を行う
scaler = StandardScaler()
data_scaled_array = scaler.fit_transform(data)

# 表示を見やすくするため、numpy.ndarray(NumPy配列)をpandas.DataFrameに再変換する
data_scaled = pd.DataFrame(data_scaled_array, columns=data.columns, index=data.index)
print(data_scaled.shape)
data_scaled
データの前処理_5

6) 読み込んだデータを、訓練データとテストデータに分割する。

from sklearn.model_selection import train_test_split 

# label, dataを訓練データとテストデータに分割する
# random_state : 実行結果を毎回固定するために指定
# stratify : 均等に分割したいデータ
# test_size : テストデータに利用したい割合
train_data, test_data, train_label, test_label = train_test_split(data_scaled, label, random_state=0, stratify=label, test_size=0.2)
print("train_data_shape : " + str(train_data.shape))
print("test_data_shape : " + str(test_data.shape))
print("train_label_shape : " + str(train_label.shape))
print("test_label_shape : " + str(test_label.shape))
データの前処理_6



DNNモデルの構築と検証

DNNモデルの構築と検証例は、以下の通り。

1) Kerasを用いて、DNNモデルを構築し検証する実装例は、以下の通り。

import keras
import tensorflow as tf
from tensorflow.keras import layers, models

# 乱数シードを固定化し、結果の再現性を確保
keras.utils.set_random_seed(0)

# Kerasを用いて、DNNモデルの構築
model = models.Sequential()
# 入力層、shapeには、dataのカラム数=13を指定
model.add(layers.Input(shape=(13,)))
# 中間層、ノード数、活性化関数(ReLU)を指定
# 過学習を防ぐためドロップアウト(Dropout)を設定
model.add(layers.Dense(16, activation='relu'))
model.add(layers.Dropout(0.2))
model.add(layers.Dense(8, activation='relu'))
model.add(layers.Dropout(0.3))
# 出力層
# ノード数は、labelが取り得る値が0か1なので、1を指定
# 活性化関数には、(確率から0~1の値に変換する)シグモイド関数を指定
model.add(layers.Dense(1, activation='sigmoid'))

# モデルのコンパイル 
model.compile(
      optimizer='adam'            # 最適化アルゴリズムにAdamを指定
    , loss='binary_crossentropy'  # 損失関数に二値交差エントロピー誤差を指定
    , metrics=['accuracy'])       # 評価関数に正解率を指定

# 学習と予測
history = model.fit(
      train_data    # 使用する訓練データの特徴量
    , train_label   # 使用する訓練データの正解値(ラベル)
    , validation_data=(test_data, test_label) # 使用するテストデータ
    , epochs=30       # エポック数(何回繰り返すか)
    , batch_size=64   # バッチサイズ(1エポックで使用するデータ量)
    , verbose=2       # 学習中の進捗ログの表示スタイル
)
DNNモデルの構築と検証_1

2) 1)の正解率をグラフ化する実装例は、以下の通り。

# 正解率の推移をグラフ化
result = pd.DataFrame(history.history) 
result[['accuracy', 'val_accuracy']].plot(ylim=(0.5, 1))
DNNモデルの構築と検証_2

3) Kerasを用いたDNNモデルに、(過学習を防ぐための)早期終了を組み込んだ実装例は以下の通りで、エポック数(30回)に到達する前に学習が打ち切られていることが確認できる。

import keras
import tensorflow as tf
from tensorflow.keras import layers, models

# 乱数シードを固定化し、結果の再現性を確保
keras.utils.set_random_seed(0)

# Kerasを用いて、DNNモデルの構築
model = models.Sequential()
# 入力層、shapeには、dataのカラム数=13を指定
model.add(layers.Input(shape=(13,)))
# 中間層、ノード数、活性化関数(ReLU)を指定
model.add(layers.Dense(16, activation='relu'))
model.add(layers.Dense(8, activation='relu'))
# 出力層
# ノード数は、labelが取り得る値が0か1なので、1を指定
# 活性化関数には、(確率から0~1の値に変換する)シグモイド関数を指定
model.add(layers.Dense(1, activation='sigmoid'))

# モデルのコンパイル 
model.compile(
      optimizer='adam'            # 最適化アルゴリズムにAdamを指定
    , loss='binary_crossentropy'  # 損失関数に二値交差エントロピー誤差を指定
    , metrics=['accuracy'])       # 評価関数に正解率を指定

# 過学習を防ぐためのEarly Stopping
early_stopping = tf.keras.callbacks.EarlyStopping(
    monitor='val_accuracy',
    mode='max',                 # 精度は高い方が良いため 'max' を指定
    patience=3,                 # 改善しないエポックの許容回数
    restore_best_weights=True   # 最も性能が良かった重みを復元)
)

# 学習と予測
history = model.fit(
      train_data    # 使用する訓練データの特徴量
    , train_label   # 使用する訓練データの正解値(ラベル)
    , validation_data=(test_data, test_label) # 使用するテストデータ
    , epochs=30       # エポック数(何回繰り返すか)
    , batch_size=64   # バッチサイズ(1エポックで使用するデータ量)
    , callbacks=[early_stopping]  # 過学習を防ぐためのEarly Stoppingを追加
    , verbose=2       # 学習中の進捗ログの表示スタイル
)
DNNモデルの構築と検証_3

4) 3)の正解率をグラフ化する実装例は、以下の通り。

# 正解率の推移をグラフ化
result = pd.DataFrame(history.history) 
result[['accuracy', 'val_accuracy']].plot(ylim=(0.5, 1))
DNNモデルの構築と検証_4

要点まとめ

  • DNN(ディープニューラルネットワーク:Deep Neural Network)とは、人間の脳の神経回路を模した人工ニューラルネットワークを多層化し、複雑なデータから高精度な特徴を自動で学習する深層学習(ディープラーニング)の中心的な技術である。
  • DNNの実装には、フレームワークTensorFlowに内蔵されているKerasを利用できる。