缺失数据揭秘:数据科学家的绝对入门指南
缺失数据揭秘
数据质量编年史
缺失数据、缺失机制和缺失数据分析
今年早些时候,我写了一篇关于严重损害我们机器学习模型的几个数据质量问题(或特性)。
其中之一,毫不奇怪的是缺失数据。
我已经研究这个主题多年了(是的,没错?!),但在我参与的一些数据中心社区的项目中,我意识到许多数据科学家仍然没有完全理解这个问题的复杂性,这激发了我创作这个全面教程的灵感。
今天,我们将深入研究缺失数据问题的复杂性,了解我们在现实数据集中可能遇到的不同缺失数据类型,并探索如何识别和标记缺失值。
缺失数据问题
缺失数据是一个有趣的数据缺陷,因为它可能是由于领域的性质自然产生,或者在数据收集、传输或处理过程中无意中创建。
本质上,缺失数据的特点是数据中出现缺失值,即数据集中某些记录或观测中存在缺失值,可以是单变量(一个特征具有缺失值)或多变量(多个特征具有缺失值):

让我们来考虑一个例子。假设我们正在对患有糖尿病的患者队列进行一项研究。
医疗数据是一个很好的例子,因为它往往是高度缺失值的:患者的数据来自于调查和实验室结果,可以在诊断或治疗过程中多次测量,以不同格式存储(有时分布在机构之间),并且通常由不同的人处理。数据可能会变得混乱!
在我们的糖尿病研究中,缺失值的存在可能与正在进行的研究或正在收集的数据相关。
例如,由于血压传感器在高血压值时关闭,可能会出现缺失数据。另一个可能性是特征“体重”的缺失值更可能在年长的女性中缺失,她们不太愿意透露这些信息。或者肥胖患者可能不太愿意分享他们的体重。
另一方面,数据也可能因与研究无关的原因而缺失。
患者可能由于汽车爆胎而错过医生约会,导致他的一些信息缺失。数据也可能因人为错误而丢失:例如,分析人员放错或误读了一些文件。
无论数据缺失的原因是什么,重要的是在模型构建之前调查数据集是否包含缺失数据,因为这个问题可能对分类器产生严重后果:
- 一些分类器无法在内部处理缺失值:这使得它们在处理具有缺失数据的数据集时无法应用。在某些情况下,这些值会使用预定义的值进行编码,例如“0”,以便机器学习算法能够处理它们,尽管这不是最佳实践,特别是对于更高比例的缺失数据(或更复杂的缺失机制);
- 基于缺失数据的预测可能存在偏差和不可靠性:尽管一些分类器可以在内部处理缺失数据,但它们的预测可能会受到损害,因为训练数据中可能缺少重要的信息。
此外,尽管缺失值可能看起来“都一样”,但事实是它们的基本机制(即缺失的原因)可以遵循3种主要模式:完全随机缺失(MCAR),非随机缺失(MAR)和非随机缺失(MNAR)。
牢记这些不同类型的缺失机制很重要,因为它们决定了处理缺失数据的适当方法的选择以及从中得出的推论的有效性。
让我们快速看一下每种机制!
缺失数据机制
如果你是一个喜欢数学的人,我建议你阅读一下这篇论文(咳咳),特别是第二节和第三节,其中包含你可能正在寻找的所有符号和数学公式(实际上我受到了这本书的启发,这也是一本非常有趣的入门书,看看第2.2.3节和2.2.4节)。
如果你也是像我一样的视觉学习者,你肯定想要“看到”它,对吧?
为此,我们将看一下在论文中使用的青少年吸烟研究示例。我们将考虑使用虚拟数据展示每种缺失机制:

有一件事需要记住:缺失机制描述了缺失模式是否可以通过观察数据和/或缺失数据来解释。这很棘手,我知道。但通过例子会更清楚!
在我们的吸烟研究中,我们关注的是青少年的吸烟情况。共有20个观察值,对应20个参与者,特征年龄
完全观察到,而香烟数量
(每天吸烟量)将根据不同的机制缺失。
完全随机缺失(MCAR):无伤无碍!
在完全随机缺失(MCAR)机制中,缺失过程与观察数据和缺失数据都没有关系。这意味着特征具有缺失值的概率是完全随机的。

