数据处理-数据集成与变换
1 数据集成
数据分析需要的数据往往分布在不同的数据源中,数据集成就是将多个数据源合并存放在一个一致的数据存储(如数据仓库)中的过程。采用何种方式进行合并数据集要依实际情况而定,如果两个数据集是行一一对应或者列一一对应,则采用cbind()和rbind()合并方式,如果两个数据集有某一列是相同的,则可以用merge()函数合并。合并的初衷是为了丰富数据集的信息,简洁明了地呈现数据,不能毫无根据毫无目的地乱合并数据。
举个例子,state.area和state.name是行一一对应的,采用按列合并的方式可以丰富数据集信息
#install.packages("DT")#安装DT软件包,为了使用datatable函数
library(DT)#加载DT软件包## Warning: package 'DT' was built under R version 3.4.4
data(state)#调用state数据集
data1=data.frame(state.area)#构造数据框
data2=data.frame(state.name)
data=cbind(data1,data2)#按列合并数据集
datatable(data)#展示数据集 在R中,数据集成是指将两个数据框中的数据以关键字为依据,以行为单位做列向合并,可通过函数merge()实现,基本书写方式为
merge(x,y,by=intersect(names(x),names(y)),by.x=by,by.y=by,all=FALSE,all.x=all,all.y=all,sort=TRUE,suffixes=c(".x",".y"),incomparables=NULL,...)
- x,y是要合并的数据集;
- by是指定合并的依据(相同的行或列);
- by.x,by.y实际上是用来告诉merge函数我们取出x的by.x列和y的by.y列中具有相同取值的行进行合并,其他的丢掉,另外如果指定了其中一个,那么另一个就必须同时指定,不然就报错;
- all,all.x,all.y是逻辑值,默认为FALSE,以all.x为例,表示当x中的行没有相应的y进行匹配时,用NA填充若为FALSE,那么仅输出x和y中都包含的行。
- 最后,merge(x,y)为默认参数的调用函数( by = intersect(names(x), names(y))),如果x,y有相同的列名,就按那个列具有相同的取值的行进行合并,x在前面,y在后面,相同的列名不再重复,如果x,y没有相同的列名,就把x的每一行和y的每一行合并一次。
举个例子,首先把state.name和state.region合并得到data0
data3=data.frame(state.region)
data0=cbind(data3,data2)#按列合并数据集 现在data0和data具有相同的列,可以用merge()函数合并
data.new=merge(data,data0,by="state.name")
datatable(data.new)在数据集成时,来自多个数据源的现实世界实体的表达形式是不一样的,有可能不匹配,要考虑实体识别问题和属性冗余问题,从而将源数据在最低层上加以转换、提炼和集成。
实体识别
实体识别是从不同数据源识别出现实世界的实体,它的任务是统一不同源数据的矛盾之处,常见的矛盾有如下几个
同名异义:数据源A中的属性ID和数据源B中的属性ID分别描述的是菜品编号和订单编号,即描述的是不同的实体;
异名同义:数据源A中的sales_dt和数据源B中的sales_date都是描述销售日期的,即A.sales_dt=B.sales_date;
单位不统一:描述同一个实体分别用的是国际单位和中国传统的计量单位。
检测和解决这些冲突就是实体识别的任务。
冗余属性识别
数据集成往往导致冗余,如:
同一属性多次出现;
同一属性命名不一致,导致重复。
仔细整合不同源数据能减少甚至避免数据冗余与不一致,从而提高数据分析的速度和质量,对于冗余属性要先分析,检测到后再将其删除。
有些冗余属性可以用相关分析检测,给定两个数值型的属性A和B,根据其属性值,用相关系数度量一个属性在多大程度上蕴含另一个属性。
2 数据变换
2.1 简单函数变换
简单函数变换是对原始数据进行某些数学函数变换,常用的包括平方、开平方、取对数、差分运算等等。简单的函数变换常用来将不具有正态分布的数据变换成具有正态分布的数据;在时间序列分析中,有时简单的对数变换或者差分运算就可以将非平稳序列转换成平稳序列。在数据分析中,简单的函数变换可能更有必要,如个人年收入的取值范围为1万~10亿元,这是个很大的区间,使用对数变换对其进行压缩是常用的一种变换处理。
2.2 规范化
数据规范化(归一化)处理是数据分析的一项基础工作,不同评价指标往往具有不同的量纲,数值间的差别可能很大,不进行处理可能会影响到数据分析的结果。为了消除指标之间的量纲和取值范围差异的影响,需要进行标准化处理,将数据按照比例进行缩放,使之落入一个特定的区域,便于进行综合分析。例如,将工资收入属性值映射到[-1,1]或者[0,1]内。数据规范化对于基于距离的数据分析尤为重要。
最小-最大规范化
最小-最大规范化也称为离差标准化,是对原始数据的线性变换,将数值映射到[0,1]。转换公式为\[x^*=\frac{x-min}{max-min}\]式中,max为样本数据的最大值;min为样本数据的最小值;max-min为极差。离差标准化保留了原来数据中存在的关系,是消除量纲和数据取值范围影响的最简单方法。这种处理方法的缺点是若数值集中且某个数值很大,则规范化后各值会接近于0,并且将会相差不大。若将来遇到超过目前属性[min,max]取值范围时,会引起系统出错,需要重新确定min和max。
零-均值规范化
零-均值规范化也叫标准差标准化,经过处理的数据的均值为0,标准差为1.转化公式为\[x^*=\frac{x-\bar x}{\sigma}\]式中,\(\bar x\)为原始数据的均值,\(\sigma\)是原始数据的标准差。这种方法是当前用得最多的数据标准化方法。
小数定标规范化
通过移动属性值的小数位数,将属性值映射到[-1,1],移动的小数位数取决于属性值绝对值的最大值。转化公式为\[x^*=\frac{x}{10^k}\]
下面通过对一个数据集使用上面三种规范化的方法对其进行处理,对比结果。数据集选用USArrests(犯罪统计)数据集,该数据集包含了美国50个州每100000个居民中因犯Assault(强暴)、Murder(谋杀)、Rape(强奸)3种罪而被逮捕的人数以及UrbanPop(各个州城镇居民的比例)。
data(USArrests)
d1=USArrests
datatable(d1)w=dim(d1)
#最小-最大规范化
for(i in 1:w[2]){
d1[,i]=(d1[,i]-min(d1[,i]))/(max(d1[,i])-min(d1[,i]))
}
datatable(d1)#零-均值规范化
d2=USArrests
d2=scale(d2)#scale函数专门用于该规范法,又叫做Z-Score方法
datatable(d2)#小数定标规范化
k=rep(0,4)
for(i in 1:w[2]){
k[i]=ceiling(log(max(abs(d2[,i])),10))#确定小数定标的指数K,ceiling函数返回不小于该数字的最小整数
d2[,i]=d2[,i]/10^(k[i])
}
datatable(d2)2.3 连续属性离散化
有一些分类算法要求数据是分类属性形式,因此常常需要将连续属性变换成分类属性,即连续属性离散化。
2.3.1 离散化过程
连续属性的离散化就是在数据的取值范围内设定若干个离散的划分点,将取值范围划分为一些离散化的区间,最后用不同的符号或整数值代表落在每个子区间中的数据值。所以离散化涉及两个子任务:确定分类数以及如何将连续属性值映射到这些分类值。
2.3.2 常用的离散化方法
常用的离散化方法有等宽法、等频法和(一维)聚类。
等宽法是将属性的值域分成具有相同宽度的区间,区间的个数由数据本身的特点决定,或者由用户指定,类似于制作频率分布表;
等频法是将相同数量的记录放进每个区间。这两种方法简单,易于操作,但都需要人为地规定划分区间的个数。同时,等宽法的缺点在于它对离群点比较敏感,倾向于不均匀地把属性值分布到各个区间。有些区间包含许多数据,而另外一些区间的数据极少,这样会严重损坏建立的决策模型。等频法虽然避免了上述问题的产生,却可能将相同的数据值分到不同的区间以满足每个区间中固定的数据个数。
(一维)聚类的方法包括两个步骤,首先将连续属性的值用聚类算法(如K-means)进行聚类,然后再将聚类得到的簇进行处理,合并到一个簇的连续属性值并做同一标记。聚类分析的离散化方法也需要用户指定簇的个数,从而决定产生的区间数。
用上述三种离散化方法对USArrests数据集中的Murder(谋杀率)进行连续属性离散化的对比
#等宽离散化
par(mfrow=c(1,3))#同一页显示多张图,共一行三列
d3=USArrests
v1=ceiling(d3[,1])#返回对应数字的天花板值,即不小于该数字的最小整数
plot(d3[,1],v1,xlab="等宽谋杀率离散化")
#等频离散化
attach(d3)#绑定数据集d3
l0=length(Murder)#绑定数据集后,可以直接引用数据集中的变量名
seq(0,l0,l0/5)#等频划分为5组## [1] 0 10 20 30 40 50
v=sort(Murder)#按大小作为离散化依据
v2=rep(0,l0)
for(i in 1:l0) v2[i]=ifelse(Murder[i]<=v[l0/5],1,
ifelse(Murder[i]<=v[2*l0/5],2,
ifelse(Murder[i]<=v[3*l0/5],3,
ifelse(Murder[i]<=v[4*l0/5],4,5))))
plot(d3[,1],v2,xlab="等频谋杀率离散化")
#聚类离散化
result=kmeans(d3,5)#聚3类
v3=result$cluster
plot(d3[,1],v3,xlab="聚类谋杀率离散化")离散化数据后,将数据分为几类,每一类记为同一个标识,之后再进行建模。
2.4 属性构造
在数据分析中,为了便于提取更有用的信息,分析更深层次的模式,提高分析结果的精度,需要利用已有的属性集构造出新的属性,并加入到现有的属性集合中。
例如,进行防窃漏电诊断建模时,已有的属性包括供入电量、供出电量(线路上各大用户用电量之和)。理论上供入电量和供出电量应该是相等的,但是由于在传输过程中存在电能损耗,使得供入电量略大于供出电量,如果该线路上的一个或多个大用户存在窃漏电行为,会使得供入电量明显大于供出电量。反过来,为了判断是否有大用户存在窃漏电行为,可以构造出一个新的指标——线损率,该过程就是构造属性。
2.5 小波变换
小波变换是一种新型的数据分析工具,是近年来兴起的信号分析手段。小波分析的理论和方法在信号处理、图像处理、语音处理、模式识别、量子物理等领域得到越来越广泛的应用,它被认为是近年来在工具及方法上的重大突破。
要讲小波变换,就不得不提到傅里叶变换,对傅里叶变换我们专门有一章具体介绍。简单地说,傅里叶变换就是用正弦波的组合来模拟信号,而小波变化则可以选择不同的基函数,这种灵活性是任何变换都无法比拟的。小波变换具有多分辨率的特点,在时域和频域都具有表征信号局部特征的能力,通过伸缩和平移等运算过程对信号进行多尺度聚焦分析,提供了一种非平稳信号的时域分析手段,可以由粗及细地逐步观察信号,从中提取有用信息。
更够刻画某个问题的特征量往往是隐含在一个信号中的某个或者某些分量中,小波变换可以把非平稳信号分解为表达不同层次、不同频段信息的数据序列,即小波系数。选取适当的小波系数,就可以完成信号的特征提取。下面介绍几种基于小波变换的信号特征提取方法。
- 基于小波变换的多尺度空间能量分布特征提取方法
各尺度空间内的平滑信号和细节信号能提供原始信号的时频局域信息,特别是能提供不同频段上信号的构成信息。把不同分解尺度上信号的能量求解出来,就可以将这些能量尺度顺序排列,形成特征向量供识别用。
- 基于小波变换的多尺度空间的模极大值特征提取方法
利用小波变换的信号局域化分析能力,求解小波变换的模极大值特性来检测信号的局部奇异性,将小波变换模极大值的尺度参数s,平移参数t及幅值作为目标的特征量。
- 基于小波包变换的特征提取方法
利用小波分解,可将时域随机信号序列映射为尺度域各子空间内的随机系数序列,按小波分解得到的最佳子空间内随机系数序列的不确定性程度最低,将最佳子空间的熵值及最佳子空间的完整二叉树中的位置参数作为特征量,可以用于目标识别。
- 基于适应性小波神经网络的特征提取方法
基于适应性小波神经网络的特征提取方法可以把信号通过分析小波拟合表示,进行特征提取。
在R语言中,我们可以用wavelim包中的dwt()函数进行小波分解
#数据生成,信号模拟
N=1024;k=6#参数赋值
x=((1:N)-N/2)*2*pi*k/N#采样
y=ifelse(x>0,sin(x),sin(3*x))#划分低频波动段和高频波动段
signal=y+rnorm(N)/10#添加干扰项,生成信号变量
#install.packages("waveslim")#安装软件包
library(waveslim)#调用软件包##
## waveslim: Wavelet Method for 1/2/3D Signals (version = 1.7.5)
d=dwt(signal,n.levels=4)#对信号进行小波分解,指定分解为4种波
dd=data.frame(d$d1,d$d2,d$d3,d$d4)
datatable(dd)输出便是模拟信号分解为4层后,各层小波系数的结果。
3 参考文献
[1]张良均. R语言数据分析与挖掘实战[M]. 机械工业出版社, 2015.
[2]李诗羽. 数据分析:R语言实战[M]. 电子工业出版社,2014.
-e1708135970882.png)