AutoML（Auto-Sklearn）を使ってみた

* 製造業出身のデータサイエンティストがお送りする記事
* 今回はAutoML ライブラリー（Auto-Sklearn）を使ってみました。

##はじめに
過去に他のAutoML ライブラリーやツールについては、別の記事に纏めておりますので下記をご参照ください。

- [PyCaret](https://qiita.com/DS27/items/bc56163b2cc48403deb0)
- [TPOT](https://qiita.com/DS27/items/0311b56972da4bef94d5)
- [VARISTA](https://qiita.com/DS27/items/32349b03e99b3f580569)
- [AutoGluon](https://qiita.com/DS27/items/032e89fe421c74b5027b)


##Auto-Sklearn　を使ってみた

必要なライブラリーは下記です。

```
pip install auto-sklearn
```

ライブラリーの依存関係で上手くいかない場合もありますので、バージョンを指定してインストールすることをオススメします。
参考までに私のrequirements.txt を下記に記載しておきます。

```requirements.txt
numpy==1.20.1
pandas==1.2.4
jupyterlab==3.0.12
pytest==5.2
pytest-cov==2.10.1
pytest-benchmark==3.2.3
black==20.8b1
isort==5.7.0
flake8==3.8.4
flake8-black==0.2.1
flake8-variables-names==0.0.3
flake8-pytest-style==1.3.0
flake8-docstrings==1.5.0
pre-commit==2.11.1
matplotlib==3.3.4
seaborn==0.11.1
scikit-learn==0.24.2
auto-sklearn
scipy==1.6.3
nb_black
```

今回もUCI Machine Learning Repositoryで公開されているボストン住宅の価格データを用いて実施します。


```php
import pandas as pd
import matplotlib.pyplot as plt
import numpy as np
import autosklearn.regression
import seaborn as sns
import matplotlib.pyplot as plt

%matplotlib inline

# ボストンの住宅価格データ
from sklearn.datasets import load_boston

# 前処理
from sklearn.preprocessing import StandardScaler
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

# データセットの読込み
boston = load_boston()

# 説明変数の格納
df = pd.DataFrame(boston.data, columns=boston.feature_names)
# 目的変数の追加
df["MEDV"] = boston.target

# ランダムシード値
RANDOM_STATE = 10

# 学習データと評価データの割合
TEST_SIZE = 0.2

# 学習データと評価データを作成
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,
)
```

下記でモデルを学習します。

```php
automl = autosklearn.regression.AutoSklearnRegressor(
    time_left_for_this_task=300,
    seed=RANDOM_STATE,
    metric=autosklearn.metrics.mean_absolute_error,
)
automl.fit(x_train, y_train)
```

`time_left_for_this_task`は、実行時間を設定できます。今回は5分で設定しました。

モデルの中身は下記コマンドで見れます。

```php
print(automl.show_models())
```
出力された結果は下記です。

```
[(0.700000, SimpleRegressionPipeline({'data_preprocessing:categorical_transformer:categorical_encoding:__choice__': 'one_hot_encoding', 'data_preprocessing:categorical_transformer:category_coalescence:__choice__': 'minority_coalescer', 'data_preprocessing:numerical_transformer:imputation:strategy': 'most_frequent', 'data_preprocessing:numerical_transformer:rescaling:__choice__': 'robust_scaler', 'feature_preprocessor:__choice__': 'select_rates_regression', 'regressor:__choice__': 'extra_trees', 'data_preprocessing:categorical_transformer:category_coalescence:minority_coalescer:minimum_fraction': 0.019566163649872924, 'data_preprocessing:numerical_transformer:rescaling:robust_scaler:q_max': 0.7200608810425068, 'data_preprocessing:numerical_transformer:rescaling:robust_scaler:q_min': 0.22968043330398744, 'feature_preprocessor:select_rates_regression:alpha': 0.18539282936320728, 'feature_preprocessor:select_rates_regression:mode': 'fwe', 'feature_preprocessor:select_rates_regression:score_func': 'f_regression', 'regressor:extra_trees:bootstrap': 'False', 'regressor:extra_trees:criterion': 'mae', 'regressor:extra_trees:max_depth': 'None', 'regressor:extra_trees:max_features': 0.9029989558220115, 'regressor:extra_trees:max_leaf_nodes': 'None', 'regressor:extra_trees:min_impurity_decrease': 0.0, 'regressor:extra_trees:min_samples_leaf': 1, 'regressor:extra_trees:min_samples_split': 2, 'regressor:extra_trees:min_weight_fraction_leaf': 0.0},
dataset_properties={
  'task': 4,
  'sparse': False,
  'multioutput': False,
  'target_type': 'regression',
  'signed': False})),
(0.260000, SimpleRegressionPipeline({'data_preprocessing:categorical_transformer:categorical_encoding:__choice__': 'one_hot_encoding', 'data_preprocessing:categorical_transformer:category_coalescence:__choice__': 'minority_coalescer', 'data_preprocessing:numerical_transformer:imputation:strategy': 'median', 'data_preprocessing:numerical_transformer:rescaling:__choice__': 'minmax', 'feature_preprocessor:__choice__': 'polynomial', 'regressor:__choice__': 'gaussian_process', 'data_preprocessing:categorical_transformer:category_coalescence:minority_coalescer:minimum_fraction': 0.052483220498897844, 'feature_preprocessor:polynomial:degree': 2, 'feature_preprocessor:polynomial:include_bias': 'True', 'feature_preprocessor:polynomial:interaction_only': 'True', 'regressor:gaussian_process:alpha': 0.017488165983844263, 'regressor:gaussian_process:thetaL': 4.199154538507709e-05, 'regressor:gaussian_process:thetaU': 18825.14718012417},
dataset_properties={
  'task': 4,
  'sparse': False,
  'multioutput': False,
  'target_type': 'regression',
  'signed': False})),
(0.040000, SimpleRegressionPipeline({'data_preprocessing:categorical_transformer:categorical_encoding:__choice__': 'no_encoding', 'data_preprocessing:categorical_transformer:category_coalescence:__choice__': 'minority_coalescer', 'data_preprocessing:numerical_transformer:imputation:strategy': 'most_frequent', 'data_preprocessing:numerical_transformer:rescaling:__choice__': 'minmax', 'feature_preprocessor:__choice__': 'polynomial', 'regressor:__choice__': 'gaussian_process', 'data_preprocessing:categorical_transformer:category_coalescence:minority_coalescer:minimum_fraction': 0.007741331259480108, 'feature_preprocessor:polynomial:degree': 2, 'feature_preprocessor:polynomial:include_bias': 'False', 'feature_preprocessor:polynomial:interaction_only': 'False', 'regressor:gaussian_process:alpha': 0.020932011717701825, 'regressor:gaussian_process:thetaL': 7.512295484675918e-08, 'regressor:gaussian_process:thetaU': 427.92917011793116},
dataset_properties={
  'task': 4,
  'sparse': False,
  'multioutput': False,
  'target_type': 'regression',
  'signed': False})),
]
```
細かい見方は今後確認しようと思います。

次にテストデータに対して予測します。

```php
y_pred = automl.predict(x_test)

# 評価
def calculate_scores(true, pred):
    """全ての評価指標を計算する

    Parameters
    ----------
    true (np.array)       : 実測値
    pred (np.array)       : 予測値

    Returns
    -------
    scores (pd.DataFrame) : 各評価指標を纏めた結果

    """
    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)
```
得られた結果は下記です。

```
              R2       MAE        MSE      RMSE
scores  0.864631  2.441843  14.156946  3.762572
```

Auto-sklearn を使ってみた感想としては、scikit-learn と同じインターフェースなので全体的に分かりやすいです。
一方で、細かいアルゴリズムの取得方法が分からないので、そこら辺は使いにくいなと思いました。

##さいごに
最後まで読んで頂き、ありがとうございました。

訂正要望がありましたら、ご連絡頂けますと幸いです。