? 今日目標
-
綜合應用本周所學的:
- 分類算法(SVM、決策樹、隨機森林等)
- 模型調參(GridSearchCV)
- 模型持久化(joblib)
- 特征工程與數據構造
-
構建一套完整的二分類建模流程
📘 項目任務說明
構建一個機器學習系統,用于判斷學生是否及格,訓練后保存模型,并支持預測新數據。
? 第一步:數據準備
模擬學生數據:
- 特征:成績、性別、是否缺勤
- 標簽:是否及格(>=60)
features: score, gender(0/1), absent(0/1)
label: 1 (pass), 0 (fail)
? 第二步:建模流程
- 拆分訓練集 / 測試集
- 使用
Pipeline
組合數據預處理 + 分類器 - 使用
GridSearchCV
尋找最佳參數組合 - 保存訓練好的模型(joblib)
- 提供預測函數,支持加載模型預測單個新樣本
? 第三步:項目結構建議
student_pass_predictor/
├── train_model.py # 訓練 + 網格搜索 + 保存模型
├── predictor.py # 加載模型 + 預測新數據
├── data/ # 存放模型或數據文件
│ └── svm_model.joblib
? 第四步:挑戰加分項(進階)
- 封裝
StudentPredictor
類,支持fit/predict/save/load
方法 - 實現命令行調用支持
- 日志輸出記錄訓練結果與模型參數
- 為預測寫一個簡單的 Flask Web 接口(未來任務)
🧾 今日總結
能力 | 具體體現 |
---|---|
模型構建 | 數據準備 → 建模 → 調參 → 測試 |
模型部署 | 保存模型,準備使用 |
編碼組織 | 使用模塊化腳本結構 |
綜合思維 | 把“算法知識”轉化為“工程實現” |
? 項目腳本:
train_model.py
(模型訓練與保存)
# train_model.py - 訓練學生是否及格預測模型并保存import numpy as np
from sklearn.model_selection import train_test_split, GridSearchCV
from sklearn.pipeline import Pipeline
from sklearn.preprocessing import StandardScaler
from sklearn.svm import SVC
from sklearn.metrics import classification_report, accuracy_score
from joblib import dump
import os# 模擬學生數據:score, gender, absent(是否缺勤),label(是否及格)
np.random.seed(42)
size = 200
scores = np.random.randint(40, 100, size)
genders = np.random.choice([0, 1], size=size)
absents = np.random.choice([0, 1], size=size, p=[0.8, 0.2]) # 缺勤較少
labels = ((scores >= 60) & (absents == 0)).astype(int) # 缺勤也可能影響及格X = np.column_stack(((scores - scores.mean()) / scores.std(), genders, absents))
y = labels# 拆分訓練集和測試集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)# 構建 pipeline
pipe = Pipeline([('scaler', StandardScaler()),('svc', SVC())
])# 網格搜索參數
param_grid = {'svc__C': [0.1, 1, 10],'svc__kernel': ['linear', 'rbf'],'svc__gamma': ['scale', 'auto']
}grid = GridSearchCV(pipe, param_grid, cv=5, verbose=1, n_jobs=-1)
grid.fit(X_train, y_train)# 模型評估
print("最佳參數:", grid.best_params_)
y_pred = grid.predict(X_test)
print("準確率:", accuracy_score(y_test, y_pred))
print(classification_report(y_test, y_pred))# 保存模型
os.makedirs("data", exist_ok=True)
dump(grid.best_estimator_, "data/svm_model.joblib")
print("模型已保存到 data/svm_model.joblib")
運行輸出
最佳參數: {'svc__C': 10, 'svc__gamma': 'scale', 'svc__kernel': 'rbf'}
準確率: 0.975precision recall f1-score support0 1.00 0.94 0.97 171 0.96 1.00 0.98 23accuracy 0.97 40macro avg 0.98 0.97 0.97 40
weighted avg 0.98 0.97 0.97 40模型已保存到 data/svm_model.joblib
predictor.py
(加載模型并預測新樣本)
# predictor.py - 加載模型并預測新學生是否及格from joblib import load
import numpy as np
import os# 加載模型
model_path = "data/svm_model.joblib"
if not os.path.exists(model_path):raise FileNotFoundError(f"未找到模型文件: {model_path}")model = load(model_path)
print("? 模型加載成功")# 示例新學生數據:[score, gender, absent]
def predict_pass(score, gender, absent):score_std = (score - 70) / 15 # 簡單標準化,建議保持一致性x = np.array([[score_std, gender, absent]])pred = model.predict(x)[0]return "及格 ?" if pred == 1 else "不及格 ?"# 示例:輸入學生信息預測
if __name__ == "__main__":while True:try:s = int(input("輸入學生成績(0-100):"))g = int(input("輸入性別(0=女,1=男):"))a = int(input("是否缺勤(0=否,1=是):"))result = predict_pass(s, g, a)print(f"預測結果:{result}")except Exception as e:print("輸入有誤,請重試:", e)print("-" * 40)
運行輸出
? 模型加載成功
輸入學生成績(0-100):90
輸入性別(0=女,1=男):0
是否缺勤(0=否,1=是):1
預測結果:不及格 ?
----------------------------------------
輸入學生成績(0-100):60
輸入性別(0=女,1=男):1
是否缺勤(0=否,1=是):0
預測結果:不及格 ?
----------------------------------------
輸入學生成績(0-100):99
輸入性別(0=女,1=男):1
是否缺勤(0=否,1=是):1
預測結果:不及格 ?
----------------------------------------
輸入學生成績(0-100):100
輸入性別(0=女,1=男):1
是否缺勤(0=否,1=是):0
預測結果:及格 ?
----------------------------------------
輸入學生成績(0-100):