ドキュメンテーション

最新のリリースでは、このページがまだ翻訳されていません。 このページの最新版は英語でご覧になれます。

findchangepts

信号の急激な変化の検出

構文

ipt = findchangepts(x)
ipt = findchangepts(x,Name,Value)
[ipt,residual] = findchangepts(___)
findchangepts(___)

説明

ipt = findchangepts(x) は、x の平均値が最も大幅に変化するインデックスを返します。

  • x が N 個の要素を持つベクトルである場合、findchangepts は、x を 2 つの領域 x(1:ipt-1)x(ipt:N) に分割します。これらは、各領域の局所的な平均値からの残差 (二乗) 誤差の和を最小化します。

  • x が M 行 N 列の行列である場合、findchangepts は、x を 2 つの領域 x(1:M,1:ipt-1)x(1:M,ipt:N) に分割し、各領域の局所的な M 次元の平均値からの残差誤差の和を最小化する列インデックスを返します。

ipt = findchangepts(x,Name,Value) は、名前と値のペアの引数を使用して追加オプションを指定します。オプションには、レポートする変化点の数や、平均値の代わりに測定する統計量があります。詳細は、変化点の検出を参照してください。

[ipt,residual] = findchangepts(___) は、前述のいずれかの指定を組み込んでモデル化された変化に対する信号の残差誤差も返します。

出力引数なしの findchangepts(___) は、信号および検出された任意の変化点をプロットします。

すべて折りたたむ

8192 Hz でサンプリングされた列車の警笛の録音を含むファイルを読み込みます。信号の平方根平均二乗レベルが最も大きく変化する点を 10 個検出します。

load train

findchangepts(y,'MaxNumChanges',10,'Statistic','rms')

信号の短時間パワー スペクトル密度を計算します。信号を 128 のサンプル セグメントに分割し、各セグメントにハミング ウィンドウを適用します。隣り合ったセグメント間のオーバーラップの 120 サンプルと 128 の DFT 点を指定します。パワー スペクトル密度が最も大きく変化する点を 10 個検出します。

[s,f,t,pxx] = spectrogram(y,128,120,128,Fs);

findchangepts(pow2db(pxx),'MaxNumChanges',10)

再現可能な結果が必要な場合は、乱数発生器をリセットします。次の条件でランダムな信号を生成します。

  • 平均値は 7 つの各領域内では一定だが、領域から領域にかけて急激に変化する。

  • 分散は 5 つの各領域内では一定だが、領域から領域にかけて急激に変化する。

rng('default')

lr = 20;

mns = [0 1 4 -5 2 0 1];
nm = length(mns);

vrs = [1 4 6 1 3];
nv = length(vrs);

v = randn(1,lr*nm*nv)/2;

f = reshape(repmat(mns,lr*nv,1),1,lr*nm*nv);
y = reshape(repmat(vrs,lr*nm,1),1,lr*nm*nv);

t = v.*y+f;

作成の手順を強調しながら信号をプロットします。

subplot(2,2,1)
plot(v)
title('Original')
xlim([0 700])