在我们的例子中,我只是随机删除了一些值。请注意,缺失值不位于特定范围的年龄
或香烟数量
值中。因此,这种机制可能是由于研究期间发生的意外事件:比如,负责登记参与者回答的人意外跳过了一项调查的问题。
随机缺失(MAR):寻找暗示!
这个名字实际上是误导人的,因为随机缺失(MAR)是指缺失过程可以与数据中的观察信息相关联(尽管与缺失信息本身无关)。
考虑下一个例子,我只删除了年轻参与者(15至16岁)的香烟数量
值。请注意,尽管缺失过程与年龄
中的观察值明显相关,但它与这些青少年吸烟的数量完全无关(如果有的话,可以在“完整”列中找到缺失值中可能存在的低和高数量的香烟)。
如果年龄较小的孩子不愿透露他们每天吸烟的数量,避免承认他们是经常吸烟者(无论吸烟量多少),那么这种情况就会出现。
非随机缺失(MNAR):恍然大悟的时刻!
正如预期的那样,非随机缺失(MNAR)机制是最棘手的,因为缺失过程可能依赖于数据中的已观测和缺失信息。这意味着特征中出现缺失值的概率可能与数据中其他特征的观测值以及该特征本身的缺失值相关!
看看下一个例子:较高数量的“烟草数量”缺失了值,这意味着“烟草数量”中缺失值的概率与其自身的缺失值相关(注意“完整”列)。
这是一种情况,即青少年拒绝报告他们每天吸烟的数量,因为他们吸了很多烟。
缺失数据机制的影响
在我们的简单例子中,我们已经看到MCAR是最简单的缺失机制。在这种情况下,我们可以忽略许多由于出现缺失值而产生的复杂性,并且一些简单的修复措施,如按案例或按变量删除,以及更简单的统计插补技术,可能会奏效。
然而,尽管方便,但事实是在现实世界的领域中,MCAR往往是不切实际的,大多数研究人员通常假设至少是MAR,在他们的研究中,MAR比MCAR更普遍和现实。在这种情况下,我们可以考虑比从观察数据中推断缺失信息更强大的策略。在这方面,基于机器学习的数据插补策略通常是最受欢迎的。
最后,MNAR是迄今为止最复杂的情况,因为很难推断缺失的原因。目前的方法侧重于使用领域专家定义的校正因子来映射缺失值的原因,从分布式系统中推断缺失数据,扩展先进模型(如生成模型)以包含多重插补,或进行敏感性分析以确定结果在不同情况下的变化。
此外,在可识别性的问题上,问题并不容易。
虽然有一些用于区分MCAR和MAR的测试,但它们并不广泛流行,并且具有对于复杂的现实世界数据集不成立的限制性假设。而且,无法区分MNAR和MAR,因为需要的信息是缺失的。
为了诊断和区分实践中缺失的机制,我们可以关注假设检验、敏感性分析、从领域专家获取一些见解,并调查可以提供对领域的一些理解的可视化技术。
当然,还有其他要考虑的复杂因素,这些因素会影响缺失数据的处理策略,即缺失数据的百分比、受影响的特征数量以及技术的最终目标(例如,为分类或回归训练模型、以最真实的方式重构原始值等)。
总而言之,这并不是一项容易的工作。
识别和标记缺失数据
让我们一点一点来。我们刚刚学到了有关缺失数据及其复杂纠缠的过载信息。
在这个例子中,我们将介绍如何在现实数据集中标记和可视化缺失数据的基础知识,并确认缺失数据给数据科学项目带来的问题。
为此,我们将使用 Kaggle 上可用的 Pima Indians Diabetes 数据集(许可证 – CC0:公共领域)。如果您想跟随本教程,可以从 Data-Centric AI Community GitHub 存储库中下载笔记本。
为了快速对数据进行概述,我们还将使用 ydata-profiling
,它可以在几行代码中为我们提供完整的数据概述。让我们从安装它开始:
安装最新版本的 ydata-profiling。作者提供的代码片段。
现在,我们可以加载数据并进行快速概述:
加载数据并创建概述报告。作者提供的代码片段。
通过查看数据,我们可以确定该数据集由768条记录/行/观察(768名患者)和9个属性或特征组成。实际上,Outcome
是目标类别(1/0),因此我们有8个预测变量(8个数值特征和1个分类特征)。

乍一看,数据集似乎没有缺失数据。然而,已知该数据集受缺失数据影响!我们如何确认这一点?
通过查看“警报”部分,我们可以看到几个“零”警报,表明存在多个特征,其中零值没有意义或在生物学上是不可能的:例如,体重指数或血压的零值是无效的!
浏览所有特征,我们可以确定怀孕数量看起来正常(怀孕次数为零是合理的),但对于其他特征,零值是可疑的:

