同じ種の地理的に隔離された2つの個体群を調べています。分布を調べると、両方が二峰性であることがわかります(発生にはある程度の季節性があります)が、1つの母集団のピークははるかに高く、非常に狭い(つまり、局所的なピークの分散は小さい)。
これらの違いが有意かどうかを判断するには、どのような統計的検定が適切でしょうか?
明確にするために、私のy軸は特定の日にトラップで識別された個人の数であり、x軸はユリウス日です。
同じ種の地理的に隔離された2つの個体群を調べています。分布を調べると、両方が二峰性であることがわかります(発生にはある程度の季節性があります)が、1つの母集団のピークははるかに高く、非常に狭い(つまり、局所的なピークの分散は小さい)。
これらの違いが有意かどうかを判断するには、どのような統計的検定が適切でしょうか?
明確にするために、私のy軸は特定の日にトラップで識別された個人の数であり、x軸はユリウス日です。
回答:
これらの分布は時間の経過によるものですか?カウント、たぶん?(もしそうなら、これまでのここでの議論とはかなり異なるものが必要になるかもしれません)
あなたが説明することは、分布の分散の違いとして非常によく拾われるようには聞こえません。
あなたはこのように漠然と何かを記述しているように聞こえます(軸上の数字は無視してください。それは、記述しているように見える一般的な種類のパターンの感覚を与えるためです):
それが正しい場合は、以下を検討してください。
局所的な中心の周りの各ピークの幅は青の曲線では狭くなりますが、赤と青の分布の分散は全体としてほとんど変わりません。
事前にモードとアンチモードを特定しておけば、局所的な変動性を測定できます。
まず、二峰性分布は2つのかなり異なるプロセスの結果である可能性が高いため、季節分布を個別に見る必要があると思います。2つの分布は異なるメカニズムによって制御される可能性があるため、たとえば冬の分布は年間の気候に対してより敏感になる可能性があります。人口の違いとその理由を確認したい場合は、季節分布を個別に調査する方が便利だと思います。
検定については、グループ間の分散を比較するために使用されるLevineの検定(基本的には同等分散性の検定)を試すことができます。Bartlettの検定は代替ですが、Leveneの検定は非正規性に対してより堅牢になるはずです(特に検定に中央値を使用する場合)。Rでは、LeveneとBartlettの検定はにありlibrary(car)
ます。
leveneTest(y ~ as.factor(group), data= datafile)
グループ間の分散の差のテストに使用できます。オプション `center =" median "を使用すると、非正規性に対してより堅牢になります。厳密に言えば、中央値に基づくとすれば、ブラウンフォーサイス検定と呼ばれていると思います。
私は他の人が言ったことに同意します-つまり、「分散」はおそらく使うのに間違った言葉です(あなたが考慮している関数は確率分布ではなく時系列であると見なすこと)。
この問題に別の視点からアプローチしたいと思うかもしれません-LOWESS曲線を使用して2つの時系列を近似してください。95%の信頼区間を計算し、その形状について定性的にコメントできます。あなたがこれよりももっと豪華なことをする必要があるとは思いません。
以下のMATLABコードを書いて、私が言っていることを説明します。私は少し急いでいますが、すぐに説明を提供できます。私がしたことの多くはここから直接取ることができます: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')
2つの時系列を正規化して、絶対レベルではなく相対トレンドを比較することができます。
%% 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')
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')
最後に、次のように95%の信頼帯を作成できます。
%% 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')
これで、最終的な図を希望どおりに解釈でき、赤い曲線のピークは実際には青い曲線よりも広いという仮説を裏付けるためのLOWESS近似があります。関数が何であるかについてより良いアイデアがある場合は、代わりに非線形回帰を行うことができます。
編集:以下のいくつかの役立つコメントに基づいて、ピーク幅を明示的に推定することについてさらに詳細を追加します。まず、最初に「ピーク」と見なす対象を定義する必要があります。おそらく、あるしきい値(上記で作成したプロットで0.05のようなもの)を超えるバンプ。基本的な原則は、「実際の」または「注目すべき」ピークをノイズから分離する方法を見つける必要があるということです。
次に、各ピークについて、いくつかの方法でその幅を測定できます。以下のコメントで述べたように、「半最大幅」を確認するのは妥当だと思いますが、ピークがしきい値を超えている合計時間を確認することもできます。理想的には、ピーク幅のいくつかの異なる測定値を使用して、これらの選択が与えられた結果の一貫性を報告する必要があります。
どのメトリックを選択しても、ブートストラップを使用して、各トレースの各ピークの信頼区間を計算できます。
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])';
このコードは、上のプロットの青と赤のトレースに対して1000のブートストラップフィットを作成します。ここで詳しく説明するのは、平滑化係数0.15の選択です。交差検証エラーを最小限に抑えるようにこのパラメーターを選択できます(私が投稿したリンクを参照)。あとは、ピークを分離してその幅を推定する関数を記述するだけです。
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...
次に、このコードを各データセットの1000曲線で実行し、各ピークの幅の2.5パーセンタイルと97.5パーセンタイルを計算します。これをY1時系列で説明します。Y2時系列またはその他の目的のデータセットについても同じようにします。
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
必要に応じて、信頼区間を計算するのではなく、仮説検定を実行できます。上記のコードは単純化されていることに注意してください-ブートストラップされた各低曲線に2つのピークがあることを前提としています。この仮定は常に成立するとは限らないため、注意が必要です。私は私が取るアプローチを説明しようとしています。
注:「mylowess」機能は、上記のリンクに記載されています。こんな感じです...
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