两个随机信号之间的相关性每次计算时都会发生变化。

4

我有两个MATLAB信号,例如

a = randn(1,1e6);
b = randn(1,1e6);

我正在寻找它们之间的相关性如下:

R=corrcoef(a,b);
r = R(2,1);

现在每次运行我的代码时,相关系数都是不同的。我甚至尝试增加样本数量(从1e6增加到更高的值),但这并没有起作用。是否有其他方法可以找到这些信号之间的相关系数?

3个回答

3
看起来你把样本相关系数和理论相关系数混淆了。前者是从模拟中生成的(随机)信号导致的随机值;后者是从信号生成过程的统计模型中计算出的数字
你在代码中计算的是样本相关系数,它取决于随机生成的实际信号(在你的代码中为ab)。这些信号是随机过程实现(在你的情况下是白色高斯过程,因为你使用randn)。
另一方面,理论相关系数由产生两个随机过程信号的随机过程的统计特性确定。因此,它不是通过模拟获得的(如在你的代码中),而是通过数学计算得出的。
您的情况中理论相关性为0,因为随机过程是独立的。请注意,我知道这一点是从代码中得到的(从您生成信号的方式),而不是从代码实际生成的值中得到的。这就是我所说的理论值的意思:它是根据您对实际信号生成方式的了解计算出来的。
样本相关性可以用作理论相关性的估计;随着信号大小的增加,该估计变得更加准确。这是大数定律。因此,您设置的样本大小越大(在您的代码中为1e6),结果(样本相关系数)就会越集中在0(理论相关系数)周围。
为了说明这一点,我进行了10组1000次模拟,每组使用不同的样本大小。因此,对于每个样本大小,我收集了1000个样本相关系数的不同值,并计算出一个直方图以查看这些值的分布情况。该图表证实随着样本量的增加,直方图变得更加狭窄(和更高),表明样本相关系数更集中在理论值0周围。

enter image description here


生成该图的代码(Matlab R2015b)如下:
S = 1e5:1e5:1e6; %// sample sizes
N = 1000; %// number of repetitions to generate histogram
binlimits = [-.015 .015]; %// set manually depending on S
B = 31; %// number of bins in the histogram
stretch = 7; %// stretch factor for plotting the histograms
result = NaN(numel(S),B); %// preallocate
for m = 1:numel(S)
    cc = NaN(1,S(m));
    for n = 1:N
        a = randn(1,S(m));
        b = randn(1,S(m));
        c = corrcoef(a,b);
        cc(n) = c(2,1); %// correlation coefficient
    end
    [hist, edges] = histcounts(cc,31,'BinLimits',binlimits,'Normalization','pdf');
    result(m,:) = hist; %// histogram of correlation coefficient for this sample size
end
bins = (edges(1:end-1) + edges(2:end))/2; %// axis for plotting the histograms
resultbar = NaN(numel(S)*stretch,B);
resultbar(1:stretch:end,:) = result; %// separate the histograms for better visualization
h = bar3(bins, resultbar.'); %'// plot histograms
set(gca,'xtick',1:stretch:numel(h),'xticklabels',S)
delete(h(mod(0:numel(h)-1,stretch)>0)) %// remove zeros
xlabel('Sample correlation coefficient')
ylabel('Sample size')

2
如果我可以换个角度解释一下:无论你采取什么样的样本容量,总会存在一个非零概率使得两个样本完全相关(相关系数在任何地方都为1),尽管当你的样本容量趋近于无穷大时,这种概率趋近于零。 - BillBokeey
1
你不能从数据中计算出理论相关性。两个随机变量X和Y之间的理论相关性定义为:Cor(X,Y)= Cov(X,Y)/(SDx * SDy)其中SDx(分别为SDy)是变量X(分别为Y)的标准偏差。在这里,你实际上可以计算出理论相关性,因为你的两个变量是独立的(正如@Luis Mendo在他的答案中所说),导致Cov(X,Y)= 0,这意味着你的理论相关性为0。 - BillBokeey
2
  1. 你会计算一个经验性的“插入术语”,而不是理论上的(请记住,如果你从数据中计算某些东西,你永远不会计算理论上的东西)。
  2. 相关不是用那种方式计算的,你必须使用正确的公式:(参见“样本相关系数”)。
- BillBokeey
1
非常好的解释@Luis Mendo和@BillBokeey!谢谢 :) - rmb
1
好问题。系数确实可以是复数,当它(是实数且)等于1时,最大相似度被实现。但对于系数的其他值,我不确定实部或模数更有意义。我通常采用模数(绝对值)。 - Luis Mendo
显示剩余4条评论

2

randn 的程序设计方式不会每次调用都生成相同的结果。如果您希望在每次调用脚本时为变量 ab 生成相同的随机数集,您需要通过设置随机生成器来告诉 Matlab。 我编写了一个名为 test 的小函数,并嵌套使用了函数 call_randn 来演示这一点。test 调用了随机生成器3次,你会发现它会为所有3次调用生成相同的 r。然而,每次您调用 test 这些数字都将是不同的。

%// test
function r = test()
    rng('default')  %// Initialise random generator.
    sa = rng;       %// Store current generator settings in sa.
    rng('shuffle')  %// Get new generator settings.
    sb = rng;       %// Store new generator settings in sb.
    n = 10;         %// Number of random numbers to be generated.

    for i = 1:3
        [a(i,1:n),b(i,1:n)] = call_randn(sa,sb,n);
        R=corrcoef(a,b);
        r(i) = R(2,1);
    end
end

function [a,b] = call_randn(sa,sb,n)
    rng(sa);         %// Load generator settings.
    a = randn(1,n);
    rng(sb);         
    b = randn(1,n);
end

1
你应该设置随机数生成器的种子,否则每次调用randn时都会得到不同的分布。 请查看randn。在其中一个示例中,随机状态被保存,并且每次调用randn时,先使用保存的随机状态设置随机状态,从而获得相同的分布:
s = rng;
r = randn(1,5)
r =
-0.0245   -1.9488    1.0205    0.8617    0.0012
rng(s);
r1 = randn(1,5)
r1 =
-0.0245   -1.9488    1.0205    0.8617    0.0012

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接