関連記事: 深層学習
前回の記事は「KerasでのData Augmentationの解説」画像のデータ拡張について解説しました。今回の記事はテーブルデータ拡張するT-GANについて解説したいと思います。
目次
1. T-GANの概要
__1.1 TGANとは
__1.2 モデルパのラメータ
2. 実験・コード
__2.1 データロード
__2.2 ライブラリの設定
__2.3. 前処理
__2.4. モデルを訓練
__2.5. 前処理
__2.6. サンプル作成
3. サンプルデータ確認
__3.1 モデルテストの関数
__3.2 モデル検証
1. T-GANの概要
1.1 TGANとは
TGANまたは、table-GANは、Table Generative Adversarial Networkの略称です。敵対的生成ネットワークで数値などの連続変数だけではなく、カテゴリ変数にも対応しています。
ネットワークの構成は下記になります。
テーブルデータから生成モデルを学習して、生成者(Generator)と識別者(Discriminator)を競わせます。
1.2 モデルパのラメータ
tgan = TGANModel(continuous_columns, output=’output’, max_epoch=5, steps_per_epoch=10000, save_checkpoints=True, restore_session=True, batch_size=200, z_dim=200, noise=0.2, l2norm=0.00001, learning_rate=0.001, num_gen_rnn=100, num_gen_feature=100, num_dis_layers=1, num_dis_hidden=100, optimizer=’AdamOptimizer’ )
max_epoch (int, default=100): エポックの数
steps_per_epoch (int, default=10000): 各エポックで実行するステップの数
save_checkpoints(bool, default=True): モデルのチェックポイントの設定
restore_session(bool, default=True): 最後のチェックポイントからトレーニングを継続するかどうか
batch_size (int, default=200): バッチのサイズ
z_dim (int, default=100): ジェネレーターのノイズ入力の次元数
noise (float, default=0.2): カテゴリカル列に追加されたガウスノイズの上限
l2norm (float, default=0.00001): 損失を計算するときのL2正規化係数
learning_rate (float, default=0.001): オプティマイザの学習率
num_gen_rnn (int, default=400): ジェネレーターのrnnセルのユニット数
num_gen_feature (int, default=100): ジェネレーターの完全に接続されたレイヤーのユニット数
num_dis_layers (int, default=2):ディスクリミネータのレイヤー数
num_dis_hidden (int, default=200): ディスクリミネータのレイヤーあたりのユニット数
optimizer (str, default=AdamOptimizer): 適合中に使用するオプティマイザーの名前。可能な値は次のとおりです:[GradientDescentOptimizer、AdamOptimizer、AdadeltaOptimizer]
2. 実験・コード
概要:
入力データ: Video Game Sales with Ratings
https://www.kaggle.com/rush4ratio/video-game-sales-with-ratings
環境:Google Colab GPU
ライブラリ: tgan
実験:tganでテーブルデータ拡張
2.1 データロード
Kaggle からのデータをロード
import os os.environ['KAGGLE_USERNAME'] = "xxx" # username from the json file os.environ['KAGGLE_KEY'] = " xxx " # key from the json file !kaggle datasets download -d rush4ratio/video-game-sales-with-ratings # api copied from kaggle #zipファイルを開放して削除する !unzip \*.zip && rm *.zip
2.2 ライブラリの設定
!pip install tgan
ライブラリのインポートとパラメータ設定
# データ処理 import os import numpy as np import pandas as pd from datetime import datetime import warnings warnings.filterwarnings("ignore") # モデル from tgan.model import TGANModel from lightgbm import LGBMRegressor # データロード from sklearn.model_selection import train_test_split # 検定 from sklearn.metrics import mean_squared_error from math import sqrt # 可視化 import matplotlib.pyplot as plt # パラメーター設定 SEED = 11 result = {}
2.3. 前処理
# データの読み込み df = pd.read_csv('Video_Games_Sales_as_at_22_Dec_2016.csv') print(df.shape) df.head()
学習データのために、カラムを選択する
filtered_df = df[['Platform', 'Year_of_Release', 'Genre', 'Publisher', 'Critic_Score', 'Critic_Count', 'User_Score', 'User_Count', 'Developer', 'Rating', 'Global_Sales']] filtered_df.head()
欠損値の確認
評価のスコアは欠損値が多いと確認しました。
# 欠損値の確認 filtered_df.isnull().sum()
欠損値の処理
色んな欠損値処理の方法があります。今回は欠損値があるサンプルデータを削除します。6千件くらいになりました。
# 欠損値の処理 processed_df = filtered_df.dropna() print(processed_df.shape)
(6825, 11)
データ型変更
‘Year_of_Release’のカラムをstring型に変更します。
# データ型の変更 processed_df['Year_of_Release'] = processed_df['Year_of_Release'].astype(str) processed_df.dtypes
モデルを作成するために、連続変数の指定します。
# カラム名の保持 df_columns = processed_df.columns # 連続変数の指定 continuous_columns = [processed_df.columns.get_loc(c) for c in processed_df.select_dtypes(include=['float']).columns]
2.4. モデルを訓練
start_time = datetime.now() tgan = TGANModel(continuous_columns, batch_size=50) tgan.fit(processed_df) result[('TGAN', 'model_fit_time')] = datetime.now() - start_time
モデルを保存します。
モデル学習時間は12分で48MB モデルファイルを作成しました。
# モデル保存 start_time = datetime.now() model_path = '/models/tgan_model.pkl' tgan.save(model_path) result[('TGAN', 'saving_time')] = datetime.now() - start_time result[('TGAN', 'file_size_MB')] = int(os.path.getsize(model_path)/ (1024 * 1024)) # 結果 result_df = pd.Series(result).unstack() result_df
2.6. サンプル作成
モデルロード
# モデルロード model_path = '/models/tgan_model.pkl' tgan = TGANModel.load(model_path)
1)万件のサンプル
# 1)万件 # サンプル作成 start_time = datetime.now() num_samples = 10000 samples = tgan.sample(num_samples) result[('1_csv_10K', 'predicting_time')] = datetime.now() - start_time # csvファイルを保存 start_time = datetime.now() output_path = 'output/csv1_10K.csv' samples.to_csv(output_path) result[('1_csv_10K', 'saving_time')] = datetime.now() - start_time # ファイルサイズ result[('1_csv_10K', 'file_size_MB')] = int(os.path.getsize(output_path)/ (1024 * 1024)) # モデル評価 result_df = pd.Series(result).unstack().reindex(columns=['model_fit_time', 'predicting_time','saving_time', 'file_size_MB']) result_df
2)10万件のサンプル
# 2)10万件 # サンプル作成 start_time = datetime.now() num_samples = 100000 samples = tgan.sample(num_samples) result[('2_csv_100K', 'predicting_time')] = datetime.now() - start_time # csvファイルを保存 start_time = datetime.now() output_path = 'output/csv2_100K.csv' samples.to_csv(output_path) result[('2_csv_100K', 'saving_time')] = datetime.now() - start_time # ファイルサイズ result[('2_csv_100K', 'file_size_MB')] = int(os.path.getsize(output_path)/ (1024 * 1024)) # モデル評価 result_df = pd.Series(result).unstack().reindex(columns=['model_fit_time', 'predicting_time','saving_time', 'file_size_MB']) result_df
3)100万件のサンプル
サンプルデータ作成時間とデータサイズは直線の関係になっています。 # 3)100万件 # サンプル作成 start_time = datetime.now() num_samples = 1000000 samples = tgan.sample(num_samples) result[('3_csv_1M', 'predicting_time')] = datetime.now() - start_time # csvファイルを保存 start_time = datetime.now() output_path = 'output/csv3_1M.csv' samples.to_csv(output_path) result[('3_csv_1M', 'saving_time')] = datetime.now() - start_time # ファイルサイズ result[('3_csv_1M', 'file_size_MB')] = int(os.path.getsize(output_path)/ (1024 * 1024)) # モデル評価 result_df = pd.Series(result).unstack().reindex(columns=['model_fit_time', 'predicting_time','saving_time', 'file_size_MB']) result_df
3. サンプルデータ確認
一万件のデータ、十万のデータ、百万件のデータでlightGBMを作成してみます。
RMSEの評価のスコアを比較します。
3.1 モデルテストの関数
def lightGBM_test(csv_list, y_col, category_col): """ Return test lightGBM test result Input csv list """ for csv in csv_list: # データの読み込み df = pd.read_csv('output/' + csv + '.csv') print(csv) print(df.shape) # 学習データとテストデータ作成 X = df.drop(["Global_Sales"], axis=1).copy() y = pd.to_numeric(df[y_col]).copy() X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=SEED) # カテゴリの設定 for col in category_col: X_train[col] = X_train[col].astype('category') X_test[col] = X_test[col].astype('category') # モデル作成 start_time = datetime.now() lgbm_rg = LGBMRegressor(eval_metric='rmse') lgbm_rg.fit(X_train, y_train) # 推論 y_pred_lgem1 = pd.DataFrame(lgbm_rg.predict(X_test)) # 検証 result2[(csv, 'lgbm_RMSE')] = round(sqrt(mean_squared_error(y_test,y_pred_lgem1)),4) result2[(csv, 'Runtime')] = datetime.now() - start_time
3.2 モデル検証
3つのサンプルデータでモデルを作成しました。百万件のサンプルデータのモデルは一番良い精度になっています。
# パラメータ設定 csv_list = ["csv1_10K", "csv2_100K", "csv3_1M"] y_col = "Global_Sales" category_col = ["Platform", "Genre", "Publisher", "Developer", "Rating"] SEED = 2 result2 = {} # 関数を実行 lightGBM_test(csv_list, y_col, category_col) # 結果 result_df = pd.Series(result2).unstack().reindex(columns=['lgbm_RMSE', 'Runtime']) result_df