数据分析(二)数据预处理

本文详细介绍了数据预处理的重要步骤,包括缺失值处理(删除法、填补法如均值填补、热平台填补等)、异常值检测(基于统计和距离的检测方法)和变量标准化(Z-Score、0-1标准化等)。这些方法在确保数据质量、提高模型性能方面起着关键作用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

数据预处理的重要性:

  • 由于数据采集技术的局限、传输过程的错误等原因,采集的原始数据通常存在不完整、含噪(包含错误或离群值)、不一致(编码不同、属性与内容对不上)、冗余(样本重复、属性之间可相互推导)等问题
  • 模型输入数据的质量直接影响了建模的效果,尤其是在追求最后的一丢丢优化的时候

广义上的数据预处理还包含了【数据质量管理】这一过程,但对于个人而言感觉这概念太抽象了,所以本文只包含了数据预处理的常规步骤:数据清洗,数据集成,数据转换和数据归约。下面先用一个表格来说明这四个步骤的任务和常见的处理技术之间的关系。

步骤 主要任务 相关技术
数据清洗 补充缺失,平滑噪声,识别或删除离群点/异常值,解决数据不一致问题 缺失值处理,异常值检测,错误发现与修复
数据集成 集成多个数据库、数据立方或文件 实体识别,冗余和相关分析,数据仓库(大数据专用)
数据转换 规范化和聚集 变量离散化,变量标准化
数据归约 特征选择和采样 特征选择,特征提取,数据抽样,数据过滤

注意:在实际的处理过程上,不一定4个步骤都需要;而且如果你看过数据分析(一)的话你会很容易发现其实不同步骤之间存在交集。这不是重点,分析步骤的划分只是为了便于学习理解,在实际处理过程中通常是一个交织循环的过程。问题来了:怎么知道该如何“交织循环”呢?无它,多逛逛优秀的博客,看看大牛们是怎么做的吧。

从上面的表格你也许已经看出来了,【步骤】是提纲挈领用的,【主要任务】是提醒分析目标用的,【相关技术】才是技术人的根基。所以接下来的内容是就主要的技术部分进行介绍。

缺失值处理

数据的缺失就是指 完全没有采集到数据 ,至于数据乱码、数据错误等不算在此列,而是归在异常检测和错误修复部分。处理缺失有两种通用的方法:删除法填补法

删除法

  • 删除样本:将存在数据缺失的样本删除
    – 适用于数据对象有多个属性发生数据缺失、且删除的数据对象占样本总量比例非常小的情况
    – 样本太少的情况下可能数据偏离,引导出错误的学习(训练)成果
  • 删除属性:将存在数据缺失的属性删除
    – 适用于变量缺失值较多,且对研究目标影响不大的情况
    – 可能出现误删重要属性的情况
''' 可用 pandas.DataFrame.dropna 清除缺失值,更多用法请查看官方文档 '''
# 删除有缺失的样本,此处可用 thresh 参数来限制仅删除非缺失值少于 thresh 个的对象
data['有缺失的列'] = data['有缺失的列'].dropna(axis='index', thresh=5)
# 删除有缺失的属性
data['有缺失的列'] = data['有缺失的列'].dropna(axis='columns')

填补法

  • 单一填补
    • 均值填补:对于非数值型数据,使用众数填补;对于数值数据,使用算术平均值
      – 适用于缺失值完全随机的情况
      – 能保证总体均值无偏,但容易使均值集中在均值附近造成“尖峰”,低估方差
      – 调整策略:将样本总体按某种方式划分为多个子集,对每个子集使用局部均值填补
    • 热平台填补:在样本总体中找到与缺失值最相似的变量进行填充
      – 可以保持数据类型,且变量值与填充前可能很接近
      – 只能利用已有信息,无法覆盖样本总体未采集到或未反应的信息
    • 冷平台填补:与热平台类似,但是是从历史数据中找到最相似的变量
      – 适用于保留有历史数据的情况
      – 不能消除估计的偏差
    • KNN填补:与热平台相似,但是是根据某种距离函数,找到k个最相似的样本,取其均值或众数估计缺失的数据
      – 引入了自相关性,容易加剧模型分析的偏差
  • 随机填补
    • 贝叶斯Bootstrap:从无缺失的数据中,随机抽取一个变量进行填补
    • 随机贝叶斯Bootstrap:类似贝叶斯Bootstrap,但是先在样本总体中【有放回地】抽取k*个样本建立子集,在子集中随机抽取
  • 基于模型填补:使用分类或回归模型,将无缺失的属性作为自变量、有缺失的属性当作标签或预测目标,构建模型进行估计
