2017-07-17 2 views
3

J'ai 2 vecteurs A et B, chacun de longueur 10 000. Pour chacun de ind=1:10000, je veux calculer la corrélation de Pearson de A(1:ind) et B(1:ind). Quand je fais cela dans une boucle for, cela prend trop de temps. Parfor ne fonctionne pas avec plus de 2 travailleurs dans ma machine. Y at-il un moyen de faire cette opération rapide et enregistrer les résultats dans un vecteur C (apparemment de longueur 10.000 où le premier élément est NaN)? J'ai trouvé la question Fast rolling correlation in Matlab, mais c'est un peu différent de ce dont j'ai besoin.MATLAB: Calcul de corrélation rapide pour tous les indices dans 2 vecteurs

Répondre

2

Vous pouvez utiliser cette méthode pour calculer le coefficient de corrélation cumulative:

function result = cumcor(x,y) 
    n = reshape(1:numel(x),size(x)); 
    sumx = cumsum(x); 
    sumy = cumsum(y); 
    sumx2 = cumsum(x.^2); 
    sumy2 = cumsum(y.^2); 
    sumxy = cumsum(x.*y); 
    result = (n.*sumxy-sumx.*sumy)./(sqrt((sumx.^2-n.*sumx2).*(sumy.^2-n.*sumy2))); 
end 
1

Solution

Je suggère l'approche suivante:

  1. corrélation de Pearson peut être calculé en utilisant the following formula: enter image description here

  2. calculer la moyenne accumulative de chacun des variabiles aléatoires ci-dessus efficacement est facilement facile (X, Y, XY, X^2, Y^2).

  3. donné la moyenne cumulative calculée en 2, on peut calculer la accumulative std de X et Y.

  4. compte tenu de la accumulative std de X, Y et accumulative moyenne ci-dessus, on peut calculer le coefficient de Pearson accumulatif.

code

%defines inputs 
N = 10000; 
X = rand(N,1); 
Y = rand(N,1); 

%calculates accumolative mean for X, Y, X^2, Y^2, XY 
EX = accumMean(X); 
EY = accumMean(Y); 
EX2 = accumMean(X.^2); 
EY2 = accumMean(Y.^2); 
EXY = accumMean(X.*Y); 

%calculates accumolative pearson correlation 
accumPearson = zeros(N,1); 
for ii=2:N 
    stdX = (EX2(ii)-EX(ii)^2).^0.5; 
    stdY = (EY2(ii)-EY(ii)^2).^0.5; 
    accumPearson(ii) = (EXY(ii)-EX(ii)*EY(ii))/(stdX*stdY); 
end 

%accumulative mean function, to be defined in an additional m file. 
function [ accumMean ] = accumMean(vec) 
accumMean = zeros(size(vec)); 
accumMean(1) = vec(1); 
for ii=2:length(vec) 
    accumMean(ii) = (accumMean(ii-1)*(ii-1) +vec(ii))/ii; 
end 

end 

Durée

pour N = 10 000:

Elapsed time is 0.002096 seconds. 

pour N = 1000000:

Elapsed time is 0.240669 seconds. 

Correctness

Test de l'exactitude du code ci-dessus pourrait être fait par calculatoire le coefficient accumulative pearson par fonction Corr, et en le comparant au résultat donné du code ci-dessus:

%ground truth for correctness comparison 
gt = zeros(N,1) 
for z=1:N 
    gt(z) = corr(X(1:z),Y(1:z)); 
end 

Malheureusement, je n'ai pas la boîte à outils Statistiques et Machine Learning, donc je ne peux pas faire cette vérification. Je pense que c'est un bon point de départ bien, et vous pouvez continuer d'ici :)