Streamlit+auto-sklearnでAutoMLツールを作成

# はじめに
こんにちは！株式会社会社エイアイフィールドに新卒で入社した傍示です。現在はフロントエンドの開発を主に担当させて頂いております。この記事は[株式会社エイアイフィールドアドベントカレンダー2021](https://qiita.com/advent-calendar/2021/aifield)の15日目の記事です。この記事ではGUI操作だけで機械学習を自動で行うことができるAutoMLツールをStreamlitとauto-sklearnで作成します。

[作成したツール](https://streamlitautoml333.herokuapp.com/)
herokuの方にデプロイしましたのでこちらからアクセスすることで利用することが出来ます。

# AutoMLとは

AutoML（Automated Machine Learning）とは直訳すると「自動化された機械学習」ですが、機械学習モデルの設計や構築を自動化すること、またはそのための手法全般のことを指します。

この機械学習モデルの設計や構築のプロセスを行うには高度な知識を持った人材(データサイエンティスト、機械学習エンジニア etc)が必要になってきます。
しかし、このAutoMLを用いることでそうした知識のない人でも簡単に機械学習モデルを構築し自分のビジネスに活用できるようになります。

実際の例としてAutoML Table(google)、Automated ML(Microsoft)、AutoAI(IBM)、DataRobot(Data Robot)、Prediction One(Sony)など多くのプロダクトがリリースされており、AI人材の調達に悩まれている企業にとってはこういったツールの活用も視野に入ってきているかと思われます。


# Streamlitとauto-sklearn
今回はそんなAutoMLを簡単に機械学習アプリを作成できるstreamlitと、機械学習ライブラリであるscikit-learnに含まれる前処理や予測モデルから入力データに合わせて自動で処理を行ってくれるauto-sklearnを用いて簡単なAutoMLアプリケーションを作成していきます。

詳しい使い方については公式ドキュメントを参照してください。

・[Streamlit](https://streamlit.io/)
・[auto-sklearn](https://automl.github.io/auto-sklearn/master/)


# 動作環境とソースコードの紹介

OS: ubuntu0.04 
※auto-sklearnがwindows環境では動かないため

[ソースコード](https://github.com/aaaa383/auto_ML_heroku)

```requirements.txt
numpy==1.21.0
matplotlib==3.4.2
pandas==1.1.3
seaborn==0.11.1
streamlit==0.84.1
scikit-learn==0.24.2
auto-sklearn==0.14.2
```

```python:regression_on_streamlit.py
#モジュールのインポート
import streamlit as st
import numpy as np
import pandas as pd
from matplotlib import 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
from sklearn.metrics import accuracy_score
from sklearn.metrics import f1_score

# auto-sklearn
import autosklearn.regression
import autosklearn.classification

# タイトルを表示
st.title('AutoMLツール')

st.sidebar.markdown("### 1. データの読み込み")
uploaded_file = st.sidebar.file_uploader("CSVファイルをドラッグ&ドロップ、またはブラウザから選択してください", type='csv', key='train')
if uploaded_file is not None:

    #データの読込み
    df = pd.read_csv(uploaded_file)

    #object型をcategory型に変更
    df.loc[:, df.dtypes == 'object'] = df.select_dtypes(['object']).apply(lambda x: x.astype('category'))

    #データの表示
    st.sidebar.markdown("### 2. データの情報の表示")
    if st.sidebar.checkbox('データの中身と基本統計量を表示しますか？'):
        st.markdown("### 1. アップロードされたデータを確認します")
        st.dataframe(df)

        st.markdown('### 2. 行数と列数を確認します')
        st.markdown(df.shape)

        st.markdown("### 3. 基本統計量を確認します")
        st.dataframe(df.describe())

        st.markdown("### 4. 欠損値の確認")
        st.dataframe(df.isnull().sum())

        st.markdown("### 5. 相関係数を確認します")
        st.dataframe(df.corr())

    st.sidebar.markdown("### 3. 目的変数の選択")
    target = st.sidebar.selectbox(
        '目的変数を選択してください',
        df.columns
    )

    # チェック時に目的変数と説明変数の相関を可視化
    st.sidebar.markdown("### 4. 説明変数と目的変数の関係性の確認")
    if st.sidebar.checkbox('散布図を表示しますか？'):
        checked_variable = st.selectbox(
            '説明変数を1つ選択してください:',
            df.select_dtypes(include='number').columns
        )
        fig, ax = plt.subplots(figsize=(5, 3))
        ax.scatter(x=df[checked_variable], y=df[target])
        plt.xlabel(checked_variable)
        plt.ylabel(target)
        st.pyplot(fig)
    
    st.sidebar.markdown("### 5. 回帰問題(regression)か分類問題(classification)かの選択")
    ml_usecase = st.sidebar.selectbox(label='ドロップダウンリストからregressionかclassificationを選択してください',
                              options=('', 'regression', 'classification'),
                              key='ml_usecase')
    if ml_usecase == 'regression':
        
        #説明変数と目的変数の設定
        x = df.drop(target,axis=1)
        y = df[target]

        #検証用データの割合を設定
        TEST_SIZE  = st.sidebar.selectbox('検証用データの割合を設定してください',
                                 [0.1, 0.2, 0.3, 0.4, 0.5])


        # 学習データと評価データを作成
        x_train, x_test, y_train, y_test = train_test_split(
            x,
            y,
            test_size=TEST_SIZE,
            random_state=2021,
            )

        if st.button('予測開始'):
            #モデルの学習
            automl = autosklearn.regression.AutoSklearnRegressor(
                time_left_for_this_task=300,
                seed=2021,
                metric=autosklearn.metrics.mean_absolute_error)
            automl.fit(x_train, y_train)

            #予測
            y_pred = automl.predict(x_test)

            #精度評価
            scores = pd.DataFrame({
                "R2": r2_score(y_test, y_pred),
                "MAE": mean_absolute_error(y_test, y_pred),
                "MSE": mean_squared_error(y_test, y_pred),
                "RMSE": np.sqrt(mean_squared_error(y_test, y_pred))},index=["scores"])
            
            st.sidebar.markdown("### 精度評価を表示")
            st.dataframe(scores)

    elif ml_usecase == 'classification':

        #説明変数と目的変数の設定
        x = df.drop(target,axis=1)
        y = df[target]

        #検証用データの割合を設定
        TEST_SIZE  = st.sidebar.selectbox('検証用データの割合を設定してください',
                                 [0.1, 0.2, 0.3, 0.4, 0.5])

        # 学習データと評価データを作成
        x_train, x_test, y_train, y_test = train_test_split(
            x,
            y,
            test_size=TEST_SIZE,
            random_state=2021,
            )


        if st.button('予測開始'):
            #モデルの学習
            automl = autosklearn.classification.AutoSklearnClassifier(
                time_left_for_this_task=300,
                seed=2021,
                metric=autosklearn.metrics.f1)
            automl.fit(x_train, y_train)

            #予測
            y_pred = automl.predict(x_test)

            #精度評価
            scores = pd.DataFrame({
                "Accracy": r2_score(y_test, y_pred),
                "F1": mean_absolute_error(y_test, y_pred)},index=["scores"])

            st.sidebar.markdown("### 精度評価を表示")
            st.dataframe(scores)

    else:
        st.text('タスクが選択されていません')
```

# 今後やりたいこと

1. auto-sklearnの部分を自分で作成した機械学習モデルに置き換える
2. 欠損値の削除、標準化、ダミー変数化などの前処理の手法をツール使用者がボタン１つで実行できるようにする
2. ファイル形式でのエラーなど細かいエラーの修正


# おわりに
今回はStreamlitとauto-sklearnを用いたAutoMLツールの紹介をさせて頂きました。
まだまだ粗は多いですが、今後完成度を高めてこの記事を更新していければと思います。

Streamlitはhtml,css,jsなどのフロントの知識なしで簡単に機械学習アプリを作成できるため、簡単なデモアプリの開発にはもってこいのモジュールです！
ちょっとした機械学習プロダクトを作ってみたいという人はぜひ使ってみてください。