用matlab代码进行数据探索、数据清洗学习笔记

1.说明

  1. 该学习笔记仅供个人学习使用,不代表任何官方指导或意见。
  2. 该学习笔记为个人原创,转载请征得博主同意,或声明原文链接。
  3. 有需要其他资料或有其他问题可私信或者加qq2356081476,这不是我的义务但也欢迎各位朋友与我讨论相关问题,共同进步。
  4. 错字,语法,排版等问题请见谅。
  5. 作者用的matlab软件是MATLAB R2018b
  6. 数据特征分析在一定程度上包括在已写的代码里面,所以暂时不作板块做笔记了,有需求会在之后记出来。

2.作文目的

继上一篇数据探索、数据清洗学习笔记,在这里用matlab代码将各个步骤表示出来。同样的,代码源可能在各大网站(如CSDN、mathwork官网、知乎、知网、百度)所查资料较为松散,故作此学习笔记以适用个人学习及复习。

3.数据质量分析3个判别方法

3-1.异常值判别

3-1-1.箱型图法

matlab的函数:boxplot(x)
其中x是你要输入的数据的矩阵。
如果x是向量(横或列),都直接自动将其排序然后画出箱型图。

x = [1 2 3 4 5 6]; % 或者列向量   x = [1;2;3;4;5;6]
                   % 或者打乱顺序 x = [1 3 2 6 4 5]
boxplot(x)

结果如下
在这里插入图片描述

如果x是矩阵,设为 m × n m \times n m×n的矩阵,那么将自动对每一列进行画箱型图的操作。(第一列如上画出一个箱型图,第二列如上画出一个箱型图,一直到第n列)

x = randn(100,25); % 随机产生100*25的矩阵,之后将画出25个箱型图。
                   % 每个箱型图是100个数据作的。
boxplot(x) 

结果如下
在这里插入图片描述

注:可以在marlab软件里面的figure界面里面点击查看上下四分位、异常值的具体信息。

红色十字为异常值,第一个图没有异常值。第二个图第一列100个数据有3个异常值,第二列100个数据没有异常值。(因为使用的是randn生成随机数,所以你们自己使用结果会和我的不一样)

那怎么得到箱型图中的异常值呢?boxplot的输出又是什么?
这个我也没有找到,太难了,希望有朋友告知,之后知道了我会补充。
(相当于好像前面都白记了一样)
但是知道箱型图的原理了就有其他代码的方法得到异常值如下:

x = [1 2 3 4 5 6 100]

Q3 = prctile(x,75) % prctile函数得到x的分位数,75代表百分之75的位置也就是上四分位。

Q1 = prctile(x,25) % 同理,25代表百分之25,下四分位。

IQR = Q3-Q1; 	   % 全称interquartile range,四分位距

y = find(x>Q3+1.5*IQR | x<Q1-1.5*IQR) % y将得到异常值点的索引,此列为7
                                      % 如果有多个异常值,y将是一个向量
                                      % 包含所有异常值的索引。

这样,y就是我们要找的异常值的索引,接下来就是去除异常值(数据清洗)的步骤了。

3-1-2.3σ准(原)则(拉依达准则)

注意使用条件:数据服从于正态分布。
如果不满足此条件结果未必可信。

现在我们假设有666个数据。

x = normrnd(10,2,[1,666])		    % normrnd函数生成以10为均值,2为标准差。			  
			  		    % 1×666的正太随机数据。
mu = mean(x);				    % mu表示x的均值
sigma = std(x);		 	 	    % sigma表示x的标准差
y = [];			 		    % y用于存储最终异常值的索引

subplot(2,1,1);plot(linspace(1,666,666),x); % 画出x的曲线
subplot(2,1,2);boxplot(x);		    % 画出箱型图(便以作对比)

for i = 1:666    			    % 此循环过后y将得到异常值索引
	if abs(x(i)-mu)>3*sigma       	    % 3σ准则判断标准
 		y = [y,i];    
	 end
 end
 y	

结果如下:
在这里插入图片描述

同前面,你们自己使用结果会和我的不一样。

此处用3σ准则所得y有68,180,313三个值,分别对应了箱型图的下面两个加号和上面的最上面那个加号(箱型图里面点击加号可以查看详细信息,这里我就不截图了)。

在曲线图中也可以看到这三个值就是三个非常突出的值,也就是异常值。但是箱型图值中上面还有几个异常值我们来具体看一下。
在这里插入图片描述

下面的箱型图我放大了,597与601相差非常小(值相差,不是索引相差),分别是15.4609和15.4585,在曲线图我用绿圈标识了。

