特征向量中多个缺失值的插补

已编辑的帖子

这是原始帖子的简短且稍作澄清的版本。

  1. 我们有一个训练数据集(一些特征显著相关)。特征空间有20个维度(全部为连续型)。
  2. 我们需要使用训练数据训练一个非参数的插补器(kNN或基于树的回归),因为大多数特征形成非线性子空间,我们不能为任何特征假设分布。
  3. 我们需要使用训练好的插补器预测查询数据中的多个缺失值(一个查询特征向量最多可以有13个缺失特征,因此插补器应该能够处理任何组合的缺失特征)。注意插补器在任何情况下都不能使用查询数据重新训练/拟合(就像我在目前找到的所有主流R包中所做的那样:Ameliaimputemimice…)。也就是说,插补应完全基于训练数据进行。
  4. 所有这些的目的在下面描述。
  5. 下面是一个小数据样本。

原始帖子(TL;DR)

简单来说,我需要进行一些复杂的数据插补。我们有一个包含约10万个20维样本的训练数据集和一个较小的测试数据集。每个特征/维度都是连续变量,但尺度不同。有两个不同的类别。两个数据集都包含大量的NA值(NA值在维度之间分布不均)。我使用sklearn.ensemble.ExtraTreesClassifier进行分类,尽管树集成可以处理缺失数据的情况,但有三个原因需要进行插补:

  1. 这样我们在对查询数据集进行分类时可以获得森林中所有树的投票(而不仅仅是那些没有缺失特征的树)。
  2. 我们在训练过程中不会丢失数据。
  3. scikit的树集成实现(包括ExtraTreesRandomForest)不处理缺失值。但这一点并不是那么重要。如果不是因为前两点,我会直接使用rpy2加上一些不错的R实现。

对于训练数据集,事情相当简单,因为我可以应用类别特定的中位数插补策略来处理缺失值,这种方法到目前为止一直工作得很好。显然,这种方法不能应用于查询数据 – 我们一开始就没有类别。由于我们知道查询中的类别可能会有显著不同的比例,我们不能应用不区分类别的方法,因为这可能会引入偏差并降低分类性能,因此我们需要从模型中插补缺失值。

线性模型由于几个原因不是一个选项:

  1. 所有特征在某种程度上是相关的;
  2. 理论上,我们可以在一个样本特征向量中得到所有可能的缺失特征组合,尽管我们的工具要求至少有7个非缺失特征,我们最终会得到约1^E6个可能的模型,这在我看来并不优雅。

基于树的回归模型由于同样的原因也不适合。因此,我们最终选择了kNN(k最近邻),更具体地说是球树或带有半径阈值的LSH。这种方法非常适合任务,因为维度(因此距离)是相关的,因此在极端NA丰富的情况下我们可以获得不错的性能,但也有几个缺点:

  1. 我在Python中没有找到任何实现(包括imputesklearn.preprocessing.Imputerorange)能够处理具有不同缺失值集的特征向量,也就是说,我们希望对所有可能的缺失特征组合只有一个插补器。
  2. kNN使用成对点距离进行预测/插补。正如我之前提到的,我们的变量具有不同的尺度,因此在进行距离估计之前必须对特征空间进行归一化。我们需要知道每个维度的理论最大/最小值来正确缩放。这并不是一个大问题,而是一个架构上的简单性问题(用户需要提供一个最小/最大值向量)。

所以我想听听你的意见:

  1. 考虑到上述列表中提到的kNN相关问题,有没有经典的方法来解决这些问题?我相信这应该是一个常见的情况,但我没有在网上找到任何具体的信息。
  2. 在我们的情况下,有没有更好的数据插补方法?你有什么推荐?请提供Python实现(也考虑R和C/C++)。

数据

这是训练数据集的一个小样本。我减少了特征数量以使其更易读。查询数据具有相同的结构,只是明显缺少category信息。

v1  v2  v3  v4  v5  category0.40524 0.71542 NA  0.81033 0.8209  10.78421 0.76378 0.84324 0.58814 0.9348  20.30055 NA  0.84324 NA  0.60003 10.34754 0.25277 0.18861 0.28937 0.41394 1NA  0.71542 0.10333 0.41448 0.07377 10.40019 0.02634 0.20924 NA  0.85404 20.56404 0.5481  0.51284 0.39956 0.95957 20.07758 0.40959 0.33802 0.27802 0.35396 10.91219 0.89865 0.84324 0.81033 0.99243 10.91219 NA  NA  0.81033 0.95988 20.5463  0.89865 0.84324 0.81033 NA  20.00963 0.06737 0.03719 0.08979 0.57746 20.59875 0.89865 0.84324 0.50834 0.98906 10.72092 NA  0.49118 0.58814 0.77973 20.06389 NA  0.22424 0.08979 0.7556  2

回答:

根据新的更新,我认为在这里不建议使用kNN或基于树的算法。由于插补是目标而不是你选择的方法的结果,你需要一个能够学会完成不完整数据的算法。

在我看来,这非常适合使用去噪自编码器。如果你熟悉神经网络,这是相同的基本原理。你不是训练模型来预测标签,而是训练模型来预测输入数据,但有一个显著的变化。

“去噪”部分指的是一个中间步骤,在尝试预测之前,你随机将输入数据的某个百分比设置为0。这迫使算法学习更丰富的特征以及在数据缺失时如何完成数据。在你的情况下,我建议在训练时使用低比例的丢弃(因为你的数据已经有缺失特征),在测试时不使用丢弃。

如果不先查看你的数据,很难写出一个有帮助的例子,但自编码器的基本原理(以及完整的代码实现)在这里有介绍:http://deeplearning.net/tutorial/dA.html

这个链接使用了一个名为Theano的Python模块,我强烈推荐用于这项工作。该模块的灵活性超过了我看过的所有其他机器学习模块,我看过很多。它不是最容易学习的,但如果你要做很多这类事情,我认为值得付出努力。如果你不想经历这一切,你仍然可以在Python中不使用它来实现去噪自编码器。

Related Posts

L1-L2正则化的不同系数

我想对网络的权重同时应用L1和L2正则化。然而,我找不…

使用scikit-learn的无监督方法将列表分类成不同组别,有没有办法?

我有一系列实例,每个实例都有一份列表,代表它所遵循的不…

f1_score metric in lightgbm

我想使用自定义指标f1_score来训练一个lgb模型…

通过相关系数矩阵进行特征选择

我在测试不同的算法时,如逻辑回归、高斯朴素贝叶斯、随机…

可以将机器学习库用于流式输入和输出吗?

已关闭。此问题需要更加聚焦。目前不接受回答。 想要改进…

在TensorFlow中,queue.dequeue_up_to()方法的用途是什么?

我对这个方法感到非常困惑,特别是当我发现这个令人费解的…

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注