subplot(2,2,2)
plot([f;v+f]')
title('Means')
xlim([0 700])

subplot(2,2,3)
plot([y;v.*y]')
title('Variances')
xlim([0 700])

subplot(2,2,4)
plot(t)
title('Final')
xlim([0 700])

信号の平均値が最も大きく変化する点を 5 つ検出します。

figure
findchangepts(t,'MaxNumChanges',5)

信号の平方根平均二乗レベルが最も大きく変化する点を 5 つ検出します。

findchangepts(t,'MaxNumChanges',5,'Statistic','rms')

信号の平均値と標準偏差が最も大きく変化する点を検出します。

findchangepts(t,'Statistic','std')

でサンプリングされた音声信号を読み込みます。ファイルには、"MATLAB®" という単語を発声している女性の録音音声が含まれています。

load mtlb

信号の分散が大きく変化している点を検出することによって、単語内の母音と子音を識別します。変化点の数を 5 つに制限します。

numc = 5;

[q,r] = findchangepts(mtlb,'Statistic','rms','MaxNumChanges',numc)
q = 5×1

         132
         778
        1646
        2500
        3454

r = -4.4055e+03

信号をプロットして変化点を表示します。

findchangepts(mtlb,'Statistic','rms','MaxNumChanges',numc)

各セグメントの後に一時停止しながら音声を再生するには、次の行のコメントを解除します。

% soundsc(1:q(1),Fs)
% for k = 1:length(q)-1
%     soundsc(mtlb(q(k):q(k+1)),Fs)
%     pause(1)
% end
% soundsc(q(end):length(mtlb),Fs)

可変振幅をもつ 2 つの正弦波と線形トレンドで構成される信号を作成します。

vc = sin(2*pi*(0:201)/17).*sin(2*pi*(0:201)/19).* ...
    [sqrt(0:0.01:1) (1:-0.01:0).^2]+(0:201)/401;

信号の平均値が最も大きく変化している点を検出します。この場合、'Statistic' の名前と値のペアはオプションです。最小残差誤差改善数に 1 を指定します。

findchangepts(vc,'Statistic','mean','MinThreshold',1)

信号の平方根平均二乗レベルが最も大きく変化する点を検出します。最小残差誤差改善数に 6 を指定します。

findchangepts(vc,'Statistic','rms','MinThreshold',6)

信号の標準偏差が最も大きく変化する点を検出します。最小残差誤差改善数に 10 を指定します。

findchangepts(vc,'Statistic','std','MinThreshold',10)

信号の平均値と勾配が最も急激に変化している点を検出します。最小改善数に 0.6 を指定します。

findchangepts(vc,'Statistic','linear','MinThreshold',0.6)

20 のランダムな制御点を使用して、1000 のサンプルの 2 次元ベジエ曲線を生成します。ベジエ曲線は次のように定義されます。

ここで、 番目の 制御点、 の範囲は 0 ~ 1、 は二項係数です。曲線と制御点をプロットします。

m = 20;
P = randn(m,2);
t = linspace(0,1,1000)';

pol = t.^(0:m-1).*(1-t).^(m-1:-1:0);
bin = gamma(m)./gamma(1:m)./gamma(m:-1:1);
crv = bin.*pol*P;

plot(crv(:,1),crv(:,2),P(:,1),P(:,2),'o:')

各セグメントの点とセグメントの平均値からの距離が最小になるように、曲線を 3 つのセグメントに分割します。

findchangepts(crv','MaxNumChanges',3)

曲線を、直線で最適サイズに調整された 20 のセグメントに分割します。

findchangepts(crv','Statistic','linear','MaxNumChanges',19)

20 のランダムな制御点を使用して、3 次元ベジエ曲線を生成してプロットします。

P = rand(m,3);
crv = bin.*pol*P;

plot3(crv(:,1),crv(:,2),crv(:,3),P(:,1),P(:,2),P(:,3),'o:')
xlabel('x')
ylabel('y')

上述から曲線を可視化します。

view([0 0 1])

各セグメントの点とセグメントの平均値からの距離が最小になるように、曲線を 3 つのセグメントに分割します。

findchangepts(crv','MaxNumChanges',3)

曲線を、直線で最適サイズに調整された 20 のセグメントに分割します。

findchangepts(crv','Statistic','linear','MaxNumChanges',19)

入力引数

すべて折りたたむ

入力信号。実数ベクトルで指定します。

例: reshape(randn(100,3)+[-3 0 3],1,300) は、平均値における 2 回の急激な変化を伴うランダムな信号です。

例: reshape(randn(100,3).*[1 20 5],1,300) は、平方根平均二乗レベルにおける 2 回の急激な変化を伴うランダムな信号です。

データ型: single | double

名前と値のペアの引数

オプションの Name,Value の引数ペアをコンマ区切りで指定します。ここで、Name は引数名で、Value は対応する値です。Name は単一引用符 ' ' で囲まなければなりません。Name1,Value1,...,NameN,ValueN のように、複数の名前/値のペア引数を、任意の順番で指定できます。

例: 'MaxNumChanges',3,'Statistic','rms','MinDistance',20 は、平方根平均二乗レベルの変化が最も大きく、かつ少なくとも 20 サンプルで隔てられている点を最大で 3 つ検出します。

返す大きな変化の最大数。'MaxNumChanges' と整数スカラーで構成されるコンマ区切りのペアとして指定します。最も大きな変化のある点を検出した後、findchangepts は、指定した最大値を超えない範囲でより多くの変化点を含めるために、徐々にその検索基準を緩和します。何らかの探索設定によってこの最大値を超えて返されている場合、それ以降、関数は何も返しません。'MaxNumChanges' が指定されていない場合、関数は最も大きな変化のある点を返します。'MinThreshold''MaxNumChanges' を同時に指定することはできません。

例: findchangepts([0 1 0]) は 2 番目のサンプルのインデックスを返します。

例: findchangepts([0 1 0],'MaxNumChanges',1) は空行列を返します。

例: findchangepts([0 1 0],'MaxNumChanges',2) は 2 番目の点と 3 番目の点のインデックスを返します。

データ型: single | double

検出する変化のタイプ。'Statistic' と次の値のいずれかで構成されるコンマ区切りペアとして指定します。

  • 'mean' — 平均値の変化を検出。

  • 'rms' — 平方根平均二乗レベルの変化を検出。

  • 'std' — ガウス対数尤度を使用して、標準偏差の変化を検出。

  • 'linear' — 平均値と勾配の変化を検出。

例: findchangepts([0 1 2 1],'Statistic','mean') は 2 番目のサンプルのインデックスを返します。

例: findchangepts([0 1 2 1],'Statistic','rms') は 3 番目のサンプルのインデックスを返します。

データ型: char

変化点間のサンプルの最小数。'MinDistance' と整数スカラーで構成されるコンマ区切りのペアとして指定します。この数値を指定しない場合、既定の設定は、平均値の変化については 1 に、その他の変化については 2 になります。

例: findchangepts(sin(2*pi*(0:10)/5),'MaxNumChanges',5,'MinDistance',1) は 5 インデックスを返します。

例: findchangepts(sin(2*pi*(0:10)/5),'MaxNumChanges',5,'MinDistance',3) は 2 インデックスを返します。

例: findchangepts(sin(2*pi*(0:10)/5),'MaxNumChanges',5,'MinDistance',5) はインデックスを返しません。

データ型: single | double

各変化点の合計残差誤差の最小改善数。'MinThreshold' とペナルティを表す実数スカラーで構成されるコンマ区切りのペアとして指定します。このオプションは、予想される各変化点に追加のペナルティを適用することによって、返される大きな変化の数を制限するように作用します。'MinThreshold''MaxNumChanges' を同時に指定することはできません。

例: findchangepts([0 1 2],'MinThreshold',0) は 2 インデックスを返します。

例: findchangepts([0 1 2],'MinThreshold',1) は 1 インデックスを返します。

例: findchangepts([0 1 2],'MinThreshold',2) はインデックスを返しません。

データ型: single | double

出力引数

すべて折りたたむ

変化点の位置。整数インデックスのベクトルとして返されます。

モデル化された変化に対する信号の残差誤差。ベクトルとして返されます。

詳細

すべて折りたたむ

変化点の検出

"変化点" は、信号のなんらかの統計プロパティが突然変化するサンプルまたは時点です。対象プロパティは、信号の平均値、その分散、スペクトル特性などが考えられます。

信号の変化点を検出するために、findchangepts はパラメトリックでグローバルな手法を採用します。関数は以下を実行します。

  1. 1 点を選択し、信号を 2 つのセクションに分割します。

  2. 各セクションの目的の統計プロパティの経験的推定値を計算します。

  3. セクション内の各点で、この経験的推定値とプロパティの偏差を計測します。すべての点の偏差を追加します。

  4. セクション間の偏差を追加して、合計残差誤差を求めます。

  5. 合計残差誤差が最小になるまで、分割点の位置を変化させます。

この手続きは、選択した統計が平均値であるときに最もはっきりします。その場合、findchangepts は各セクションの "ベストな" 水平レベルから合計残差誤差を最小化します。信号 x1, x2, …, xN が与えられると、関数は

J=i=1k1(xix1k1)2+i=kN(xixkN)2=i=1k1(xi1k1r=1k1xr)2+i=kN(xi1Nk+1r=kNxr)2=(k1)var([x1xk1])+(Nk+1)var([xkxN]),

が最小になるような k を求めます。平均値と分散は通常の定義をもちます(分散は、1 を差し引かないサンプル数によって正規化されます)。

結果は、一般化して他の統計を組み込むことができます。findchangepts は、セクションの経験的推定 χ と偏差測定 Δ が与えられる場合、

J(k)=i=1k1Δ(xi;χ([x1xk1]))+i=kNΔ(xi;χ([xkxN]))

が最小となるような k を求めます。残差誤差を最小化することは対数尤度を最大化することと等価です。平均値が μ、分散が σ2 の標準偏差が与えられると、N 個の独立した観測値の対数尤度は

logi=1N12πσ2e(xiμ)2/2σ2=N2(log2π+logσ2)12σ2i=1N(xiμ)2.

です。

  • 'Statistic''mean' に指定した場合、分散は固定になり、関数は直前に得たとおり

    i=mnΔ(xi;χ([xmxn])|)=i=mn(xiμ([xmxn]))2=(nm+1)var([xmxn]),

    を使用します。

  • 'Statistic''std' に指定した場合、平均値は固定になり、関数は

    i=mnΔ(xi;χ([xmxn]))=(nm+1)logi=mnσ2([xmxn])=(nm+1)log(1nm+1i=mn(xi1nm+1r=mnxr)2)=(nm+1)logvar([xmxn]).

    を使用します。

  • 'Statistic''rms' に指定した場合、総偏差は 'std' と同じになりますが、平均値はゼロに設定されます。

    i=mnΔ(xi;χ([xmxn]))=(nm+1)log(1nm+1r=nmxr2).

  • 'Statistic''linear' に指定した場合、関数は

    i=mnΔ(xi;χ([xmxn]))=(nm+1)var([xmxn])(i=mn(xiμ([xmxn]))(iμ([mm+1n])))2(nm+1)var([mm+1n])SxxSxt2Stt.

    を使用します。

多くの場合、対象信号は複数の変化点を持ちます。変化点の数が既知の場合、手続きの一般化は簡単です。変化点の数が不明の場合は、残差誤差にペナルティ項を追加しなければなりません。変化点が増えると常に残差誤差が少なくなり過適合になるからです。極端なケースでは、すべての点が変化点になり、残差誤差がゼロになります。findchangepts は変化点の数によって線形に増大するペナルティ項を使用します。K 個の変化点が見つかった場合、関数は以下のように最小化します。

J(K)=r=0K1i=krkr+11Δ(xi;χ([xkrxkr+11]))+βK,

ここで k0kK はそれぞれ信号の最初と最後のサンプルです。

  • β と表記され 'MinThreshold' で指定される比例定数は、各変化点で追加された固定ペナルティに対応します。findchangepts は、残差誤差の減少がしきい値を満たさない場合は、さらに変化点の追加を除外します。考えられるすべての変化を返すには、'MinThreshold' をゼロに設定します。

  • 使用されているしきい値がわからない場合、または信号の変化点数が大まかにしかわからない場合は、代わりに 'MaxNumChanges' を指定します。このオプションは、関数が指定された値より少ない変化を検出するようになるまで、しきい値を徐々に増やします。

最小化そのものを実行するために、findchangepts は、早い段階で放棄する動的プログラミングに基づく網羅的なアルゴリズムを使用します。

参照

[1] Lavielle, Marc. “Using penalized contrasts for the change-point problem.” Signal Processing. Vol. 85, August 2005, pp. 1501–1510.

[2] Killick, Rebecca, Paul Fearnhead, and Idris A. Eckley. “Optimal detection of changepoints with a linear computational cost.” Journal of the American Statistical Association. Vol. 107, No. 500, 2012, pp. 1590–1598.

参考

R2016a で導入