🐳

[streamlit]Pythonで機械学習アプリを作ってみよう vol.02 Docker編

2022/07/16に公開

はじめに

前回、Pythonライブラリstreamlitを用いて簡単な機械学習アプリの実装を試みました。その際はAnacondaを用いたのですが、近頃はDockerを用いるケースも多くなっていると思いますのでそちらも試してみました。個人的にはあまり慣れていない領域ですので変なこと書くかもしれません。

前回の記事)
https://zenn.dev/littledarwin/articles/8b5372e2f2c249

概要

  • 個人のMac/WinのDocker環境にstreamlitの機械学習アプリをデプロイします
  • ついでにjupyter notebook環境もインストールしてしまいましょう
  • 機械学習アプリそのものは前回と同じです。streamlitを知りたい方はvol.1をご覧ください

イメージ


WEBアプリ画面(前回と同じ)


jupyter notebookもついでに実装


準備

準備するフォルダ・ファイル構成は下記の通り。ファイルの中身は後述します。

Docker_streamlit/
        ├Dockerfile
        ├docker-compose.yml
	├requirements.txt
	└src/
	  └app.py


こんな感じ(srcフォルダ内にはapp.pyが格納されています)

ここで唐突に出てくるファイル類が意味不明かもしれませんが、ここではdocker composeというコマンドを使うことで、複数のDockerコンテナを一括で作成するという作業をしています。複数のコンテナというのはstreamlitとjupyter notebookです。docker composeについてはこちらに丁寧に記載されているのでご参照ください。
https://docs.docker.jp/compose/toc.html

Dockerfile

Dockerイメージを構築するファイルです。
VS Code等のテキストエディタを用いて下記をコピペし、Docker_streamlitフォルダにDockerfileというファイル名で保存してください。拡張子は不要です。

FROM python:3

COPY requirements.txt .

RUN pip3 install --upgrade pip && \
    pip3 install --no-cache-dir -r requirements.txt && \
    pip3 install notebook

WORKDIR /src
COPY /src /src

docker-compose.yml

サービスを定義するファイルです。jupyter notebookとstreamlitを定義しています。
こちらもコピペしてdocker-compose.ymlで保存してください。

version: '3'
services:
  jupyter_notebook:
    restart: always
    build:
      context: .
      dockerfile: Dockerfile
    container_name: jupyter_notebook
    working_dir: '/src'
    tty: true
    volumes:
      - ./src:/src
    ports: 
      - '8888:8888'
    command: jupyter notebook --port=8888 --ip=0.0.0.0 --allow-root --NotebookApp.token=''

  streamlit:
    restart: always
    build: 
      context: .
      dockerfile: Dockerfile
    container_name: streamlit
    working_dir: '/src'
    tty: true
    volumes: 
      - ./src:/src
    ports: 
      - '8501:8501'
    command: streamlit run app.py

requirements.txt

環境構築時にインストールするライブラリを記述するファイルrequirements.txtです。アプリを改変する際は必要なライブラリを追記してください。

streamlit
pandas
numpy
matplotlib
scikit-learn
seaborn

app.py

前回の記事と同じサンプルアプリです。app.pysrcフォルダに保存してください。

#ライブラリの読み込み
import time
import streamlit as st
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
from sklearn.model_selection import train_test_split
from sklearn import linear_model
from sklearn.linear_model import LogisticRegression


#タイトル
st.title("機械学習アプリ")
st.write("streamlitで実装")

