返回目錄
A
掌握時序預測:Python 與統計學的實務指南 - 第 5 章
第五章:模型部署與監控
發布於 2026-02-21 11:57
# 第五章:模型部署與監控
時序預測不只是一個數學或程式碼的問題,真正的挑戰在於如何將模型「投入使用」並且讓它隨著業務環境變化持續維持效能。以下將從三個層面拆解:
1. **模型封裝** – 如何將模型轉成可重複使用的服務。
2. **部署管線** – 自動化 CI/CD、容器化與服務化。
3. **監控與自動調整** – 監測模型表現、資料漂移與預測偏差。
---
## 5.1 模型封裝:從 scikit‑learn 轉成 API
在模型訓練階段,我們通常會使用 `scikit‑learn`、`statsmodels` 或 `Prophet` 等工具。為了讓這些模型能在 web 服務中被呼叫,我們需要將模型序列化並提供簡單的 REST 接口。
### 5.1.1 序列化
python
import joblib
from pathlib import Path
# 假設 model 是先前訓練好的 ProphetRegressor
MODEL_PATH = Path("/srv/models/prophet_regressor.pkl")
joblib.dump(model, MODEL_PATH)
> **備註**:Prophet 的 `Prophet` 物件本身可以直接序列化;若使用 PyTorch 或 TensorFlow,則建議使用 `torch.save` 或 `tf.keras.models.save_model`。
### 5.1.2 FastAPI 服務範例
python
from fastapi import FastAPI
from pydantic import BaseModel
import joblib
import pandas as pd
app = FastAPI(title="時序預測 API")
model = joblib.load("/srv/models/prophet_regressor.pkl")
class ForecastRequest(BaseModel):
ds: str # 日期字串,格式 YYYY-MM-DD
periods: int = 1
@app.post("/forecast")
def predict(request: ForecastRequest):
future = pd.DataFrame({"ds": pd.date_range(request.ds, periods=request.periods)})
forecast = model.predict(future)
return {"forecast": forecast["yhat"].tolist()}
> **提示**:若你使用 `ProphetRegressor` 包裝類,請確保 `predict` 方法已實作並接受 DataFrame 作為輸入。
---
## 5.2 部署管線:容器化、CI/CD 與自動化
### 5.2.1 Docker 容器
dockerfile
# Dockerfile
FROM python:3.10-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
EXPOSE 8000
CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"]
bash
# build & run
docker build -t ts-forecast-api .
docker run -d -p 8000:8000 ts-forecast-api
> **小技巧**:使用 `--no-cache-dir` 可減少映像檔大小;若有 GPU 需求,可改用 `pytorch/pytorch` 官方映像。
### 5.2.2 CI/CD Pipeline(GitHub Actions 範例)
yaml
name: Deploy Forecast API
on:
push:
branches: [ main ]
jobs:
build-and-deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2
- name: Build image
uses: docker/build-push-action@v3
with:
context: .
push: true
tags: ghcr.io/${{ github.repository }}:latest
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Deploy to ECS
uses: jwalton/gh-ecr-deploy@v2
with:
registry: ${{ secrets.ECR_REGISTRY }}
repository: ts-forecast-api
tag: latest
> **說明**:上述流程將模型 API 以 Docker 映像推送至 GitHub Container Registry,並在 AWS ECS 上自動部署。實務上可依據自己的雲環境(Azure AKS、GKE 等)調整。
---
## 5.3 監控:資料漂移、預測偏差與自動化調整
部署後,模型仍須持續監測。以下介紹三個關鍵面向。
### 5.3.1 資料漂移檢測
- **工具**:Evidently AI、River、Sklearn‑evidently。
- **流程**:定期將新資料與訓練資料做統計檢驗(Kolmogorov‑Smirnov、Chi‑square 等),若偵測到顯著差異,觸發 retrain。
python
# 使用 Evidently
import pandas as pd
from evidently import ColumnMapping
from evidently.report import Report
from evidently.metric_preset import DataDriftPreset
train_df = pd.read_csv("/data/train.csv")
new_df = pd.read_csv("/data/new.csv")
column_mapping = ColumnMapping(datetime='ds', numeric_columns=['y'])
report = Report(metrics=[DataDriftPreset()])
report.run(reference_data=train_df, current_data=new_df, column_mapping=column_mapping)
print(report.json())
### 5.3.2 預測偏差監控
- **指標**:RMSE、MAPE、SMAPE、Mean Absolute Error (MAE) 的滑動平均。
- **閾值**:根據業務容忍度設定,例如 RMSE 超過 1.5 倍歷史平均值時觸發告警。
python
import numpy as np
preds = np.array([1.2, 1.5, 1.1])
actuals = np.array([1.0, 1.4, 1.3])
rmse = np.sqrt(np.mean((preds - actuals) ** 2))
print("RMSE:", rmse)
> **實務技巧**:將預測與實際值寫入 InfluxDB 或 TimescaleDB,利用 Grafana 以時間序列方式可視化。
### 5.3.3 自動化 Retrain 與 Canary
1. **排程**:使用 Airflow 或 Prefect 定期執行 `train_model` DAG。
2. **Canary**:先在少量流量上測試新模型,若表現未低於基準,再完全切換。
3. **回溯**:使用版本控制(MLflow、Weights & Biases)追蹤模型參數、訓練資料、評估指標。
python
# Airflow DAG 範例(簡化)
from airflow import DAG
from airflow.operators.python_operator import PythonOperator
from datetime import datetime
with DAG("retrain_prophet", start_date=datetime(2023, 1, 1), schedule_interval="@weekly") as dag:
def retrain():
# 讀取最新資料、訓練模型、儲存新版本
pass
run = PythonOperator(task_id="run_retrain", python_callable=retrain)
---
## 5.4 完整案例:零售銷售預測服務
以下以「每週零售銷售」為例,示範從模型封裝到部署與監控的完整流程。
| 步驟 | 主要動作 | 工具 | 目標 |
|------|----------|------|------|
| 1 | 封裝 Prophet 模型 | joblib、FastAPI | 提供 `/forecast` API |
| 2 | 容器化 | Docker | 可在雲端即時啟動 |
| 3 | CI/CD | GitHub Actions、ECR | 自動構建 & 部署 |
| 4 | 資料漂移 | Evidently AI | 監測 `ds` 與 `sales` 分佈 |
| 5 | 預測偏差 | InfluxDB + Grafana | 追蹤 RMSE、MAPE |
| 6 | Retrain | Airflow | 每週自動重訓 |
> **總結**:這樣的管線不僅減少人為介入,還能在發生「模型衰退」時即時做出調整,確保業務決策基於最新、最準確的預測。
---
## 5.5 小結
1. **封裝**:將模型序列化並用 FastAPI 或 Flask 建立 API。
2. **部署**:使用 Docker、CI/CD 及雲原生服務快速推廣。
3. **監控**:資料漂移、預測偏差與自動 Retrain 是維持模型效能的關鍵。
4. **持續優化**:監控告警後,透過版本管理與實驗平台快速迭代。
> **未來展望**:下一章將探討「多模型集成與增強學習」,藉由結合不同類型模型提升預測精度與穩定性。