网站首页  |  幼儿教育  |  中小学教育  |  电脑教育  |  英语教育  |  教育论文  |  家长教育 设为首页加入收藏联系投稿 
 位置: 中国教育学习网 > 电脑教育 > 机械电子 > MATLAB > 正文

数据分析和统计

字号:   

面向列的数据集

  这年头似乎十分风行”面向”这个词,这儿故也套用,其英文为"Column-Oriented Data Sets",可理解为MatLab按列的存储方式来分析数据,下面是一个例子: 

Time   Location 1   Location 2   Location 3
01h00    11        11       9
02h00    7        13       11
03h00    14        17       20
04h00    11        13       9
05h00    43        51       69
06h00    38        46       76
07h00    61        132      186
08h00    75        135      180
09h00    38        88       115
10h00    28        36       55
11h00    12        12       14
12h00    18        27       30
13h00    18        19       29
14h00    17        15       18
15h00    19        36       48
16h00    32        47       10
17h00    42        65       92
18h00    57        66       151
19h00    44        55       90
20h00    114       145       257
21h00    35        58       68
22h00    11        12       15
23h00    13        9       15
24h00    10        9        7

以上数据被保存在一个称为count.dat的文件中.

11 11 9
7 13 11
14 17 20
11 13 9
43 51 69
38 46 76
61 132 186
75 135 180
38 88 115
28 36 55
12 12 14
18 27 30
18 19 29
17 15 18
19 36 48
32 47 10
42 65 92
57 66 151
44 55 90
114 145 257
35 58 68
11 12 15
13 9 15
10 9 7

下面,我们调入此文件,并看看文件的一些参数

load count.dat
[n,p] = size(count)
n =
  24
p =
  3

创建一个时间轴后,我们可以把图画出来:

