问小白 wenxiaobai
资讯
历史
科技
环境与自然
成长
游戏
财经
文学与艺术
美食
健康
家居
文化
情感
汽车
三农
军事
旅行
运动
教育
生活
星座命理

深度学习之“缺失数据处理”

创作时间:
作者:
@小白创作中心

深度学习之“缺失数据处理”

引用
CSDN
1.
https://m.blog.csdn.net/qq_30479517/article/details/145406082

在深度学习和数据分析中,缺失数据是一个常见的问题。如何处理这些缺失值,直接影响到模型的训练效果和预测准确性。本文将详细介绍几种常用的缺失数据处理方法,并通过Python代码示例展示具体实现过程。

缺失值检测

缺失数据就是我们没有的数据。如果数据集是由向量表示的特征组成,那么缺失值可能表现为某些样本的一个或多个特征因为某些原因而没有测量的值。通常情况下,缺失值由特殊的编码方式。如果正常值都是正数,那么缺失值可能被标记为-1;如果正常值是字符串,那么缺失值可能是空的字符串;如果正常值是浮点数,那么缺失值可能是NaN。

在Python中,我们能够通过使用np.isnan来判断数据是否为NaN:

import numpy as np

a = np.arange(10, dtype="float64")
a[3] = np.nan

print(np.isnan(a[3]))  # True
print(a[3] == np.nan)  # False
print(a[3] is np.nan)  # False
print(np.isnan(a))
# array([False, False, False,  True, False, False, False, False, False,
#        False])

可以看到,只能用np.isnan来判断,“==”和“is”进行比较是无效的。

缺失值处理

假定我们已经知道数据中存在缺失值,那么我们就需要寻找一些手段来对其进行处理,从而避免对模型训练产生负面影响。

首先我们先生成一组数据,其中包含1000个样本,且每个样本都具有四维特征:

import numpy as np

N = 1000
np.random.seed(100)
x = np.zeros((N, 4))
x[:, 0] = 5 * np.random.random(N)
x[:, 1] = np.random.normal(10, 1, size=N)
x[:, 2] = 3 * np.random.beta(5, 2, N)
x[:, 3] = 0.3 * np.random.lognormal(size=N)

其中我们固定随机种子,从而确保结果的可复现性,并且1-4维的数据分别来自均匀分布、正态分布、贝塔分布和对数正态分布。之后我们向其中随机添加5%的缺失值:

i = np.random.randint(0, N, size=int(0.05 * N))
x[i, 0] = np.nan
i = np.random.randint(0, N, size=int(0.05 * N))
x[i, 1] = np.nan
i = np.random.randint(0, N, size=int(0.05 * N))
x[i, 2] = np.nan
i = np.random.randint(0, N, size=int(0.05 * N))
x[i, 3] = np.nan

那么我们应该如何来处理这些缺失值呢?

直接丢弃

如果我们拥有的数据集较为庞大,而缺失值的占比很小,且分布较为均匀,那么直接丢弃这些缺失值也是可以的。但是如果缺失值与某个类别存在相关性,直接丢掉这些样本可能在某种程度上会导致数据集有偏,进而影响模型的准确性。

均值/中位数填充

我们还可以参考剔除缺失值后数据的分布形态,选择使用数据均值或者中位数来对缺失值进行填充。我们首先剔除数据中的缺失值,并使用matplotlib.pyplot中的boxplot函数来查看剔除缺失值后数据的箱形图:

import matplotlib.pyplot as plt

def remove_nan_columnwise(data):
    """从每一列中剔除NaN值"""
    return [data[~np.isnan(data[:, col]), col] for col in range(data.shape[1])]

cleaned_data = remove_nan_columnwise(x)

plt.figure(figsize=(10, 6))
plt.boxplot(cleaned_data, labels=['Column 1', 'Column 2', 'Column 3', 'Column 4'])
plt.title('Box Plot of Data After Removing Missing Values')
plt.ylabel('Value')
plt.show()

从图中可以看出,第1、2维的数据偏差较小,且箱形框较为对称;第3维的数据偏上,第4维的数据偏下。因此我们使用均值来替代第1、2维的缺失数据,使用中位数来替换第3、4维的数据。

i = np.where(np.isnan(x[:, 0]) == False)
m = np.mean(x[i, 0])
i = np.where(np.isnan(x[:, 0]) == True)
x[i, 0] = m

i = np.where(np.isnan(x[:, 1]) == False)
m = np.mean(x[i, 1])
i = np.where(np.isnan(x[:, 1]) == True)
x[i, 1] = m

i = np.where(np.isnan(x[:, 2]) == False)
m = np.median(x[i, 2])
i = np.where(np.isnan(x[:, 2]) == True)
x[i, 2] = m

i = np.where(np.isnan(x[:, 3]) == False)
m = np.median(x[i, 3])
i = np.where(np.isnan(x[:, 3]) == True)
x[i, 3] = m

关于何时用中位数替代缺失值,何时用均值替代缺失值,给出的参考如下:

使用中位数填充的情况

  1. 当数据是偏斜分布或存在异常值时:如果数据不是正态分布,而是偏向一侧(即有长尾),或者存在极端值(outliers),那么使用中位数可能是更好的选择。因为中位数不受极值影响,可以更好地代表中心趋势。
  2. 对于非正态分布的数据:如果变量不符合正态分布,中位数可能是一个更稳健的选择,因为它更能反映大多数观测值的集中位置。
  3. 对于有序分类数据:当处理有序分类变量(例如,教育水平、满意度评分等)时,中位数也可能是更合适的选择。
  4. 当需要保持数据的原始分布特征时:在某些情况下,使用中位数可以帮助保持数据集的原有分布特性,尤其是在存在明显偏斜的情况下。

使用平均值填充的情况

  1. 当数据接近正态分布且没有显著异常值时:如果数据大致呈正态分布,并且不存在明显的异常值,那么使用平均值填充可能是合适的,因为它会考虑所有观测值。
  2. 对于数值型数据:平均值通常用于数值型数据,尤其是那些期望值具有实际意义的变量。
  3. 当想要最小化总平方误差时:平均值是使得预测误差平方和最小化的估计量,因此在某些统计分析中,它可能是首选。
  4. 对于回归分析中的连续变量:在进行回归分析时,如果变量是连续的,并且你认为缺失值应该反映总体的“平均水平”,那么平均值可能是一个合理的选择。
© 2023 北京元石科技有限公司 ◎ 京公网安备 11010802042949号