在大多数现实世界的数据集中,缺失数据通过哨兵值进行编码:
- 超出范围的条目,例如
999
; - 有正值的特征出现负数,例如
-1
; - 一个特征中的零值永远不可能为0。
在我们的例子中,Glucose
、BloodPressure
、SkinThickness
、Insulin
和BMI
都有缺失数据。让我们统计这些特征中的零值数量:
统计零值的数量。作者提供的代码片段。
我们可以看到,Glucose
、BloodPressure
和BMI
只有少量零值,而SkinThickness
和Insulin
有更多的零值,几乎覆盖了现有观察的一半。这意味着我们可能需要考虑不同的策略来处理这些特征:某些特征可能需要比其他特征更复杂的插补技术。
为了使我们的数据集与数据特定的约定一致,我们应该将这些缺失值设置为 NaN
值。
这是在Python中处理缺失数据的标准方法,也是流行的包(如pandas
和scikit-learn
)遵循的约定。这些值在某些计算(如sum
或count
)中被忽略,并且某些函数会识别它们以执行其他操作(例如,删除缺失值,填充它们,用固定值替换它们等)。
我们将使用replace()
函数标记缺失值,然后调用isnan()
函数验证它们是否正确编码:
将零值标记为NaN值。由作者提供的代码段。
NaN
值的计数与0
值相同,这意味着我们已经正确标记了我们的缺失值!然后,我们可以再次使用概要报告来检查现在是否识别了缺失数据。以下是我们的“新”数据的样子:

我们还可以通过查看报告的“缺失值”部分进一步检查缺失过程的一些特征:

除了“Count”图,该图给出了每个特征的所有缺失值的概览,我们还可以更详细地探索“Matrix”和“Heatmap”图,以猜测数据可能遭受的潜在缺失机制。特别是,缺失特征之间的相关性可能是有信息量的。在这种情况下,Insulin
和SkinThicknes
之间似乎存在显著相关性:这两个值似乎都对某些患者同时缺失。无论这是巧合(不太可能),还是缺失过程可以通过已知因素解释,即描绘MAR或MNAR机制,都值得我们深入研究!
无论如何,现在我们已经准备好进行分析了!不幸的是,处理缺失数据的过程还远未结束。许多经典的机器学习算法无法处理缺失数据,我们需要找到专家方法来缓解这个问题。让我们尝试在该数据集上评估线性判别分析(LDA)算法:
使用缺失值评估线性判别分析(LDA)算法。由作者提供的代码段。
如果您尝试运行此代码,它将立即抛出错误:

修复这个问题的最简单(也是最天真的!)方法是删除包含缺失值的所有记录。我们可以通过创建一个新的数据框,其中包含删除了包含缺失值的行,使用dropna()
函数来实现这一点…
删除所有包含缺失值的行/观测。由作者提供的代码段。
然后再次尝试:
在没有缺失值的情况下评估LDA算法。由作者提供的代码段。

就是这样了!通过删除缺失值,LDA算法现在可以正常运行。
然而,数据集的大小大大减少到仅有392个观测值,这意味着我们丢失了将近一半的可用信息。
因此,我们应该寻找缺失值填补的策略,可以是统计学的,也可以是基于机器学习的。根据我们的最终应用,我们还可以使用合成数据来替换缺失值。
为此,我们可以尝试了解数据中潜在的缺失机制。这是未来文章中值得期待的内容吗?
最后的思考
在这篇文章中,我们涵盖了数据科学家在开始处理缺失数据时需要掌握的所有基础知识。
从问题本身到缺失机制,我们发现缺失信息对我们的数据科学项目可能产生的影响,尽管所有的NaN
看起来一样,但它们可能传达着截然不同的故事。
在我的后续文章中,我将专门讨论每个缺失机制,重点关注生成、填补和可视化策略,敬请关注新的博客文章,不要忘记为数据中心AI存储库加星标,以便不会错过代码更新!
如往常一样,非常欢迎反馈、问题和建议!您可以给我留言、为存储库做贡献,甚至可以在数据中心AI社区找到我,讨论其他与数据相关的话题。我们在那里见吧?
关于我
博士,机器学习研究员,教育家,数据倡导者,总体来说是个“多面手”。在VoAGI上,我写关于数据中心AI和数据质量的文章,教育数据科学和机器学习社区如何从不完善的数据到智能数据。
YData的开发者关系 | 数据中心AI社区 | GitHub | Instagram | Google Scholar | LinkedIn