t = 1:n;
set(0,'defaultaxeslinestyleorder’,’-|--|-.’)
set(0,'defaultaxescolororder’,[0 0 0])
plot(t,count), legend('Location 1','Location 2','Location 3',0)
xlabel('Time'), ylabel('Vehicle Count'), grid on

数据分析和统计

足以证明,以上是对3个对象的24次观测.

基本数据分析函数

(一定注意是面向列的)

继续用上面的数据,其每列最大值.均值.及偏差分别为:

mx = max(count)
mu = mean(count)
sigma = std(count)
mx =
  114   145   257
mu =
  32.0000   46.5417   65.5833
sigma =
   25.3703   41.4057   68.0281

重载函数,还可以定位出最大.最小值的位置

[mx,indx] = min(count)
mx =
  7   9   7
indx =
  2   23   24

试试看,你能看懂下面的命令是干什么的吗?

[n,p] = size(count)
e = ones(n,1)
x = count – e*mu

点这看看答案!

下面这句命令则找出了整个矩阵的最小值:

min(count(:))
ans =
   7

协方差及相关系数

下面,我们来看看第一列的方差:

cov(count(:,1))
ans =
   643.6522

cov()函数作用于矩阵,则会计算其协方差矩阵.

corrcoef()用于计算相关系数,如:

corrcoef(count)
ans =
  1.0000 0.9331 0.9599
  0.9331 1.0000 0.9553
  0.9599 0.9553 1.0000

数据的预处理

未知数据

NaN(Not a Number--不是一个数)被定义为未经定义的算式的结果,如 0/0.在处理数据中,NaN常用来表示未知数据或未能获得的数据.所有与NaN有关的运算其结果都是NaN.

a = magic(3);
a(2,2) = NaN
a =
  8  1  6
  3  NaN 7
  4  9  2
sum(a)
ans =
  15  NaN 15

在做统计时,常需要将NaN转化为可计算的数字或去掉,以下是几种方法:
注:判断一个值是否为NaN,只能用 isnan(),而不可用 x==NaN;

i = find( ~ isnan(x));
x = x(i) 先找出值不是NaN的项的下标,将这些元素保留 x = x(find( ~ isnan(x))) 同上,去掉NaN x = x( ~ isnan(x)); 更快的做法 x(isnan(x)) = []; 消掉NaN X(any(isnan(X)’),:) = []; 把含有NaN的行都去掉

用此法可以从数据中去掉不相关的数据,看看下面的命令是干什么用的:

mu = mean(count);
sigma = std(count);
[n,p] = size(count)
outliers = abs(count — mu(ones(n, 1),:)) > 3*sigma(ones(n, 1),:);
nout = sum(outliers)
nout =
   1  0  0
count(any(outliers'),:) = [];

点这看看答案

回归与曲线拟合

  我们经常需要把观测到的数据表达为函数,假如有如下的对时间的观测:

t = [0 .3 .8 1.1 1.6 2.3]’;
y = [0.5 0.82 1.14 1.25 1.35 1.40]’;
plot(t,y,’o’),
grid on

数据分析和统计

多项式回归

由图可以看出应该可以用多项式来表达:y=a0+a1*t+a2*t^2
系数a0,a1,a2可以由最小平方拟合来确定,这一步可由反除号"\"来完成
解下面的三元方程组可得:

X = [ones(size(t)) t t.^2]
X =
  1.0000  0    0
  1.0000  0.3000  0.0900
  1.0000  0.8000  0.6400
  1.0000  1.1000  1.2100
  1.0000  1.6000  2.5600
  1.0000  2.3000  5.2900
a = X\y
a =
   0.5318  0.9191  –0.2387

a即为待求的系数,画图比较可得

T = (0:0.1:2.5)’;
Y = [ones(size(T)) T T.^2]*a;
plot(T,Y,'–',t,y,'o',), grid on

数据分析和统计

结果令人失望,但我们可以增加阶数来提高精确度,但更明智的选择是用别的方法.

线性参数回归

形如:y=a0+a1*exp(-t)+a2*t*exp(-t)
计算方法同上:

X = [ones(size(t)) exp(– t) t.*exp(– t)];
a = X\y
a =
   1.3974 – 0.8988 0.4097
T = (0:0.1:2.5)';
Y = [ones(size(T)) exp(– T) T.exp(– T)]*a;
plot(T,Y,'–',t,y,'o'), grid on

数据分析和统计

看起来是不是好多了!

例子研究:曲线拟合

  下面我们以美国人口普查的数据来研究一下有关曲线拟合的问题(MatLab是别人的,教学文档是别人的,例子也是别人的,我只是一个翻译而已...)

load census

这样我们得到了两个变量,cdate是1790至1990年的时间列向量(10年一次),pop是相应人口数列向量.

上一小节所讲的多项式拟合可以用函数polyfit()来完成,数字指明了阶数

p = polyfit(cdate,pop,4)
  Warning: Matrix is close to singular or badly scaled.
  Results may be inaccurate. RCOND = 5.429790e–20
p =
  1.0e+05 *
  0.0000 –0.0000 0.0000 –0.0126 6.0020

产生警告的原因是计算中的cdata值太大,在计算中的Vandermonde行列式使变换产生了问题,解决的方法之一是使数据标准化.

预处理:标准化数据

数据的标准化是对数据进行缩放,以使以后的计算能更加精确,一种方法是使之成为0均值:

sdate = (cdate – mean(cdate))./std(cdate)

现在再进行曲线拟合就没事了!

p = polyfit(sdate,pop,4)
p =
0.7047 0.9210 23.4706 73.8598 62.2285
pop4 = polyval(p,sdate);
plot(cdate,pop4,'–',cdate,pop,'+'), grid on

数据分析和统计

在上面的数据标准化中,也可以有别的算法,如令1790年的人口数为0.

余量分析

p1 = polyfit(sdate,pop,1);
pop1 = polyval(p1,sdate);
plot(cdate,pop1,'–',cdate,pop,'+')
数据分析和统计

res1 = pop – pop1;
figure, plot(cdate,res1,'+')
数据分析和统计

p = polyfit(sdate,pop,2);
pop2 = polyval(p,sdate);
plot(cdate,pop2,'–',cdate,pop,'+')
数据分析和统计

res2 = pop – pop2;
figure, plot(cdate,res2,’+’)
数据分析和统计

p = polyfit(sdate,pop,4);
pop4 = polyval(p,sdate);
plot(cdate,pop4,'–',cdate,pop,'+')
数据分析和统计

res4 = pop – pop4;
figure, plot(cdate,res4,'+')
数据分析和统计

  可以看出,多项式拟合即使提高了阶次也无法达到令人满意的结果

指数拟合

  从人口增长图可以发现人数的增长基本是呈指数增加的,因此我们可以用年份的对数来进行拟合,这儿,年数是标准化后的!

logp1 = polyfit(sdate,log10(pop),1);
logpred1 = 10.^polyval(logp1,sdate);
semilogy(cdate,logpred1,'–',cdate,pop,'+');
grid on

数据分析和统计

logres2 = log10(pop) –polyval(logp2,sdate);
plot(cdate,logres2,'+')

数据分析和统计

上面的图不令人满意,下面,我们用二阶的对数分析:

logp2 = polyfit(sdate,log10(pop),2);
logpred2 = 10.^polyval(logp2,sdate);
semilogy(cdate,logpred2,'–',cdate,pop,'+');
grid on

数据分析和统计

r = pop – 10.^(polyval(logp2,sdate));
plot(cdate,r,'+')

数据分析和统计

这种余量分析比多项式拟合的余量分析图案要随机的多(没有很强的规律性),可以预见,随着人数的增加,余粮所反映的不确定度也在增加,但总的说来,这种拟合方式要强好多!

误差边界

误差边界常用来反映你所用的拟合方式是否适用于数据,为得到误差边界,只需在polyfit()中传递第二个参数,并将其送入polyval().
下面是一个二阶多项式拟合模型,年份已被标准化,下面的代码用了2σ,对应于95%的可置信度:

[p2,S2] = polyfit(sdate,pop,2);
[pop2,del2] = polyval(p2,sdate,S2);
plot(cdate,pop,'+',cdate,pop2,'g–',cdate,pop2+2*del2,'r:',... cdate,pop2–2*del2,'r:'),
grid on

数据分析和统计

 

差分方程和滤波

  MatLab中的差分和滤波基本都是对向量而言的,向量则是存储取样信号或序列的.
  函数y = filter(b, a, x)将用a,b描述的滤波器处理向量x,然后将其存储在向量y中,
  filter()函数可看为是一差分方程a1y(n)=b1*x(1)+b2*x(2)+...-a2*y(2)-...
  如有以下差分方程:y(n)=1/4*x(n)+1/4*x(n-1)+1/4*x(n-2)+1/4*x(n-3),则

a = 1;
b = [1/4 1/4 1/4 1/4];

我们载入数据,取其第一列,并计算有:

load count.dat
x = count(:,1);
y = filter(b,a,x);
t = 1:length(x);
plot(t,x,'–.',t,y,'–'),
grid on
legend('Original Data','Smoothed Data',2)

数据分析和统计

实现所表示的就是滤波后的数据,它代表了4小时的平均车流量
MatLab的信号处理工具箱中提供了很多用来滤波的函数,可用来处理实际问题!

快速傅立叶变换(FFT)

傅立叶变换能把信号按正弦展开成不同的频率值,对于取样信号,用的是离散傅立叶变换.
FFT是离散傅立叶变换的一种高速算法,在信号和图像处理中有极大的用处!

fft 离散傅立叶变换 fft2 二维离散傅立叶变换 fftn n维离散傅立叶变换 ifft 离散傅立叶反变换 ifft2 二维离散傅立叶反变换 ifftn n维离散傅立叶反变换 abs 幅度 angle 相角 unwrap 相位按弧度展开,大于π的变换为2π的补角 fftshift 把零队列移至功率谱中央 cplxpair 把数据排成复数对 nextpow2 下两个更高的功率

向量x的FFT可以这样求:

x = [4 3 7 –9 1 0 0 0]’
y = fft(x)
y =
  6.0000
  11.4853 –2.7574i
 –2.0000  –12.0000i
 –5.4853  +11.2426i
  18.0000
 –5.4853  –11.2426i
 –2.0000  +12.0000i
  11.4853  +2.7574i

x虽然是实数,但y是复数,其中,第一个是因为它是常数相加的结果,第五个则对应于奈奎斯特频率,后三个数是由于负频率的影响,它们是前面三个数的共轭值!

下面,让我们来验证一下太阳黑子活动周期是11年!Wolfer数记录了300年太阳黑子的数量及大小:

load sunspot.dat
year = sunspot(:,1);
wolfer = sunspot(:,2);
plot(year,wolfer)
title(’Sunspot Data’)

数据分析和统计

现在来看看其FFT:

Y = fft(wolfer);

Y的幅度是功率谱,画出功率谱和频率的对应关系就得出了周期图,去掉第一点,因为他只是所有数据的和,画图有:

N = length(Y);
Y(1) = [];
power = abs(Y(1:N/2)).^2;
nyquist = 1/2;
freq = (1:N/2)/(N/2)*nyquist;
plot(freq,power),
grid on
xlabel(’cycles/year’)
title(’Periodogram’)

数据分析和统计

上面的图看起来不大方便,下面我们画出频谱-周期图

period = 1./freq;
plot(period,power),
axis([0 40 0 2e7]),
grid on
ylabel(’Power’)
xlabel(’Period(Years/Cycle)’)

数据分析和统计

为了得出精确一点的解,如下:

[mp index] = max(power);
period(index)
ans =
   11.0769

变换后的幅度和相位

abs()和angle()是用来计算幅度和相位的

先创建一信号,再进行分析,unwarp()把相位大于π的变换为2π的补角:

t = 0:1/99:1;
x = sin(2*pi*15*t) + sin(2*pi*40*t);
y = fft(x);
m = abs(y);
p = unwrap(angle(y));
f = (0:length(y)–1)'*99/length(y);
subplot(2,1,1), plot(f,m),
ylabel('Abs. Magnitude'), grid on
subplot(2,1,2), plot(f,p*180/pi)
ylabel('Phase [Degrees]'), grid on
xlabel('Frequency [Hertz]')

数据分析和统计

可以发现幅度曲线关于奈奎斯特频率对称,只有0-50Hz的信息是有用的!

FFT的长度与速度

可以为FFT加上第二个参数,告诉MatLab这是n点FFT.如y = fft(x,n),若x长度大于n,软件自动补0,否则截取x.

若:

1. n为2的幂,软件将执行基2快速傅立叶算法,这时的运算速度是最快的
2. n为合数,软件将n分解为素数来算,计算量与n的值有关.n为1013将比1000点的速度慢的多!
3. n为素数,软件执行DFT的公式,此时最慢!

收藏此文  |  打印  

 
  • 上一篇教程:

  • 下一篇教程:

  •   GoogLe
     
      最新推荐
  • 此栏目下没有推荐教程

  •   最近更新

      GoogLe

     
    Powered by Cn-Education.Com (c) 2005-2008 中国教育学习网 教育网站长QQ交流群60041790
    设为首页  |  加入收藏  |  版权申明  |  广告服务  |  联系我们  |  友情链接  |  网站地图  |  返回顶部 ↑