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

Correlation between two random signals changes each time it is calculated

我在 MATLAB 中有两个信号,比方说

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

我发现它们之间的相关性如下:

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

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

您似乎混淆了 样本 相关系数与 理论 相关系数。前者是一个随机值,由模拟中产生的(随机)信号产生;后者是一个数字,它是根据信号生成过程的统计模型计算得到的。

您在代码中计算的是 样本 相关系数,它取决于随机生成的实际信号(ab在你的代码中)。这些信号是 实现 随机过程 (白色高斯过程,在你的例子中,因为你使用 randn)。

另一方面,理论相关系数是由随机过程的统计特征决定的生成的两个随机过程的信号。所以它不是从模拟中获得的(如在您的代码中),而是通过数学计算得到的。

你的案例中的理论相关性是 0,因为随机过程是 独立的。请注意,我从代码(从如何你生成信号)知道这个,而不是从代码恰好生成的实际值。这就是我所说的理论值的意思:它是根据您对如何生成实际信号的了解计算得出的。

样本相关性可以作为和估计的理论相关性;随着信号大小的增加,该估计变得更好。这就是law of large numbers。所以,你设置的样本量越大(代码中的1e6),结果(样本相关系数)就会越集中在0(理论相关系数)附近。

为了说明这一点,我进行了 101000 模拟,每组具有不同的样本大小。因此,对于每个样本量,我收集 1000 个样本相关系数的不同值,并计算 直方图 以查看这些值的分布情况。该图证实,随着样本量的增加,直方图变得更窄(和更高),表明样本相关系数更集中在理论值 0 附近。


用于生成图(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')

您应该设置随机数生成器的种子,否则每次调用 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

randn 的编程方式使其每次调用时不会默认产生相同的结果。如果您想在每次调用脚本时为变量 ab 生成同一组随机数,则必须通过相应地设置随机生成器来告诉 Matlab。 我用嵌套函数 call_randn 编写了一个小函数 test 来说明这一点。 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