如何处理数据集内的缺失值?

news2024/11/25 20:22:41

照片 

奥坎·耶尼贡

由Pierre Bamin在Unsplash上拍摄

一、说明

        也许数据科学或机器学习问题研究中要求最高的阶段是数据预处理阶段,其目的是最终创建有用的数据集。如果说处理很酷的机器学习模型是阿喀琉斯的热门,那么数据预处理就是被诅咒的西西弗斯。

资料来源:维基百科

        数据集通常包含缺失数据。原因通常因数据集的性质、问题或收集方式而异。如果是通过调查获得的,则某些问题可能无法得到解答。或者,如果它是从数据流中收集的,则在某些情况下该流可能存在问题。如果数据是从系统中获取的,那么有些特征在某些情况下可能没有数据,等等。

        我们必须处理缺失值。因为缺失值直接影响模型的成功。此外,许多机器学习模型不适用于包含缺失值的数据集。

        缺失值的分布可能是随机的,也可能遵循某种模式。在某些情况下,缺失值实际上可能是另一个讲述故事的独特数据。因此,应该探索它们的结构和模式,如果可以的话,应与领域知识相结合。例如,假设调查的第一个问题是“你有工作吗?”,第二个问题是“你的薪水是多少?”。只有当第一个问题的答案为“”时,参与者才能回答第二个问题,否则,应用程序将不允许她/他回答。在这种情况下,工资列中的缺失数据不是随机的,而是遵循一定的模式。

二、缺失数据模式

        我们可以对缺失数据分布在哪个结构中进行分类。我们可以列出 3 个广义类别:MCAR、MAR 和 MNAR。

2.1 MCAR:完全随机缺失

        数据丢失的概率对于所有情况都是相同的,并且与可观察和不可观察参数无关。在这种情况下,信息会因缺失值而丢失,但是,它不会增加模型的复杂性。考虑一个电池即将耗尽的电视遥控器。有时它会改变频道,有时则不会。当它不起作用时,那就只是运气不好。

如果缺失的数据无法填写,可以将其删除。因为即使信息丢失,它也不会增加额外的复杂性。

2.2 三月:随机失踪

        缺失仅取决于我们实际观察到的数据。不同组内的缺失概率相同,但不同组之间的缺失概率不同。假设我们不小心损坏了上述遥控器。下部按键损坏。上下键之间不起作用的概率会有所不同。然而,组内的密钥仍然具有随机性。

由于各组在其内部表示相同的行为,而在彼此之间表示不同的行为,因此可以应用插补。

2.3 MNAR:并非随机缺失

        缺失背后有一个机制。这取决于未观察到的数据。在这种情况下,最好处理数据集并收集新数据来克服 MNAR。

三、检测

        我将使用经典的泰坦尼克号数据集来演示探索数据集中缺失值的方法。

df.isnull()
#True if the cell is missing.

每个特征的缺失值总数。

df.isnull().sum()
-----------
PassengerId      0
Survived         0
Pclass           0
Name             0
Sex              0
Age            177
SibSp            0
Parch            0
Ticket           0
Fare             0
Cabin          687
Embarked         2
dtype: int64

可视化

我们可以使用可视化技术来发现缺失值。热图适合可视化。每行表示一行中缺失的数据。

sns.heatmap(df.isnull(),yticklabels=False,cbar=False,cmap='YlGnBu')

我们还可以使用Missingno库来实现此目的。

import missingno as msno
msno.matrix(data)

我们也可以更改行的顺序。

msno.matrix(df.sort_values('Ticket'))

四、处理程序方法

缺失数据可以通过多种方法处理。这些方法可分为以下几类:

  • 删除列或行
  • 插补——填充一个值
  • 创建新功能
  • 使用估计器

4.1 移动

        最简单但效果最差的解决方案。如果大部分列或行丢失(一定太多了!),我们可以考虑将其删除。请记住,删除列比删除行要糟糕得多,因为列是一项功能,因此我们可能会丢失大量信息。

#removing all of the missing rows
print(df.shape)
df.dropna(inplace=True)
print(df.shape)
-------
(891, 12)
(183, 12)

如您所见,删除了太多行。

#removing columns with nan values
print(df.shape)
df.dropna(axis='columns',inplace=True)
print(df.shape)
-----------
(891, 12)
(891, 9)

年龄、船舱和登船列均被删除。

另一种方法是设置阈值以删除某些列或行。例如,如果缺失的百分比大于 75%,我们可以删除列。

#removing columns if missing val ratio is bigger than .75
df = df.loc[:, df.isnull().mean() < .75]
print(df.shape)
---------
(891, 11)

