一、前言
缺失值是数据处理过程中不可跳过的一个步骤!当然,如果你的数据不存在缺失值,那就不需要这个文档了!你可能需要查看一下异常值了!!!
现在我们来理解一下缺失值(类型):
完全随机缺失(missing completely at random,MCAR)
:指的是数据的缺失是随机的,数据的缺失不依赖于任何不完全变量或完全变量
。空值的出现与数据集中已知或者未知的特征是完全无关的(没有任何已知特征与其相关,类似自然选择无筛选条件)。比如:一调查问卷中的性别字段,是否缺失属于完全随机,它取决于调查对象。随机缺失 (missing at random,MAR)
:指的是数据的缺失不是完全随机的,即该类数据的缺失依赖于其他完全变量
。比如:一个关于教育的数据集缺失了很多小孩的IQ测试分数,只是因为相比十二岁的孩子,四岁的孩子很少会通过这个测试。所以出现的空值与IQ实际值没有相关性,而与年龄相关。IQ字段缺失记录主要集中在低年龄人群中!非随机缺失 (missing not at random,MNAR)
:指的是数据的缺失依赖于不完全变量自身
。 比如:只有具有低分个体的IQ变量值缺失。
二、基于KNN算法的数值插补
我们可以简单的理解其算法为:通过距离测量来识别数据集中空间相似或相近的
k
k
k个样本。然后,使用这些
k
k
k 样本来估计缺失数据点的值。每个样本的缺失值使用数据集中找到的
k
k
k 邻域的平均值进行插补
。
2.1 含有缺失值的欧几里得距离的计算
在存在缺失坐标的情况下,通过忽略缺失值并放大非缺失坐标的权重来计算欧几里德距离。
d
x
y
=
w
e
i
g
h
t
×
s
q
u
a
r
e
d
d
i
s
t
a
n
c
e
f
r
o
m
p
r
e
s
e
n
t
c
o
o
r
d
i
n
a
t
e
s
d_{xy} = \sqrt{weight \times squared \; distance \; from \; present \; coordinates}
dxy=weight×squareddistancefrompresentcoordinates
其中,
w
e
i
g
h
t
=
T
o
t
a
l
n
u
m
b
e
r
o
f
c
o
o
r
d
i
n
a
t
e
s
N
u
m
b
e
r
o
f
p
r
e
s
e
n
t
c
o
o
r
d
i
n
a
t
e
s
weight = \frac{Total \; number \; of \; coordinates}{Number \; of \; present \; coordinates}
weight=NumberofpresentcoordinatesTotalnumberofcoordinates
示例
例如:两点(3,NA,5)和(1,0,0)之间的欧几里德距离为:
3
2
×
{
(
3
−
1
)
2
+
(
5
−
0
)
2
}
=
6.595453
\sqrt{\frac{3}{2} \times \{(3-1)^2+(5-0)^2\}} = 6.595453
23×{(3−1)2+(5−0)2}=6.595453
示例1:两个一维数组的计算
# 基于sklearn.metrics.pairwise的计算
import numpy as np
from sklearn.metrics.pairwise import nan_euclidean_distances
x = [[3, np.nan, 5]]
y = [[1, 0, 0]]
nan_euclidean_distances(x, y)
# reuslts
Out[6]: array([[6.59545298]])
示例2:具有多个维度的单个数组
x = [[3, np.nan, 5], [1, 0, 0]]
nan_euclidean_distances(x, x)
# results
Out[8]:
array([[0. , 6.59545298],
[6.59545298, 0. ]])
2.2 基于KNNImputer插补方法
基本思想:KNNImputer通过欧几里德距离矩阵寻找最近邻样本,使用最近邻样本的对应位置的非空数值的均值填补缺失的数值。
Step 1: 计算距离
from sklearn.impute import KNNImputer
import numpy as np
X = [[1, 2, np.nan], [3, 4, 3], [np.nan, 6, 5], [8, 8, 7]]
np.array(X)
Out[16]:
array([[ 1., 2., nan],
[ 3., 4., 3.],
[nan, 6., 5.],
[ 8., 8., 7.]])
nan_euclidean_distances(X, X)
Out[12]:
array([[ 0. , 3.46410162, 6.92820323, 11.29158979],
[ 3.46410162, 0. , 3.46410162, 7.54983444],
[ 6.92820323, 3.46410162, 0. , 3.46410162],
[11.29158979, 7.54983444, 3.46410162, 0. ]])
结果:以点(1,2,np.nan)为例,距离最近的两个是(3,4,3)和(np.nan,6,5);此时,点(1,2,np.nan)中的缺失值为: ( 5 + 3 ) 2 = 4 \frac{(5+3)}{2} = 4 2(5+3)=4
Step 2. 填补缺失值
imputer = KNNImputer(n_neighbors=2)
imputer.fit_transform(X)
Out[14]:
array([[1. , 2. , 4. ],
[3. , 4. , 3. ],
[5.5, 6. , 5. ],
[8. , 8. , 7. ]])
大家可以自己计算一下另一个缺失值。