其实这里也可以一定程度的看出来,箱型图比拉依达 “更加精确” 的找出了异常值。

3-2.缺失值判别

有两个函数判别是否缺失(判别是否是nan值),ismissing和isnan
如果是nan值返回1,不是nan值返回0。

有时候数据为0时是缺失值,后面会作笔记。

% 以下设想x为1到100的顺序数据,任意10个缺失,缺失值为nan。
x = linspace(1,100,100);
y = randi(100,1,10); 	 % y是x中将要作为nan值的索引。
x(y) = nan; 		 % 将索引为y的地方设为nan值。
z = isnan(x);		 % 用ismissing(x)结果是一样的。
z

上述z是与x规格相同的矩阵,x中是nan值的z中为1,x中不是nan值的z中为0

% 以下设想x为1到100的顺序数据,任意10个缺失,缺失值为0。

x = linspace(1,100,100);
y = randi(100,1,10);   % y是x中将要作为nan值的索引。
x(y) = 0;    	       % 将索引为y的地方设为0值。
z = [];

for i = 1:100
	if x(i) == 0
		z = [z,1];
	elseif x(i) ~= 0
		z = [z,0];
	end
end
z

上述z是与x规格相同的矩阵,x中是0值的z中为1,x中不是0值的z中为0

3-3.不一致的值判别

对于给定的本应完全一致两个数据集,判别出不一致的地方。

data1 = [1 2 3 4 5 6 7 8 9 10];		% 假设data1和data2是本应相同的数据集
data2 = [1 2 2 3 4 6 7 8 9 10];
size = numel(data1) 	       		% 求data1的元素个数
y = [];			       		% y最终存储不一致的值索引
for i = 1:size
	if data1(i) ~= data2(i)
		y = [y,i];
	end
end
y

4.数据清洗的几种方法

通过上面所述的几个判别方法把异常值、缺失值、不一致的值的 索引 都存储在了名为 y 的矩阵上,下面将通过几种方法来清洗(改善)。

注:清洗一个数据后要重新进行数据质量分析,以下为了简便,将所有脏数据一次性清洗了。

4-1.删除

  • 如果删除nan值,matlab提供一个简单的函数rmmissing
A = [nan 1 nan 2 3 1 4 5 nan 6 7 nan nan 7];
y = rmmissing(A)

%以下是命令行窗口的输出
y = 
	1     2     3     1     4     5     6     7     7
  • 如果删除异常值,其他缺失值、不一致的值
A = linspace(1,100,100);	
y = [21 59 100];			% 假设y是上面求得的索引
for i = 1:numel(y)
		A(y(i)-i+1) = [];	% 为什么-i+1,解释在下面
A

为什么-i+1?
每删除一个元素后,后面的元素会向前移动一个元素的位置。21删除后,59不在59上了,而在58上,所以-i+1就是-1(此时i=2),删除100这时是100-i+1也就是-2(此时i=3)

4-2.均值替补填充以及其他简单替补填充

  • 如果填充nan值,matlab提供一个很方便的函数fillmissing
    mathwork官网有此函数的详细说明,想看点这里
    下面我简单记一下我觉得重要的部分:
  1. F = fillmissing(A,‘constant’,v) 使用常量值 v 填充缺失的数组或表条目。如果 A 是矩阵或多维数组,则 v 可以是标量或向量。如果 v 是向量,每个元素指定 A 对应列中的填充值。
  2. F = fillmissing(A,method) 使用 method 指定的方法填充缺失的条目,该方法可能是下列各项之一:
  • ‘previous’ - 上一个非缺失值
  • ‘next’ - 下一个非缺失值
  • ‘nearest’ - 距离最近的非缺失值
  • ‘linear’ - 相邻非缺失值的线性插值(仅限数值、duration 和 datetime 数据类型)
  • ‘spline’ - 分段三次样条插值(仅限数值、duration 和 datetime 数据类型)
  • ‘pchip’ - 保形分段三次样条插值(仅限数值、duration 和 datetime 数据类型)
  1. F = fillmissing(A,movmethod,window) 使用窗口长度为 window 的移动窗口均值或中位数填充缺失条目。
    例如
    fillmissing(A,‘movmean’,5) 使用窗口长度为 5 的移动均值替换 A 中的 NaN 值,并绘制原始数据和填充的数据。
    fillmissing(A,‘movmedian’,10)使用窗口长度为 10 的移动中位数替换 A 中的 NaN 值,并绘制原始数据和填充的数据。
  2. F = fillmissing(___,dim) 指定要沿其进行运算的 A 的维度。默认情况下,fillmissing 沿其大小不为 1 的第一个维度进行运算。
    例如
    如果 A 是矩阵,则 fillmissing(A,2) 跨 A 的各列进行运算,逐行填充缺失的数据。
  3. F = fillmissing(___,Name,Value) 使用一个或多个名称-值对组参数指定用于填充缺失值的其他参数。
    例如
    如果 t 是时间值向量,则 fillmissing(A,‘linear’,‘SamplePoints’,t) 会基于 t 中的时间值对 A 中的数据进行插值。
  4. [F,TF] =fillmissing(___) 还会返回对应于填充的 A 条目的逻辑数组。
  • 如果替补填充异常值,其他缺失值、不一致的值