或者,我们可以通过给出最小数量的非缺失值来删除行。这次,一行必须至少填充 90%,否则,它将被删除。

thres_val = df.shape[1] * 0.9
df.dropna(thresh=thres_val, inplace=True)
------
(733, 12)

4.2 插补

我们可以用另一个值替换缺失值。这可以以不同的方式应用于数值和分类值。

可以为数值特征分配一个常数值。关于常数值是什么的信息应该来自域。例如,只有在领域知识支持的情况下,我们才可以将Age列中的缺失值设置为 18。

df["Age"].fillna(18,inplace=True)

同样,我们可以在分类特征中分配一组新的类别。例如,我们可以将缺失的数据替换为新类别“缺失”。

df["Embarked"].fillna("Missing",inplace=True)

使用聚合值是另一种选择。数值特征的平均值可以用Nans代替。对于小型数据集,使用平均值是一种简单的方法,并且可能效果很好,但对于大型数据集则效果不佳。如果特征中存在异常值,则总体上可能会损害模型的质量,因为均值将是偏态值。由于这些原因,应事先检查特征偏度。

df["Age"] = df["Age"].fillna(df["Age"].mean())

如果特征有偏差,可以使用中值代替平均值

df["Age"] = df["Age"].fillna(df["Age"].median())

类似地,分类特征可以用众数来估算。它也适用于数字特征。如果特征不平衡(类不平衡问题),则用众数填充缺失值可能会给数据带来偏差。

df["Cabin"] = df["Cabin"].fillna(df["Cabin"].mode()[0])

另一种可用于分类特征的方法是为缺失数据创建新特征。这个新特征可以是一个布尔值,如果数据存在于引用的特征中则为真,否则可以设置为假。因此,丢失数据提供的信息不会丢失。

df["Cabin_MV"] = df["Cabin"].isnull()

缺失的数据可以用上一行或下一行的数据填充。如果观测值之间存在顺序关系,则可以应用此方法。

#forward
df["Cabin"] = df["Cabin"].fillna(method ='ffill')
#back
df["Cabin"] = df["Cabin"].fillna(method ='bfill')

4.3 简单输入器

from sklearn.impute import SimpleImputer
class sklearn.impute.SimpleImputer(*, missing_values=nan, strategy='mean', fill_value=None, verbose=0, copy=True, add_indicator=False)[source]

它是 sklearn 的自动输入器类。它需要的参数;

缺失值int、float、str、np.nan、None、默认=np.nan

缺失值的类型。在 pandas 数据框中,它们的类型是 np.nan

策略str,默认='mean'

{'平均值', '中位数', '最频繁', '常量'}

插补策略。

fill_value字符串或数字,默认=无

如果策略设置为常量,则使用常量值。

复制布尔值,默认=True

Imputer 创建给定X的副本。

add_indicator布尔值,默认=False

如果启用,估算器可以在进行插补的情况下解释缺失情况。

imputer = SimpleImputer(missing_values=np.nan, strategy='mean')
imputer = imputer.fit(df[["Age"]])
df["Age"] = imputer.transform(df[["Age"]])

4.4 插值法

插值是一种估计序列中缺失数据的数学技术。它获取观察结果并根据它们调整函数。函数的范围空间与数据一样广泛。这就是为什么它被称为插值,如果我们从范围进一步估计数据,那就是外推法。插值法尤其适用于时间序列问题,因为它很可能用以前的值来填充缺失值。

插值法与外推法 来源:statology

DataFrame.interpolate(method='linear', axis=0, limit=None, inplace=False, limit_direction=None, limit_area=None, downcast=None, **kwargs)[source]

方法str,默认='线性'