# 以下をサイドバーに表示
st.sidebar.markdown("### 機械学習に用いるcsvファイルを入力してください")
#ファイルアップロード
uploaded_files = st.sidebar.file_uploader("Choose a CSV file", accept_multiple_files= False)
#ファイルがアップロードされたら以下が実行される
if uploaded_files:
    df = pd.read_csv(uploaded_files)
    df_columns = df.columns
    #データフレームを表示
    st.markdown("### 入力データ")
    st.dataframe(df.style.highlight_max(axis=0))
    #matplotlibで可視化。X軸,Y軸を選択できる
    st.markdown("### 可視化 単変量")
    #データフレームのカラムを選択オプションに設定する
    x = st.selectbox("X軸", df_columns)
    y = st.selectbox("Y軸", df_columns)
    #選択した変数を用いてmtplotlibで可視化
    fig = plt.figure(figsize= (12,8))
    plt.scatter(df[x],df[y])
    plt.xlabel(x,fontsize=18)
    plt.ylabel(y,fontsize=18)
    st.pyplot(fig)

    #seabornのペアプロットで可視化。複数の変数を選択できる。
    st.markdown("### 可視化 ペアプロット")
    #データフレームのカラムを選択肢にする。複数選択
    item = st.multiselect("可視化するカラム", df_columns)
    #散布図の色分け基準を1つ選択する。カテゴリ変数を想定
    hue = st.selectbox("色の基準", df_columns)
    
    #実行ボタン(なくてもよいが、その場合、処理を進めるまでエラー画面が表示されてしまう)
    execute_pairplot = st.button("ペアプロット描画")
    #実行ボタンを押したら下記を表示
    if execute_pairplot:
            df_sns = df[item]
            df_sns["hue"] = df[hue]
            
            #streamlit上でseabornのペアプロットを表示させる
            fig = sns.pairplot(df_sns, hue="hue")
            st.pyplot(fig)


    st.markdown("### モデリング")
    #説明変数は複数選択式
    ex = st.multiselect("説明変数を選択してください(複数選択可)", df_columns)

    #目的変数は一つ
    ob = st.selectbox("目的変数を選択してください", df_columns)

    #機械学習のタイプを選択する。
    ml_menu = st.selectbox("実施する機械学習のタイプを選択してください", ["重回帰分析","ロジスティック回帰分析"])
    
    #機械学習のタイプにより以下の処理が分岐
    if ml_menu == "重回帰分析":
            st.markdown("#### 機械学習を実行します")
            execute = st.button("実行")
            
            lr = linear_model.LinearRegression()
            #実行ボタンを押したら下記が進む
            if execute:
                  df_ex = df[ex]
                  df_ob = df[ob]
                  X_train, X_test, y_train, y_test = train_test_split(df_ex.values, df_ob.values, test_size = 0.3)
                  lr.fit(X_train, y_train)
                  #プログレスバー(ここでは、やってる感だけ)
                  my_bar = st.progress(0)
                  
                  for percent_complete in range(100):
                        time.sleep(0.02)
                        my_bar.progress(percent_complete + 1)
                  
                  #metricsで指標を強調表示させる
                  col1, col2 = st.columns(2)
                  col1.metric(label="トレーニングスコア", value=lr.score(X_train, y_train))
                  col2.metric(label="テストスコア", value=lr.score(X_test, y_test))
                  
    #ロジスティック回帰分析を選択した場合
    elif ml_menu == "ロジスティック回帰分析":
            st.markdown("#### 機械学習を実行します")
            execute = st.button("実行")
            
            lr = LogisticRegression()

            #実行ボタンを押したら下記が進む
            if execute:
                  df_ex = df[ex]
                  df_ob = df[ob]
                  X_train, X_test, y_train, y_test = train_test_split(df_ex.values, df_ob.values, test_size = 0.3)
                  lr.fit(X_train, y_train)
                  #プログレスバー(ここでは、やってる感だけ)
                  my_bar = st.progress(0)
                  for percent_complete in range(100):
                        time.sleep(0.02)
                        my_bar.progress(percent_complete + 1)

                  col1, col2 = st.columns(2)
                  col1.metric(label="トレーニングスコア", value=lr.score(X_train, y_train))
                  col2.metric(label="テストスコア", value=lr.score(X_test, y_test))
                  

参考)前回の記事
https://zenn.dev/littledarwin/articles/8b5372e2f2c249

ここまでで、とりあえず必要なファイルは揃いました。


実装

では、いよいよ実装してきます。今回は個人のMac/Winを想定しているのでDocker Desktopを用いるのが簡単です。
https://www.docker.com/products/docker-desktop/


Docker Desktpを立ち上げるとこんな感じ

Docker Desktopを起動したら、次はターミナル(コマンドプロンプト)を立ち上げます。ターミナルにコマンドを入力して今回作ったDocker_streamlitフォルダまで移動しましょう。

cd Docker_streamlit

Docker_streamlitフォルダに移動したらDocker composeを実行します。
環境構築が完了するまで少々お待ちください。

Docker compose up

You can now view your Streamlit app in your browser.

と出れば完了です。ブラウザを立ち上げて下記のURLを入力してください。

http://localhost:8501/

正常に環境構築ができていたらサンプルの機械学習アプリが起動するはずです。
では次にjupyter notebook環境を確認します。

http://localhost:8888/

お馴染みのjupyter画面が表示されるかと思います。notebookを立ち上げたらpip listをしてみると、streamlitやseabornがインストールされていることも確認できます。notebookを保存するとsrcフォルダ内に保存されます。

以上で、Docker環境にstreamlitアプリをデプロイできました。


後片付け

作ったコンテナの容量はそこそこ大きいので、遊び終わったら削除しましょう。

まずターミナルでCtl + Cを入力しコンテナを停止させます。
停止させたらターミナルで削除コマンドを打ちます。

docker compose down --rmi 'all'

なお、ターミナルコマンドを打つのが面倒なら、Docker DesktopのメニューにあるContainers,Imagesからマウス操作で簡単に削除できます。


おわりに

streamlitのアプリ作成というよりDockerの手順という記事になりました。streamlitアプリ、Dockerでの環境構築、いずれも様々な用途に応用が利くと思いますのでこれまで馴染みが薄かった方もvol.1と併せて役立てていただければ幸いです。

https://zenn.dev/littledarwin/articles/8b5372e2f2c249

ただ置いているだけという感じですが、コード、ファイルはこちらにも格納しています
https://github.com/LittleDarwin2021/streamlit_ML

Discussion