特征工程之缺失值处理
文章目录
- 缺失值处理
- 直接删除
- 统计值填充
- 统一值填充
- 前后向值填充
- 插值法填充
- 预测填充
- KNN填充
- 具体分析
- 缺失数据可视化
- 微信公众号:邯郸路220号子彬院 获取更多内容
缺失值处理
一般来说,未经处理的原始数据中通常会存在缺失值、离群值等,因此在建模训练之前需要处理好缺失值。
缺失值处理方法一般可分为:删除、统计值填充、统一值填充、前后向值填充、插值法填充、建模预测填充和具体分析7种方法。
直接删除
理论部分
缺失值最简单的处理方法是删除,所谓删除就是删除属性或者删除样本,删除一般可分为两种情况:
删除属性(特征)
如果某一个特征中存在大量的缺失值(缺失量大于总数据量的40%~50%及以上),
那么我们可以认为这个特征提供的信息量非常有限,这个时候可以选择删除掉这一维特征。删除样本
如果整个数据集中缺失值较少或者缺失值数量对于整个数据集来说可以忽略不计的情况下,
那么可以直接删除含有缺失值的样本记录。
注意事项:
如果数据集本身数据量就很少的情况下,不建议直接删除缺失值。
代码实现
构造假数据做演示,就上面两种情况进行代码实现删除。
import numpy as np
import pandas as pd# 构造数据
def dataset():col1 = [1, 2, 3, 4, 5, 6, 7, 8, 9,10]col2 = [3, 1, 7, np.nan, 4, 0, 5, 7, 12, np.nan]col3 = [3, np.nan, np.nan, np.nan, 9, np.nan, 10, np.nan, 4, np.nan]y = [10, 15, 8, 12, 17, 9, 7, 14, 16, 20]data = {'feature1':col1, 'feature2':col2, 'feature3':col3, 'label':y}df = pd.DataFrame(data)return dfdata = dataset()
data
feature1 | feature2 | feature3 | label | |
---|---|---|---|---|
0 | 1 | 3.0 | 3.0 | 10 |
1 | 2 | 1.0 | NaN | 15 |
2 | 3 | 7.0 | NaN | 8 |
3 | 4 | NaN | NaN | 12 |
4 | 5 | 4.0 | 9.0 | 17 |
5 | 6 | 0.0 | NaN | 9 |
6 | 7 | 5.0 | 10.0 | 7 |
7 | 8 | 7.0 | NaN | 14 |
8 | 9 | 12.0 | 4.0 | 16 |
9 | 10 | NaN | NaN | 20 |
data.isnull().sum()
feature1 0
feature2 2
feature3 6
label 0
dtype: int64
# 删除属性
def delete_feature(df):N = df.shape[0] # 样本数no_nan_count = df.count().to_frame().T # 每一维特征非缺失值的数量del_feature, save_feature = [], []for col in no_nan_count.columns.tolist():loss_rate = (N - no_nan_count[col].values[0])/N # 缺失率# print(loss_rate)if loss_rate > 0.5: # 缺失率大于 50% 时,将这一维特征删除del_feature.append(col)else:save_feature.append(col)return del_feature, df[save_feature]del_feature, df11 = delete_feature(data)
print(del_feature)
df11
['feature3']
feature1 | feature2 | label | |
---|---|---|---|
0 | 1 | 3.0 | 10 |
1 | 2 | 1.0 | 15 |
2 | 3 | 7.0 | 8 |
3 | 4 | NaN | 12 |
4 | 5 | 4.0 | 17 |
5 | 6 | 0.0 | 9 |
6 | 7 | 5.0 | 7 |
7 | 8 | 7.0 | 14 |
8 | 9 | 12.0 | 16 |
9 | 10 | NaN | 20 |
从上面可以看出,feature2 的缺失值较少,可以采取直接删除措施
# 删除样本
def delete_sample(df):df_ = df.dropna()return df_delete_sample(df11)
feature1 | feature2 | label | |
---|---|---|---|
0 | 1 | 3.0 | 10 |
1 | 2 | 1.0 | 15 |
2 | 3 | 7.0 | 8 |
4 | 5 | 4.0 | 17 |
5 | 6 | 0.0 | 9 |
6 | 7 | 5.0 | 7 |
7 | 8 | 7.0 | 14 |
8 | 9 | 12.0 | 16 |
统计值填充
理论部分
对于特征的缺失值,可以根据缺失值所对应的那一维特征的统计值来进行填充。
统计值一般泛指平均值、中位数、众数、最大值、最小值等,具体使用哪一种统计值要根据具体问题具体分析。
注意事项:当特征之间存在很强的类别信息时,需要进行类内统计,效果比直接处理会更好。
比如在填充身高时,需要先对男女进行分组聚合之后再进行统计值填充处理(男士的一般平均身高1.70,女士一般1.60)。
代码实现
使用上面数据帧 df11 作为演示数据集,分别实现使用各个统计值填充缺失值。
# 使用上面 df11 的数据帧作为演示数据
df11
feature1 | feature2 | label | |
---|---|---|---|
0 | 1 | 3.0 | 10 |
1 | 2 | 1.0 | 15 |
2 | 3 | 7.0 | 8 |
3 | 4 | NaN | 12 |
4 | 5 | 4.0 | 17 |
5 | 6 | 0.0 | 9 |
6 | 7 | 5.0 | 7 |
7 | 8 | 7.0 | 14 |
8 | 9 | 12.0 | 16 |
9 | 10 | NaN | 20 |
# 均值填充
print(df11.mean())
df11.fillna(df11.mean())
feature1 5.500
feature2 4.875
label 12.800
dtype: float64
feature1 | feature2 | label | |
---|---|---|---|
0 | 1 | 3.000 | 10 |
1 | 2 | 1.000 | 15 |
2 | 3 | 7.000 | 8 |
3 | 4 | 4.875 | 12 |
4 | 5 | 4.000 | 17 |
5 | 6 | 0.000 | 9 |
6 | 7 | 5.000 | 7 |
7 | 8 | 7.000 | 14 |
8 | 9 | 12.000 | 16 |
9 | 10 | 4.875 | 20 |
# 中位数填充
print(df11.median())
df11.fillna(df11.median())
feature1 5.5
feature2 4.5
label 13.0
dtype: float64
feature1 | feature2 | label | |
---|---|---|---|
0 | 1 | 3.0 | 10 |
1 | 2 | 1.0 | 15 |
2 | 3 | 7.0 | 8 |
3 | 4 | 4.5 | 12 |
4 | 5 | 4.0 | 17 |
5 | 6 | 0.0 | 9 |
6 | 7 | 5.0 | 7 |
7 | 8 | 7.0 | 14 |
8 | 9 | 12.0 | 16 |
9 | 10 | 4.5 | 20 |
由于众数可能会存在多个,因此返回的是序列而不是一个值所以在填充众数的时候,我们可以 df11[‘feature’].mode()[0],可以取第一个众数作为填充值
# 众数填充
print(df11.mode())def mode_fill(df):for col in df.columns.tolist():if df[col].isnull().sum() > 0: # 有缺失值就进行众数填充df_ = df.fillna(df11[col].mode()[0])return df_mode_fill(df11)
feature1 feature2 label
0 1 7.0 7
1 2 NaN 8
2 3 NaN 9
3 4 NaN 10
4 5 NaN 12
5 6 NaN 14
6 7 NaN 15
7 8 NaN 16
8 9 NaN 17
9 10 NaN 20
feature1 | feature2 | label | |
---|---|---|---|
0 | 1 | 3.0 | 10 |
1 | 2 | 1.0 | 15 |
2 | 3 | 7.0 | 8 |
3 | 4 | 7.0 | 12 |
4 | 5 | 4.0 | 17 |
5 | 6 | 0.0 | 9 |
6 | 7 | 5.0 | 7 |
7 | 8 | 7.0 | 14 |
8 | 9 | 12.0 | 16 |
9 | 10 | 7.0 | 20 |
# 最大值/最小值填充
df11.fillna(df11.max())
df11.fillna(df11.min())
feature1 | feature2 | label | |
---|---|---|---|
0 | 1 | 3.0 | 10 |
1 | 2 | 1.0 | 15 |
2 | 3 | 7.0 | 8 |
3 | 4 | 0.0 | 12 |
4 | 5 | 4.0 | 17 |
5 | 6 | 0.0 | 9 |
6 | 7 | 5.0 | 7 |
7 | 8 | 7.0 | 14 |
8 | 9 | 12.0 | 16 |
9 | 10 | 0.0 | 20 |
统一值填充
理论部分
- 对于缺失值,把所有缺失值都使用统一值作为填充词,所谓统一值是指自定义指定的某一个常数。
- 常用的统一值有:空值、0、正无穷、负无穷或者自定义的其他值
- 注意事项:当特征之间存在很强的类别信息时,需要进行类内统计,效果比直接处理会更好。
比如在填充身高时,需要先对男女进行分组聚合之后再进行统一值填充处理
(男士的身高缺失值使用统一填充值就自定为常数1.70,女士自定义常数1.60)。
代码实现
任然使用数据帧 df11 进行演示,实现统一值填充缺失值的应用。
df11
feature1 | feature2 | label | |
---|---|---|---|
0 | 1 | 3.0 | 10 |
1 | 2 | 1.0 | 15 |
2 | 3 | 7.0 | 8 |
3 | 4 | NaN | 12 |
4 | 5 | 4.0 | 17 |
5 | 6 | 0.0 | 9 |
6 | 7 | 5.0 | 7 |
7 | 8 | 7.0 | 14 |
8 | 9 | 12.0 | 16 |
9 | 10 | NaN | 20 |
# 统一值填充
# 自定义统一值常数为 10
df11.fillna(value=10)
feature1 | feature2 | label | |
---|---|---|---|
0 | 1 | 3.0 | 10 |
1 | 2 | 1.0 | 15 |
2 | 3 | 7.0 | 8 |
3 | 4 | 10.0 | 12 |
4 | 5 | 4.0 | 17 |
5 | 6 | 0.0 | 9 |
6 | 7 | 5.0 | 7 |
7 | 8 | 7.0 | 14 |
8 | 9 | 12.0 | 16 |
9 | 10 | 10.0 | 20 |
前后向值填充
理论部分
前后向值填充是指使用缺失值的前一个或者后一个的值作为填充值进行填充。
代码实现
任然使用数据帧 df11 作为演示的数据集,实现前后向值填充。
df11
feature1 | feature2 | label | |
---|---|---|---|
0 | 1 | 3.0 | 10 |
1 | 2 | 1.0 | 15 |
2 | 3 | 7.0 | 8 |
3 | 4 | NaN | 12 |
4 | 5 | 4.0 | 17 |
5 | 6 | 0.0 | 9 |
6 | 7 | 5.0 | 7 |
7 | 8 | 7.0 | 14 |
8 | 9 | 12.0 | 16 |
9 | 10 | NaN | 20 |
df11.fillna(method='ffill') # 前向填充
feature1 | feature2 | label | |
---|---|---|---|
0 | 1 | 3.0 | 10 |
1 | 2 | 1.0 | 15 |
2 | 3 | 7.0 | 8 |
3 | 4 | 7.0 | 12 |
4 | 5 | 4.0 | 17 |
5 | 6 | 0.0 | 9 |
6 | 7 | 5.0 | 7 |
7 | 8 | 7.0 | 14 |
8 | 9 | 12.0 | 16 |
9 | 10 | 12.0 | 20 |
从上面的后向填充我们发现明显的 Bug:
如果最后一个是缺失值,那么后向填充无法处理最后一个的缺失值;
如果第一个是缺失值,那么前向填充无法处理第一个的缺失值。
因此在进行前后向值填充时,要根据具体情况来进行填充,
一般同时进行前向填充+后向填充就可以解决上面的问题。
插值法填充
工作原理
所谓的插值法,就是在X范围区间中挑选一个或者自定义一个数值,
然后代进去插值模型公式当中,求出数值作为缺失值的数据。
** 1. 多项式插值**
理论公式及推导
已知n+1个互异的点 P 1 : ( x 1 , y 1 ) , P 2 : ( x 2 , y 2 ) , . . . , P n + 1 : ( x n + 1 , y n + 1 ) P1:(x1,y1),P2:(x2,y2),...,P_{n+1}:(x_{n+1},y_{n+1}) P1:(x1,y1),P2:(x2,y2),...,Pn+1:(xn+1,yn+1),
可以求得经过这n+1个点,最高次不超过n的多项式 Y = a 0 + a 1 X + a 2 X 2 + . . . + a n X n Y=a_0+a_1X+a_2X^2+...+a_nX^n Y=a0+a1X+a2X2+...+anXn,
其中计算系数A的公式如下:
A = [ a 0 , a 1 , . . . , a n ] T = X − 1 Y , 其 中 X − 1 是 X 的 逆 矩 阵 A=[a_0,a_1,...,a_n]^T=X^{-1}Y,其中X^{-1}是X的逆矩阵 A=[a0,a1,...,an]T=X−1Y,其中X−1是X的逆矩阵
(1)其中X,Y形式如下,求待定系数A:
X = [ 1 x 1 x 1 2 . . . x 1 n 1 x 2 x 2 2 . . . x 2 n . . . . . 1 x n + 1 x n + 1 2 . . . x n + 1 n ] , Y = [ y 1 y 2 . y n + 1 ] X=\begin{bmatrix} 1&x_1&x_1^2&...&x_1^n\\ 1&x_2&x_2^2&...&x_2^n\\ .&.&.&.&.\\ 1&x_{n+1}&x_{n+1}^2&...&x_{n+1}^n \end{bmatrix},Y=\begin{bmatrix} y_1&\\ y_2&\\ .&\\ y_{n+1}& \end{bmatrix} X=⎣⎢⎢⎡11.1x1x2.xn+1x12x22.xn+12..........x1nx2n.xn+1n⎦⎥⎥⎤,Y=⎣⎢⎢⎡y1y2.yn+1⎦⎥⎥⎤
(2)进行插值的公式, Y = A X Y=AX Y=AX
工作原理
(1)在事先已知的n+1个P点,可以通过A=X^(-1) Y求解得到待定系数A。
(2)假设有一空值,已知X(test_x)值,但Y值(缺失值的填充词)不知道,
由步骤1求解到的待定系数根据公式Y=AX可以求解出缺失值的数值。
import numpy as npdef Polynomial(x, y, test_x):'''test_x 的值一般是在缺失值的前几个或者后几个值当中,挑出一个作为参考值,将其值代入到插值模型之中,学习出一个值作为缺失值的填充值'''# 求待定系数array_x = np.array(x) # 向量化array_y = np.array(y)n, X = len(x), []for i in range(n): # 形成 X 矩阵l = array_x ** iX.append(l)X = np.array(X).TA = np.dot(np.linalg.inv(X), array_y) # 根据公式求待定系数 A# 缺失值插值xx = []for j in range(n):k = test_x ** jxx.append(k)xx=np.array(xx)return np.dot(xx, A)x, y, test_x = [1, 2, 3, 4], [1, 5, 2, 6], 3.5
Polynomial(x, y, test_x)
2.2499999999999716
2. lagrange插值
工作原理
可以证明,经过n+1个互异的点的次数不超过n的多项式是唯一存在的。
也就是说,无论是否是使用何种基底,只要基底能张成所需要的空间,都不会影响最终结果。 。
理论公式及推导
已知n+1个互异的点 P 1 : ( x 1 , y 1 ) , P 2 : ( x 2 , y 2 ) , . . . , P n + 1 : ( x n + 1 , y n + 1 ) P1:(x1,y1),P2:(x2,y2),...,P_{n+1}:(x_{n+1},y_{n+1}) P1:(x1,y1),P2:(x2,y2),...,Pn+1:(xn+1,yn+1),令
l i ( x ) = ∏ ( j ≠ i ) ( j = 1 ) n + 1 x − x j x i − x j , 公 式 ( 1 ) l_i(x)=\prod_{(j\ne i)(j=1)}^{n+1}\frac{x-x_j}{x_i-x_j},公式(1) li(x)=(j=i)(j=1)∏n+1xi−xjx−xj,公式(1)
作为插值基底,则Lagrange值 L i ( x ) = ∑ i = 1 n + 1 l i ( x ) y i , 公 式 ( 2 ) L_i(x)=\sum \limits_{i=1}^{n+1}l_i(x)y_i,公式(2) Li(x)=i=1∑n+1li(x)yi,公式(2)
工作原理
(1)先求出插值基底值
(2)再求Lagrange拉格朗日值
def Lagrange(x, y, test_x):'''所谓的插值法,就是在X范围区间中挑选一个或者自定义一个数值,然后代进去插值公式当中,求出数值作为缺失值的数据。'''n = len(x)L = 0for i in range(n):# 计算公式 1li = 1for j in range(n):if j != i:li *= (test_x-x[j])/(x[i]-x[j])# 计算公式 2L += li * y[i]return LLagrange(x, y, test_x)
2.25
Pandas也自带差值方法
df11['feature2'].interpolate(method="linear")
0 3.0
1 1.0
2 7.0
3 5.5
4 4.0
5 0.0
6 5.0
7 7.0
8 12.0
9 12.0
Name: feature2, dtype: float64
df11['feature2'].interpolate(method="polynomial",order=2)
# order代表多项式的项数
0 3.000000
1 1.000000
2 7.000000
3 7.856922
4 4.000000
5 0.000000
6 5.000000
7 7.000000
8 12.000000
9 NaN
Name: feature2, dtype: float64
预测填充
理论部分
预测填充思路如下:
(1)把需要填充缺失值的某一列特征(Feature_A)作为新的标签(Label_A)
(2)然后找出与 Label_A 相关性较强的特征作为它的模型特征
(3)把 Label_A 非缺失值部分作为训练集数据,而缺失值部分则作为测试集数据
(4)若 Label_A 的值属于连续型数值,则进行回归拟合;若是类别(离散)型数值,则进行分类学习
(5)将训练学习到评分和泛化能力较好的模型去预测测试集,从而填充好缺失值
代码实现部分
使用 seaborn 模块中内置 IRIS 数据集进行演示,实现使用算法模型进行预测填充。
import seaborn as sns
import numpy as np
import warnings
import matplotlib.pyplot as plt
%matplotlib inline
warnings.filterwarnings('ignore')dataset = sns.load_dataset('iris')
print(dataset.shape)
print(dataset.isnull().sum())
dataset.head()
(150, 5)
sepal_length 0
sepal_width 0
petal_length 0
petal_width 0
species 0
dtype: int64
sepal_length | sepal_width | petal_length | petal_width | species | |
---|---|---|---|---|---|
0 | 5.1 | 3.5 | 1.4 | 0.2 | setosa |
1 | 4.9 | 3.0 | 1.4 | 0.2 | setosa |
2 | 4.7 | 3.2 | 1.3 | 0.2 | setosa |
3 | 4.6 | 3.1 | 1.5 | 0.2 | setosa |
4 | 5.0 | 3.6 | 1.4 | 0.2 | setosa |
- 把需要填充缺失值的某一列特征(petal_width)作为新的标签(Label_petal_width)
# 将特征 petal_width 处理成含有 30 个缺失值的特征
dataset['Label_petal_length'] = dataset['petal_length']
for i in range(0, 150, 5):dataset.loc[i, 'Label_petal_length'] = np.nan
print(dataset.isnull().sum())
dataset.head()
sepal_length 0
sepal_width 0
petal_length 0
petal_width 0
species 0
Label_petal_length 30
dtype: int64
sepal_length | sepal_width | petal_length | petal_width | species | Label_petal_length | |
---|---|---|---|---|---|---|
0 | 5.1 | 3.5 | 1.4 | 0.2 | setosa | NaN |
1 | 4.9 | 3.0 | 1.4 | 0.2 | setosa | 1.4 |
2 | 4.7 | 3.2 | 1.3 | 0.2 | setosa | 1.3 |
3 | 4.6 | 3.1 | 1.5 | 0.2 | setosa | 1.5 |
4 | 5.0 | 3.6 | 1.4 | 0.2 | setosa | 1.4 |
- 然后找出与 Label_petal_length 相关性较强的特征作为它的模型特征
dataset.corr()
sepal_length | sepal_width | petal_length | petal_width | Label_petal_length | |
---|---|---|---|---|---|
sepal_length | 1.000000 | -0.117570 | 0.871754 | 0.817941 | 0.875744 |
sepal_width | -0.117570 | 1.000000 | -0.428440 | -0.366126 | -0.449716 |
petal_length | 0.871754 | -0.428440 | 1.000000 | 0.962865 | 1.000000 |
petal_width | 0.817941 | -0.366126 | 0.962865 | 1.000000 | 0.963768 |
Label_petal_length | 0.875744 | -0.449716 | 1.000000 | 0.963768 | 1.000000 |
可以发现特征 sepal_length、petal_width 与 Label_petal_width 有着强关联,
因此 sepal_length、petal_width 作为 Label_petal_length 的模型特征
- 把 Label_petal_length 非缺失值部分作为训练集数据,而缺失值部分则作为测试集数据
data = dataset[['sepal_length', 'petal_width', 'Label_petal_length']].copy()
train = data[data['Label_petal_length'].notnull()]
test = data[data['Label_petal_length'].isnull()]
print(train.shape)
print(test.shape)
(120, 3)
(30, 3)
- 由于 Label_petal_length 的值属于连续型数值,则进行回归拟合
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LinearRegression
from sklearn.metrics import r2_score# 将训练集进行切分,方便验证模型训练的泛化能力
x_train, x_valid, y_train, y_valid = train_test_split(train.iloc[:, :2], train.iloc[:, 2], test_size=0.3)
print(x_train.shape, x_valid.shape)
print(y_train.shape, y_valid.shape)# 使用简单的线性回归进行训练
lr = LinearRegression()
lr.fit(x_train, y_train)
y_train_pred = lr.predict(x_train)
print('在训练集中的表现:', r2_score(y_train_pred, y_train))
y_valid_pred = lr.predict(x_valid)
print('在验证集中的表现:', r2_score(y_valid_pred, y_valid))
(84, 2) (36, 2)
(84,) (36,)
>>>在训练集中的表现: 0.9513919768204693
>>>在验证集中的表现: 0.9375742227297561
- 将训练学习到评分和泛化能力较好的模型去预测测试集,从而填充好缺失值
由上面来看,模型在训练集以及验证集上的表现相差不大并且效果挺不错的,
这说明模型的泛化能力不错,可以用于投放使用来预测测试集
y_test_pred = lr.predict(test.iloc[:, :2])
test.loc[:, 'Label_petal_length'] = y_test_pred
df_no_nan = pd.concat([train, test], axis=0)
print(df_no_nan.isnull().sum())
df_no_nan.head()
sepal_length 0
petal_width 0
Label_petal_length 0
dtype: int64
sepal_length | petal_width | Label_petal_length | |
---|---|---|---|
1 | 4.9 | 0.2 | 1.4 |
2 | 4.7 | 0.2 | 1.3 |
3 | 4.6 | 0.2 | 1.5 |
4 | 5.0 | 0.2 | 1.4 |
6 | 4.6 | 0.3 | 1.4 |
上面就是预测填充的代码示例以及详细讲解。
KNN填充
利用knn算法填充,其实是把目标列当做目标标量,利用非缺失的数据进行knn算法拟合,最后对目标列缺失进行预测。(对于连续特征一般是加权平均,对于离散特征一般是加权投票)
df11
feature1 | feature2 | label | |
---|---|---|---|
0 | 1 | 3.0 | 10 |
1 | 2 | 1.0 | 15 |
2 | 3 | 7.0 | 8 |
3 | 4 | NaN | 12 |
4 | 5 | 4.0 | 17 |
5 | 6 | 0.0 | 9 |
6 | 7 | 5.0 | 7 |
7 | 8 | 7.0 | 14 |
8 | 9 | 12.0 | 16 |
9 | 10 | NaN | 20 |
from fancyimpute import KNN
fill_knn = KNN(k=3).fit_transform(df11)
data_2 = pd.DataFrame(fill_knn)
data_2
Imputing row 1/10 with 0 missing, elapsed time: 0.001
0 | 1 | 2 | |
---|---|---|---|
0 | 1.0 | 3.000000 | 10.0 |
1 | 2.0 | 1.000000 | 15.0 |
2 | 3.0 | 7.000000 | 8.0 |
3 | 4.0 | 1.333333 | 12.0 |
4 | 5.0 | 4.000000 | 17.0 |
5 | 6.0 | 0.000000 | 9.0 |
6 | 7.0 | 5.000000 | 7.0 |
7 | 8.0 | 7.000000 | 14.0 |
8 | 9.0 | 12.000000 | 16.0 |
9 | 10.0 | 8.818182 | 20.0 |
具体分析
上面两次提到具体问题具体分析,为什么要具体问题具体分析呢?因为属性缺失有时并不意味着数据缺失,
缺失本身是包含信息的,所以需要根据不同应用场景下缺失值可能包含的信息进行合理填充。
下面通过一些例子来说明如何具体问题具体分析,仁者见仁智者见智,仅供参考:
- “年收入”:商品推荐场景下填充平均值,借贷额度场景下填充最小值;
- “行为时间点”:填充众数;
- “价格”:商品推荐场景下填充最小值,商品匹配场景下填充平均值;
- “人体寿命”:保险费用估计场景下填充最大值,人口估计场景下填充平均值;
- “驾龄”:没有填写这一项的用户可能是没有车,为它填充为0较为合理;
- ”本科毕业时间”:没有填写这一项的用户可能是没有上大学,为它填充正无穷比较合理;
- “婚姻状态”:没有填写这一项的用户可能对自己的隐私比较敏感,应单独设为一个分类,如已婚1、未婚0、未填-1。
缺失数据可视化
手工查看每个变量的缺失值是非常麻烦的一件事情,
missingno提供了一个灵活且易于使用的缺失数据可视化和实用程序的小工具集,可以快速直观地总结数据集的完整性。
import missingno as msno
data
feature1 | feature2 | feature3 | label | |
---|---|---|---|---|
0 | 1 | 3.0 | 3.0 | 10 |
1 | 2 | 1.0 | NaN | 15 |
2 | 3 | 7.0 | NaN | 8 |
3 | 4 | NaN | NaN | 12 |
4 | 5 | 4.0 | 9.0 | 17 |
5 | 6 | 0.0 | NaN | 9 |
6 | 7 | 5.0 | 10.0 | 7 |
7 | 8 | 7.0 | NaN | 14 |
8 | 9 | 12.0 | 4.0 | 16 |
9 | 10 | NaN | NaN | 20 |
- 无效矩阵的数据密集显示
如果data太大,需要data.sample(250)
重新随机抽样
msno.matrix(data,labels=True)
<matplotlib.axes._subplots.AxesSubplot at 0x18e33f710f0>
我们可以一目了然的看到每个变量的缺失情况,
变量feature1,label数据是完整的,feature2变量中间段和最后部分有缺失,feature3确实较多。
- msno.bar 是列缺失值的简单可视化:
msno.bar(data,labels=True)
<matplotlib.axes._subplots.AxesSubplot at 0x18e2f767668>
- missingno相关性热图:一个变量的存在或不存在如何强烈影响的另一个的存在:
msno.heatmap(data,figsize=(16, 7))
<matplotlib.axes._subplots.AxesSubplot at 0x18e2f895550>
- missingno树形图使用层次聚类算法通过它们的无效性相关性(根据二进制距离测量)将变量彼此相加。在树的每个步骤,基于哪个组合最小化剩余簇的距离来分割变量。变量集越单调,它们的总距离越接近零,并且它们的平均距离(y轴)越接近零。
msno.dendrogram(data)
<matplotlib.axes._subplots.AxesSubplot at 0x18e33a560b8>
微信公众号:邯郸路220号子彬院 获取更多内容
特征工程之缺失值处理相关推荐
- 零基础入门数据挖掘-Task3 特征工程
Datawhale 零基础入门数据挖掘-Task3 特征工程 前言 内容介绍 数据清洗 缺失值 异常值 箱型图 3∂原则 Box-Cox 变换 特征缩放 特征编码 特征工程 特征提取 特征选择 特征构 ...
- 数据挖掘实战:特征工程python实战
特征工程是数据科学和机器学习中的重要技巧,对机器模型性能和EDA(exploratory data analysis)的质量有重要影响.本文介绍几种特征工程技巧 详见 notebook 目录 什么是特 ...
- R语言构建xgboost模型:使用xgboost模型训练tweedie回归模型,特征工程(dataframe转化到data.table、独热编码、缺失值删除、DMatrix结构生成)
R语言构建xgboost模型:使用xgboost模型训练tweedie回归模型,特征工程(dataframe转化到data.table.独热编码.缺失值删除.DMatrix结构生成) 目录
- ML之FE:特征工程中数据缺失值填充的简介、方法、全部代码实现之详细攻略
ML之FE:特征工程中数据缺失值填充的简介.方法.全部代码实现之详细攻略 目录 特征工程中数据缺失值填充的简介.方法.经典案例
- ML之FE:特征工程中常用的一些处理手段(缺失值填充、异常值检测等)及其对应的底层代码的实现
ML之FE:特征工程中常用的一些处理手段(缺失值填充.异常值检测等)及其对应的底层代码的实现 目录 特征工程中常用的一些处理手段(缺失值填充.异常值检测等)及其对应的底层代码的实现
- 特征工程-使用随机森林进行缺失值填补
特征工程-使用随机森林进行缺失值填补 一.前言 特征工程在传统的机器学习中是非常重要的一个步骤,我们对机器学习算法的优化通常是有限的.如果在完成任务时发现不管怎么优化算法得到的结果都不满意,这个时候就 ...
- pandas用众数填充缺失值_sklearn中的数据预处理和特征工程
小伙伴们大家好~o()ブ,我是菜菜,我的开发环境是Jupyter lab,所用的库和版本大家参考: Python 3.7.1(你的版本至少要3.4以上 Scikit-learn 0.20.0 (你的版 ...
- 手把手教你用Python实现自动特征工程
任何参与过机器学习比赛的人,都能深深体会特征工程在构建机器学习模型中的重要性,它决定了你在比赛排行榜中的位置. 特征工程具有强大的潜力,但是手动操作是个缓慢且艰巨的过程.Prateek Joshi,是 ...
- 用机器学习神器sklearn做特征工程!
Datawhale干货 作者:jasonfreak,编辑:数据STUDIO 使用sklearn做特征工程 特征工程是什么? 有这么一句话在业界广泛流传:数据和特征决定了机器学习的上限,而模型和算法只是 ...
最新文章
- jira mysql 启动 失败_重启机器导致mysql启动失败
- Fiori UI上my contact加了Dr. 后搜索不出数据的奇怪问题
- python 投资组合_成功投资组合的提示
- python基本原理概论_优学院《2020年马克思主义基本原理概论题库(高职类)》查题教程2020高校邦《Python程序设计基础【实境编程】》答案完整...
- “=” “:=” 区别
- python基础之字符编码、文件处理
- 总结列表显示ListView知识点
- PDF怎么转换成CAD图纸?PDF转CAD教程
- 吕林涛计算机网络知识点,计算机网络——习题与解析
- 说说基于BS架构的三维地图引擎如arcgis以及三维引擎cesium等在数字孪生三维可视化项目中踩过的那些坑
- TINA仿真系列之555定时器
- Canvas绘制地图
- linux下解压war格式的包
- Vue指令概述,v-if与v-show的区别
- matlab封装的模块,matlab模块封装
- 图书预约管理系统的设计与实现
- IntelliJ IDEA 下载安装(含注册码)
- Phoenix重磅 | Phoenix核心功能原理及应用场景介绍
- 泰勒级数定义及相关展开式
- FPGA控制DDS_AD9850输出正弦波(“并行spi”)
热门文章
- java中jgit中checkout,如何在JGit中合并?
- mysql 查看数据库、表的基本命令
- /* */注释的代替
- 社区疫情|基于SpringCloudAlibaba的社区疫情管理平台设计与实现
- 从入门到精通的java职业路线
- C++ 创建链表并输出
- chosen宽度太小
- OpenCV 之 cvCvtColor (色彩空间转换)
- Wampserver集成Mysql更改密码后无法登陆,提示(HY000/1045)解决方案
- 计算机在外贸英语上的应用,视景仿真技术在外贸英语项目学习中的应用鄢.PDF...