• 第06章 数据缺失值处理与归一化


    序言

    1. 内容介绍

    本章详细介绍了数据缺失的原因、影响及处理方式、数据归一化处理的方法等内容。

    2. 理论目标

    • 了解数据缺失的原因、影响及处理方式
    • 了解数据归一化处理的方法

    3. 实践目标

    • 掌握数据缺失值处理方法,能完成数据缺失值处理
    • 掌握数据归一化处理方法,能完成数据归一化处理

    4. 实践案例

    5. 内容目录


    第1节 数据缺失值处理

    1. 缺失值的概述

    缺失值定义

    百度百科:缺失值是指粗糙数据中由于缺少信息而造成的数据的聚类、分组、删失或截断。它指的是现有数据集中某个或某些属性的值是不完全的。简单来说就是:部分数据缺失了

    缺失值产生原因

    1. 无意的:信息被遗漏,比如由于工作人员的疏忽忘记而缺失;或由于数据采集器故障等原因造成的缺失,比如系统实时性要求较高的时候,机器来不及判和决策而造成缺失;
    2. 有意的:有些数据集在特征描述中会规定将缺失值也作为一种特征值,这时候缺失值就可以看作是一种特殊的特征值;
    3. 不存在:有些特征属性根本就是不存在的,比如一个未婚者的配偶名字就没法填写,再如一个孩子的收入状况也无法填写。

    2. 缺失值的分类

    按照数据缺失机制,缺失值可分类为:

    1. 完全随机缺失(missing completely at random, MCAR)

    所缺失的数据发生的概率既与已观察到的数据无关,也与未观察到的数据无关。数据的缺失是完全随机的,不依赖于任何不完全变量或完全变量,不影响样本的无偏性,如家庭地址缺失;

    1. 随机缺失(missing at random, MAR)

    设缺失数据发生的概率与所观察到的变量是有关的,而与未观察到的数据的特征是无关的。数据缺失不是完全随机的,即该类数据的缺失依赖于其他完全变量,如财务数据缺失情况与企业的大小有关;

    1. 非随机缺失(not missing at random, NMAR)

    如果不完全变量中数据的缺失既依赖于完全变量又依赖于不完全变量本身,这种缺失即为不可忽略的缺失。数据的缺失与不完全变量自身的取值有关,如高收入人群不原意提供家庭收入;

    3. 缺失值的影响

    缺失值的影响

    1. 数据挖掘建模将丢失大量有用信息。
    2. 数据挖掘模型更加不确定,数据规律更难把握。
    3. 包含空值的数据会使建模过程陷入混乱,导致不可靠输出。

    4. 缺失值的处理方法

    对于缺失值的处理,从总体上来说分为:

    1. 不处理。
    2. 删除存在缺失值的记录,即删除存在缺失值的记录。
    3. 缺失值插补处理,即以特定数值对缺失值进行补齐处理。

    以下主要针对处理方式 2 和处理方式 3 展开。

    删除存在缺失值的记录

    删除法,简单来说就是将存在缺失值的记录删除。
    如果数据缺失问题可以通过简单的删除小部分样本来达到目标,那么这个方法是最有效的。

    注意:此处是针对删除样本量是小部分的,如果删除样本比例较大时,需谨慎使用。

    完整语法:

     
    

    DataFrame.dropna(axis=0, how='any', subset=None, inplace=False)

    • 参数说明:
    • axis:维度,axis=0表示index行,axis=1表示columns列,默认为0
    • how:"all"表示这一行或列中的元素全部缺失(为nan)才删除这一行或列,"any"表示这一行或列中只要有元素缺失,就删除这一行或列
    • subset:在某些列的子集中选择出现了缺失值的列删除,不在子集中的含有缺失值得列或行不会删除
    • inplace:筛选过缺失值得新数据是存为副本还是直接在原数据上进行修改。默认是False,即创建新的对象进行修改,原对象不变。
     
    

    import pandas as pd import numpy as np df = pd.DataFrame({"name": ['Alfred', 'Batman', 'Catwoman'], "toy": [np.nan, 'Batmobile', 'Bullwhip'], "born": [np.nan, pd.Timestamp("1940-04-25"),np.nan]}) print(df) print(df.dropna()) print(df.dropna(how='any')) print(df.dropna(subset=['toy']))

    1. name toy born
    2. 0 Alfred NaN NaT
    3. 1 Batman Batmobile 1940-04-25
    4. 2 Catwoman Bullwhip NaT
    5. name toy born
    6. 1 Batman Batmobile 1940-04-25
    7. name toy born
    8. 1 Batman Batmobile 1940-04-25
    9. name toy born
    10. 1 Batman Batmobile 1940-04-25
    11. 2 Catwoman Bullwhip NaT

    缺失值插补处理

    缺失值插补处理,思想来源是以最可能的值来插补缺失值比全部删除不完全样本所产生的信息丢失要少,即填补数据比删除数据更好。

    在数据挖掘中,面对的通常是大型的数据库,它的属性有几十个甚至几百个,因为一个属性值的缺失而放弃大量的其他属性值,这种删除是对信息的极大浪费,所以产生了以可能值对缺失值进行插补的思想与方法。常用的有如下几种方法:

    1. 均值插补
    2. 标量值替换法
    3. 向前和向后填充法

    方法1. 均值插补

    数据的属性分为连续型和离散型:

    • 如果缺失值是连续型的,就以该属性存在值的平均值来插补缺失的值;
    • 如果缺失值是离散型的,就根据统计学中的众数原理,用该属性的众数(即出现频率最高的值)来补齐缺失的值。
     
    

    import pandas as pd import numpy as np df = pd.DataFrame([[np.nan, 2, np.nan, 0], ['高', 4, np.nan, 1], ['高', np.nan, np.nan, 5], ['中', 3, np.nan, 4]], columns=['A', 'B', 'C', 'D']) print(df) ## 连续型的数值 Bmean = df['B'].mean() ## 计算B 列均值 df['B'].fillna(Bmean, inplace=True) ## 以均值填充,inplace=True 表示更换原DataFrame数据 print(df) ## 离散型的数值 Amode = df['A'].mode() ## 计算A 列众数 df['A'].fillna(Amode, inplace=True) ## 以众数填充,inplace=True 表示更换原DataFrame数据 print(df)

    1. A B C D
    2. 0 NaN 2.0 NaN 0
    3. 14.0 NaN 1
    4. 2 高 NaN NaN 5
    5. 33.0 NaN 4
    6. A B C D
    7. 0 NaN 2.0 NaN 0
    8. 14.0 NaN 1
    9. 23.0 NaN 5
    10. 33.0 NaN 4
    11. A B C D
    12. 02.0 NaN 0
    13. 14.0 NaN 1
    14. 23.0 NaN 5
    15. 33.0 NaN 4

    方法2. 标量值替换法

    标量值替换法,即采用一个对数据结果影响不大的标量值填充到缺失值里面。该方法的标量值的选择对结果影响不是很大。

     
    

    import pandas as pd import numpy as np df = pd.DataFrame([[np.nan, 2, np.nan, 0], ['高', 4, np.nan, 1], ['高', np.nan, np.nan, 5], ['中', 3, np.nan, 4]], columns=['A', 'B', 'C', 'D']) print(df) ## 以标量 3 对 所有列缺失值进行替换 df.fillna(3, inplace=True) ## inplace=True 表示更换原DataFrame数据 print(df)

    1. A B C D
    2. 0 NaN 2.0 NaN 0
    3. 14.0 NaN 1
    4. 2 高 NaN NaN 5
    5. 33.0 NaN 4
    6. A B C D
    7. 0 3 2.0 3.0 0
    8. 14.0 3.0 1
    9. 23.0 3.0 5
    10. 33.0 3.0 4

    方法3. 向前和向后填充法

    • 向前填充法,是指在缺失值位置填充对应到列的前一个值;
    • 向后填充法,是指在缺失值位置填充对应到列的后一个值。

    对应方法 .fillna() 中参数method ,向前填充法取‘pad’、向后填充法取‘backfill’

     
    

    import pandas as pd import numpy as np df = pd.DataFrame([[np.nan, 2, np.nan, 0], ['高', 4, np.nan, 1], ['高', np.nan, np.nan, 5], ['中', 3, np.nan, 4]], columns=['A', 'B', 'C', 'D']) ## 向前填充法,method='pad' df.fillna(method='pad', inplace=True) ## inplace=True 表示更换原DataFrame数据 print(df)

    1. A B C D
    2. 0 NaN 2.0 NaN 0
    3. 14.0 NaN 1
    4. 24.0 NaN 5
    5. 33.0 NaN 4
     
    

    import pandas as pd import numpy as np df = pd.DataFrame([[np.nan, 2, np.nan, 0], ['高', 4, np.nan, 1], ['高', np.nan, np.nan, 5], ['中', 3, np.nan, 4]], columns=['A', 'B', 'C', 'D']) ## 向后填充法,method='backfill' df.fillna(method='backfill', inplace=True) ## inplace=True 表示更换原DataFrame数据 print(df)

    1. A B C D
    2. 02.0 NaN 0
    3. 14.0 NaN 1
    4. 23.0 NaN 5
    5. 33.0 NaN 4

    5. 缺失值的处理方法小结

    插补处理只是将未知值补以我们的主观估计值,不一定完全符合客观事实。

    以上的分析都是理论分析,对于缺失值由于它本身无法观测,也就不可能知道它的缺失所属类型,也就无从估计一个插补方法的插补效果。另外这些方法通用于各个领域,具有了普遍性,那么针对一个领域的专业的插补效果就不会很理想,正是因为这个原因,很多专业数据挖掘人员通过他们对行业的理解,手动对缺失值进行插补的效果反而可能比这些方法更好。缺失值的插补是在数据挖掘过程中为了不放弃大量的信息,而采用的人为干涉缺失值的情况,无论是那种处理方法都会影响变量间的相互关系,在对不完备信息进行补齐处理的同时,我们或多或少地改变了原始的数据的信息系统,对以后的分析存在潜在的影响,所以对缺失值的处理一定要慎重。

    其他插补处理方法还有:

    • 人工填写

    • 特殊值填充

    • 热卡填充

    • K最近距离邻近

    • 组合完整化方法

    • 回归

    • 期望值最大化方法

    • 多重填补


    开始实验

    第2节 数据归一化处理

    1. 数据归一化概述

    数据归一化处理,是要把需要处理的数据经过处理后(通过某种算法)限制在一定范围内(0~1 之间 或 -1~1之间)。

    数据归一化处理的目的:

    1. 让算法收敛得更快,提升计算效率;
    2. 消除量纲(单位)影响,提升计算精度。

    量纲,指物理量的大小与单位有关,因此量纲是有两部分组成:数、单位。就比如1块钱和1分钱,就是两个不同的量纲,因为度量的单位不同了。

    数据归一化处理的目的就是要把数据由受单位影响,转换为不受单位影响。

    2. 数据归一化处理原因

    数据标准化(归一化)处理是数据挖掘的一项基础工作

    不同评价指标往往具有不同的量纲和量纲单位,这样的情况会影响到数据分析的结果,为了消除指标之间的量纲影响,需要进行数据标准化处理,以解决数据指标之间的可比性。简单来说,就是让各影响指标更加平等。

    假设:结果数据同时受两个因素影响(theta1theta2

    未归一化

    归一化之后

    以上两图说明,指标未经归一化之前,影响权重往往会倾向于数据更大的指标。

    3. 数据归一化处理方法

    min-max标准化

    min-max标准化,也称为离差标准化,是对原始数据的线性变换,使得结果映射到0-1之间。

    转换函数
    -(X-Min)/(Max-Min)

    X为样本数据,max为样本数据的最大值,min为样本数据的最小值,Mean表示数据的均值。

    适用场景:

    • 在不涉及距离度量、协方差计算、数据不符合正太分布的时候,可以使用min-max标准化。比如图像处理中,将RGB图像转换为灰度图像后将其值限定在(0 ,255)的范围。
     
    

    import pandas as pd import numpy as np df = pd.DataFrame({"height":np.random.randint(150,190,size=10), "weight":np.random.randint(40,90,size = 10), "sex":np.random.randint(0,2,size = 10)} ) print(df) df = (df-df.min())/(df.max()-df.min()) ## min-max标准化转换函数:(X-Min)/(Max-Min) print(df)

    1. height weight sex
    2. 0 164 42 0
    3. 1 170 57 0
    4. 2 189 85 1
    5. 3 180 54 1
    6. 4 157 48 0
    7. 5 168 83 0
    8. 6 171 89 0
    9. 7 172 55 1
    10. 8 172 74 1
    11. 9 153 87 1
    12. height weight sex
    13. 0 0.305556 0.000000 0.0
    14. 1 0.472222 0.319149 0.0
    15. 2 1.000000 0.914894 1.0
    16. 3 0.750000 0.255319 1.0
    17. 4 0.111111 0.127660 0.0
    18. 5 0.416667 0.872340 0.0
    19. 6 0.500000 1.000000 0.0
    20. 7 0.527778 0.276596 1.0
    21. 8 0.527778 0.680851 1.0
    22. 9 0.000000 0.957447 1.0

    Z-score标准化方法

    样本数据与原始数据的均值(mean)和标准差(standard deviation)进行数据的标准化。经过处理的数据符合标准正态分布,即均值为0,标准差为1。

    转换函数:(X-Mean)/(Standard deviation)

    • X为样本数据,Mean为所有样本数据的均值。Standard deviation为所有样本数据的标准差。

    适用场景

    • 在分类、聚类算法中,需要使用距离来度量相似性的时候、或者使用PCA技术进行降维的时候,Z-score标准化方法表现更好。
     
    

    import pandas as pd import numpy as np df = pd.DataFrame({"height":np.random.randint(150,190,size=10), "weight":np.random.randint(40,90,size = 10), "sex":np.random.randint(0,2,size = 10)} ) print(df) df = (df-df.mean())/df.std() ## Z-score标准化转换函数:(X-Mean)/(Standard deviation) print(df)

    1. height weight sex
    2. 0 162 71 0
    3. 1 176 72 1
    4. 2 165 56 1
    5. 3 182 88 1
    6. 4 156 47 0
    7. 5 175 68 0
    8. 6 181 86 1
    9. 7 174 67 1
    10. 8 175 85 0
    11. 9 174 63 1
    12. height weight sex
    13. 0 -1.197130 0.052564 -1.161895
    14. 1 0.478852 0.127656 0.774597
    15. 2 -0.837991 -1.073810 0.774597
    16. 3 1.197130 1.329121 0.774597
    17. 4 -1.915409 -1.749634 -1.161895
    18. 5 0.359139 -0.172711 -1.161895
    19. 6 1.077417 1.178938 0.774597
    20. 7 0.239426 -0.247802 0.774597
    21. 8 0.359139 1.103846 -1.161895
    22. 9 0.239426 -0.548168 0.774597

    4. 数据归一化处理小结

    数据归一化的结果:

    • 整体样本层面,对不同特征维度的数据进行伸缩变换的目的是使各个特征维度对目标函数的影响权重是一致的,即让那些扁平分布的数据伸缩变成类圆形。

    • 单一特征属性层面,归一化是对数据的数值范围进行特定缩放,但不改变其数据分布的一种线性特征变换。

    目的:

    • 提高算法速度
    • 提高算法精度

    注意:

    1. 不是所有数据都需要归一化处理;
    2. 不是归一化处理都可以提高模型性能。

    比如0/1取值的数据特征就不需要归一化处理(如上例的sex取值),因为归一化会破坏源数据的稀疏性。


    开始实验

    第3节 附录

  • 相关阅读:
    电脑重装系统后桌面图标如何调小尺寸
    Linux系统中的ps命令详解及用法介绍
    数据挖掘是什么?
    Nginx优化
    1011 World Cup Betting
    Vue生命周期
    vue组件通信方式有哪些?
    桥接设计模式
    QUIC协议包头保护(四)
    Java概述
  • 原文地址:https://blog.csdn.net/a1234556667/article/details/126447454