[数据挖掘]数据预处理-缺失值处理
数据预处理架构:
ETL:是一个数据管道 ,负责将分布的,异构的数据根据一定的业务规则进行数据清洗转换,继承(transform),最后将处理后的数据加载到数据目的地—数据仓库;
数据抽取
Oralcle SQL Server Flat data teradata,检查数据类型,确保数据完整,去除重复数据,去除脏数据,确保导出数据属性与元数据一致;
- 更新抽取:
将源系统中有新的数据加入或发生数据更新操作时,系统会发出提醒提醒;
- 全量抽取:
当数据源中有新的数据加入或发生数据更新操作时,系统不会发出提醒,类似于数据迁移或数据复制,将数据源中的表或视图数据原封不动的从数据库中抽取出来,并转换成自己的ETL工具可以识别的格式 ,一般只在系统初始化时使用,全量一次后,就要每天采用增量抽取;
- 增量抽取:
当数据源中有新的数据加入或发生数据更新操作时,系统不会发出提醒,但可以识别出更新的数据,增量抽取只抽取自上次依赖数据库表中新增或者修改的数据
流处理:适合小数据集,实时数据采集
批量抽取:适合大数据集
适合增量抽取方式的数据:
• 源数据的数据量较小
• 源数据不易发生变化
• 源数据诚信啊规律性变化
• 目标数据量巨大
捕获方法
- 触发器捕获(快照式捕获):
源表增加捕获变化数据的触发器,变化数据录入临时表,目标系统从临时表录入数据,抽取后做标记或删除
优点自动化程度高
缺点:对原系统性能有一定影响,不建议频繁使用 - 增加时间戳:
源表增加时间戳字段,数据变化后更新时间戳值,抽取时判断通过判断时间戳值就饿顶抽取的记录
有自动更新,手动更新
优点:性能优化,抽取思路清洗
缺点:对业务系统倾入性较大
- 全表删除插入方式:抽取时删除目标表,源表全表重新导入
优点:抽取规则简单
缺点:维表加外键不适合
数据转换
- 数据转换:清洗+转换
清洗重复+不完整+错误
根据具体的业务规则,对数据做转换规则,从而实现数据转换的目的;
o Cleaning:把空值变成“0”或“NULL”,Male 变成 M。
o Deduplication:删除重复数据。
o Data Threshold Validation Check:结合现实世界对数据进行判断,比如年龄不能超过3位数。
o Transpose:行列转置。
o Filtering:只选取确定的数据加载到数据目的地。
o Joining:把多个数据源的数据结合在一起 (merge,lookup)。
o Splitting:把一列数据分成多列。
o Integration:把多列数据整合成一列
高质量数据:pass through data 不需要进行转换
数据加载
将已转换后的数据加载到指定的数据仓库中,为后续数据的分析,挖掘提供数据准备;
• 缺失值和空值检测
• 目标数据和元数据一致性检测
• 远征已转换数据是否符合预期,即测试数据加载验证
- 全量加载:清空表后再进行数据加载,比增量加载简单。一般只需在数据加载之前,清空目标表,再全量导入源表数据即可。但当源数据量较大 、业务实时性较高时,大批量的数据无法在短时间内加载成功,此时需要与增量加载结合使用
- 增量加载:
o 目标表仅更新源表中变化的数据。
o 增量加载难度在于更新数据的定位,必须设计明确的规则从数据源中抽取信息发生变化的的数据,并将这些变化的数据在完成相应的逻辑转换后更新到数据目的地中。
增量加载:
o 系统日志分析:
该方式通过分析数据库自身的日志来判断变化的数据。关系型数据库系统都会将所有的 DML 操作存储在日志文件中,以实现数据库的备份和还原功能。ETL 增量抽取进程通过对数据库的日志进行分析,提取对相关源表在特定时间后发生的 DML 操作信息,就可以得知自上次抽取时刻以来该表的数据变化情况,从而指导增量抽取动作。
o 触发器:
直接进行数据加载:
创建一个与源表结构类似的临时表,然后创建一个三种类型的触发器,分别对应 insert , update , delete 操作。每当源表有数据变动的时候,利用触发器将变化的数据填入此临时表表中。最后通过维护这个临时表,在进行 ETL 过程的时候,将目标表中相应的数据进行修改。ETL 过程结束后,清空此临时表
利用增量日志表进行增量加载
o 时间戳
o 全表对比
增量数据直接或转换后加载
ETL
抽取—转换—加载
数据转换后加载到数据仓库中
ELT
抽取—加载—转换
加载到数据仓库中,在进行转换
(1)简化ETL架构
(2)降低抽取的额实际和性能开销
ETL需要多次抽取,转换,加载,而ELT能实现一次抽取,加载,多次转换
数据清洗
- 缺失值处理
:人为疏忽,机器故障,认为可以隐瞒;
数据本身不存在,如学生工资;
系统实时性要求高;
历史局限性导致数据收集不完整;
-
影响:数据和特征决定了机器学习的上限,而模型和算法的应用只是逼近这个上限。
数据集中缺少部分数据可以降低模型过拟合几率,但也存在模型偏差过大的风险,因为没有正确的分析变量的行为和关系,从而导致错误的预测或分析。 -
完全变量:数据中不含缺失值的变量
-
不完全变量:数据集中含有缺失值的变量
-
完全随机缺失MCAR:所有变量的缺失概率都是相同的数据的缺失不依赖于不完全变量或完全变量,抛硬币
-
随机缺失MAR:数据的缺失与其他完全变量有关,收集家庭收入信息这一变量,女性比男性高,但性别是完全变量
-
非随机缺失MNAR:数据缺失与不完全变量自身的取值有关,MNAP分两种
缺失值依赖于未观察变量:
数据缺失不是随机的,取决于未观测到的变量。比如,学校开设一门课程,中途退出的人较多,可能与课程内容质量不好有关,但数据集中并未收集“课程质量评分”这一变量。
取决于缺失值本身:
缺失值的概率与缺失值本身直接相关,比如收入过高或过低的人群不愿意提供自己的收入证明
处理方法
-
删除:适用于数据量大,数据缺失值少的数据集,完全随机缺失时可直接使用删除操作,遵循80%法则,缺点:直接删除会会丢失部分分原始数据,破坏数据的历史完整性;数据缺失占比较多时,直接删除可能会改变原始数据的分布情况;降低模型准确性
-
填充:人工填充,特殊值填充,平均值填充,热卡填充,KNN,预测模型,缺点:可能会改变原始数据的分布情况;可能会引入噪音节点;降低模型准确性。
KNN:通过KNN的方法将所有样本进行划分,通过欧式距离,选取与缺失样本最近的K个样本,通过投票发或K个值加权(权值)平均来估算该样本的缺失值
k值得选择会对k近邻法的结果产生重大影响,k值一般取一个比较小的数值,通过交叉验证法来选取最优的k值
具体KNN算法的学习可参考以下博文:
https://blog.csdn.net/eeeee123456/article/details/79927128 -
不处理:xgboost
-
回归:把数据中不含数据缺失的部分作为训练集,根据训练集建立回归模型,将次回归模型用来预测缺失值并进行填充,只适用于缺失值是连续的情况。
预测填充理论上比填充效果好,但若缺失值与其他变量没有相关性,则预测出的缺失值没有统计意义 -
变量映射:把变量映射到高维空间中
实例:客户信息表中,性别一栏有“男”、“女”和null值(数据表中信息缺失)三种情况,可将客户信息表中性别属性值更改为“是否男”,“是否女”,“是否缺失”三种。
优点:可以保留原始数据完整性,无需考虑缺失值
缺点:计算开销大大提升
可能会出现稀疏矩阵,反而降低模型质量
数据预处理Python实现
实验工具:anaconda,python自带的iris公有数据集
- 删除缺失值:
基本格式:DataFrame.dropna(axis=0, how='any', thresh=None, subset=None, inplace=False)
1.axis=0代表行 axis=1代表列。
2.how=any代表若某行或某列中存在缺失值,则删除该行或该列。how=all代表若某行或某列中数值全部为空,则删除该行或该列。
3.thresh=N,可选参数,代表若某行或某列中至少含有N个缺失值,则删除该行或该列。
4.subset=列名,可选参数,代表若指定列中有缺失值,则删除该行。
5.inplace=True/False,Boolean数据, 默认为False。inplace=True代表直接对原数据集N做出修改。
6.inplace=False代表修改后生成新数据集M,原数据集N保持不变。
#导入pandas库和numpy库
import pandas as pd
import numpy as np
#导入数据集iris
from sklearn.datasets import load_iris
iris=load_iris()
print(iris)
#数据转换,由于dropna ( ) 函数适用于DataFrame结构的数据集,因此需先将iris数据集转换成DataFrame结构
dfx=pd.DataFrame(data=iris.data, columns=iris.feature_names)
#人为加入缺失值
c=pd.DataFrame({"sepal length (cm)":[np.nan,4.9],
"sepal width (cm)":[np.nan,3],
"petal length (cm)":[np.nan,1.4],
"petal width (cm)":[0.2,np.nan]})
df=dfx.append(c,ignore_index=True)
#删除含缺失值的数据行
df.dropna()
#删除含缺失值的数据列
df.dropna(axis='columns')
#删除各属性全为NaN的数据行
df.dropna(how='all')
#删除存在缺失值NaN的数据行
df.dropna(how='any')
#删除属性列sepal width (cm)中含有缺失值NaN的数据行。
df.dropna(subset=['sepal width (cm)'])
#删除含缺失值NaN的数据行,并生成新数据集
df.dropna(inplace=False)
- 填充
数据导入与上一方法一致
基本格式:
Imputer(missing_values='NaN', strategy='mean', axis=0, verbose=0, copy=True)
fit_transform() 先拟合数据,再标准化
missing_value,可选参数,int型或NaN,默认为NaN。
strategy =mean/median/most_frequent,可选参数。
strategy=mean代表用某行或某列的均值填充缺失值。
strategy=median代表用某行或某列的中位数值填充缺失值。
strategy =most_frequent代表用某行或某列的众数填充缺失值。
axis=0/1,默认为0,可选参数。axis=0代表行数据,axis=1代表列数据。一般实际应用中,axis取0。
verbose, 默认为0,可选参数。控制Imputer的冗长。
copy=True/False, Boolean数据, 默认为True,可选参数。copy=True代表创建数据集的副本。
#导入pandas库和numpy库
import pandas as pd
import numpy as np
#导入数据集iris
from sklearn.datasets import load_iris
iris=load_iris()
dfx=pd.DataFrame(data=iris.data, columns=iris.feature_names)
c=pd.DataFrame({"sepal length (cm)":[np.nan,4.9],
"sepal width (cm)":[np.nan,3],
"petal length (cm)":[np.nan,1.4],
"petal width (cm)":[0.2,np.nan]})
df=dfx.append(c,ignore_index=True)
#众数填充
#导入Imputer类
from sklearn.preprocessing import Imputer
#使用Imputer函数进行缺失值填充,参数strategy设置为'most_frequent'代表用众数填充
data = Imputer(missing_values='NaN', strategy='most_frequent', axis=0)
#对填充后的数据做归一化操作
df=dfx.append(c,ignore_index=True)
dataMode = data.fit_transform(df)
#输出dataMode
print(dataMode)
#均值填充
data = Imputer(missing_values='NaN', strategy='mean', axis=0)
dataMode = data.fit_transform(df)
``
![在这里插入图片描述](https://img-blog.csdnimg.cn/20200309140106663.png)
```python
#中位数填充
data = Imputer(missing_values='NaN', strategy='median', axis=0)
dataMode = data.fit_transform(df)
- KNN
基本格式:
KNeighborsClassifier(n_neighbors=5, weights='uniform', algorithm='auto', leaf_size=30, p=2, metric='minkowski', metric_params=None, n_jobs=1, **kwargs)
n_neighbors可选参数,代表聚类数量,默认为5。
weights可选参数,代表近邻的权重值,uniform代表近邻权重一样,distance代表权重为距离的倒数,也可自定义函数确定权重,默认为uniform。
algorithm可选参数,代表计算近邻的方式,具体包括{'auto', 'ball_tree', 'kd_tree', 'brute'}。
leaf_size可选参数,代表构造树的大小,默认为30。值一般选取默认值即可,太大会影响建模速度。
n_jobs可选参数,代表数据计算的jobs数量,选取-1后虽然占据CPU比重会减小,但运行速度会变慢,所有的core都会运行,默认为1
#导入pandas库和numpy库
import pandas as pd
import numpy as np
#导入数据集iris
from sklearn.datasets import load_iris
iris=load_iris()
# 导入iris数据集,自变量X命名为dfx,分类变量Y命名为dfy
dfx=pd.DataFrame(data=iris.data, columns=iris.feature_names)
dfy=pd.DataFrame(data=iris.target)
#手动导入含缺失值的测试集
x_test=pd.DataFrame({"sepal length (cm)":[5.6,4.9],
"sepal width (cm)":[2.5,3],
"petal length (cm)":[4.5,1.4],
"petal width (cm)":[0.2,2.1]})
# 导入KNeighborsClassifier
from sklearn.neighbors import KNeighborsClassifier
# KNN模型建立,将此数据集分为三簇,因此n_neighbors=3
modelKNN = KNeighborsClassifier(n_neighbors=3)
modelKNN.fit(dfx,dfy)
# 预测
predicted = modelKNN.predict(x_test)
print (predicted)
说明测试数据所属类别为 2 和1 ,2对应第一行数据,1对应第二行数据
上一篇: linux时区修改