作者 | Satyam Kumar
https://cloud.tencent.com/developer/article/1680427
编译 | VK
来源 | Towards Data Science
现实世界中的数据往往有很多缺失值。丢失值的原因可能是数据损坏或未能记录数据。在数据集的预处理过程中,丢失数据的处理非常重要,因为许多机器学习算法不支持缺失值。
本文介绍了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