0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

处理缺失值的三个层级的方法总结

冬至子 来源:Honzik Jurza 作者:Honzik Jurza 2023-05-24 17:15 次阅读

缺失值

缺失值是现实数据集中的常见问题,处理缺失值是数据预处理的关键步骤。缺失值可能由于各种原因而发生,例如数据的结构和质量、数据输入错误、传输过程中的数据丢失或不完整的数据收集。这些缺失的值可能会影响机器学习模型的准确性和可靠性,因为它们可能会引入偏差并扭曲结果,有些模型甚至在在缺少值的情况下根本无法工作。所以在构建模型之前,适当地处理缺失值是必要的。

本文将展示如何使用三种不同级别的方法处理这些缺失值:

  • 初级:删除,均值/中值插补,使用领域知识进行估计
  • 中级:回归插补, K-Nearest neighbors (KNN) 插补
  • 高级:链式方程(MICE)的多元插补, MICEforest

检查缺失的值

首先必须检查每个特性中有多少缺失值。作为探索性数据分析的一部分,我们可以使用以下代码来做到这一点:

导入pandas并在数据集中读取它们,对于下面的示例,我们将使用葡萄酒质量数据集。

importpandasaspd
 df=pd.read_csv('Wine_Quality.csv')

然后可以用下面的代码行检查缺失的值。

df.isnull().sum()

可以使用以下方法查看任何特性中包含缺失值的行:

df_filtered=df[df.isnull().any(axis=1)]
 df_filtered.head()

现在我们可以开始处理这些缺失的值了。

初级方法

最简单的方法是删除行或列(特性)。这通常是在缺失值的百分比非常大或缺失值对分析或结果没有显著影响时进行的。

删除缺少值的行。

df_droprows=df.dropna()
 df_droprows.isnull().sum()

使用以下方法删除列或特性:

df_dropcols=df.drop(columns=['type', 'fixed acidity', 'citric acid', 'volatile acidity', 'residual sugar', 'chlorides', 'pH', 'sulphates'])
 df_dropcols.isnull().sum()

通过删除行,我们最终得到一个更短的数据集。当删除特征时,我们最终会得到一个完整的数据集,但会丢失某些特征。

print("Shape when dropping rows: ", df_droprows.shape)
 print("Shape when dropping features: ", df_dropcols.shape)

这两种方法都最直接的方法,而且都会导致丢失有价值的数据——所以一般情况下不建议使用。

均值/中值插补

下一个初级的方法是用特征的平均值或中值替换缺失的值。在这种情况下不会丢失特征或行。但是这种方法只能用于数值特征(如果使用平均值,我们应该确保数据集没有倾斜或包含重要的异常值)。

比如下面用均值来计算缺失值:

df=df.fillna(df.mean())

现在让我们检查其中一个估算值:

df[df.index==86]

如果要用中值,可以使用:

df = df.fillna(df.median())
 df[df.index==86]

可以看到这里中值和平均值还是有区别的

众数

与上面的方法一样,该方法用特征的模式或最常见的值替换缺失的值。这种方法可以用于分类特征。

首先,让我们检查一下是否有一个类别占主导地位。我们可以通过value_counts方法来实现:

df['type'].value_counts()

可以看到有一个“白色”数量最多。因此可以用下面的方式进行填充:

df['type'] =df['type'].fillna(df['type'].mode())

Scikit-Learn的SimpleImputer类

也可以使用Scikit-learn的SimpleImputer类执行平均值、中值和众数的插补。将策略设置为“mean”,“median”或“most_frequency”即可

df_numeric=df.drop(columns='type')
 imputer_median=SimpleImputer(strategy='median')
 imputer_median.fit(df_numeric)
 df_imputed_median=pd.DataFrame(imputer_median.transform(df_numeric), columns=df_numeric.columns)
 df_imputed_median.head()

我们也可以将策略设置为' constant ',并指定' fill_value '来填充一个常量值。

均值/中位数/众数的优点:

  • 简单和快速实现
  • 它保留了样本量,并降低了下游分析(如机器学习模型)的偏差风险。
  • 与更复杂的方法相比,它的计算成本更低。

缺点:

  • 没有说明数据的可变性或分布,可能会导致估算值不能代表真实值。
  • 可能会低估或高估缺失值,特别是在具有极端值或异常值的数据集中。
  • 减少方差和人为夸大相关系数在估算数据集。
  • 它假设缺失的值是完全随机缺失(MCAR),这可能并不总是这样

使用领域知识进行评估

