如何按参与者与条件两列分层实现K折交叉验证拆分?
按参与者+条件分层的K折交叉验证实现方案
你可以直接利用StratifiedKFold,把你之前生成的stratCol作为分层依据传入,而不是用原始的condition标签。核心思路是让拆分器根据参与者ID+实验条件的组合分布来划分数据,确保每折里每个参与者的两种条件数据都按比例保留,完全匹配你的需求。
具体步骤与代码示例
- 先生成分层组合列(和你之前的做法一致):
df['stratCol'] = df['pp_id'].astype(str) + "_" + df['condition'].astype(str)
- 初始化
StratifiedKFold拆分器,指定折数,然后用stratCol作为分层依据进行拆分:
from sklearn.model_selection import StratifiedKFold from sklearn.ensemble import RandomForestClassifier from sklearn.metrics import accuracy_score # 初始化拆分器,设置折数并开启打乱 skf = StratifiedKFold(n_splits=5, shuffle=True, random_state=42) # 准备特征矩阵与真实标签 X = df[feature_cols] y_true = df['condition'] # 遍历每折完成训练与评估 for train_idx, val_idx in skf.split(X, y=df['stratCol']): X_train, X_val = X.iloc[train_idx], X.iloc[val_idx] y_train, y_val = y_true.iloc[train_idx], y_true.iloc[val_idx] # 训练模型(示例用随机森林,可替换为你需要的模型) model = RandomForestClassifier(random_state=42) model.fit(X_train, y_train) # 输出当前折的验证精度 val_acc = accuracy_score(y_val, model.predict(X_val)) print(f"验证集精度: {val_acc:.4f}")
- 若想用
cross_val_score简化流程,同样把基于stratCol的拆分器传入:
from sklearn.model_selection import cross_val_score # 一键计算各折精度 scores = cross_val_score(model, X, y_true, cv=skf, scoring='accuracy') print(f"各折精度: {scores}") print(f"平均精度: {scores.mean():.4f} ± {scores.std():.4f}")
关键说明
StratifiedKFold的分层逻辑是基于传入的y参数的类别分布,这里我们传入stratCol(每个值对应一个参与者+条件的唯一组合),拆分器就会保证每折中每个组合的样本占比和整体数据一致。这样既避免了某一参与者的所有数据被分到同一折,也保证了两种实验条件在训练/验证集中的分布稳定,完全符合你的实验需求。
内容的提问来源于stack exchange,提问作者elfe
相关产品推荐
相关产品推荐

