PyCaretを使ったデータ前処理の自動化
はじめに
- PyCaretは僅かなコーディングで機械学習ができるライブラリです。
- 非常に便利なライブラリですが、TensorFlowやPyTorchのようなニューラルネットワークモデルには対応していません(scikit-learnのMLPは実装可能)。
- 本稿ではPycaretを前処理用ツールとして使い、ニューラルネットワークモデル(TabNet)を構築する手法を紹介します。
前処理の自動化
PyCaretの基本的な使い方は割愛します。
初めて使う方は以下の記事を参照ください。
※環境はgoogle colaboratoryで実行しています。
今回はボストン不動産価格データを使います。
from pycaret.datasets import get_data
from pycaret.regression import *
dataset = get_data('boston')
setup関数を使って前処理を行います。
exp = setup(dataset,
session_id=123, #ランダムシードの値
train_size = 0.7, #学習データとテストデータを7:3に分割
target = 'medv', #目的関数
categorical_features = ['chas'], #カテゴリー変数
numeric_features = ['rad'], #数値変数
normalize = True, #標準化の有無
normalize_method = 'zscore', #標準化の方法
)
前処理の詳細は下図になります。
前処理されたデータを確認します。get_config
で全ての説明変数のデータを取得します。
X = get_config('X') #全ての説明変数
X
numeric_features(chas以外)は標準化され、
categorical_featuresであるchasはダミー変数になりました(元からダミー変数でしたが)。
続いて目的変数medvを確認します。
y = get_config('y') # 全ての目的変数
y
ここでは使用しませんが、分割された学習データ、テストデータの確認も可能です。上記の「Transformed Train Set」、「Transformed Test Set」にあたります。
X_train = get_config('X_train') # 分割後の学習用説明変数
X_train.head()
目的変数は以下です。
y_train = get_config('y_train') # 分割後の学習用目的変数
y_train.head()
同様に分割されたテストデータ「Transformed Test Set」は以下です。
X_test = get_config('X_test') # 分割後のテスト用説明変数
X_test.head()
目的変数は以下です。
y_test = get_config('y_test') # 分割後のテスト用目的変数
y_test.head()
前処理した学習データとテストデータを結合して前処理後のデータセットを作成します。
df=pd.merge(X, y,left_index=True,right_index=True)
df
実は本稿で重要なのはここまでです。
前処理されたデータにさらにひと手間加えるも良し、好きなモデルに組み込むも良しです。
PyCaretをデータ前処理ツールとして使ってみたら如何でしょうかという提案でした。
3. TabNetの構築
以降はほぼ蛇足になりますがTabNetでの学習です。
#ライブラリ
import torch
from torch import nn
import torch.optim as optim
import torch.nn.functional as F
from torch.optim.lr_scheduler import ReduceLROnPlateau
from sklearn.model_selection import StratifiedKFold
from pytorch_tabnet.tab_model import TabNetRegressor
import os
import random
import pandas as pd
import numpy as np
import seaborn as sns
import matplotlib.pyplot as plt
from sklearn.model_selection import train_test_split
from sklearn.metrics import r2_score
from sklearn.metrics import mean_absolute_error
from sklearn.metrics import mean_squared_error
%matplotlib inline
def seed_everything(seed_value):
random.seed(seed_value)
np.random.seed(seed_value)
torch.manual_seed(seed_value)
os.environ["PYTHONHASHSEED"] = str(seed_value)
if torch.cuda.is_available():
torch.cuda.manual_seed(seed_value)
torch.cuda.manual_seed_all(seed_value)
torch.backends.cudnn.deterministic = True
torch.backends.cudnn.benchmark = False
seed_everything(10)
# ランダムシード値
RANDOM_STATE = 10
# 学習データと評価データの割合
TEST_SIZE = 0.3
# 学習データと評価データを作成
x_train, x_test, y_train, y_test = train_test_split(
df.iloc[:, 0 : df.shape[1] - 1],
df.iloc[:, df.shape[1] - 1],
test_size=TEST_SIZE,
random_state=RANDOM_STATE,
)
# trainのデータセットの3割をモデル学習時のバリデーションデータとして利用する
x_train, x_valid, y_train, y_valid = train_test_split(
x_train, y_train, test_size=TEST_SIZE, random_state=RANDOM_STATE
)
# モデルのパラメータ
tabnet_params = dict(
n_d=8,
n_a=8,
n_steps=8,
gamma=0.2,
seed=10,
lambda_sparse=1e-3,
optimizer_fn=torch.optim.Adam,
optimizer_params=dict(lr=2e-2, weight_decay=1e-5),
mask_type="entmax",
scheduler_params=dict(
max_lr=0.01,
steps_per_epoch=int(x_train.shape[0] / 256),
epochs=200,
is_batch_level=True,
),
verbose=5,
)
# model
model = TabNetRegressor(**tabnet_params)
model.fit(
X_train=x_train.values,
y_train=y_train.values.reshape(-1, 1),
eval_set=[(x_valid.values, y_valid.values.reshape(-1, 1))],
eval_metric=["rmse"],
max_epochs=200,
patience=30,
batch_size=256,
virtual_batch_size=128,
num_workers=2,
drop_last=False,
loss_fn=torch.nn.functional.l1_loss,
)
特徴量の重要度を表示します。
# Feature Importance
feat_imp = pd.DataFrame(model.feature_importances_, index=X.columns)
feature_importance = feat_imp.copy()
feature_importance["imp_mean"] = feature_importance.mean(axis=1)
feature_importance = feature_importance.sort_values("imp_mean")
plt.figure(figsize=(10,20))
plt.tick_params(labelsize=15)
plt.barh(feature_importance.index.values, feature_importance["imp_mean"])
plt.title("feature_importance", fontsize=18)
各特徴のマスクを表示します。
# Mask(Local interpretability)
explain_matrix, masks = model.explain(x_test.values)
fig, axs = plt.subplots(1, 3, figsize=(10, 7))
for i in range(3):
axs[i].imshow(masks[i][:25])
axs[i].set_title(f"mask {i}")
評価指標を算出します。あまり結果は良くないです。
# TabNet推論
y_pred = model.predict(x_test.values)
# 評価
def calculate_scores(true, pred):
scores = {}
scores = pd.DataFrame(
{
"R2": r2_score(true, pred),
"MAE": mean_absolute_error(true, pred),
"MSE": mean_squared_error(true, pred),
"RMSE": np.sqrt(mean_squared_error(true, pred)),
},
index=["scores"],
)
return scores
scores = calculate_scores(y_test, y_pred)
print(scores)
テストデータで推論する方法
テストデータを使って推論をする場合は以下のようにします。
ここで重要なのはsetup関数の設定を学習データと揃える事です。
test = pd.read_csv("test.csv")
exp2 = setup(test,
session_id=123, #ランダムシードの値
#train_sizeは無くてOK
target = 'medv', #目的関数
categorical_features = ['chas'], #カテゴリー変数
numeric_features = ['rad'], #数値変数
normalize = True, #標準化の有無
normalize_method = 'zscore', #標準化の方法
)
テストデータの前処理が終わったら全ての説明変数だけを取り出して推論に回します。
# 全説明変数
X = get_config('X')
# TabNet推論
y_pred = model.predict(X.values)
y_pred=pd.DataFrame(y_pred)
さいごに
如何だったでしょうか?
以下の記事では「PyCaretはscikit-learnモデル以外も対応できるよ!」とありますが、
ニューラルネットワークへの適応は出来なさそうなので今回の手法は有効ではと思います。
参考
https://qiita.com/maskot1977/items/5de6605806f8918d2283
https://pycaret.org/preprocessing/
Author And Source
この問題について(PyCaretを使ったデータ前処理の自動化), 我々は、より多くの情報をここで見つけました https://qiita.com/okm_6880/items/c5a99b9165d31ae05d5f著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .