本章详细介绍了数据缺失的原因、影响及处理方式、数据归一化处理的方法等内容。
无
1.数据缺失值处理
2.数据归一化处理
百度百科:缺失值是指粗糙数据中由于缺少信息而造成的数据的聚类、分组、删失或截断。它指的是现有数据集中某个或某些属性的值是不完全的。简单来说就是:部分数据缺失了
按照数据缺失机制,缺失值可分类为:
所缺失的数据发生的概率既与已观察到的数据无关,也与未观察到的数据无关。数据的缺失是完全随机的,不依赖于任何不完全变量或完全变量,不影响样本的无偏性,如家庭地址缺失;
设缺失数据发生的概率与所观察到的变量是有关的,而与未观察到的数据的特征是无关的。数据缺失不是完全随机的,即该类数据的缺失依赖于其他完全变量,如财务数据缺失情况与企业的大小有关;
如果不完全变量中数据的缺失既依赖于完全变量又依赖于不完全变量本身,这种缺失即为不可忽略的缺失。数据的缺失与不完全变量自身的取值有关,如高收入人群不原意提供家庭收入;
缺失值的影响
对于缺失值的处理,从总体上来说分为:
以下主要针对处理方式 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']))
- name toy born
- 0 Alfred NaN NaT
- 1 Batman Batmobile 1940-04-25
- 2 Catwoman Bullwhip NaT
- name toy born
- 1 Batman Batmobile 1940-04-25
- name toy born
- 1 Batman Batmobile 1940-04-25
- name toy born
- 1 Batman Batmobile 1940-04-25
- 2 Catwoman Bullwhip NaT
缺失值插补处理,思想来源是以最可能的值来插补缺失值比全部删除不完全样本所产生的信息丢失要少,即填补数据比删除数据更好。
在数据挖掘中,面对的通常是大型的数据库,它的属性有几十个甚至几百个,因为一个属性值的缺失而放弃大量的其他属性值,这种删除是对信息的极大浪费,所以产生了以可能值对缺失值进行插补的思想与方法。常用的有如下几种方法:
方法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)
- A B C D
- 0 NaN 2.0 NaN 0
- 1 高 4.0 NaN 1
- 2 高 NaN NaN 5
- 3 中 3.0 NaN 4
- A B C D
- 0 NaN 2.0 NaN 0
- 1 高 4.0 NaN 1
- 2 高 3.0 NaN 5
- 3 中 3.0 NaN 4
- A B C D
- 0 高 2.0 NaN 0
- 1 高 4.0 NaN 1
- 2 高 3.0 NaN 5
- 3 中 3.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)
- A B C D
- 0 NaN 2.0 NaN 0
- 1 高 4.0 NaN 1
- 2 高 NaN NaN 5
- 3 中 3.0 NaN 4
- A B C D
- 0 3 2.0 3.0 0
- 1 高 4.0 3.0 1
- 2 高 3.0 3.0 5
- 3 中 3.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)
- A B C D
- 0 NaN 2.0 NaN 0
- 1 高 4.0 NaN 1
- 2 高 4.0 NaN 5
- 3 中 3.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)
- A B C D
- 0 高 2.0 NaN 0
- 1 高 4.0 NaN 1
- 2 高 3.0 NaN 5
- 3 中 3.0 NaN 4
插补处理只是将未知值补以我们的主观估计值,不一定完全符合客观事实。
以上的分析都是理论分析,对于缺失值由于它本身无法观测,也就不可能知道它的缺失所属类型,也就无从估计一个插补方法的插补效果。另外这些方法通用于各个领域,具有了普遍性,那么针对一个领域的专业的插补效果就不会很理想,正是因为这个原因,很多专业数据挖掘人员通过他们对行业的理解,手动对缺失值进行插补的效果反而可能比这些方法更好。缺失值的插补是在数据挖掘过程中为了不放弃大量的信息,而采用的人为干涉缺失值的情况,无论是那种处理方法都会影响变量间的相互关系,在对不完备信息进行补齐处理的同时,我们或多或少地改变了原始的数据的信息系统,对以后的分析存在潜在的影响,所以对缺失值的处理一定要慎重。
其他插补处理方法还有:
人工填写
特殊值填充
热卡填充
K最近距离邻近
组合完整化方法
回归
期望值最大化方法
多重填补
开始实验
数据归一化处理,是要把需要处理的数据经过处理后(通过某种算法)限制在一定范围内(0~1 之间 或 -1~1之间)。
数据归一化处理的目的:
量纲,指物理量的大小与单位有关,因此量纲是有两部分组成:数、单位。就比如1块钱和1分钱,就是两个不同的量纲,因为度量的单位不同了。
数据归一化处理的目的就是要把数据由受单位影响,转换为不受单位影响。
数据标准化(归一化)处理是数据挖掘的一项基础工作
不同评价指标往往具有不同的量纲和量纲单位,这样的情况会影响到数据分析的结果,为了消除指标之间的量纲影响,需要进行数据标准化处理,以解决数据指标之间的可比性。简单来说,就是让各影响指标更加平等。
假设:结果数据同时受两个因素影响(theta1、theta2)
未归一化
归一化之后
以上两图说明,指标未经归一化之前,影响权重往往会倾向于数据更大的指标。
min-max标准化,也称为离差标准化,是对原始数据的线性变换,使得结果映射到0-1之间。
转换函数
-(X-Min)/(Max-Min)
X为样本数据,max为样本数据的最大值,min为样本数据的最小值,Mean表示数据的均值。
适用场景:
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)
- height weight sex
- 0 164 42 0
- 1 170 57 0
- 2 189 85 1
- 3 180 54 1
- 4 157 48 0
- 5 168 83 0
- 6 171 89 0
- 7 172 55 1
- 8 172 74 1
- 9 153 87 1
- height weight sex
- 0 0.305556 0.000000 0.0
- 1 0.472222 0.319149 0.0
- 2 1.000000 0.914894 1.0
- 3 0.750000 0.255319 1.0
- 4 0.111111 0.127660 0.0
- 5 0.416667 0.872340 0.0
- 6 0.500000 1.000000 0.0
- 7 0.527778 0.276596 1.0
- 8 0.527778 0.680851 1.0
- 9 0.000000 0.957447 1.0
样本数据与原始数据的均值(mean)和标准差(standard deviation)进行数据的标准化。经过处理的数据符合标准正态分布,即均值为0,标准差为1。
转换函数:(X-Mean)/(Standard deviation)
适用场景
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)
- height weight sex
- 0 162 71 0
- 1 176 72 1
- 2 165 56 1
- 3 182 88 1
- 4 156 47 0
- 5 175 68 0
- 6 181 86 1
- 7 174 67 1
- 8 175 85 0
- 9 174 63 1
- height weight sex
- 0 -1.197130 0.052564 -1.161895
- 1 0.478852 0.127656 0.774597
- 2 -0.837991 -1.073810 0.774597
- 3 1.197130 1.329121 0.774597
- 4 -1.915409 -1.749634 -1.161895
- 5 0.359139 -0.172711 -1.161895
- 6 1.077417 1.178938 0.774597
- 7 0.239426 -0.247802 0.774597
- 8 0.359139 1.103846 -1.161895
- 9 0.239426 -0.548168 0.774597
数据归一化的结果:
整体样本层面,对不同特征维度的数据进行伸缩变换的目的是使各个特征维度对目标函数的影响权重是一致的,即让那些扁平分布的数据伸缩变成类圆形。
单一特征属性层面,归一化是对数据的数值范围进行特定缩放,但不改变其数据分布的一种线性特征变换。
目的:
注意:
比如0/1取值的数据特征就不需要归一化处理(如上例的sex取值),因为归一化会破坏源数据的稀疏性。
开始实验