Je suis d'accord avec ce que d'autres ont dit - à savoir que "variance" est probablement le mauvais mot à utiliser (vu que la fonction que vous envisagez n'est pas une distribution de probabilité mais une série chronologique).
Je pense que vous voudrez peut-être aborder ce problème sous un angle différent - il suffit d'adapter les deux séries temporelles avec des courbes BASSE. Vous pouvez calculer des intervalles de confiance à 95% et commenter qualitativement leurs formes. Je ne suis pas sûr que vous ayez besoin de faire quelque chose de plus sophistiqué que cela.
J'ai écrit du code MATLAB ci-dessous pour illustrer ce que je dis. Je suis un peu pressé mais je pourrai bientôt apporter des clarifications. Une grande partie de ce que j'ai fait peut être prise directement à partir d'ici: http://blogs.mathworks.com/loren/2011/01/13/data-driven-fitting/
%% Generate Example data
npts = 200;
x = linspace(1,100,npts)';
y1 = (1e3*exp(-(x-25).^2/20) + 5e2*exp(-(x-65).^2/40));
y1_noisy = 50*randn(npts,1) + y1;
y2 = (1e3*exp(-(x-25).^2/60) + 5e2*exp(-(x-65).^2/100));
y2_noisy = 50*randn(npts,1) + y2;
figure; hold on
plot(x,y1_noisy,'ob')
plot(x,y2_noisy,'or')
title('raw data'); ylabel('count'); xlabel('time')
legend('y1','y2')
Vous voudrez peut-être normaliser les deux séries chronologiques pour comparer leurs tendances relatives plutôt que leurs niveaux absolus.
%% Normalize data sets
figure; hold on
Y1 = y1_noisy./norm(y1_noisy);
Y2 = y2_noisy./norm(y2_noisy);
plot(x,Y1,'ob')
plot(x,Y2,'or')
title('normalized data'); ylabel('normalized count'); xlabel('time')
legend('Y1','Y2')
Maintenant, faites des ajustements LOWESS ...
%% Make figure with lowess fits
figure; hold on
plot(x,Y1,'o','Color',[0.5 0.5 1])
plot(x,Y2,'o','Color',[1 0.5 0.5])
plot(x,mylowess([x,Y1],x,0.15),'-b','LineWidth',2)
plot(x,mylowess([x,Y2],x,0.15),'-r','LineWidth',2)
title('fit data'); ylabel('normalized count'); xlabel('time')
Enfin, vous pouvez créer des bandes de confiance à 95% comme suit:
%% Use Bootstrapping to determine 95% confidence bands
figure; hold on
plot(x,Y1,'o','Color',[0.75 0.75 1])
plot(x,Y2,'o','Color',[1 0.75 0.75])
f = @(xy) mylowess(xy,x,0.15);
yboot_1 = bootstrp(1000,f,[x,Y1])';
yboot_2 = bootstrp(1000,f,[x,Y2])';
meanloess(:,1) = mean(yboot_1,2);
meanloess(:,2) = mean(yboot_2,2);
upper(:,1) = quantile(yboot_1,0.975,2);
upper(:,2) = quantile(yboot_2,0.975,2);
lower(:,1) = quantile(yboot_1,0.025,2);
lower(:,2) = quantile(yboot_2,0.025,2);
plot(x,meanloess(:,1),'-b','LineWidth',2);
plot(x,meanloess(:,2),'-r','LineWidth',2);
plot(x,upper(:,1),':b');
plot(x,upper(:,2),':r');
plot(x,lower(:,1),':b');
plot(x,lower(:,2),':r');
title('fit data -- with confidence bands'); ylabel('normalized count'); xlabel('time')
Vous pouvez maintenant interpréter le chiffre final comme vous le souhaitez, et vous avez les ajustements LOWESS pour confirmer votre hypothèse selon laquelle les pics dans la courbe rouge sont en fait plus larges que la courbe bleue. Si vous avez une meilleure idée de la fonction, vous pouvez effectuer une régression non linéaire à la place.
Modifier: Sur la base de quelques commentaires utiles ci-dessous, j'ajoute plus de détails sur l'estimation explicite des largeurs de pic. Tout d'abord, vous devez trouver une définition de ce que vous considérez comme un «pic» en premier lieu. Peut-être n'importe quelle bosse qui dépasse un certain seuil (quelque chose comme 0,05 dans les parcelles que j'ai faites ci-dessus). Le principe de base est que vous devez trouver un moyen de séparer les pics "réels" ou "notables" du bruit.
Ensuite, pour chaque pic, vous pouvez mesurer sa largeur de deux manières. Comme je l'ai mentionné dans les commentaires ci-dessous, je pense qu'il est raisonnable de regarder la "demi-largeur maximale" mais vous pouvez également regarder le temps total pendant lequel le pic se situe au-dessus de votre seuil. Idéalement, vous devez utiliser plusieurs mesures différentes de la largeur du pic et indiquer dans quelle mesure vos résultats ont été cohérents avec ces choix.
Quelle que soit la ou les mesures de votre choix, vous pouvez utiliser le bootstrap pour calculer un intervalle de confiance pour chaque pic de chaque trace.
f = @(xy) mylowess(xy,x,0.15);
N_boot = 1000;
yboot_1 = bootstrp(N_boot,f,[x,Y1])';
yboot_2 = bootstrp(N_boot,f,[x,Y2])';
Ce code crée 1000 ajustements bootstrap pour les traces bleues et rouges dans les tracés ci-dessus. Un détail que je vais passer en revue est le choix du facteur de lissage 0,15 - vous pouvez choisir ce paramètre de telle sorte qu'il minimise l'erreur de validation croisée (voir le lien que j'ai publié). Il ne vous reste plus qu'à écrire une fonction qui isole les pics et estime leur largeur:
function [t_peaks,heights,widths] = getPeaks(t,Y)
%% Computes a list of times, heights, and widths, for each peak in a time series Y
%% (column vector) with associated time points t (column vector).
% The implementation of this function will be problem-specific...
Ensuite, vous exécutez ce code sur les 1000 courbes de chaque jeu de données et calculez les 2,5e et 97,5e centiles pour la largeur de chaque pic. Je vais illustrer cela sur la série temporelle Y1 - vous feriez de même pour la série temporelle Y2 ou tout autre ensemble de données d'intérêt.
N_peaks = 2; % two peaks in example data
t_peaks = nan(N_boot,N_peaks);
heights = nan(N_boot,N_peaks);
widths = nan(N_boot,N_peaks);
for aa = 1:N_boot
[t_peaks(aa,:),heights(aa,:),widths(aa,:)] = getPeaks(x,yboot_1(:,aa));
end
quantile(widths(:,1),[0.025 0.975]) % confidence interval for the width of first peak
quantile(widths(:,2),[0.025 0.975]) % same for second peak width
Si vous le souhaitez, vous pouvez effectuer des tests d'hypothèse plutôt que de calculer des intervalles de confiance. Notez que le code ci-dessus est simpliste - il suppose que chaque courbe inférieure amorcée aura 2 pics. Cette hypothèse n'est pas toujours valable, alors soyez prudent. J'essaie simplement d'illustrer l'approche que j'adopterais.
Remarque: la fonction "mylowess" est donnée dans le lien que j'ai posté ci-dessus. Voilà à quoi ça ressemble ...
function ys=mylowess(xy,xs,span)
%MYLOWESS Lowess smoothing, preserving x values
% YS=MYLOWESS(XY,XS) returns the smoothed version of the x/y data in the
% two-column matrix XY, but evaluates the smooth at XS and returns the
% smoothed values in YS. Any values outside the range of XY are taken to
% be equal to the closest values.
if nargin<3 || isempty(span)
span = .3;
end
% Sort and get smoothed version of xy data
xy = sortrows(xy);
x1 = xy(:,1);
y1 = xy(:,2);
ys1 = smooth(x1,y1,span,'loess');
% Remove repeats so we can interpolate
t = diff(x1)==0;
x1(t)=[]; ys1(t) = [];
% Interpolate to evaluate this at the xs values
ys = interp1(x1,ys1,xs,'linear',NaN);
% Some of the original points may have x values outside the range of the
% resampled data. Those are now NaN because we could not interpolate them.
% Replace NaN by the closest smoothed value. This amounts to extending the
% smooth curve using a horizontal line.
if any(isnan(ys))
ys(xs<x1(1)) = ys1(1);
ys(xs>x1(end)) = ys1(end);
end