处理缺失数据的另一种可能方法是使用基于领域知识或业务规则的估计来替换缺失的值。可以通过咨询相关领域的专家,让他们提供专业的见解,这样能够估算出合理和可信的缺失值。

但是这种方法并不一定在现实中就能够很好的实施,因为我们需要专业的人士来确保它产生准确和可靠的估算,但是这样的领域专家并不多。所以我们这里把它归在初级方法中。

中级方法

还有一些稍微高级一些的技术来填充那些缺失的值,我们将使用预测模型来解决问题。但在此之前需要更好地理解缺失值的性质。

缺失值的类型

在我们继续使用更高级的技术之前,需要考虑一下在数据集中可能遇到的缺失类型。数据集中有不同类型的缺失,了解缺失类型有助于确定合适的方法。以下是一些常见的类型:

完全随机缺失( Missing Completely at Random):在这种类型中,缺失的值是完全随机的,这意味着一个值缺失的概率不依赖于任何观察到的或未观察到的变量。例如,如果一个受访者在调查中不小心跳过了一个问题,这就是MCAR。

随机丢失(Missing at Random):在这种类型中,一个值缺失的概率取决于观察到的变量,而不是值本身。例如,如果调查对象不太可能回答敏感问题,但不回答问题的倾向取决于可观察到的变量(如年龄、性别和教育),那么这就是MAR。

非随机丢失(Missing Not at Random):在这种类型中,一个值缺失的概率取决于未观察到的变量,包括缺失值值本身。例如,如果抑郁程度较高的个体不太可能报告他们的抑郁水平,而不报告的倾向在数据中是无法观察到的,那么这就是MNAR。

回归插补

我们将使用一个回归模型来对那些缺失的值进行有根据的猜测,通过分析数据集中的其他特征,并使用它们的相关性来填补。

在处理遵循某种模式(MAR或MCAR)的缺失数据时,回归插补特别有用。因为当特征之间存在很强的相关性时,这种方法很有效。

我们这里将创建一个不包含分类特征的数据版本。然后以为每一列的缺失值拟合线性回归模型。这里就需要使用Scikit-learn的线性回归模块。

importpandasaspd
 fromsklearn.linear_modelimportLinearRegression
 
 # Read data
 df=pd.read_csv('Wine_Quality.csv')
 
 # Make sub dataframe with only numeric features
 df=df.drop(columns='type')
 
 # Separate the columns with missing values
 missing_cols=df.columns[df.isna().any()].tolist()
 non_missing_cols=list(set(df.columns) -set(missing_cols))
 
 print(missing_cols)
 
 # loop over each column with missing values
 forcolinmissing_cols:
     # Create a copy of the dataframe without missing values in the current column
     df_temp=df.dropna(subset=[col] +non_missing_cols)
     
     # Split the dataframe into features (X) and target variable (y)
     X=df_temp[non_missing_cols]
     y=df_temp[col]
     
     # Create and fit a linear regression model
     lr=LinearRegression()
     lr.fit(X, y)
     
     # Impute missing values in the current column using the fitted model
     df.loc[df[col].isna(), col] =lr.predict(df.loc[df[col].isna(), non_missing_cols])

回归插补的优点:

  • 可以处理大量缺失值。
  • 可以保留数据集的统计属性,例如均值、方差和相关系数。
  • 可以通过减少偏差和增加样本量来提高下游分析(例如机器学习模型)的准确性。

回归插补的缺点:

  • 它假设缺失变量和观察到的变量之间存在线性关系。
  • 如果缺失值不是随机缺失 (MAR) 或完全随机缺失 (MCAR),则可能会引入偏差。
  • 可能不适用于分类或有序变量。
  • 在计算上昂贵且耗时,尤其是对于大型数据集。

(KNN) 插补

另一种方法是聚类模型,例如K-最近邻 (KNN) 来估计那些缺失值。这与回归插补类似,只是使用不同的算法来预测缺失值。

importpandasaspd
 fromsklearn.imputeimportKNNImputer
 
 # Read data
 df=pd.read_csv('Wine_Quality.csv')
 
 # Make sub dataframe with only numeric features
 df=df.drop(columns='type')
 
 # create a KNN imputer object
 imputer=KNNImputer(n_neighbors=5)
 
 # impute missing values using KNN
 df=pd.DataFrame(imputer.fit_transform(df), columns=df.columns)

这里我们就要介绍一个包fancyimpute,它包含了各种插补方法:

pip install fancyimpute

使用的方法如下:

