scikits 机器学习中的缺失值
Posted
技术标签:
【中文标题】scikits 机器学习中的缺失值【英文标题】:Missing values in scikits machine learning 【发布时间】:2012-03-11 01:55:16 【问题描述】:scikit-learn 中是否可能存在缺失值?他们应该如何表现?我找不到任何相关文档。
【问题讨论】:
【参考方案1】:scikit-learn 根本不支持缺失值。之前已经在邮件列表上讨论过这个问题,但没有尝试实际编写代码来处理它们。
无论你做什么,不要使用 NaN 来编码缺失值,因为许多算法拒绝处理包含 NaN 的样本。
上面的答案已经过时了; scikit-learn 的最新版本有一个类Imputer
,它可以进行简单的、每个特征的缺失值插补。您可以为其提供包含 NaN 的数组,以将其替换为相应特征的均值、中位数或众数。
【讨论】:
我只是想指出随机森林很好地处理了 nan 值 GBM 还是这样吗? scikit learn 版本没有反映 R 中优雅地处理缺失值的编码是否有原因?这是该算法的吸引人的特性之一,我希望它在 scikit 中被这样编码。 @B_Miner:几乎所有 scikit-learn 估计器都是这种情况。缺失值处理与学习分开进行,但可以使用Pipeline
将两者结合起来。
一个人需要聪明地知道将缺失值归咎于什么,而不仅仅是选择平均值、中位数或众数。在某些情况下0
可能最有意义,在这种情况下可以使用df[column_name].fillna(0, inplace=True)
。同样对于像monthsSinceLastDelinquency
这样的功能,将缺失值归入有效范围之外的值是最有意义的。决策树可以以此进行有意义的拆分,并保留数据中的信息。【参考方案2】:
我希望我能提供一个简单的例子,但我发现 RandomForestRegressor 确实不优雅地处理 NaN。添加具有越来越多 NaN 百分比的功能时,性能会逐渐变差。具有“太多” NaN 的特征将被完全忽略,即使 nan 表示非常有用的信息。
这是因为算法将从不在“isnan”或“ismissing”决策上创建拆分。如果该特征在该样本子集中具有单个 NaN,则该算法将忽略树的特定级别的特征。但是,在树的较低级别,当样本量较小时,样本子集更有可能在特定特征的值中没有 NaN,并且可能会在该特征上发生分裂。
我尝试了各种插补技术来解决这个问题(用均值/中值替换,使用不同的模型预测缺失值等),但结果好坏参半。
相反,这是我的解决方案:用一个明显超出范围的值(如 -1.0)替换 NaN。这使树能够按照“未知值与已知值”的标准进行拆分。然而,使用这种超出范围的值有一个奇怪的副作用:当算法试图找到一个好位置时,超出范围值附近的已知值可能会与超出范围值混为一谈分开。例如,已知的 0 可能与用于替换 NaN 的 -1 混为一谈。因此,您的模型可能会根据您的超出范围值是小于最小值还是大于最大值而改变(它可能分别与最小值或最大值混为一谈)。这可能有助于技术的泛化,也可能无助,结果将取决于行为最小值或最大值样本与 NaN 值样本的相似程度。
【讨论】:
使用“明显超出范围”的值作为缺失值的好主意。这对决策树应该很有效。 我经常使用 -1。看来我需要尝试一些更明显的东西,比如“-999”以获得更好的 NaN 性能。【参考方案3】:Orange 是另一个 python 机器学习库,具有专门用于插补的设施。我还没有机会使用它们,但可能很快就会使用它们,因为用零、平均值或中位数替换 nan 的简单方法都有很大的问题。
【讨论】:
【参考方案4】:在对数据运行 RandomForestRegressor 时,我遇到了非常相似的问题。 NA 值的存在将“nan”用于预测。通过浏览几个讨论,Breiman 的文档分别为连续数据和分类数据推荐了两种解决方案。
-
计算列中数据的中位数(特征)并使用
this(连续数据)
确定最常出现的类别并使用它
(分类数据)
根据 Breiman 的说法,算法的随机性和树的数量将允许进行校正,而不会对预测的准确性产生太大影响。如果 NA 值的存在是稀疏的,我认为会出现这种情况,我认为包含许多 NA 值的特征很可能会产生影响。
【讨论】:
【参考方案5】:用平均值/中值/其他统计数据替换缺失值可能无法解决问题,因为缺失值的事实可能很重要。例如,在一项关于身体特征的调查中,如果受访者因异常高或异常矮而感到尴尬,他们可能不会填写自己的身高。这意味着缺失值表明受访者异常高或异常矮 - 与中值相反。
模型需要有一个单独的缺失值规则,任何猜测缺失值的尝试都可能会降低模型的预测能力。
例如:
df['xvariable_missing'] = np.where(df.xvariable.isna(),1,0)
df.xvariable = df.xvariable.fillna(df.xvariable.median())
【讨论】:
是的。此外,在许多情况下,数据可能非常严重 NULL(假设每行的 20% 已填充)。基于 DT 的方法应该能够解决这个问题——如果使用得当,该模型可能比使用估算数据的模型要好得多。 @Johnny V “具有单独规则的模型”是什么意思? 我使用的策略是添加一个缺失值标志列以及用中位数或众数填充缺失值。这样做是为了让模型将记录视为正常,除非缺失值很重要,在这种情况下,模型将为缺失数据标志制定规则。例如“如果记录缺少数据点,则归类为 A 类”【参考方案6】:我确实遇到过这个问题。在一个实际案例中,我在 R 中发现了一个名为 missForest 的包,它可以很好地处理这个问题,填补缺失值并大大增强了我的预测。 missForest 不是简单地用中值或平均值替换 NA,而是用它认为缺失值应该是什么的预测来替换它们。它使用在数据矩阵的观察值上训练的随机森林进行预测。它在包含大量缺失值的大型数据集上运行非常缓慢。因此,这种方法需要权衡取舍。 python中类似的选项是predictive_imputer
【讨论】:
【参考方案7】:当您在输入特征上遇到缺失值时,首要任务不是如何估算缺失值。最重要的问题是你为什么要这样做。除非您清楚明确地知道数据背后的“真实”现实是什么,否则您可能希望减少推算的冲动。这首先与技术或包装无关。
从历史上看,我们采用决策树之类的树方法主要是因为我们中的一些人至少认为估算回归(如线性回归、逻辑回归甚至 NN)的估算缺失具有足够的扭曲性,因此我们应该有不需要估算缺失的方法'列之间'。所谓信息缺失。对于熟悉贝叶斯的人来说,这应该是熟悉的概念。
如果你真的是在大数据上建模,除了谈论它,你可能会面临大量的列。在文本分析等特征提取的常见实践中,您可能会说缺失意味着 count=0。这很好,因为你知道根本原因。现实情况是,尤其是在面对结构化数据源时,您不知道或根本没有时间了解根本原因。但是您的引擎强制插入一个值,无论是 NAN 还是引擎可以容忍的其他占位符,我很可能会认为您的模型与您估算的一样好,这没有意义。
一个有趣的问题是:如果我们在分裂过程中通过其紧密的上下文来判断缺失,一级或二级代理,森林化是否真的使上下文判断没有实际意义,因为上下文本身是随机选择?然而,这是一个“更好”的问题。至少不会那么疼。它当然应该使保留缺失变得不必要。
实际上,如果你有大量的输入特征,你可能根本就没有一个“好的”策略来估算。从纯粹的插补角度来看,最佳实践绝不是单变量。在 RF 的竞争中,这几乎意味着在使用 RF 建模之前使用 RF 进行估算。
因此,除非有人告诉我(或我们),“我们无法做到这一点”,否则我认为我们应该启用缺失的“细胞”,完全绕过如何“最好”估算的主题。
【讨论】:
以上是关于scikits 机器学习中的缺失值的主要内容,如果未能解决你的问题,请参考以下文章
[机器学习与scikit-learn-9]:数据预处理-2-缺失数据na的预处理