在特征向量中估算多个缺失值
Impute multiple missing values in a feature-vector
已编辑post
这是原始版本 post 的简短版本,在一定程度上做了澄清。
- 我们有一个训练数据集(一些特征显着相关)。特征 space 有 20 个维度(都是连续的)。
- 我们需要使用训练数据训练非参数(大多数特征形成非线性子space,我们不能假设其中任何一个的分布)输入器(kNN 或基于树的回归)。
- 我们需要使用经过训练的输入器预测查询数据中的多个缺失值(一个查询特征向量最多可以有 13 个缺失特征,因此输入器应该处理缺失特征的任意组合)。 注意 imputer 不应该以任何方式 retrained/fitted 使用查询数据(就像我目前发现的所有主流 R 包中所做的那样:
Amelia
、impute
、mi
和 mice
...)。也就是说,插补应该完全基于训练数据。
- 所有这些的目的如下所述。
- 下面是一个小数据样本。
原始 post (TL;DR)
简而言之,我需要进行一些复杂的数据估算。我们有一个约 100k 20D 样本的训练数据集和一个较小的测试数据集。每个feature/dimension都是连续变量,只是尺度不同。有两个不同的 classes。这两个数据集的 NA 都非常膨胀(NA 在维度上分布不均)。我使用 sklearn.ensemble.ExtraTreesClassifier
进行 class 化,虽然树集成可以处理缺失数据的情况,但执行插补有三个原因
- 通过这种方式,我们可以在查询数据集 class 化期间获得森林中所有树木的投票(而不仅仅是那些没有缺失 feature/features 的树木)。
- 我们在训练期间不会丢失数据。
scikit
树集成的实现(ExtraTrees
和 RandomForest
)不处理缺失值。但这一点并不那么重要。如果不是前两个,我会使用 rpy2
+ 一些不错的 R 实现。
训练数据集的事情非常简单,因为我可以应用 class 特定的中值插补策略来处理缺失值,并且这种方法到目前为止一直运行良好。显然,这种方法不能应用于查询——我们没有 class 开头。因为我们知道 classes 在查询中可能有明显不同的份额,所以我们不能应用 class-indifferent 方法,因为这可能会引入偏差并降低 classification 性能,因此我们需要从模型中估算缺失值。
出于以下几个原因,线性模型不是一种选择:
- 所有特征都在某种程度上相关;
- 理论上我们可以获得样本特征向量中缺失特征的所有可能组合,即使我们的工具需要至少 7 个非缺失特征我们最终得到 ~1^E6 个可能的模型,这看起来并不如果你问我的话,非常优雅。
出于同样的原因,基于树的回归模型并不适用。因此,我们最终选择了 kNN(k 最近邻)、球树或具有半径阈值的 LSH 以更具体。这种方法非常适合这个任务,因为维度(ergo 距离)是相关的,因此我们在极度 NA 丰富的情况下获得了很好的性能,但有几个缺点:
- 我没有在 Python(包括
impute
、sklearn.preprocessing.Imputer
、orange
)中找到处理具有不同缺失值集的特征向量的单一实现,也就是说,我们只想为缺失特征的所有可能组合使用一个输入器。
- kNN 使用 prediction/imputation 的成对点距离。正如我已经提到的,我们的变量具有不同的尺度,因此必须在距离估计之前对特征 space 进行归一化。我们需要知道每个维度的理论 max/min 值才能正确缩放它。这不是什么大问题,因为它是架构简单性的问题(用户必须提供 min/max 值的向量)。
所以我想听听您的意见:
- 是否有任何 classic 方法来解决上面列表中给出的与 kNN 相关的问题?我相信这一定是一个常见的情况,但我还没有在网上找到任何具体的内容。
- 在我们的案例中是否有更好的方法来估算数据?你会推荐什么?请在 Python 中提供实现(R 和 C/C++ 也被考虑在内)。
数据
这是训练数据集的一小部分样本。我减少了功能的数量以使其更具可读性。查询数据具有相同的结构,除了明显缺少 category
信息。
v1 v2 v3 v4 v5 category
0.40524 0.71542 NA 0.81033 0.8209 1
0.78421 0.76378 0.84324 0.58814 0.9348 2
0.30055 NA 0.84324 NA 0.60003 1
0.34754 0.25277 0.18861 0.28937 0.41394 1
NA 0.71542 0.10333 0.41448 0.07377 1
0.40019 0.02634 0.20924 NA 0.85404 2
0.56404 0.5481 0.51284 0.39956 0.95957 2
0.07758 0.40959 0.33802 0.27802 0.35396 1
0.91219 0.89865 0.84324 0.81033 0.99243 1
0.91219 NA NA 0.81033 0.95988 2
0.5463 0.89865 0.84324 0.81033 NA 2
0.00963 0.06737 0.03719 0.08979 0.57746 2
0.59875 0.89865 0.84324 0.50834 0.98906 1
0.72092 NA 0.49118 0.58814 0.77973 2
0.06389 NA 0.22424 0.08979 0.7556 2
基于新的更新,我想我会在这里反对 kNN 或基于树的算法。由于插补是目标而不是您选择的方法的结果,因此您需要一种算法来学习完成不完整的数据。
对我来说,这似乎非常适合使用去噪自动编码器。如果您熟悉神经网络,它的基本原理是相同的。不是训练来预测标签,而是训练模型以显着扭曲来预测输入数据。
'denoising' 部分指的是一个中间步骤,在该步骤中,您在尝试预测之前将输入数据的某个百分比随机设置为 0。这迫使算法学习更丰富的特征,以及在数据缺失的情况下如何补全数据。在您的情况下,我建议在训练中少量退出(因为您的数据已经缺少功能)并且在测试中不要退出。
如果不先查看您的数据就很难编写一个有用的示例,但是此处涵盖了自动编码器的基本功能(以及完整的代码实现):http://deeplearning.net/tutorial/dA.html
这个 link 使用一个名为 Theano 的 python 模块,我强烈推荐它用于这项工作。该模块的灵活性胜过我看过的所有其他机器学习模块,而且我看过很多。这不是最容易学习的东西,但如果你打算做很多这样的事情,我会说这是值得的。如果你不想经历所有这些,那么你仍然可以在没有它的情况下在 Python 中实现去噪自动编码器。
已编辑post
这是原始版本 post 的简短版本,在一定程度上做了澄清。
- 我们有一个训练数据集(一些特征显着相关)。特征 space 有 20 个维度(都是连续的)。
- 我们需要使用训练数据训练非参数(大多数特征形成非线性子space,我们不能假设其中任何一个的分布)输入器(kNN 或基于树的回归)。
- 我们需要使用经过训练的输入器预测查询数据中的多个缺失值(一个查询特征向量最多可以有 13 个缺失特征,因此输入器应该处理缺失特征的任意组合)。 注意 imputer 不应该以任何方式 retrained/fitted 使用查询数据(就像我目前发现的所有主流 R 包中所做的那样:
Amelia
、impute
、mi
和mice
...)。也就是说,插补应该完全基于训练数据。 - 所有这些的目的如下所述。
- 下面是一个小数据样本。
原始 post (TL;DR)
简而言之,我需要进行一些复杂的数据估算。我们有一个约 100k 20D 样本的训练数据集和一个较小的测试数据集。每个feature/dimension都是连续变量,只是尺度不同。有两个不同的 classes。这两个数据集的 NA 都非常膨胀(NA 在维度上分布不均)。我使用 sklearn.ensemble.ExtraTreesClassifier
进行 class 化,虽然树集成可以处理缺失数据的情况,但执行插补有三个原因
- 通过这种方式,我们可以在查询数据集 class 化期间获得森林中所有树木的投票(而不仅仅是那些没有缺失 feature/features 的树木)。
- 我们在训练期间不会丢失数据。
scikit
树集成的实现(ExtraTrees
和RandomForest
)不处理缺失值。但这一点并不那么重要。如果不是前两个,我会使用rpy2
+ 一些不错的 R 实现。
训练数据集的事情非常简单,因为我可以应用 class 特定的中值插补策略来处理缺失值,并且这种方法到目前为止一直运行良好。显然,这种方法不能应用于查询——我们没有 class 开头。因为我们知道 classes 在查询中可能有明显不同的份额,所以我们不能应用 class-indifferent 方法,因为这可能会引入偏差并降低 classification 性能,因此我们需要从模型中估算缺失值。
出于以下几个原因,线性模型不是一种选择:
- 所有特征都在某种程度上相关;
- 理论上我们可以获得样本特征向量中缺失特征的所有可能组合,即使我们的工具需要至少 7 个非缺失特征我们最终得到 ~1^E6 个可能的模型,这看起来并不如果你问我的话,非常优雅。
出于同样的原因,基于树的回归模型并不适用。因此,我们最终选择了 kNN(k 最近邻)、球树或具有半径阈值的 LSH 以更具体。这种方法非常适合这个任务,因为维度(ergo 距离)是相关的,因此我们在极度 NA 丰富的情况下获得了很好的性能,但有几个缺点:
- 我没有在 Python(包括
impute
、sklearn.preprocessing.Imputer
、orange
)中找到处理具有不同缺失值集的特征向量的单一实现,也就是说,我们只想为缺失特征的所有可能组合使用一个输入器。 - kNN 使用 prediction/imputation 的成对点距离。正如我已经提到的,我们的变量具有不同的尺度,因此必须在距离估计之前对特征 space 进行归一化。我们需要知道每个维度的理论 max/min 值才能正确缩放它。这不是什么大问题,因为它是架构简单性的问题(用户必须提供 min/max 值的向量)。
所以我想听听您的意见:
- 是否有任何 classic 方法来解决上面列表中给出的与 kNN 相关的问题?我相信这一定是一个常见的情况,但我还没有在网上找到任何具体的内容。
- 在我们的案例中是否有更好的方法来估算数据?你会推荐什么?请在 Python 中提供实现(R 和 C/C++ 也被考虑在内)。
数据
这是训练数据集的一小部分样本。我减少了功能的数量以使其更具可读性。查询数据具有相同的结构,除了明显缺少 category
信息。
v1 v2 v3 v4 v5 category
0.40524 0.71542 NA 0.81033 0.8209 1
0.78421 0.76378 0.84324 0.58814 0.9348 2
0.30055 NA 0.84324 NA 0.60003 1
0.34754 0.25277 0.18861 0.28937 0.41394 1
NA 0.71542 0.10333 0.41448 0.07377 1
0.40019 0.02634 0.20924 NA 0.85404 2
0.56404 0.5481 0.51284 0.39956 0.95957 2
0.07758 0.40959 0.33802 0.27802 0.35396 1
0.91219 0.89865 0.84324 0.81033 0.99243 1
0.91219 NA NA 0.81033 0.95988 2
0.5463 0.89865 0.84324 0.81033 NA 2
0.00963 0.06737 0.03719 0.08979 0.57746 2
0.59875 0.89865 0.84324 0.50834 0.98906 1
0.72092 NA 0.49118 0.58814 0.77973 2
0.06389 NA 0.22424 0.08979 0.7556 2
基于新的更新,我想我会在这里反对 kNN 或基于树的算法。由于插补是目标而不是您选择的方法的结果,因此您需要一种算法来学习完成不完整的数据。
对我来说,这似乎非常适合使用去噪自动编码器。如果您熟悉神经网络,它的基本原理是相同的。不是训练来预测标签,而是训练模型以显着扭曲来预测输入数据。
'denoising' 部分指的是一个中间步骤,在该步骤中,您在尝试预测之前将输入数据的某个百分比随机设置为 0。这迫使算法学习更丰富的特征,以及在数据缺失的情况下如何补全数据。在您的情况下,我建议在训练中少量退出(因为您的数据已经缺少功能)并且在测试中不要退出。
如果不先查看您的数据就很难编写一个有用的示例,但是此处涵盖了自动编码器的基本功能(以及完整的代码实现):http://deeplearning.net/tutorial/dA.html
这个 link 使用一个名为 Theano 的 python 模块,我强烈推荐它用于这项工作。该模块的灵活性胜过我看过的所有其他机器学习模块,而且我看过很多。这不是最容易学习的东西,但如果你打算做很多这样的事情,我会说这是值得的。如果你不想经历所有这些,那么你仍然可以在没有它的情况下在 Python 中实现去噪自动编码器。