「機械学習モデルを作ったけど、チームに見せる方法がわからない」「データ分析の結果を、わかりやすくビジュアル化したい」そんな悩みを抱えていませんか?
この記事では、Streamlitを使って実際に機械学習ダッシュボードを作る過程を解説します。scikit-learnで学習したモデルを使った予測アプリ、データ可視化、インタラクティブな分析ツールを、実践的なコード例とともに紹介します。
📁 完成版のコードはGitHubで公開中
この記事で作成するダッシュボードの完全なコードは、GitHubリポジトリで公開しています。クローンしてすぐに試せます:
# クローンして実行
git clone https://github.com/masvc/streamlit-ml-dashboard.git
cd streamlit-ml-dashboard
pip install -r requirements.txt
streamlit run app.py今回作るもの: アヤメ分類ダッシュボード
機械学習の入門でよく使われるIris(アヤメ)データセットを使って、以下の機能を持つダッシュボードを作ります。
ダッシュボードの機能:
- データ探索: データセットの統計情報と可視化
- モデル学習: パラメータを調整して学習実行
- 予測機能: 新しいデータで品種を予測
- モデル評価: 精度や混同行列の表示

ステップ1: 環境準備とデータ読み込み
まず、必要なライブラリをインストールします。
必要なライブラリのインストール
pip install streamlit scikit-learn pandas numpy matplotlib seaborn plotly基本構造の作成
app.pyを作成し、基本的な構造を実装します。
import streamlit as st
import pandas as pd
import numpy as np
from sklearn import datasets
from sklearn.model_selection import train_test_split
from sklearn.ensemble import RandomForestClassifier
from sklearn.metrics import accuracy_score, confusion_matrix
import plotly.express as px
import plotly.graph_objects as go
# ページ設定
st.set_page_config(
page_title="アヤメ分類ダッシュボード",
page_icon="🌸",
layout="wide"
)
# タイトル
st.title('🌸 機械学習ダッシュボード: アヤメ品種分類')
st.markdown('Irisデータセットを使った分類モデルの学習・評価・予測')
# データ読み込み
@st.cache_data
def load_data():
iris = datasets.load_iris()
df = pd.DataFrame(iris.data, columns=iris.feature_names)
df['species'] = iris.target
df['species_name'] = df['species'].map({0: 'setosa', 1: 'versicolor', 2: 'virginica'})
return df, iris
df, iris = load_data()ステップ2: データ探索機能の実装
サイドバーでセクションを切り替えられるようにし、まずはデータ探索機能を実装します。
# サイドバーでセクション選択
section = st.sidebar.selectbox(
'セクションを選択',
['データ探索', 'モデル学習', '予測', 'モデル評価']
)
# データ探索セクション
if section == 'データ探索':
st.header('📊 データ探索')
# データ表示
st.subheader('データセット')
st.dataframe(df.head(10))
# 基本統計量
st.subheader('基本統計量')
st.write(df.describe())
# データの分布を可視化
st.subheader('データ分布')
col1, col2 = st.columns(2)
with col1:
# 散布図
feature_x = st.selectbox('X軸の特徴量', iris.feature_names, index=0)
feature_y = st.selectbox('Y軸の特徴量', iris.feature_names, index=1)
fig = px.scatter(
df,
x=feature_x,
y=feature_y,
color='species_name',
title=f'{feature_x} vs {feature_y}',
labels={'species_name': '品種'}
)
st.plotly_chart(fig, use_container_width=True)
with col2:
# ヒストグラム
selected_feature = st.selectbox('特徴量を選択', iris.feature_names)
fig = px.histogram(
df,
x=selected_feature,
color='species_name',
title=f'{selected_feature}の分布',
labels={'species_name': '品種'}
)
st.plotly_chart(fig, use_container_width=True)
# 相関行列
st.subheader('特徴量の相関')
corr_matrix = df[iris.feature_names].corr()
fig = go.Figure(data=go.Heatmap(
z=corr_matrix.values,
x=corr_matrix.columns,
y=corr_matrix.columns,
colorscale='RdBu',
zmid=0
))
fig.update_layout(title='相関行列')
st.plotly_chart(fig, use_container_width=True)ステップ3: モデル学習機能の実装
次に、ユーザーがパラメータを調整してモデルを学習できる機能を実装します。
# モデル学習セクション
elif section == 'モデル学習':
st.header('🤖 モデル学習')
st.markdown('ランダムフォレストのパラメータを調整してモデルを学習します')
# パラメータ設定
col1, col2, col3 = st.columns(3)
with col1:
n_estimators = st.slider('決定木の数', 10, 200, 100, 10)
with col2:
max_depth = st.slider('木の最大深さ', 1, 20, 10)
with col3:
test_size = st.slider('テストデータの割合', 0.1, 0.5, 0.3, 0.05)
# データ分割
X = df[iris.feature_names]
y = df['species']
X_train, X_test, y_train, y_test = train_test_split(
X, y, test_size=test_size, random_state=42
)
# 学習実行
if st.button('学習を開始', type='primary'):
with st.spinner('学習中...'):
# モデル作成
model = RandomForestClassifier(
n_estimators=n_estimators,
max_depth=max_depth,
random_state=42
)
# 学習
model.fit(X_train, y_train)
# 予測
y_pred = model.predict(X_test)
# 精度計算
accuracy = accuracy_score(y_test, y_pred)
# セッションステートに保存
st.session_state['model'] = model
st.session_state['accuracy'] = accuracy
st.session_state['X_test'] = X_test
st.session_state['y_test'] = y_test
st.session_state['y_pred'] = y_pred
st.success('学習完了!')
st.metric('テストデータの精度', f'{accuracy:.2%}')
# 特徴量の重要度
st.subheader('特徴量の重要度')
feature_importance = pd.DataFrame({
'特徴量': iris.feature_names,
'重要度': model.feature_importances_
}).sort_values('重要度', ascending=False)
fig = px.bar(
feature_importance,
x='重要度',
y='特徴量',
orientation='h',
title='特徴量の重要度'
)
st.plotly_chart(fig, use_container_width=True)
# データ分割の可視化
st.subheader('データ分割')
col1, col2 = st.columns(2)
with col1:
st.metric('訓練データ', f'{len(X_train)} サンプル')
with col2:
st.metric('テストデータ', f'{len(X_test)} サンプル')ステップ4: 予測機能の実装
学習したモデルを使って、ユーザーが入力した値から品種を予測する機能を実装します。
# 予測セクション
elif section == '予測':
st.header('🔮 品種予測')
# モデルが学習済みかチェック
if 'model' not in st.session_state:
st.warning('先に「モデル学習」セクションでモデルを学習してください')
else:
st.markdown('各特徴量の値を入力して、アヤメの品種を予測します')
# 入力フォーム
col1, col2 = st.columns(2)
with col1:
sepal_length = st.number_input(
'がく片の長さ (cm)',
min_value=0.0,
max_value=10.0,
value=5.0,
step=0.1
)
sepal_width = st.number_input(
'がく片の幅 (cm)',
min_value=0.0,
max_value=10.0,
value=3.0,
step=0.1
)
with col2:
petal_length = st.number_input(
'花びらの長さ (cm)',
min_value=0.0,
max_value=10.0,
value=4.0,
step=0.1
)
petal_width = st.number_input(
'花びらの幅 (cm)',
min_value=0.0,
max_value=10.0,
value=1.5,
step=0.1
)
# 予測実行
if st.button('予測を実行', type='primary'):
model = st.session_state['model']
# 入力データを作成
input_data = np.array([[sepal_length, sepal_width, petal_length, petal_width]])
# 予測
prediction = model.predict(input_data)[0]
prediction_proba = model.predict_proba(input_data)[0]
# 品種名
species_names = ['setosa', 'versicolor', 'virginica']
predicted_species = species_names[prediction]
# 結果表示
st.success(f'予測結果: **{predicted_species}**')
# 確信度を表示
st.subheader('各品種の確率')
proba_df = pd.DataFrame({
'品種': species_names,
'確率': prediction_proba
})
fig = px.bar(
proba_df,
x='品種',
y='確率',
title='予測確率',
range_y=[0, 1]
)
st.plotly_chart(fig, use_container_width=True)
# 入力値の可視化
st.subheader('入力した特徴量')
input_df = pd.DataFrame({
'特徴量': iris.feature_names,
'値': [sepal_length, sepal_width, petal_length, petal_width]
})
fig = px.bar(
input_df,
x='特徴量',
y='値',
title='入力データ'
)
st.plotly_chart(fig, use_container_width=True)ステップ5: モデル評価機能の実装
最後に、学習したモデルの性能を詳細に評価する機能を実装します。
# モデル評価セクション
elif section == 'モデル評価':
st.header('📈 モデル評価')
# モデルが学習済みかチェック
if 'model' not in st.session_state:
st.warning('先に「モデル学習」セクションでモデルを学習してください')
else:
accuracy = st.session_state['accuracy']
y_test = st.session_state['y_test']
y_pred = st.session_state['y_pred']
# 精度表示
st.metric('テストデータの精度', f'{accuracy:.2%}')
# 混同行列
st.subheader('混同行列')
cm = confusion_matrix(y_test, y_pred)
species_names = ['setosa', 'versicolor', 'virginica']
fig = go.Figure(data=go.Heatmap(
z=cm,
x=species_names,
y=species_names,
text=cm,
texttemplate='%{text}',
colorscale='Blues'
))
fig.update_layout(
title='混同行列',
xaxis_title='予測ラベル',
yaxis_title='真のラベル'
)
st.plotly_chart(fig, use_container_width=True)
# 品種ごとの精度
st.subheader('品種ごとの詳細')
from sklearn.metrics import classification_report
report = classification_report(y_test, y_pred, target_names=species_names, output_dict=True)
report_df = pd.DataFrame(report).transpose()[:-3] # micro/macro avgを除外
report_df = report_df.reset_index()
report_df.columns = ['品種', '適合率', '再現率', 'F1スコア', 'サポート']
st.dataframe(report_df, use_container_width=True)
# 予測結果の分布
st.subheader('予測結果の分布')
comparison_df = pd.DataFrame({
'真のラベル': [species_names[i] for i in y_test],
'予測ラベル': [species_names[i] for i in y_pred]
})
fig = px.scatter(
comparison_df,
x='真のラベル',
y='予測ラベル',
title='予測結果の比較'
)
st.plotly_chart(fig, use_container_width=True)完成したダッシュボードの使い方
ダッシュボードが完成しました!以下の手順で使います。
1. アプリを起動
streamlit run app.py2. データ探索
サイドバーで「データ探索」を選択し、データセットの統計情報や分布を確認します。散布図やヒストグラムで、各品種の特徴を視覚的に理解できます。
3. モデル学習
「モデル学習」セクションで、パラメータを調整してモデルを学習します。決定木の数や深さを変更して、精度の変化を確認できます。
4. 予測実行
「予測」セクションで、新しいアヤメのデータ(がく片・花びらのサイズ)を入力して品種を予測します。確信度もグラフで表示されます。
5. モデル評価
「モデル評価」セクションで、混同行列や品種ごとの精度を確認します。モデルの性能を詳しく分析できます。
応用: より高度な機能の追加
基本的なダッシュボードができたら、以下の機能を追加してみましょう。
1. 複数のアルゴリズム比較
from sklearn.svm import SVC
from sklearn.neighbors import KNeighborsClassifier
from sklearn.tree import DecisionTreeClassifier
# アルゴリズム選択
algorithm = st.selectbox(
'アルゴリズムを選択',
['ランダムフォレスト', 'SVM', 'k-NN', '決定木']
)
# モデル作成
if algorithm == 'ランダムフォレスト':
model = RandomForestClassifier(n_estimators=n_estimators, max_depth=max_depth)
elif algorithm == 'SVM':
model = SVC(probability=True)
elif algorithm == 'k-NN':
n_neighbors = st.slider('近傍数', 1, 20, 5)
model = KNeighborsClassifier(n_neighbors=n_neighbors)
else:
model = DecisionTreeClassifier(max_depth=max_depth)2. モデルの保存・読み込み
import pickle
# モデル保存
if st.button('モデルを保存'):
with open('model.pkl', 'wb') as f:
pickle.dump(model, f)
st.success('モデルを保存しました')
# モデル読み込み
uploaded_file = st.file_uploader('モデルファイルを選択', type=['pkl'])
if uploaded_file is not None:
model = pickle.load(uploaded_file)
st.success('モデルを読み込みました')3. カスタムデータセットのアップロード
# CSVアップロード機能
uploaded_file = st.file_uploader('CSVファイルをアップロード', type=['csv'])
if uploaded_file is not None:
# データ読み込み
custom_df = pd.read_csv(uploaded_file)
# ターゲット列を選択
target_column = st.selectbox('ターゲット列を選択', custom_df.columns)
feature_columns = st.multiselect('特徴量を選択',
[col for col in custom_df.columns if col != target_column])
if feature_columns:
X = custom_df[feature_columns]
y = custom_df[target_column]
# 以降の処理は同じパフォーマンス最適化のコツ
ダッシュボードが重くなった場合の最適化方法を紹介します。
1. キャッシュの活用
# データ読み込みをキャッシュ
@st.cache_data
def load_data():
# 重い処理
return data
# モデル学習をキャッシュ
@st.cache_resource
def train_model(params):
# モデル学習
return model2. 大量データの処理
# データをサンプリング
if len(df) > 10000:
df_sample = df.sample(n=10000, random_state=42)
st.warning('データが大きいため、10,000サンプルを表示しています')
else:
df_sample = df
# Plotlyで軽量化
fig.update_traces(marker_size=3) # マーカーサイズを小さく機械学習開発をさらに効率化する関連記事
Streamlitで機械学習ダッシュボードを作成したら、他のAI開発ツールやデータ分析ツールも活用して、さらに開発効率を向上させましょう:
AI開発・機械学習
- Genstack – AI開発を効率化する汎用SDK・マルチモデル統合プラットフォーム – 複数のAIモデルを統合管理
- Hierarchical Reasoning Model – 脳科学に基づく27Mパラメータの次世代AI推論モデル – 効率的なAI推論モデル
データ分析・可視化
- Capalyze – Webスクレイピングからデータ可視化までを自動化するAI分析プラットフォーム – データ収集から可視化まで自動化
- MyLens.ai – アイデアやコンテンツを瞬時にビジュアル化するAI支援ツール – データのビジュアル化を効率化
Python開発支援
- opencode – ターミナル向けAIコーディングエージェント!複数モデル対応で柔軟な開発支援を実現 – ターミナルからPythonコーディングを効率化
- Cipher by Byterover – AIコーディング支援のための共有メモリー管理プラットフォーム – コーディング支援の記憶管理
ノーコード・AI統合
- Instruct – 自然言語指示だけでAI自動化を実現する次世代ノーコードプラットフォーム – ノーコードでAIワークフロー構築
- Emergent – 英語入力でフルスタックアプリを自動生成するAIコード開発プラットフォーム – AIでアプリ開発を加速
まとめ: Streamlitで作る実践的な機械学習ダッシュボード
この記事では、Streamlitを使った機械学習ダッシュボードの作り方を、実践的なコード例とともに解説しました。
実装した主な機能:
- データ探索: 統計情報、散布図、ヒストグラム、相関行列
- モデル学習: パラメータ調整、学習実行、特徴量の重要度表示
- 予測機能: ユーザー入力による予測、確信度の可視化
- モデル評価: 精度、混同行列、品種ごとの詳細評価
開発のポイント:
- セッションステート:
st.session_stateでモデルやデータを保持 - キャッシュ:
@st.cache_dataで重い処理を最適化 - レイアウト:
st.columns()で見やすい配置 - Plotly: インタラクティブなグラフで可視化
応用の方向性:
- アルゴリズム比較: 複数のモデルを試して最適なものを選択
- モデル管理: 学習したモデルの保存・読み込み
- カスタムデータ: ユーザーがCSVをアップロードして分析
- 高度な可視化: ROC曲線、学習曲線、特徴量の分布
Streamlitを使えば、機械学習モデルを誰でも使えるWebアプリに変換できます。データサイエンティストが作ったモデルを、エンジニアでない人も簡単に試せるようになるため、チーム全体でモデルの評価や改善ができます。
まずは今回のコードをベースに、自分のプロジェクトに合わせてカスタマイズしてみましょう。Streamlitなら、数時間で本格的なダッシュボードが完成します!
