sklearn基础『预处理』之缺失值处理

2023年 10月 12日 28.7k 0

数据的预处理是数据分析,或者机器学习训练前的重要步骤。通过数据预处理,可以

  • 提高数据质量,处理数据的缺失值、异常值和重复值等问题,增加数据的准确性和可靠性
  • 整合不同数据,数据的来源和结构可能多种多样,分析和训练前要整合成一个数据集
  • 提高数据性能,对数据的值进行变换,规约等(比如无量纲化),让算法更加高效

本篇介绍的缺失值处理,是数据预处理中非常重要的一步,因为很多机器学习算法都假设数据是完整的,算法的执行过程中没有考虑缺失值的影响。所以,为了提高数据质量、改进数据分析结果、提高数据挖掘和机器学习的效果,缺失值处理必不可少。

1. 原理

处理缺失值的手段大致有4类:

  • 删除存在缺失值数据行
  • 填充缺失值
  • 不处理缺失值
  • 用深度学习方法处理
  • 1.1. 删除缺失值数据

    删除缺失值是最简单的一种处理方式,不过,在某些情况下,这可能会导致数据的大量丢失。如果数据丢失过多,可能会改变数据的分布,影响模型的准确性。

    所以,只有在缺失值占比很小的情况下,才会考虑使用这种处理方式。删除缺失值用pandas库的方法即可,比如:

    import pandas as pd
    
    df = pd.util.testing.makeMissingDataframe()
    print("删除前: {} 行".format(len(df)))
    
    df = df.dropna()
    print("删除后: {} 行".format(len(df)))
    
    # 运行结果
    删除前: 30 行
    删除后: 19 行
    

    1.2. 填充缺失值

    直接删除存在缺失值的数据行虽然简单,但是在实际应用中,使用的并不多。实际情况下,使用最多的还是填充缺失值。

    scikit-learn库中,填充缺失值的方式主要有:

    1.2.1. 均值填充

    均值填充就是用缺失值所在列的平均值来填充缺失值。

    from sklearn.impute import SimpleImputer
    
    data = np.array([[1, 2, 3], [4, np.nan, 6], [7, 8, np.nan]])
    print("均值填充前:\n{}".format(data))
    
    imp = SimpleImputer(missing_values=np.nan, strategy="mean")
    data = imp.fit_transform(data)
    print("均值填充后:\n{}".format(data))
    
    # 运行结果
    均值填充前:
    [[ 1.  2.  3.]
     [ 4. nan  6.]
     [ 7.  8. nan]]
    均值填充后:
    [[1.  2.  3. ]
     [4.  5.  6. ]
     [7.  8.  4.5]]
    

    填充的54.5分别是第二列和第三列的平均值。

    1.2.2. 中位数填充

    中位数填充就是用缺失值所在列的中位数来填充缺失值。

    from sklearn.impute import SimpleImputer
    
    data = np.array([[1, 2, 3], [4, np.nan, 6], [7, 8, np.nan], [10, 11, 12]])
    print("中位数填充前:\n{}".format(data))
    
    imp = SimpleImputer(missing_values=np.nan, strategy="median")
    data = imp.fit_transform(data)
    print("中位数填充后:\n{}".format(data))
    
    # 运行结果
    中位数填充前:
    [[ 1.  2.  3.]
     [ 4. nan  6.]
     [ 7.  8. nan]
     [10. 11. 12.]]
    中位数填充后:
    [[ 1.  2.  3.]
     [ 4.  8.  6.]
     [ 7.  8.  6.]
     [10. 11. 12.]]
    

    填充的86分别是第二列和第三列的中位数。

    1.2.3. 众数填充

    众数填充就是用缺失值所在列的众数数来填充缺失值。

    from sklearn.impute import SimpleImputer
    
    data = np.array([[1, 2, 3], [4, np.nan, 6], [7, 8, np.nan], [10, 8, 3]])
    print("众数填充前:\n{}".format(data))
    
    imp = SimpleImputer(missing_values=np.nan, strategy="most_frequent")
    data = imp.fit_transform(data)
    print("众数填充后:\n{}".format(data))
    
    # 运行结果
    众数填充前:
    [[ 1.  2.  3.]
     [ 4. nan  6.]
     [ 7.  8. nan]
     [10.  8.  3.]]
    众数填充后:
    [[ 1.  2.  3.]
     [ 4.  8.  6.]
     [ 7.  8.  3.]
     [10.  8.  3.]]
    

    填充的83分别是第二列和第三列的众数。

    1.2.4. 常量填充

    常量填充就是用指定的常量来填充缺失值。

    from sklearn.impute import SimpleImputer
    
    data = np.array([[1, 2, 3], [4, np.nan, 6], [7, 8, np.nan]])
    print("常量填充前:\n{}".format(data))
    
    imp = SimpleImputer(missing_values=np.nan, fill_value=100, strategy="constant")
    data = imp.fit_transform(data)
    print("常量填充后:\n{}".format(data))
    
    # 运行结果
    常量填充前:
    [[ 1.  2.  3.]
     [ 4. nan  6.]
     [ 7.  8. nan]]
    常量填充后:
    [[  1.   2.   3.]
     [  4. 100.   6.]
     [  7.   8. 100.]]
    

    缺失值用常量100填充了。

    1.2.5. 插值填充

    插值填充就是使用线性插值或多项式插值等方法,基于已知的数据点估计缺失值。

    from sklearn.experimental import enable_iterative_imputer
    from sklearn.impute import IterativeImputer
    
    data = np.array([[1, 2, 3], [4, np.nan, 6], [7, 8, np.nan]])
    print("插值填充前:\n{}".format(data))
    
    imp = IterativeImputer(max_iter=10, random_state=0)
    data = imp.fit_transform(data)
    print("插值填充后:\n{}".format(data))
    
    # 运行结果
    插值填充前:
    [[ 1.  2.  3.]
     [ 4. nan  6.]
     [ 7.  8. nan]]
    插值填充后:
    [[1.         2.         3.        ]
     [4.         5.00203075 6.        ]
     [7.         8.         8.99796726]]
    

    1.2.6. K近邻填充

    K近邻填充就是利用K近邻算法,找到与缺失值最近的K个数据点,用它们的值的平均数或中位数来填充缺失值。

    from sklearn.impute import KNNImputer  
    
    data = np.array([[1, 2, 3], [4, np.nan, 6], [7, 8, np.nan], [10, 11, 12]])
    print("K近邻填充前:\n{}".format(data))
    
    imp = KNNImputer(n_neighbors=2)  
    data = imp.fit_transform(data)
    print("K近邻填充后:\n{}".format(data))
    
    # 运行结果
    K近邻填充前:
    [[ 1.  2.  3.]
     [ 4. nan  6.]
     [ 7.  8. nan]
     [10. 11. 12.]]
    K近邻填充后:
    [[ 1.  2.  3.]
     [ 4.  5.  6.]
     [ 7.  8.  9.]
     [10. 11. 12.]]
    

    2. 作用

    缺失值处理的主要作用包括:

  • 提高数据完整性和准确性:如果数据中存在缺失值,可能会影响分析的准确性,甚至导致错误的结论。因此,通过填补缺失值,我们可以确保数据的完整性和准确性。
  • 提升数据质量:缺失值可能会降低数据的质量,使得数据分析变得更为困难。通过处理缺失值,我们可以提升数据的质量,使得分析结果更加可靠。
  • 提高算法性能:许多机器学习和数据挖掘算法在处理不完整数据时性能会下降。处理缺失值可以使得这些算法更好地运行,提高其性能。
  • 减少信息丢失:在某些情况下,缺失值可能代表着某些信息的丢失。通过对这些缺失值进行处理,我们可以尽量减少信息丢失的数量。
  • 消除或减少噪声:缺失值的存在可能会引入数据中的噪声,这种噪声可能会对数据分析产生干扰,甚至影响模型的训练效果。通过填补这些缺失值,我们可以消除或减少这种噪声。
  • 3. 总结

    在选择处理缺失值的方法时,需要考虑数据的性质、缺失值的比例、数据的分布以及具体的分析任务等因素。同时,不同的方法可能适用于不同的场景,需要结合具体情况进行选择。

    相关文章

    JavaScript2024新功能:Object.groupBy、正则表达式v标志
    PHP trim 函数对多字节字符的使用和限制
    新函数 json_validate() 、randomizer 类扩展…20 个PHP 8.3 新特性全面解析
    使用HTMX为WordPress增效:如何在不使用复杂框架的情况下增强平台功能
    为React 19做准备:WordPress 6.6用户指南
    如何删除WordPress中的所有评论

    发布评论