Spaces:
Sleeping
Sleeping
| """Run only channel ablation LOPO (no leave-one-out). Quick run for paper data.""" | |
| import os | |
| import sys | |
| import numpy as np | |
| from sklearn.preprocessing import StandardScaler | |
| from sklearn.metrics import f1_score | |
| from xgboost import XGBClassifier | |
| _PROJECT_ROOT = os.path.abspath(os.path.join(os.path.dirname(__file__), "..")) | |
| sys.path.insert(0, _PROJECT_ROOT) | |
| from data_preparation.prepare_dataset import load_per_person, SELECTED_FEATURES | |
| SEED = 42 | |
| FEATURES = SELECTED_FEATURES["face_orientation"] | |
| CHANNEL_SUBSETS = { | |
| "head_pose": ["head_deviation", "s_face", "pitch"], | |
| "eye_state": ["ear_left", "ear_avg", "ear_right", "perclos"], | |
| "gaze": ["h_gaze", "gaze_offset", "s_eye"], | |
| } | |
| def main(): | |
| by_person, _, _ = load_per_person("face_orientation") | |
| persons = sorted(by_person.keys()) | |
| results = {} | |
| for subset_name, feat_list in CHANNEL_SUBSETS.items(): | |
| idx_keep = [FEATURES.index(f) for f in feat_list] | |
| f1s = [] | |
| for held_out in persons: | |
| train_X = np.concatenate([by_person[p][0] for p in persons if p != held_out]) | |
| train_y = np.concatenate([by_person[p][1] for p in persons if p != held_out]) | |
| X_test, y_test = by_person[held_out] | |
| X_tr = train_X[:, idx_keep] | |
| X_te = X_test[:, idx_keep] | |
| scaler = StandardScaler().fit(X_tr) | |
| xgb = XGBClassifier(n_estimators=600, max_depth=8, learning_rate=0.05, | |
| subsample=0.8, colsample_bytree=0.8, reg_alpha=0.1, reg_lambda=1.0, | |
| eval_metric="logloss", random_state=SEED, verbosity=0) | |
| xgb.fit(scaler.transform(X_tr), train_y) | |
| pred = xgb.predict(scaler.transform(X_te)) | |
| f1s.append(f1_score(y_test, pred, average="weighted")) | |
| results[subset_name] = np.mean(f1s) | |
| print(f"{subset_name}: {results[subset_name]:.4f}") | |
| # baseline | |
| f1s = [] | |
| for held_out in persons: | |
| train_X = np.concatenate([by_person[p][0] for p in persons if p != held_out]) | |
| train_y = np.concatenate([by_person[p][1] for p in persons if p != held_out]) | |
| X_test, y_test = by_person[held_out] | |
| scaler = StandardScaler().fit(train_X) | |
| xgb = XGBClassifier(n_estimators=600, max_depth=8, learning_rate=0.05, | |
| subsample=0.8, colsample_bytree=0.8, reg_alpha=0.1, reg_lambda=1.0, | |
| eval_metric="logloss", random_state=SEED, verbosity=0) | |
| xgb.fit(scaler.transform(train_X), train_y) | |
| pred = xgb.predict(scaler.transform(X_test)) | |
| f1s.append(f1_score(y_test, pred, average="weighted")) | |
| results["all_10"] = np.mean(f1s) | |
| print(f"all_10: {results['all_10']:.4f}") | |
| return results | |
| if __name__ == "__main__": | |
| main() | |