目前,大数据和人工智能在全国上下掀起一波浪潮,很多人都开始致力于这方面的研究。而绝大部分人的研究工作都集中在了数据挖掘的大算法的探讨上而忽视了对数据处理的研究。事实上,数据预处理对于数据挖掘是十分重要的,成熟的算法对于其处理的数据集合都会有一定的要求:比如数据的完整性好,冗余性小,属性的相关性小等。
数据预处理是数据挖掘的重要一环,而且必不可少。要使算法从大量的数据中挖掘出潜在的规律,必须为其提供干净,准确,简洁的数据。然而,实际应用系统中收集的数据通常是“脏”数据。这就需要我们在实现算法前对这些“脏”数据进行数据预处理。
数据预处理是指把采集的数据进行一系列的处理,通过删除、估计等方式完善一些缺失或者错误的信息,使得冗余、残缺的数据变得简洁、准确。通过某种方法将数据格式进行统一,使得各种复杂的、难以用机器算法处理的数据变成机器算法易于操作的数据。
数据预处理的方法有很多,常见的预处理方法有数据清洗、数据集成、数据变换、数据规约等。在本文中我们主要介绍数据清洗。数据清洗是将重复、多余的数据筛选清除,将缺失的数据补充完整,将错误的数据纠正或者删除,最后整理成为我们可以进一步加工、使用的数据。常见的数据清洗方法有空缺值处理、噪声数据处理以及不一致数据处理。空缺值是指由于人为的失误或者其他技术上的原因造成的缺失的数据,针对这样的缺失数据一般采取直接删除整条信息或者均值插补的方式来处理;噪声数据是指一些超出人们认知范围的或者与事实不符的数据,对于这样的数据通常直接删除;不一致数据是指数据形式和所需的形式不一致,对于这样的数据通常是通过人为的根据实际情况判断处理。
下面,我们来分享一个简单的数据预处理案例。
题目背景:本题目为我们提供了3个数据文件,每个数据文件为同一辆车在不同时间段内的实际道路行驶采集的数据(采样频率1Hz),数据样本如图1所示。
图1 原始数据样本
解决问题:
由汽车行驶数据的采集设备直接记录的原始采集数据往往会包含一些不良数据值,不良数据主要包括几个类型:
(1)由于高层建筑覆盖或过隧道等,GPS信号丢失,造成所提供数据中的时间不连续;
(2)汽车加、减速度异常的数据(普通轿车一般情况下:0至100km/h的加速时间大于7秒,紧急刹车最大减速度在7.5~8 m/s2);
(3)长时间堵车、断断续续低速行驶情况(最高车速小于10km/h),通常可按怠速情况处理。
(4)一般认为怠速时间超过180秒为异常情况,怠速最长时间可按180秒处理。
解决办法:
步骤一:将excel中的数据导入matlab;
步骤二:选取数据中的时间,速度列所在的数据来进行预处理:
(1)把时间信息统一转化秒,表中的数据为字符串形式,将所有数据转换成数值形式才方便后面的计算;
(2)运用相邻时间点做差,找出不连续的点。具体做法是将相邻的时间做差,差值为1便是连续点,差值大于1就是时间不连续的点。将所有时间不连续点的位置记录下来,为了下面数据预处理做准备;
(3)运用运动学公式,找出汽车加、减速度异常的数据删掉。由于汽车100km加速时间大于7秒便是异常,所以求出小于7秒到达100km/h的平均加速度的临界值(即100km/h除以7s所求出的平均加速度),再根据汽车时间和速度的数据求出该一小段时间(1s)的加速度,与临界值进行比较,来判断该点的数据是否为异常,异常数据就将其删掉;
(4)当速度小于10km/h按照怠速处理,即为0,就是将该时刻的速度变为0处理;
(5)怠速时长超过180秒,直接取前180秒处理,后面的速度为0,并且将速度为0的时间超过180秒的数据删掉。
问题求解:
图2为使用matlab对文件1中数据预处理完后的工作区,可以观察到许多参数的变化情况。
图2 文件1数据预处理后的工作区
在图2所示变量中:
a为将时间的字符串如:2017/12.06/12:45:34转换为数值时,存储每一个字符的ASCII表的所对应的数值的数组。与实际值会有一个固定的数值差距,将每一个数字所对应的数值减去48作为中间变量,每转换一个时间,就会更新一组新的数据;
time_v表示存储速度和时间这两维数据的矩阵,其中第一列存储的是时间,第二列存储的是同一行中对应时间点的速度;
acc为判断实际加速度是否异常的平均加速度临界值;
daisu数组中存储的是time_v中速度为0的值;
delta为daisu数组中每两行数据做差分后存储的结果;
differ存储的是每两行时间数值作差值存储的数据;
flag记录的就是由于GPS信号丢失的时间断点;
len为time_v的数组的长度,即数组的行数;
stop记录的是怠速时间大于180秒的数据所在的行数,作为异常数据的索引;
time_acc为计算的所有一小段时间的加速度;
x为导入到matlab中的所有数据;
xGPS为数据中的所有速度值;
xiao为time_v表的数据中所有速度小于10km/h的数据所在行值。
图3所示是文件1中数据经过上述处理后的变量time_v。
图3 文件1预处理后的数据情况
由图3可知,可以看到文件1的数据经上述处理后,还剩余174561个有效数据。
文件2和文件3的处理过程同文件1,这里就不再赘述。
这里只是介绍了一个简单的数据预处理案例,在实际的工程应用中有更多更复杂的数据预处理问题,其解决过程就要比这困难的多。当然,数据预处理的工具也有很多,除了使用matlab还有很多方便灵活的工具。这些就需要我们更多的去深入了解学习啦。
本文案例的预处理代码如下所示:
Code:
% 将日期转换为时间
[xhead]=xlsread('文件1.xlsx'); %读取表格x为数据head表头
xGPSv=x(:,1); %速度列
t=head(:,1); %时间列
time_len=size(t,1);
time=zeros(time_len,1);
for i=2:time_len
a=[double(t{i,1}(9)),double(t{i,1}(10)),double(t{i,1}(12)),double(t{i,1}(13)),double(t{i,1}(15)),double(t{i,1}(16)),double(t{i,1}(18)),double(t{i,1}(19))];
a=a-48;
time(i-1)=a(8)+a(7)*10+60*(a(6)+a(5)*10)+(a(4)+a(3)*10)*3600+(a(2)+a(1)*10)*24*3600;
end
time(time_len)=[];
%找出时间断点
differ=zeros(size(time,1)-1,1);
fori=1:size(time,1)-1
differ(i)=time(i+1)-time(i);
end
flag=find(differ~=1); %时间断点
% 将时间和速度项从原始数据中提出
time_v=zeros(size(time,1),2);
time_v(:,1)=time;
time_v(:,2)=xGPSv;
% 将加速度异常的数据去掉
acc=100/7/3.6;
while 1
time_v_diff=diff(time_v);
time_acc=time_v_diff(:,2)./time_v_diff(:,1);
location_acc=find(time_acc>acc |time_acc<-8);
acc_len=size(location_acc,1);
for i=acc_len:-1:1
time_v(location_acc(i,1)+1,:)=[];
end
if acc_len==0
break
end
end
time_v(:,1)=time_v(:,1)-time_v(1,1);
%将速度小于10的置零
xiao=find(time_v(:,2)<10/3.6);
time_v(xiao,2)=0;
% 将速度为0的时间超过180秒的按180秒处理
len=size(time_v,1);
stop=[];
med=0;
j=0;
for i=1:len
if time_v(i,2)==0
flag1=time_v(i,1);
for j=1:len-i
if time_v(i+j,2)==0
flag2_1=time_v(i+j,1);
if flag2_1-flag1>=180
for k=0:len-i-j
if time_v(i+j+k,2)==0
stop=[stop,i+j+k];
else
med=i+j+k+1;
break
end
end
end
else
i=i+j;
break
end
if med~=0
med=0;
i=i+j+k;
break
end
end
end
end