1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56
| from sklearn.model_selection import LeaveOneGroupOut from sklearn.ensemble import RandomForestClassifier from sklearn.metrics import f1_score import numpy as np
class CrossDriverEvaluation: """跨驾驶员泛化评估""" def __init__(self, X, y, driver_ids): self.X = X self.y = y self.driver_ids = driver_ids def evaluate(self, model_class, **model_params): """ Leave-One-Subject-Out交叉验证 Args: model_class: 分类器类 model_params: 模型参数 Returns: mean_f1: 平均F1分数 std_f1: F1标准差 """ logo = LeaveOneGroupOut() f1_scores = [] for train_idx, test_idx in logo.split(self.X, self.y, self.driver_ids): X_train, X_test = self.X[train_idx], self.X[test_idx] y_train, y_test = self.y[train_idx], self.y[test_idx] model = model_class(**model_params) model.fit(X_train, y_train) y_pred = model.predict(X_test) f1 = f1_score(y_test, y_pred, average="macro") f1_scores.append(f1) return np.mean(f1_scores), np.std(f1_scores)
if __name__ == "__main__": from sklearn.ensemble import RandomForestClassifier np.random.seed(42) X = np.random.randn(1000, 10) y = np.random.choice(["low", "medium", "high"], 1000) driver_ids = np.random.choice(["D1", "D2", "D3", "D4", "D5"], 1000) evaluator = CrossDriverEvaluation(X, y, driver_ids) mean_f1, std_f1 = evaluator.evaluate(RandomForestClassifier, n_estimators=100) print(f"跨驾驶员泛化F1: {mean_f1:.2f} ± {std_f1:.2f}")
|