# Import the necessary libraries
 importnumpyasnp
 importpandasaspd
 fromfancyimputeimportKNN
 
 # Load the dataset
 df=pd.read_csv('Wine_Quality.csv')
 
 # Drop non-numeric features
 df=df.drop(columns='type')
 
 # Get list of columns with missing values
 missing_cols=df.columns[df.isna().any()].tolist()
 
 # Create an instance of the KNN imputer
 imputer=KNN()
 
 # Fit and transform the imputer to the dataset
 imputed_array=imputer.fit_transform(df[missing_cols])
 
 # Replace the missing values in the original dataset
 df[missing_cols] =imputed_array
 
 # View the imputed dataset
 df

KNN 插补的优点:

  • 可以捕获变量之间复杂的非线性关系。
  • 不对数据的分布或变量之间的相关性做出假设。
  • 比简单的插补方法(例如均值或中值插补)更准确,尤其是对于中小型数据集。

缺点:

  • 计算上可能很昂贵,尤其是对于大型数据集或高维数据。
  • 可能对距离度量的选择和选择的最近邻居的数量敏感,这会影响准确性。
  • 对于高度倾斜或稀疏的数据表现不佳。

高级方法

通过链式方程 (MICE) 进行多元插补

MICE 是一种常用的估算缺失数据的方法。它的工作原理是将每个缺失值替换为一组基于模型的合理值,该模型考虑了数据集中变量之间的关系。

该算法首先根据其他完整的变量为数据集中的每个变量创建一个预测模型。然后使用相应的预测模型估算每个变量的缺失值。这个过程重复多次,每一轮插补都使用前一轮的插补值,就好像它们是真的一样,直到达到收敛为止。

然后将多个估算数据集组合起来创建一个最终数据集,其中包含所有缺失数据的估算值。MICE 是一种强大而灵活的方法,可以处理具有许多缺失值和变量之间复杂关系的数据集。它已成为许多领域(包括社会科学、健康研究和环境科学)中填补缺失数据的流行选择。

fancyimpute包就包含了这个方法的实现,我们可以直接拿来使用

importnumpyasnp
 importpandasaspd
 fromfancyimputeimportIterativeImputer
 
 # Read data
 df=pd.read_csv('Wine_Quality.csv')
 
 # Convert type column to category (so that miceforest can handle as a categorical attribute rather than string)
 df=df.drop(columns='type')
 
 # Get list of columns with missing values
 missing_cols=df.columns[df.isna().any()].tolist()
 
 # Create an instance of the MICE algorithm
 imputer=IterativeImputer()
 
 # Fit the imputer to the dataset
 imputed_array=imputer.fit_transform(df[missing_cols])
 
 # Replace the missing values in the original dataset
 df[missing_cols] =imputed_array
 
 # View the imputed dataset
 df

这个实现没法对分类变量进行填充,那么对于分类变量怎么办呢?

MICEforest

MICEforest 是 MICE的变体,它使用 lightGBM 算法来插补数据集中的缺失值,这是一个很奇特的想法,对吧。

我们可以使用 miceforest 包来实现它

pipinstallmiceforest
 #或
 condainstall-cconda-forgemiceforest

使用也很简单:

importpandasaspd
 importmiceforestasmf
 
 # Read data
 df=pd.read_csv('Wine_Quality.csv')
 
 # Convert type column to category (so that miceforest can handle as a categorical attribute rather than string)
 df['type'] =df['type'].astype('category')
 
 # Create an instance of the MICE algorithm
 imputer=mf.ImputationKernel(data=df, 
                               save_all_iterations=True, 
                               random_state=42)
 
 # Fit the imputer to the dataset. Set number of iterations to 3
 imputer.mice(3, verbose=True)
 
 # Generate the imputed dataset
 imputed_df=imputer.complete_data()
 
 # View the imputed dataset
 imputed_df

可以看到,分类变量 'type' 的缺失值已经被填充了

总结

我们这里介绍了三个层级的缺失值的处理方法,这三种方法的选择将取决于数据集、缺失数据的数量和分析目标。也需要仔细考虑输入缺失数据对最终结果的潜在影响。处理缺失数据是数据分析中的关键步骤,使用合适的填充方法可以帮助我们解锁隐藏在数据中的见解,而从主题专家那里寻求输入并评估输入数据的质量有助于确保后续分析的有效性。

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 机器学习
    +关注

    关注

    66

    文章

    8353

    浏览量

    132324
  • python
    +关注

    关注

    55

    文章

    4772

    浏览量

    84382
  • Mar
    Mar
    +关注

    关注

    0

    文章

    4

    浏览量

    5281
