今天,我們要讓推薦系統不只會記錄點擊事件,
還能分析模型在真實互動下的表現差異。
透過 Streamlit 的多頁功能,我們將新增一個「📊 AB Test 分析」頁面,
自動讀取 workspace/logs/ab_events.csv
,
統計出各模型的:
最後用 Plotly 繪出圖表,讓模型成效一目了然。
FastAPI → 記錄使用者行為
↓
workspace/logs/ab_events.csv
↓
Streamlit pages/ab_report.py
↓
📊 模型成效報表(CTR、使用者數)
在 /src/api/
新增一個資料夾:
src/api/
┣ main_streamlit.py ← 主頁(推薦互動)
┗ pages/
┗ ab_report.py ← 第二頁(A/B Test 分析)
Streamlit 會自動將 /pages/
下的檔案載入為多頁應用,
打開介面時,左上角會出現「📄 Pages」選單可切換。
/src/api/pages/ab_report.py
import os
import pandas as pd
import streamlit as st
import plotly.express as px
# ✅ CSV 對應容器內路徑(主機 workspace/logs 對應 /src/api/workspace/logs)
LOG_PATH = "/src/api/workspace/logs/ab_events.csv"
st.set_page_config(page_title="📊 AB Test 分析", layout="wide")
st.title("📊 A/B Test 結果分析")
st.markdown("""
此頁面會從 `ab_events.csv` 中讀取紀錄,
分析不同推薦模型的表現差異(點擊率、使用者數、事件數)。
""")
# --- Step 1. 讀取紀錄檔 ---
@st.cache_data
def load_logs():
if not os.path.exists(LOG_PATH):
st.warning("⚠️ 找不到 ab_events.csv,請先進行幾次推薦互動。")
return pd.DataFrame()
try:
# ✅ 忽略格式錯誤的行(on_bad_lines="skip")
df = pd.read_csv(LOG_PATH, on_bad_lines="skip")
except Exception as e:
st.error(f"❌ 無法讀取 CSV:{e}")
return pd.DataFrame()
if "timestamp" in df.columns:
df["timestamp"] = pd.to_datetime(df["timestamp"], errors="coerce")
return df
df = load_logs()
if df.empty:
st.stop()
# --- Step 2. 顯示原始資料 ---
st.markdown("### 🧾 最新事件紀錄(最近 10 筆)")
st.dataframe(df.tail(10), use_container_width=True)
# --- Step 3. 模型統計 ---
summary = (
df.groupby("model_name")
.agg(
total_clicks=("clicked", "sum"),
unique_users=("user_id", pd.Series.nunique),
total_events=("user_id", "count"),
)
.reset_index()
)
summary["CTR(%)"] = round(summary["total_clicks"] / summary["total_events"] * 100, 2)
st.markdown("### 📈 模型表現摘要")
st.dataframe(summary, use_container_width=True)
# --- Step 4. 視覺化 ---
st.markdown("### 📊 點擊率比較圖")
fig = px.bar(
summary,
x="model_name",
y="CTR(%)",
color="model_name",
text="CTR(%)",
title="不同模型的點擊率比較"
)
fig.update_traces(textposition="outside")
st.plotly_chart(fig, use_container_width=True)
st.markdown("### 👥 使用者參與數量")
fig2 = px.bar(
summary,
x="model_name",
y="unique_users",
color="model_name",
text="unique_users",
title="各模型參與使用者數"
)
fig2.update_traces(textposition="outside")
st.plotly_chart(fig2, use_container_width=True)
st.success("✅ 分析完成!您可以透過此頁面觀察模型互動差異。")
docker/requirements-streamlit.txt
新增 Plotly 套件
streamlit==1.38.0
requests==2.32.3
pandas==2.2.2
plotly==5.24.1
streamlit:
build:
context: .
dockerfile: docker/Dockerfile.streamlit
container_name: streamlit_app
ports:
- "8501:8501"
environment:
- FASTAPI_URL=http://fastapi:8000
volumes:
- ./src/api:/src/api
- ./notebooks:/src/api/notebooks
- ./workspace:/src/api/workspace # ✅ 新增用於讀取 logs
working_dir: /src/api
command: >
streamlit run main_streamlit.py
--server.port=8501
--server.address=0.0.0.0
--server.runOnSave=true
depends_on:
- fastapi
networks:
- mlops-net
docker-compose up --build streamlit
在左上角「📄 Pages」選單中會看到兩頁:
進入「AB Test 分析」後即可看到:
項目 | 說明 |
---|---|
🧩 多頁應用 | 透過 pages/ 結構在同一容器內切換頁面 |
📊 資料分析 | 讀取 ab_events.csv 並計算 CTR |
🖥️ 可視化 | 使用 Plotly 繪出模型表現差異 |
🧠 容錯處理 | on_bad_lines="skip" 自動忽略格式錯誤行 |
🎉 Day 28 完成!
你已建立一個能即時呈現推薦系統成效的分析頁。
明天(Day 29),我們將在同一個頁面中展示兩個模型的推薦結果,
讓使用者能直接比較模型輸出並同步記錄點擊事件,
實現完整的 A/B 測試互動介面。