自定义交叉验证和极端不平衡类的验证
Posted
技术标签:
【中文标题】自定义交叉验证和极端不平衡类的验证【英文标题】:Custom Cross Validating and Validation with extremly imbalanced classes 【发布时间】:2019-06-04 11:38:01 【问题描述】:我有一个数据高度不平衡的多类问题。
他们是一个拥有几千名成员的绝大多数班级,有些班级有 100-1000 名成员,还有 10-30 个班级只有 1 名成员。
抽样是不可能的,因为它可能导致错误的类权重。
为了评估我的模型,我想使用交叉验证。我试过cross_val_predict(x,y, cv=10)
导致错误代码:
警告:y 中人口最少的类只有 1 个成员,这太少了。任何类的最小成员数不能少于 n_splits=10。
我尝试构建自己的交叉验证,这非常简单。
我通过StratifiedKFold 拆分我的数据,然后执行以下操作:
clf = DecisionTreeClassifier()
for ta, te in splits
xTrain, xTest = x.iloc[ta], x.iloc[te]
yTrain, yTest = y.iloc[ta], y.iloc[te]
clf.fit(xTrain, yTrain)
prediction = clf.predict(xTest)
cnf_matrix[ta] = confusion_matrix(yTest, prediction)
classRepo[ta] = classification_report(y, prediction)
因为我在 jupyter notebook 中工作,所以我必须手动打印cnf_matrix
和classRepo
的每个位置,然后自己浏览。
有没有更优雅的解决方案,比如手动融合classRepo
和cnf_matrix
,这样我就可以获得与cross_val_predict(x,y, cv=x)
提供的相同结果?
有更好的指标来解决我的问题吗?
【问题讨论】:
当类只有 1 个成员时,不可能创建分层拆分。这不是任何实现的限制。 但使用 StratifiedKFold 我实际上可以拆分数据集 拆分不会完全分层。会有一些折叠,其中训练集或测试集不包含单例类。因此 scikit-learn 的警告。 但是,如果我使用 StratifiedKFolds 并且代码提供了我所有的混淆矩阵,则会显示每个拆分的所有类。仅当我尝试 cros_val_predict 时才会出现错误。 如果您运行的代码与您的问题中出现的完全一样,那么您实际上并不适合火车和测试拆分。在您的示例中,您在XTa
、yTa
上反复训练,而不是 xTrain
、yTrain
的拆分。这可能会解释你的预测包含所有类。
【参考方案1】:
“抽样是不可能的,因为它可能导致错误的类权重。”
这是一个强有力的断言,因为您假设您的训练数据是所有剩余数据的完美表示,即未来可观察的数据。如果我在你的团队中,我会挑战你用实验数据来支持这个假设。
事实上,有许多专门用于处理少数族裔不平衡的方法。例如SMOTE 和ADASYN。我会向您指出,imbalanced learn 用于在 sklearn 框架中实现这些和其他技术的 python 包。
【讨论】:
感谢您的回答和建议。具有一个成员的类通过特征的精确组合进行分类。因此,综合方法可能会导致错误的预测。 如果我要使用 SMOTE afaik,有必要在过采样之前拆分训练和测试数据,这样我就不会通过合成测试数据遇到过度乐观的预测。但如果它甚至不可能拆分,导致实现中的限制 - 我还有哪些选择? 这对单身人士来说是公平的。如果您无法收集更多数据,我认为@Dan 通过将其中一些组合在一起的想法是正确的。诸如最近邻方法之类的方法可能会帮助您减少课程。 我从来没有听说过 - 什么是分组类?如果每个类都需要独立存在,并且绝对不应该与另一个类混合,那么它仍然可以使用吗?感觉自己陷入了死胡同。 好吧,您已经描述了一种情况,您有大约 30 个单例类和数千个类。这种粒度级别可能是矫枉过正。如果不知道您在哪个领域工作以及任务的背景,很难真正说出来。以上是关于自定义交叉验证和极端不平衡类的验证的主要内容,如果未能解决你的问题,请参考以下文章
在使用 5 折交叉验证时,在高度不平衡的数据中混淆 F1 分数和 AUC 分数
R语言编写自定义K折交叉验证(k-fold crossValidation)函数使用使用bootstrap包中的crossval函数来交叉验证模型的R方指标验证模型的效能的可靠性和稳定性