sklearn - 模型一直过拟合

Posted

技术标签:

【中文标题】sklearn - 模型一直过拟合【英文标题】:sklearn - model keeps overfitting 【发布时间】:2015-11-04 13:09:23 【问题描述】:

我正在寻找有关解决我当前机器学习问题的最佳方法的建议

问题的概要和我所做的如下:

我有 900 多次 EEG 数据试验,每次试验时长为 1 秒。每个人都知道基本事实,并对状态 0 和状态 1 进行分类(40-60% 分裂) 每个试验都经过预处理,我过滤并提取某些频段的功率,这些构成一组特征(特征矩阵:913x32) 然后我使用 sklearn 来训练模型。 cross_validation 用于我使用 0.2 的测试大小的地方。分类器设置为 SVC,带有 rbf 内核,C = 1,gamma = 1(我尝试了许多不同的值)

您可以在此处找到代码的简化版本:http://pastebin.com/Xu13ciL4

我的问题:

当我使用分类器为我的测试集预测标签时,每个预测都是 0 训练准确度为 1,而测试集准确度约为 0.56 我的学习曲线图如下所示:

现在,这似乎是这里过度拟合的经典案例。然而,这里的过度拟合不太可能是由于样本的特征数量不成比例(32 个特征,900 个样本)造成的。我已经尝试了很多方法来缓解这个问题:

我尝试过使用降维 (PCA),以防我有太多的样本数量的特征,但准确度得分和学习曲线图看起来与上面相同。除非我将组件的数量设置为 10 以下,否则训练准确度会开始下降,但考虑到您开始丢失信息,这是否有点意料之中? 我已尝试对数据进行规范化和标准化。标准化 (SD = 1) 不会改变训练或准确度分数。归一化 (0-1) 将我的训练准确度降低到 0.6。 我为 SVC 尝试了各种 C 和 gamma 设置,但它们都不会改变任何一个分数 尝试使用 GaussianNB 等其他估计器,甚至使用 adaboost 等集成方法。没有变化 尝试使用 linearSVC 显式设置正则化方法,但没有改善情况 我尝试使用 theano 通过神经网络运行相同的特征,我的训练准确度约为 0.6,测试约为 0.5

我很高兴继续思考这个问题,但在这一点上,我正在寻找正确方向的推动力。我的问题可能出在哪里,我能做些什么来解决它?

我的一组功能完全有可能无法区分这两个类别,但在得出这个结论之前,我想尝试一些其他选项。此外,如果我的特征无法区分,那将解释测试集分数低的原因,但在这种情况下如何获得完美的训练集分数?这可能吗?

【问题讨论】:

在当前涉及 EEG 数据的 Kaggle 竞赛中,竞争对手所做的可能值得一试——尤其是脚本和论坛。 kaggle.com/alexandrebarachant/grasp-and-lift-eeg-detection/… 和 kaggle.com/c/grasp-and-lift-eeg-detection 测试中 0.56 的平坦学习曲线非常奇怪。所有样本都是独立的(都来自不同的主题)吗?你如何建立你的训练/测试分割? 所有样本都需要独立吗?我有大约 900 次试验,大约在 20 名受试者之间,所以不,不是独立的...... 样本不需要是独立的。但这会影响您在训练/测试中拆分数据集的方式。不过,这也取决于您的预测任务。如果您在训练中拥有主题 1-​​16 和测试中主题 17-20 的所有样本,则可能是您的模型正在寻找与主题 17-20 无关的特征。这只是一个想法,并不是说如果没有意义就应该“拆分”给定的主题。 啊是的,这是一个很好的观点。最初我按照您提到的方式将其拆分,这是不正确的。从那以后我开始使用 sklearn.train_test_split 和 sklearn.ShuffleSplit,我相信这两个都会随机打乱特征向量,除非我弄错了? 【参考方案1】:

我会首先尝试在参数空间上进行网格搜索,但同时也在训练集上使用 k 折交叉验证(当然,将测试集放在一边)。然后选择一组参数,而不是从 k 折交叉验证中概括出最好的。我建议将GridSearchCV 与StratifiedKFold 一起使用(当将分类器作为估计器传递时,它已经是GridSearchCV 的default strategy)。

假设具有 rbf 的 SVM 可以完美拟合任何训练集,因为 VC 维度是无限的。因此,如果调整参数无助于减少过拟合,那么您可能需要针对更简单的假设尝试类似的参数调整策略,例如线性 SVM 或您认为可能适合您的领域的其他分类器。

如果可用的话,您提到的正则化绝对是一个好主意。

相同标签的预测让我认为标签不平衡可能是一个问题,对于这种情况,您可以使用不同的类权重。因此,在 SVM 的情况下,每个类都有自己的 C 惩罚权重。 sklearn 中的一些估计器接受拟合参数,允许您设置样本权重来设置单个训练样本的惩罚量。

现在,如果您认为特征可能是一个问题,我会通过查看 f_classif 提供的 F 值来使用特征选择,并且可以与 SelectKBest 之类的东西一起使用。另一种选择是使用交叉验证进行递归特征消除。如果您使用 sklearns Pipeline API,也可以将特征选择包装到网格搜索中。

【讨论】:

您应该使用随机网格搜索。它速度更快,并且已被证明优于经典的网格搜索。尝试在[0, 1] 范围内搜索,然后,如果随机搜索返回的值接近该超参数的区间边缘,则增加该超参数的搜索范围。见jmlr.org/papers/volume13/bergstra12a/bergstra12a.pdf 明天我会尝试更多的参数调整。我在想也许还有比这更明显的问题,但我们会看到的。你能解释一下 f_classif 究竟做了什么吗?它只是一个单向方差分析,其中我的每个功能都是综合测试中的一个级别吗?因为我只是在我的功能集上运行它并且我的 p 值都没有出现 我使用 optunity 来选择最理想的超参数,而不是 GridSearchCV,但在参数调整后,我的训练精度下降到 0.6 左右,这很好,因为我不再过度拟合。我想我只是没有很好的功能

以上是关于sklearn - 模型一直过拟合的主要内容,如果未能解决你的问题,请参考以下文章

莫烦sklearn学习自修第八天过拟合问题

莫烦sklearn学习自修第九天过拟合问题处理

欠拟合和过拟合的一般解决方法

神经网络+过拟合+避免

sklearn 通过检查是否具有属性确定是否拟合过了

判断模型是不是过拟合、欠拟合、数据问题?