Matlab的crossval方法在二分类场景下是否遵循类别频率?
MATLAB crossval 与类别比例的处理:分层抽样的必要性
先直接回应你的核心疑问:默认情况下,MATLAB的crossval函数不会主动维持类别频率比例——它是对整个数据集做随机划分,完全依赖随机性让各fold的类别比例趋近原数据集。这种方式在数据集规模大、类别分布相对均衡时可能没问题,但在你提到的极不平衡数据集或小型数据集场景下,确实会出现严重的比例失衡,甚至某类样本在某个fold里完全缺失,直接导致交叉验证的泛化误差评估结果失真。
下面展开说说细节:
你的观点完全正确
当类别0样本是类别1的5倍时,随机划分很可能出现某个fold里类别1样本极少甚至没有的情况,这类fold上的模型评估完全没有参考价值,最终的交叉验证结果会被异常fold拉偏。你自定义的按类别比例拆分的做法,本质就是分层抽样(Stratified Sampling),这正是解决这类问题的标准方案。如何在MATLAB中实现分层交叉验证
你需要手动创建分层的分区对象,传给crossval或者直接在训练模型时指定:- 用
cvpartition创建分层K折分区:
其中% y为你的类别标签向量 cvp = cvpartition(y, 'KFold', 10, 'Stratify', true);'Stratify', true会强制每个fold的类别比例与原数据集一致。 - 将分区对象传给
crossval:svm = fitcsvm(X, y); cv = crossval(svm, 'CVPartition', cvp); - 更高效的方式:直接在训练模型时启用交叉验证并指定分层分区:
cv_svm = fitcsvm(X, y, 'CrossVal', 'on', 'CVPartition', cvp);
- 用
额外小提示
除了K折交叉验证,cvpartition还支持分层留出法(Holdout),比如拆分出20%的分层测试集:cvp_holdout = cvpartition(y, 'Holdout', 0.2, 'Stratify', true);
内容的提问来源于stack exchange,提问作者normanius
相关产品推荐
相关产品推荐

