机器学习中处理缺失值的7种方法

时间:2022-07-23
本文章向大家介绍机器学习中处理缺失值的7种方法,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

作者 | Satyam Kumar

编译 | VK

来源 | Towards Data Science

现实世界中的数据往往有很多缺失值。丢失值的原因可能是数据损坏或未能记录数据。在数据集的预处理过程中,丢失数据的处理非常重要,因为许多机器学习算法不支持缺失值。

本文介绍了7种处理数据集中缺失值的方法:

  1. 删除缺少值的行
  2. 为连续变量插补缺失值
  3. 为分类变量插补缺失的值
  4. 其他插补方法
  5. 使用支持缺失值的算法
  6. 缺失值预测
  7. 使用深度学习库-Datawig进行插补

❝使用的数据是来自Kaggle的泰坦尼克号数据集:https://www.kaggle.com/c/titanic ❞

data = pd.read_csv("train.csv")
msno.matrix(data)

删除缺少值的行:

可以通过删除具有空值的行或列来处理缺少的值。如果列中有超过一半的行为null,则可以删除整个列。也可以删除具有一个或多个列值为null的行。

「优点」

  • 可以创建一个健壮的模型。

「缺点」

  • 大量信息丢失。
  • 如果与完整的数据集相比,缺失值的百分比过大,则效果不佳。

用平均值/中位数估算缺失值:

数据集中具有连续数值的列可以替换为列中剩余值的平均值、中值或众数。与以前的方法相比,这种方法可以防止数据丢失。替换上述两个近似值(平均值、中值)是一种处理缺失值的统计方法。

在上例中,缺失值用平均值代替,同样,也可以用中值代替。

data["Age"] = data["Age"].replace(np.NaN, data["Age"].mean())
data["Age"] = data["Age"].replace(np.NaN, data["Age"].median())

「优点」

  • 防止导致删除行或列的数据丢失
  • 在一个小的数据集上运行良好,并且易于实现。

「缺点」

  • 仅适用于数值连续变量。
  • 不考虑特征之间的协方差。

分类列的插补方法:

如果缺少的值来自分类列(字符串或数值),则可以用最常见的类别替换丢失的值。如果缺失值的数量非常大,则可以用新的类别替换它。

「优点」

  • 防止导致删除行或列的数据丢失
  • 在一个小的数据集上运行良好,并且易于实现。
  • 通过添加唯一类别来消除数据丢失

「缺点」

  • 仅适用于分类变量。
  • 在编码时向模型中添加新特征,这可能会导致性能较差

其他插补方法:

根据数据或数据类型的性质,某些其他插补方法可能更适合于对缺失值进行插补。

例如,对于具有纵向行为的数据变量,使用最后一个有效观察值来填充缺失的值可能是有意义的。这就是所谓的末次观测值结转法(LOCF)方法。

data["Age"] = data["Age"].fillna(method='ffill')

对于时间序列数据集变量,对于缺失的值,在时间戳之前和之后使用变量的插值是有意义的。

data["Age"] = data["Age"].interpolate(method='linear', limit_direction='forward', axis=0)

使用支持缺失值的算法:

所有的机器学习算法都不支持缺失值,但有些ML算法对数据集中的缺失值具有鲁棒性。当一个值丢失时,k-NN算法可以忽略距离度量中的列。朴素贝叶斯也可以在进行预测时支持缺失值。当数据集包含空值或缺少值时,可以使用这些算法。

Python中朴素贝叶斯和k近邻的sklearn实现不支持缺失值。

这里可以使用的另一个算法是RandomForest,它对非线性和分类数据很有效。它适应于考虑高方差或偏差的数据结构,在大数据集上产生更好的结果。

「优点」

  • 不需要处理每列中缺少的值,因为ML算法可以有效地处理它

「缺点」

  • scikit learn库中没有这些ML算法的实现。

缺失值预测:

在前面处理缺失值的方法中,我们没有利用包含缺失值的变量与其他变量的相关性优势。使用其他没有空值的特征可以用来预测丢失的值。

回归或分类模型可用于根据具有缺失值的特征的性质(分类或连续)来预测缺失值。

这里'Age'列包含缺少的值,因此为了预测空值,数据的拆分将是,

y_train: 数据[“Age”]中具有非空值的行
y_test: 数据[“Age”]中的行具有空值
X_train: 数据集[“Age”]特征除外,具有非空值
X_test: 数据集[“Age”]特征除外,具有空值
from sklearn.linear_model import LinearRegression
import pandas as pd

data = pd.read_csv("train.csv")
data = data[["Survived", "Pclass", "Sex", "SibSp", "Parch", "Fare", "Age"]]

data["Sex"] = [1 if x=="male" else 0 for x in data["Sex"]]

test_data = data[data["Age"].isnull()]
data.dropna(inplace=True)

y_train = data["Age"]
X_train = data.drop("Age", axis=1)
X_test = test_data.drop("Age", axis=1)

model = LinearRegression()
model.fit(X_train, y_train)

y_pred = model.predict(X_test)

「优点」

  • 给出了比以前的方法更好的结果
  • 考虑缺失值列与其他列之间的协方差。

「缺点」

  • 只作为真实值的代理

使用深度学习库-Datawig进行插补

这种方法适用于分类、连续和非数值特征。Datawig是一个库,它使用深层神经网络学习ML模型,以填补数据报中的缺失值。

安装datawig库

pip3 install datawig

Datawig可以获取一个数据帧,并为每一列(包含缺失值)拟合插补模型,将所有其他列作为输入。

下面是示例代码

import pandas as pd
pip install datawig
import datawig

data = pd.read_csv("train.csv")

df_train, df_test = datawig.utils.random_split(data)

#初始化一个简单的imputer模型
imputer = datawig.SimpleImputer(
    input_columns=['Pclass','SibSp','Parch'], # 我们要输入的列
    output_column= 'Age', # 我们要为其注入值的列
    output_path = 'imputer_model' #存储模型数据和度量
    )

#拟合训练数据的模型
imputer.fit(train_df=df_train, num_epochs=50)

#输入丢失的值并返回原始的数据模型和预测
imputed = imputer.predict(df_test)

「优点」

  • 与其他方法相比相当精确。
  • 它支持CPU和GPU。

「缺点」

  • 对于大型数据集可能会非常慢。

结论:

每个数据集都有缺失的值,需要智能地处理这些值以创建健壮的模型。在本文中,我讨论了7种处理缺失值的方法,这些方法可以处理每种类型列中的缺失值。

没有最好的规则处理缺失值。但是可以根据数据的内容对不同的特征使用不同的方法。拥有关于数据集的领域知识非常重要,这可以帮助你深入了解如何预处理数据和处理丢失的值。

「参考文献」

Datawig: https://github.com/awslabs/datawig

原文链接:https://towardsdatascience.com/7-ways-to-handle-missing-values-in-machine-learning-1a6326adf79e