見出し画像

Streamlit: データサイエンティストのためのフロントエンド

こんにちは、けんにぃです。ナビタイムジャパンで公共交通の時刻表を使ったサービス開発やリリースフローの改善を担当しています。

今回はデータサイエンティストのためのフロントエンドとして最近注目を集めている Streamlit を使ってみた話をしようと思います。

Streamlit とは

Streamlit は Python でフロントエンドを構築することが出来るフレームワークです。

https://www.streamlit.io/

画像7

なぜ Streamlit なのか?

最近流行りの React や Vue でフロントエンドを構築するのではダメなのでしょうか?全くそんなことはありません。むしろ表現力の高さでいうと React や Vue のほうがずっと優れています。

問題になってくるのはデータサイエンティストが分析データをプロダクトに組み込むために必要とする作業コストがかなり高いということです。
例として Python でデータ分析をする場合の作業フローをまとめてみるとこんな感じです。

1. Python でデータ分析
2. Flask などで REST API を実装し分析結果を提供
3. React や Vue などで可視化

まず 1. のデータ分析だけでも Hadoop を使ったり、機械学習を使ったりして計算を行う必要があるため、分析結果をまとめるまでに結構時間がかかります。

2. のフェーズでも API の設計が必要ですし、サーバのデプロイ作業も必要になるので手間がかかります。

また 3. のフェーズでも使いやすさを考慮した UI にするには実装と出来栄えのチェックを何度も往復しながらコンポーネントの構成を検討する必要があります。

これら 3 つの作業を行うには最低でも Python と JavaScript を習得する必要があります。またデータ分析・サーバ・UI デザインのスキルも求められます。

Python だけで完結させる

この高コストなデータ分析のプロダクト開発を軽減させるために Streamlit は開発されました。

データ分析は Python を使うことが多いため、 Streamlit も Python さえあればオシャレなフロントエンドを作れるようになっています。

React や Vue を使った時の柔軟性を妥協した分、Python さえ分かっていればいいという作りを目指したのです。

Jupyter との違い

Python のコードがキレイな UI として表示されるという点は Jupyter に似てるなと思いました。

Streamlit の方が優れていると感じた点は、テキストボックスやスライダーなどのウィジェットが作れて、ウィジェットに入力した値に応じて UI が動的に変化する点です。

棲み分け方としては、データ分析で試行錯誤をする過程では Jupyter を使用し、完成したデータをプロダクトに組み込む過程では Streamlit を使うというのが良さそうな印象を持ちました。

使い方

インストールは pip で行います。

$ pip install streamlit numpy pandas opencv-python

データ分析では NumPy と Pandas をよく使うので一緒にインストールしておきます。OpenCV はこの後のサンプルで使用するためのライブラリです。

まずはサンプルを見てみます。このデータは画像内に映るオブジェクト検出器のサンプルです。

$ streamlit run https://raw.githubusercontent.com/streamlit/demo-self-driving/master/app.py

コマンドを実行するとブラウザが起動し、データのダウンロードが始まります。ダウンロードが終わると下記のような Web ページが表示されます。

画像6

左のサイドバーにあるパラメータを調整すると、それに応じてオブジェクト検出の結果が変わります。

次は自分でコードを書いてみます。Streamlit は NumPy の配列や Pandas のデータフレームを自動で表に変換する機能を持っているので、簡単に表の作成ができます。

main.py

import streamlit as st
import pandas as pd
import numpy as np

"""
# 初めての Streamlit
データフレームを表として出力できます:
"""

df = pd.DataFrame({
   'first column': [1, 2, 3, 4],
   'second column': [10, 20, 30, 40]
})

df

文字列の部分は Markdown が記述できます。このスクリプトを次のようにして実行します。

$ streamlit run main.py

結果

画像2

さらにグラフ描画も試してみます。Streamlit は起動させたままで大丈夫です。

main.py

# 前のコードに下記を追加

"""
# グラフ描画の例
"""

chart_data = pd.DataFrame(
    np.random.randn(20, 3),
    columns=['a', 'b', 'c'])

st.line_chart(chart_data)

Streamlit はソースコードの更新を自動で検知してくれます。ソースコードを更新すると UI の右上に下記のようなボタンが表示されるので Rerun を押してページを更新するとグラフが表示されます。

画像4

結果

画像3

今度は地図を描画してみます。東京駅の周辺で適当にプロットしてみます。

main.py

# 前のコードに下記を追加

"""
# 地図を描画
"""

map_data = pd.DataFrame(
   np.random.randn(1000, 2) / [50, 50] + [35.68109, 139.76719],
   columns=['lat', 'lon'])

st.map(map_data)

結果

画像5

最後にウィジェットのサンプルです。

main.py

# 前のコードに下記を追加

"""
# ウィジェットの例
"""

if st.checkbox("チェックボックス"):
   st.write("チェックが入りました。")

selection = st.selectbox("セレクトボックス", ["1", "2", "3"])
st.write(f"{selection} を選択")

"""
## プログレスバーとボタン
"""

import time

if st.button("ダウンロード"):
   text = st.empty()
   bar = st.progress(0)

   for i in range(100):
       text.text(f"ダウンロード中 {i + 1}/100")
       bar.progress(i + 1)
       time.sleep(0.01)

結果

画像6

まとめ

Streamlit を使うことで簡単にオシャレなフロントエンドが作れるようになります。これでデータ分析に注力することが出来るようになると思うので、ぜひお試しください。