{ '线性'、'时间'、'索引'、'值'、'垫'、'最近'、'零'、'线性'、'二次'、'三次'、'样条'、'重心'、'多项式”、“krogh”、“分段多项式”、“样条”、“芯片”、“akima”、“三次样条”、“from_derivatives”}

线性插值是默认方法。它将点按顺序连接成直线,并按照与之前相同的顺序估计未知值。连接点时它不使用索引。它根据数字的值对数字进行排序。如果时间间隔设置相等的话,时间 插值也是一样的,都是以时间间隔为基础的。

索引 使用索引的实际值。可应用于顺序数据。Pad使用前一个或下一个非缺失数据。

最近的很明显。零、线性、二次三次分别是样条插值的零阶、一阶、二阶或三阶。

重心多项式插值的一种变体。它将问题视为有理函数插值的特例。我们在线性插值中使用直线。但如果数据不是线性的而是多项式的,那么我们应该使用多项式插值。Krogh是另一种特殊的多项式插值方法。如果我们有大量的点,那么多项式插值可能会出现问题,在这种情况下,您应该采用更高的阶数,但这一次会出现振荡问题。这就是piecewise_polynomial发挥作用的地方。from_derivatives是piecewise_polynomial的一种特殊方法。

多项式插值。资料来源:维基百科

是分段多项式的特例。它们是一组低阶多项式。因此,您可以使用 9 个低阶三次多项式,而不是给出高阶多项式。Chip、anima三次样条方法是样条插值的特殊情况。

样条线。资料来源:维基百科

{0或'索引,1或'列,无},默认=无

限制:整数,可选(>0)

您可以设置连续填充的最大限制。

limit_direction: {'向前','向后','两者'}, 默认=无

如果方法选择为 'pad','ffil' => 方向必须为正向。否则,方法选择为“backfill”、“brill”,且方向必须为向后。

limit_area : {无, '内部', '外部'}, 默认=无

内部:插值;外:推断。

4.5 KNN:K 最近邻

        KNN 是一种用于分类和回归问题的监督机器学习方法。它计算数据点(大多数时候是欧几里德)和彼此接近的组之间的距离。在应用 KNN 插补之前,必须对数值特征进行缩放,并且必须对分类特征进行转换。

from sklearn.impute import KNNImputer
imputer = KNNImputer(n_neighbors=3)
df = pd.DataFrame(imputer.fit_transform(df),columns = df.columns)

4.6 其他预测模型

        线性或逻辑回归可分别用于填充数值和分类特征。使用包含非缺失值的数据帧子集来训练模型。该模型预测包含缺失值的数据帧的另一个子集的结果。

from sklearn.linear_model import LinearRegression
train = df[df['Age'].isnull()==False]
test = df[df['Age'].isnull()==True]
model = LinearRegression()
y= train["Age"]
train.drop(['Age'],axis=1,inplace=True)
test.drop(['Age'],axis=1,inplace=True)
model.fit(train,y)
y_pred = model.predict(test)

任何机器学习模型都可以用上述逻辑来实现。

4.7 MissForest

from missingpy import MissForest

        它是一种基于机器学习的插补,使用随机森林模型。它不关心数据是否分类,并且您不需要像 KNN 那样调整数据。这是一种迭代方法,每次迭代后都会变得更好。

missForest(xmis, maxiter = 10, ntree = 100, variablewise = FALSE,
decreasing = FALSE, verbose = FALSE,mtry = floor(sqrt(ncol(xmis))), replace = TRUE,classwt = NULL, cutoff = NULL, strata = NULL,
sampsize = NULL, nodesize = NULL, maxnodes = NULL,
xtrue = NA, parallelize = c('no', 'variables', 'forests'))

您可以在此处获取参数。

4.8 MICE:通过链式方程进行多元插补

        在这种方法中,我们使用各种估计器对剩余特征上缺失数据的特征进行建模。数据的随机子集被输入到多个模型中,并返回平均结果作为结果。

//pseudocode for mice
//Algorithm: multiple imputation filling missing values in dataset
//for each iteration
//   for each f<-feature
        s <- subset data
        train model with s
        do replace missing values

4.9 迭代输入器

Sklearn 的多元输入器

from sklearn.experimental import enable_iterative_imputer
from sklearn.impute import IterativeImputer

estimator估计器对象,默认=BayesianRidge()

将估计器提供给输入器。

缺失值int 或 np.nan,默认=np.nan

数据集中缺失值的类型。

Sample_Postterior布尔值,默认=False

当模型产生输出分布(而不是单个预测)时,设置 True。在此过程中获得多个估算数据集,并从中提取样本。

max_iter整数,默认=10

最大插补轮次。

tol浮动,默认=1e-3

可以定义停止的容差值。

n_nearest_features整数,默认=无

并非所有功能都会被使用,相反,您可以定义它们的子集。根据每对特征之间的绝对相关系数来选择特征。

初始策略str,默认='mean'

{'平均值', '中位数', '最频繁', '常量'}

与 SimpleImputer 相同

imputation_orderstr,默认='升序'

{'升序', '降序', '罗马', '阿拉伯语', '随机'}

要填充的特征的顺序。'上升';首先处理缺失最少的特征。“罗马”是从左到右,“阿拉伯”是从右到左。

Skip_complete布尔值,默认=False

如果许多特征没有缺失值,则将其设置为 True 以节省计算。

min_value浮点数或形状数组(n_features,),默认=np.inf

您可以定义要估算的最小可能值。

max_value浮点数或形状数组(n_features,),默认= np.ing

与上面的逻辑相同。

add_indicator布尔值,默认=False

与 SimpleImputer 相同

imputer = IterativeImputer()
train_mice['Age'] = df.fit_transform(train_mice[['Age']])

五、结论

        为了使机器学习模型正常工作并提高其准确性,必须首先优化数据集。这种预处理工作往往是整个工作中漫长且困难的部分,有时甚至比模型本身更重要。由于多种原因,数据集中可能存在缺失值。许多机器学习模型在缺少值的数据集中也会失败或无法正常工作。因此,我们需要处理缺失值。在这篇博客中,我尝试总结可以使用哪些方法来处理缺失值。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1186597.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Git的高效使用 git的基础 高级用法

Git的高效使用 git的基础 高级用法 前言 什么是Git 在日常的软件开发过程中&#xff0c;软件版本的管理都离不开使用Git&#xff0c;Git是一个开源的分布式版本控制系统&#xff0c;可以有效、高速地处理从很小到非常大的项目版本管理。 也是Linus Torvalds为了帮助管理Linu…

认识EPLAN软件中的各种“点”

原文是网络上的一篇文章&#xff0c;内容有很多错字&#xff0c;我重新编辑了一下发出来&#xff0c;供参考。 在 EPLAN 中&#xff0c;有很多"点"&#xff0c;不同的点的具体含义各有不同&#xff0c;只有弄清楚了不同点的含义&#xff0c;在软件应用中才会得心应手…

【爬虫】Java爬虫爬取某招聘网站招聘信息

目录 前言 一、爬虫程序的基本架构 二、如何获取目标网站的页面内容 三、解析HTML页面&#xff0c;提取所需信息 四、代理IP的使用 五、完整代码 总结 前言 随着互联网的普及&#xff0c;越来越多的人开始关注网络上的招聘信息&#xff0c;而传统的求职方式愈发显得不够…

壹基金防灾减灾宣传进社区 提升家庭安全能力

11月7日&#xff0c;瑞金市赋能济困公益协会、蓝天救援队等联合沙洲坝镇红都新城社区一起走进梦想家园小区&#xff0c;开展家庭安全计划社区活动包挑战赛活动暨壹基金安全家园项目防灾减灾宣传社区行活动。 活动中&#xff0c;志愿者针对从洪涝灾害、风灾、火灾、雪灾、地质灾…

k8s:kubectl 详解

目录 1 kubectl 2 基本信息查看 2.1 查看 master 节点状态 2.2 查看命名空间 2.3 查看default命名空间的所有资源 2.4 创建命名空间app 2.5 删除命名空间app 2.6 在命名空间kube-public 创建副本控制器&#xff08;deployment&#xff09;来启动Pod&#xff08;nginx-wl…

基于SpringBoot+Redis的前后端分离外卖项目-苍穹外卖(二)

新增员工功能开发 1. 新增员工1.1 需求分析和设计1.1.1 产品原型1.1.2 接口设计1.1.3 表设计 1.2 代码开发1.2.1 设计DTO类1.2.2 Controller层1.2.3 Service层接口1.2.4 Service层实现类1.2.5 Mapper层 1.3 功能测试1.3.1 接口文档测试 1.4 代码完善1.4.1 问题一1.4.2 问题二1.…

从零开始的C++(十四)

继承&#xff1a; 作用&#xff1a;减少重复代码&#xff0c;简化程序。 用法&#xff1a; class b&#xff1a;public a {//...b中成员 } 在如上代码中&#xff0c;b类以public的方式继承了a类。规定a类是父类、基类&#xff0c;b类是子类、派生类。 关于继承方式&#xf…

Tcl语言:SDC约束命令create_generated_clock详解(下)

相关阅读 Tcl语言https://blog.csdn.net/weixin_45791458/category_12488978.html?spm1001.2014.3001.5482 设定生成时钟特性 前文的末尾提到&#xff0c;当使用-divide by或-multiply_by选项创建生成时钟时&#xff0c;会根据master clock的时钟周期派生出生成时钟的周期&am…

【Java 进阶篇】Java Filter 快速入门

欢迎来到这篇有关 Java Filter 的快速入门指南&#xff01;如果你是一名 Java 开发者或者正在学习 Java Web 开发&#xff0c;Filter 是一个强大的工具&#xff0c;可以帮助你管理和控制 Web 应用程序中的请求和响应。本文将向你解释 Filter 的基本概念&#xff0c;如何创建和配…

安全认证框架Shiro入门学习(shiro概述和shiro入门小案例);后续整合SpringBoot,应用程序安全;

权限概述 什么是权限 什么是权限 权限管理&#xff0c;一般指根据系统设置的安全策略或者安全规则&#xff0c;用户可以访问而且只能访问自己被授权的资源&#xff0c;不多不少。权限管理几乎出现在任何系统里面&#xff0c;只要有用户和密码的系统。 权限管理再系统中一般分…

小米6安装Ubuntu Touch系统也不是很难嘛

序言 这个文章是用来解说,小米6如何安装Ubuntu Touch系统 正文 安装这个系统需要注意的几点 1.手机必须已经解BL锁 2.没了 安装步骤 先双击打开压缩包查看,按照第一步第二步来进行执行,下面是解压图片 第一步 1.打开第一个文件夹 复制刷入rec的命令.txt里面的内容,然后打开红…

pytorch(小土堆)深度学习

第五节课讲项目的创建和对比 第六节&#xff1a;Dataset,Dataloader Dataset提供一种方式区获取数据及其label(如何获取每一个数据及其label&#xff0c;告诉我们总共有多少的数据) Dataloader为后面的网络提供不同的数据形式 第七节&#xff1a;Dataset类代码实战 显示图片 f…

挑战100天 AI In LeetCode Day05(热题+面试经典150题)

挑战100天 AI In LeetCode Day05&#xff08;热题面试经典150题&#xff09; 一、LeetCode介绍二、LeetCode 热题 HOT 100-72.1 题目2.2 题解 三、面试经典 150 题-73.1 题目3.2 题解 一、LeetCode介绍 LeetCode是一个在线编程网站&#xff0c;提供各种算法和数据结构的题目&am…

开源的全能维护 U 盘工具:Ventoy

开源的全能维护 U 盘工具&#xff1a;Ventoy 本篇文章聊聊迄今为止&#xff0c;我用着最舒服的一款开源 U 盘启动工具&#xff0c;Ventoy。 写在前面 好久不见&#xff0c;接下来计划写一个比较连续的内容&#xff0c;就先从最小的处着手吧。 经过长久的折腾&#xff0c;除…

Docker本地镜像发布到阿里云或私有库

本地镜像发布到阿里云流程 &#xff1a; 1.自己生成个要传的镜像 2.将本地镜像推送到阿里云: 阿里云开发者平台:开放云原生应用-云原生&#xff08;Cloud Native&#xff09;-云原生介绍 - 阿里云 2.1.创建仓库镜像&#xff1a; 2.1.1 选择控制台&#xff0c;进入容器镜像服…

Makefile 总述

目录 一、Makefile 里有什么&#xff1f; 1、显式规则 2、隐晦规则 3、变量的定义 4、文件指示 5、注释 二、Makefile 的文件名 三、引用其它的 Makefile 四、环境变量 MAKEFILES 五、make 的工作方式 一、Makefile 里有什么&#xff1f; Makefile 里主要包含了五个东…

Ps:图层蒙版的基本操作

点击图层蒙版缩览图选中图层蒙版之后&#xff0c;方可进行图层蒙版的操作。 反相蒙版 Invert 将图层蒙版上的白色转换为黑色&#xff0c;黑色转换为白色。 方法一&#xff1a; Ps菜单&#xff1a;图像/调整/反相 Adjustments/Invert 方法二&#xff1a; 快捷键&#xff1a;Ctrl…

window10单机部署hbase-2.5.5-hadoop3

一、介绍 hbase是什么&#xff0c;Hbase是一个分布式&#xff0c;可扩展&#xff0c;支持海量数据存储的noSQL数据库 二、下载hbase https://mirrors.tuna.tsinghua.edu.cn/apache/hbase/2.5.6/ 三、配置hbase环境变量 三、修改hbase配置文件 在hbase-env.cmd添加如下配置…

【算法-链表2】反转链表 和 两两交换链表节点

今天&#xff0c;带来链表相关算法的讲解。文中不足错漏之处望请斧正&#xff01; 理论基础点这里 反转链表 1. 思路 链表操作的本质是修改连接关系&#xff0c;本题我们需要反转链表&#xff0c;也就是每次都让当前节点的next指向自己的上一个。而题目给的是单链表&#xf…

Linux tail命令:显示文件结尾的内容

tail 命令和 head 命令正好相反&#xff0c;它用来查看文件末尾的数据&#xff0c;其基本格式如下&#xff1a; [rootlocalhost ~]# tail [选项] 文件名 此命令常用的选项及含义 【例 1】查看 /etc/passwd 文件最后 3 行的数据内容。 [rootlocalhost ~]# tail -n 3 /etc/passwd…