收藏 人收藏

    评论

    相关推荐

    STM32H743ADC数据转换输出缺失的原因?

    有突变,现象就像这一区域的模拟数据无法转换成ADC(32585-32767),这样的区域在真个ADC转换范围并不唯一,而且同一芯片,三个ADC有的
    发表于 03-08 06:39

    如何实现VISA三个不同延迟的独立循环抓

    第一数据控件每100ms循环抓取仪器的,第二数据控件每500ms循环抓取仪器的,第三个数据控件每800ms循环抓取仪器的
    发表于 03-30 10:02

    处理数据缺失的结构化解决办法

    就是处理缺失数据。首先我们需要明白的是,没有任何方法能够完美解决这个问题。不同问题有不同的数据插补方法——时间序列分析,机器学习,回归模型等等,很难提供通用解决方案。在这篇文章中,我将
    发表于 10-26 15:36

    FPGA三个按键给同一信号赋三个不同的按键回弹为 000 后变量的将改变怎么解决?

    FPGA 按键问题,三个按键给同一信号赋三个不同的,可是按键回弹为 000 后变量的将改变,如何解决这个问题呢?
    发表于 05-29 09:33

    鉴别可控硅三个极的方法

    鉴别可控硅三个极的方法 鉴别可控硅三个极的方法很简单,根据P-N结的原理,只要用万用表测量一下三个极之间的电
    发表于 01-14 16:20 1226次阅读

    无线传感网络缺失估计方法

    针对无线传感器网络(WSN)中感知数据易缺失问题,提出了一种基于感知数据属性相关性的缺失估计方法。该方法采用多元线性回归模型,对属性相关的
    发表于 12-27 16:56 0次下载

    一文读懂处理器,内核,芯片三个概念的区别

    本文对处理器、内核和芯片的这三个概念分别进行了介绍,最后总结处理器,内核,芯片这三个概念的区别。
    的头像 发表于 04-23 15:42 7.8w次阅读
    一文读懂<b class='flag-5'>处理</b>器,内核,芯片<b class='flag-5'>三个</b>概念的区别

    缺失处理你确定你真的会了吗

    缺失处理是一数据分析工作者永远避不开的话题,如何认识与理解缺失,运用合适的方式
    的头像 发表于 10-11 11:21 4551次阅读
    <b class='flag-5'>缺失</b><b class='flag-5'>值</b><b class='flag-5'>处理</b>你确定你真的会了吗

    工业4.0的工厂自动化系统通常主要包括三个层级的设备

    针对工业4.0的工厂自动化系统通常主要包括三个层级的设备,用于驱动实时通信和控制: 在现场层级,I/O模块、制动器和驱动器负责工厂内的物理运作; 在控制层级,可编程逻辑控制器(
    的头像 发表于 01-26 15:50 3635次阅读
    工业4.0的工厂自动化系统通常主要包括<b class='flag-5'>三个</b><b class='flag-5'>层级</b>的设备

    三个不同的去耦电容器

    今天的许多设计都包括三个不同的去耦电容器,或者当只使用一电容器时,可以使用 0.1 uF 这样的小。这些建议基于 50 年前不适用的假设。是时候重新考虑这些过时的遗留设计指南了。
    的头像 发表于 07-19 17:30 1402次阅读

    数据清洗、缺失填充和异常值处理

    综上所述,数据清洗、缺失填充和异常值处理对数据分析非常重要,并且 MATLAB 提供了许多工具来实现这些步骤。可以根据具体情况选择合适的函数和方法来处理数据。
    的头像 发表于 06-21 15:30 2846次阅读

    mosfet的三个电极怎么区分 mos管三个极电压关系

    MOSFET(金属氧化物半导体场效应晶体管)有三个主要电极,分别是栅极(Gate)、漏极(Source)和源极(Drain)。这三个电极的区分方法如下
    的头像 发表于 09-18 12:42 3.2w次阅读

    电工三个要点准确判断和处理故障关键

    在电力工作中,电工们需要具备多种技能和素质,其中最为重要的三个要素是“听”、“看”、“摸”。这三个要素是电工们在工作中迅速准确地判断和处理故障的关键。
    的头像 发表于 11-09 11:39 630次阅读

    python中input怎么输入3

    () 函数,每一函数用于获取一。例如,如果你想要输入三个整数,你可以这样写: a = int ( input ( "请输入第一整数:
    的头像 发表于 11-23 15:31 9464次阅读

    建立神经网络模型的三个步骤

    建立神经网络模型是一复杂的过程,涉及到多个步骤和细节。以下是对建立神经网络模型的三个主要步骤的介绍: 第一步:数据准备 1.1 数据收集 数据是神经网络的基础。首先,你需要收集足够的数据来训练
    的头像 发表于 07-02 11:20 667次阅读