''' 在 python 中,可用 pandas.DataFrame.fillna 或 interpolate 进行填充,注意在 DataFrame 中,缺失值为 NaN 值(可用 numpy.nan 表示) '''
# 用均值
data['有缺失的列'] = data['有缺失的列'].fillna(data['有缺失的列'].mean())
# 用众数
data['有缺失的列'] = data['有缺失的列'].fillna(data['有缺失的列'].mode())
# 用 KNN,k 取 4
data['有缺失的列'] = data['有缺失的列'].interpolate(method='nearest', order=4)
# 或者用这种
data['有缺失的列'].interpolate(method='nearest', order=4, inplace=True)

# 至于热平台冷平台就和具体的作法用关了;而随机填补方面,个人尚未了解到有既成的库可以调用,自己按需 def 一个吧,随机抽取部分的代码可以参考下面:
import random

chosen = random.randint(0, data.shape[0] - 1)
# 或者
chosen = random.randrange(0, data.shape[0])

异常值检测

这里推荐 一篇总结比较全面的文章 ,建议与本文相互对照下

基于统计

  • 3 σ \sigma σ 探测法:基于正态分布的特性,有超过95%的面积在平均数左右两个标准差的范围内。因此可能通过适当设置 α \alpha α 分位点,将极小概率出现的数值作为异常值剔除,在如下示意图中,若 Z0.025=1.96,那么通过仅保留 ∣ x − μ σ ∣ &lt; 1.96 {\lvert \frac {x - \mu}{\sigma} \rvert &lt; 1.96} σxμ<1.96 的样本,就可以剔除出现概率仅为 5% 的样本:
    正态分布分位点
    – 适用于数值型数据
  • 画散点图:适用于数值型数据,直观地(根据个人经验)发现异常点
  • 四分位法——箱形图观察:对每个属性画出对应的箱形图,将上下截断点之外的值视为异常值
    – 适用于数值型的属性
    – 相较方差和极差,受极值影响小,处理大规模数据效果不错;但对于小规模数据略显粗糙
    – 记上分位点为Q3,下分位点为Q1,IQR = Q3 - Q1,则通常取上截断点 = Q3 + 1.5IQR,下截断点 = Q1 - 1.5IQR
    箱形图四分位点示意图
''' 在 python 中可尝试用 Dataframe.boxplot 实现这一处理过程,不过这一做法要求所有属性值都已处理为数值型,如下 '''
# boxplot 中自动记录了箱形图的基本统计信息,所以 return_type 必须设置为 dict 型
box = data.boxplot(return_type='dict')
col = data.columns
# fliers 记录了每个属性下的异常值,所以不难理解 len(box['fliers']) = 属性个数
for i in range(len(box['fliers'])):
	# boxplot 中把截断点到分位点之间的连线形象地称为胡须(即 whiskers),box['whiskers'] 总共有(2 * 属性个数)个 values,下面的这个调用结果是自动按上面说的公式计算的结果。至于 get_ydata 还是 get_xdata 好像不同版本不同,需要的时候就一个个 print 出来确认下吧
	lower_bound = box['whiskers'][i * 2].get_ydata()[1]
	upper_bound = box['whikders'][i * 2 + 1].get_ydata()[1]
	# 通常的手段是先将异常值设置为缺失值,然后再用处理缺失值的方法完成后续流程
	data[col[i]] = data[col[i]].apply(lambda x: np.nan if (x < lower_bound) | (x > upper_bound) else x)
# 后续的处理缺失值过程自行脑补
' ...... '

基于距离

  • 局部异常因子算法( LOF 算法,Local Outlier Factor)
    – 基本思想:通过定义某种距离度量方法,比较每个点 p (样本)和其邻域点的密度,p 密度越小,越可能被认为是异常点
    – 适用于二维或高维坐标体系(即至少要有2个属性)
    – 先定义一些符号:
符号 含义
d(A, B) 点 A 与 B 之间的距离
dk(A) 点 A 的第 k 距离,即以 A 为圆心,半径从 0 不断加大,接触到第 k 个点时的【半径长度】
Nk(A) 点 A 的第 k 距离以内的所有点,包括第 k 距离对应的点在内
reach-distancek(B, A) max { dk(A), d(A, B) } (可参考下面第一张图
lrdk(A) 点 A 的局部可达密度(local reachability density),计算公式为 l r d k ( A ) = 1 / ∑ O ∈ N k ( A ) r e a c h − d i s t a n c e k ( A , O ) ∣ N k ( A ) ∣ lrd_k(A) = 1/ \frac{\sum_{O\in {N_k(A)} reach-distance_k(A, O)}}{\lvert N_k(A) \rvert} lrdk(A)=1/Nk(A)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值