% 以下举出几个可以用来替补填充的值

a = [5 4 4 3 2 1 0];		% a是我们的数据集
mina = min(a);			% min函数求最小值
maxa = max(a); 			% max函数求最大值
mu = mean(a);			% mean函数求均值
%mu = nanmean(a); 		% 当a中含有nan值时用nanmean函数求均值
sigma = std(a);			% std函数求标准差
%sigma = nanstd(a)		% 当a中含有nan值时用nanstd函数求标准差
sigmafang = cov(a); 		% cov函数求方差
sigmafang = var(a);		% var函数与cov函数一样求方差
%sigmafang = nancov(a)		% 同理有nan值用nancov和nanvar
median = prctile(a,50);		% prctile函数求百分位数
modea = mode(a);		% mode函数求众数

由于前面我们已经知道了要替补的地方(索引),所以替换很简单如下了:

A = linspace(1,100,100);	
A(29) = nan; 				% 假设数据有nan值未去除
y = [21 59 100];			% 假设y是索引
mu = nanmean(A);
A(y) = mu;

4-3.k最近邻算法

沿用上面的一段代码,假设我们用k最近邻算法去除nan值

A = linspace(1,100,100); A(29) = nan; 	% 我们用nan值替换29,看能不能求出来29
y = 29;					% y是nan值的索引
k = 4;				        % nan左边四个右边四个
sum = 0;				% sum用来求距离k内的数据和
for i = 1:k	
	sum = sum + A(y+i) + A(y-i);
end
A(y) = sum/(2*k);
A(y)					% 可以得结果是29

因为上面A数据是1到100的顺序整数,难免有些巧合。下面我们用数学上的正弦函数sin看能不能求得原数据。

A = [0:(1/64)*pi:2*pi];		% 生成0-2π的数
x = A;
[rowA,columnA] = size(A)	% columnA求得A的列
plot(A,sin(A),'.')		% 画出sin函数图像
y = [21 59 columnA]; 		% 这次我们多加几个nan值,其中一个nan值放在最后
[rowy,columny] = size(y)	% columny求得y的列
A
A(y) = nan;
A
plot(A,sin(A),'r.');            % 画出有缺失值的sin函数图像,r代表红色
k = 4;       
for j = 1:columny
    sum = 0;
    count = 0; 			% 用count代替最终求平均数时的k,
    for i = 1:k			% 因为当越界时我们除以k会多除
        if y(j)+i <= columnA && y(j)-i >= 1    % 用if循环判断越界情况
           sum = sum + A(y(j)+i) + A(y(j)-i);  
           count = count + 2;
        elseif y(j)+i > columnA && y(j)-i >= 1
           sum = sum + A(y(j)-i);
           count = count + 1;	
        elseif y(j)+i <= columnA && y(j)-i < 1    
           sum = sum + A(y(j)+i);          
           count = count + 1;       
        end    
    end    
    A(y(j)) = sum/count;
end
A
hold on;
plot(x(y),sin(A(y)),'k.')       % 在原红色有缺图像中用黑色补出我们求出的值

结果如下截图:
在这里插入图片描述

可看到,前面两个符合得很好,但是最后一个不理想。
究其原因,可知因为我们算的是它前面四个值的平均值。没有算它右边的四个值(毕竟我们没有给出)
由此可得k最近邻算法的一些优缺点:

  • 对于边缘值不宜使用此方法。
  • 对于随机性较强的数据不宜使用此方法。(函数关系、近似关系使用此方法较好)

下面图片来源于mathwork官网fillmissing示例
红色表示填补的缺失值。
在这里插入图片描述

4-4.回归

前面一篇文章(这里可以看)所作的关于回归的笔记定义介绍可能有些错误,我下一篇专门作回归的笔记,包括matlab代码的。

  • 42
    点赞
  • 300
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值