Main Content

findchangepts

신호 내 급격한 변화 찾기

설명

예제

ipt = findchangepts(x)x의 평균값이 가장 크게 변한 인덱스를 반환합니다.

  • x가 N개 요소를 가진 벡터이면, findchangeptsx를 두 개의 영역 x(1:ipt-1)x(ipt:N)으로 분할합니다. 이 두 영역은 각 영역의 국소 평균으로부터 해당 영역의 잔차(제곱) 오차의 합이 최소화되는 영역입니다.

  • x가 M×N 행렬이면, findchangeptsx를 두 영역 x(1:M,1:ipt-1)x(1:M,ipt:N)으로 분할합니다. 그리고 각 영역의 M차원 국소 평균으로부터 해당 영역의 잔차 오차의 합이 최소화되는 열 인덱스를 반환합니다.

예제

ipt = findchangepts(x,Name,Value)는 이름-값 인수를 사용하여 추가 옵션을 지정합니다. 이런 옵션에는 찾아낼 변화 지점 개수와 평균 대신에 측정할 통계량 등이 있습니다. 자세한 내용은 변화 지점 감지 항목을 참조하십시오.

예제

[ipt,residual] = findchangepts(___)는 위에 나열된 어떤 구문도 적용할 수 있는데, 이에 덧붙여 모델링된 변화에 대한 신호의 잔차 오차도 반환합니다.

예제

출력 인수 없이 findchangepts(___)를 실행하면 신호와 검출된 모든 변화 지점이 플로팅됩니다. 자세한 내용은 Statistic 항목을 참조하십시오.

참고

플로팅하기 전에 findchangepts 함수는 현재 Figure를 지웁니다(clf). 신호와 검출된 변화 지점을 서브플롯에 플로팅하려면 플로팅 함수를 사용하십시오. 오디오 파일 분할 항목을 참조하십시오.

예제

모두 축소

8192Hz로 샘플링된 기차 기적 소리 녹음이 있는 데이터 파일을 불러옵니다. 신호의 RMS 레벨이 가장 크게 변한 10개 지점을 찾습니다.

load train

findchangepts(y,MaxNumChanges=10,Statistic="rms")

Figure contains an axes object. The axes object with title Number of changepoints = 10 Total log weighted dispersion = -34290.1456 contains 2 objects of type line.

신호의 단시간 파워 스펙트럼 밀도를 계산합니다. 신호를 한 세그먼트당 128개 샘플이 있도록 여러 세그먼트로 나누고 해밍 윈도우를 사용하여 각 세그먼트에 윈도우를 적용합니다. 인접 세그먼트 간에 120개 샘플이 중첩되도록 지정하고 128개 DFT 점을 지정합니다. 파워 스펙트럼 밀도의 평균이 가장 크게 변한 10개 지점을 찾습니다.

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

findchangepts(pow2db(pxx),MaxNumChanges=10)

Figure contains 2 axes objects. Axes object 1 contains 131 objects of type line. Axes object 2 with title Number of changepoints = 10 Total residual error = 2820745.8453 contains 11 objects of type image, line.

재현 가능한 결과를 얻기 위해 난수 생성기를 재설정합니다. 다음 특징을 갖는 랜덤 신호를 생성합니다.

  • 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])

Figure contains 4 axes objects. Axes object 1 with title Original contains an object of type line. Axes object 2 with title Means contains 2 objects of type line. Axes object 3 with title Variances contains 2 objects of type line. Axes object 4 with title Final contains an object of type line.

신호의 평균이 가장 크게 변한 5개 지점을 찾습니다.

figure
findchangepts(t,MaxNumChanges=5)

Figure contains an axes object. The axes object with title Number of changepoints = 5 Total residual error = 1989.3814 contains 3 objects of type line.

신호의 RMS 레벨이 가장 크게 변한 5개 지점을 찾습니다.

findchangepts(t,MaxNumChanges=5,Statistic="rms")

Figure contains an axes object. The axes object with title Number of changepoints = 5 Total log weighted dispersion = 871.1003 contains 2 objects of type line.

신호의 평균과 표준편차가 가장 크게 변한 지점을 찾습니다.

findchangepts(t,Statistic="std")

Figure contains an axes object. The axes object with title Number of changepoints = 1 Total log weighted dispersion = 1263.4625 contains 3 objects of type line.

Fs=7418Hz로 샘플링된 음성 신호를 불러옵니다. 이 파일에는 "MATLAB®"이라는 단어를 발음한 여성의 음성이 들어 있습니다.

load mtlb

신호의 분산이 크게 변한 지점을 찾아 단어의 모음과 자음을 구별합니다. 변화 지점 개수를 5개로 제한합니다.

numc = 5;

[q,r] = findchangepts(mtlb,Statistic="rms",MaxNumChanges=numc);

변화 지점 인덱스에 기반하여 음성 신호를 위한 신호 마스크를 만듭니다. 신호 마스크를 사용하는 방법에 대한 자세한 내용은 signalMask 항목을 참조하십시오.

t = (0:length(mtlb)-1)/Fs;
roitable = ([[1;q] [q;length(mtlb)]]);

x = ["M" "A" "T" "L" "A" "B"]';
c = categorical(x,unique(x,"stable"));

msk = signalMask(table(t(roitable),c),SampleRate=Fs,RightShortening=1);
roimask(msk)
ans=6×2 table
           Var1            c
    ___________________    _

          0    0.017525    M
    0.01766     0.10461    A
    0.10475     0.22162    T
    0.22176     0.33675    L
    0.33688     0.46535    A
    0.46549     0.53909    B

신호 마스크의 관심 영역과 함께 음성 신호와 검출된 변화 지점을 서브플롯에 플로팅합니다.

  • 상부 서브플롯에 plotsigroi 함수를 사용하여 신호 마스크 영역을 시각화합니다. 설정을 조정하여 컬러바가 상단에 표시되도록 합니다.

  • 하부 서브플롯에 원래 음성 신호를 플로팅하고 검출된 변화 지점을 세로선으로 추가합니다.

subplot(2,1,1)
plotsigroi(msk,mtlb)
colorbar("off")
nc = numel(c)-1;
colormap(gca,lines(nc));
colorbar(TickLabels=categories(c),Ticks=1/2/nc:1/nc:1, ...
    TickLength=0,Location="northoutside")
xlabel("")

subplot(2,1,2)
plot(t,mtlb)
hold on
xline(q/Fs)
hold off
xlim([0 t(end)])
xlabel("Seconds")

Figure contains 2 axes objects. Axes object 1 contains 6 objects of type line. Axes object 2 with xlabel Seconds contains 6 objects of type line, constantline.

각 세그먼트를 실행하고 나서 일시 중지한 후 소리를 재생하려면 다음 라인의 주석 처리를 제거하십시오.

% for k = 1:length(roitable)
%     intv = roitable(k,1):roitable(k,2);
%     soundsc(mtlb(intv).*hann(length(intv)),Fs)
%     pause(.5)
% end

변하는 진폭과 선형 추세를 갖는 두 정현파로 구성된 신호를 생성합니다.

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)

Figure contains an axes object. The axes object with title Number of changepoints = 2 Total residual error = 9.3939 contains 3 objects of type line.

신호의 RMS 레벨이 가장 크게 변한 지점을 찾습니다. 잔차 오차 최소 개선을 6으로 지정합니다.

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

Figure contains an axes object. The axes object with title Number of changepoints = 4 Total log weighted dispersion = -436.5368 contains 2 objects of type line.

신호의 표준편차가 가장 크게 변한 지점을 찾습니다. 잔차 오차 최소 개선을 10으로 지정합니다.

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

Figure contains an axes object. The axes object with title Number of changepoints = 26 Total log weighted dispersion = -1110.8065 contains 3 objects of type line.

신호의 평균과 기울기가 가장 급격히 변한 지점을 찾습니다. 잔차 오차 최소 개선을 0.6으로 지정합니다.

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

Figure contains an axes object. The axes object with title Number of changepoints = 3 Total residual error = 7.9824 contains 3 objects of type line.

임의의 20개 제어점을 갖고 1000개 샘플로 구성된 2차원 베지에 곡선을 생성합니다. 베지에 곡선은 다음과 같이 정의됩니다.

C(t)=k=0m(mk)tk(1-t)m-kPk,

여기서 Pkm개 제어점 중에서 k번째 제어점이고, t의 범위는 0부터 1까지며, (mk)는 이항 계수입니다. 곡선과 제어점을 플로팅합니다.

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:")

Figure contains an axes object. The axes object contains 2 objects of type line.

곡선을 세 개의 세그먼트로 분할합니다. 이때 각 세그먼트의 지점들이 세그먼트 평균으로부터 최소 거리에 있도록 합니다.

findchangepts(crv',MaxNumChanges=3)

Figure contains 2 axes objects. Axes object 1 contains 5 objects of type line. Axes object 2 with title Number of changepoints = 2 Total residual error = 158.2579 contains 3 objects of type line.

이 곡선을 직선에 최적으로 피팅되는 20개의 세그먼트로 분할합니다.

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

Figure contains 2 axes objects. Axes object 1 contains 5 objects of type line. Axes object 2 with title Number of changepoints = 19 Total residual error = 0.090782 contains 21 objects of type line.

임의의 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")

Figure contains an axes object. The axes object with xlabel x, ylabel y contains 2 objects of type line.

위 곡선을 시각화합니다.

view([0 0 1])

Figure contains an axes object. The axes object with xlabel x, ylabel y contains 2 objects of type line.

곡선을 세 개의 세그먼트로 분할합니다. 이때 각 세그먼트의 지점들이 세그먼트 평균으로부터 최소 거리에 있도록 합니다.

findchangepts(crv',MaxNumChanges=3)

Figure contains 2 axes objects. Axes object 1 contains 7 objects of type line. Axes object 2 with title Number of changepoints = 2 Total residual error = 7.2855 contains 3 objects of type line.

이 곡선을 직선에 최적으로 피팅되는 20개의 세그먼트로 분할합니다.

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

Figure contains 2 axes objects. Axes object 1 contains 7 objects of type line. Axes object 2 with title Number of changepoints = 19 Total residual error = 0.0075362 contains 21 objects of type line.

입력 인수

모두 축소

입력 신호로, 실수 값 벡터나 행렬로 지정됩니다.

  • x가 N개 요소를 가진 벡터이면, findchangeptsx를 두 개의 영역 x(1:ipt-1)x(ipt:N)으로 분할합니다. 이 두 영역은 Statistic에 지정된 통계량의 국소 값으로부터 각 영역의 잔차(제곱) 오차의 합이 최소화되는 영역입니다.

  • x가 M×N 행렬이면, findchangeptsx를 두 영역 x(1:M,1:ipt-1)x(1:M,ipt:N)으로 분할합니다. 그리고 Statistic에 지정된 통계량의 M차원 국소 값으로부터 각 영역의 잔차 오차의 합이 최소화되는 열 인덱스를 반환합니다.

예: reshape(randn(100,3)+[-3 0 3],1,300)은 평균에 2번의 급격한 변화가 있는 랜덤 신호입니다.

예: reshape(randn(100,3).*[1 20 5],1,300)은 RMS(제곱평균제곱근) 레벨에 2번의 급격한 변화가 있는 랜덤 신호입니다.

데이터형: single | double

이름-값 인수

선택적 인수 쌍을 Name1=Value1,...,NameN=ValueN으로 지정합니다. 여기서 Name은 인수 이름이고 Value는 대응값입니다. 이름-값 인수는 다른 인수 뒤에 와야 하지만, 인수 쌍의 순서는 상관없습니다.

예: MaxNumChanges=3,Statistic="rms",MinDistance=20은 RMS 레벨에서의 변화가 가장 급격하고 최소 20개의 샘플로 서로 분리되어 있는 지점을 최대 3개 찾습니다.

R2021a 이전 릴리스에서는 쉼표를 사용하여 각 이름과 값을 구분하고 Name을 따옴표로 묶으십시오.

예: 'MaxNumChanges',3,'Statistic',"rms",'MinDistance',20은 RMS 레벨에서의 변화가 가장 급격하고 최소 20개의 샘플로 서로 분리되어 있는 지점을 최대 3개 찾습니다.

급격한 변화 지점에 대한 최대 반환 개수로, 정수 스칼라로 지정됩니다. 가장 급격한 변화가 있는 한 지점을 찾은 후, findchangepts는 서서히 검색 기준을 완화하여 지정된 최대 개수를 초과하지 않는 범위에서 더 많은 변화 지점을 포함할 수 있도록 합니다. 검색 설정 결과에서 최대 개수보다 더 많은 항목을 반환하면 함수는 아무것도 반환하지 않습니다. MaxNumChanges가 지정되지 않은 경우 함수는 가장 큰 변화가 있는 지점 하나를 반환합니다. MinThresholdMaxNumChanges를 동시에 지정할 수 없습니다.

예: findchangepts([0 1 0])은 두 번째 샘플의 인덱스를 반환합니다.

예: findchangepts([0 1 0],MaxNumChanges=1)은 빈 행렬을 반환합니다.

예: findchangepts([0 1 0],MaxNumChanges=2)는 두 번째와 세 번째 지점의 인덱스를 반환합니다.

데이터형: single | double

감지할 변화 유형으로, 다음 값 중 하나로 지정됩니다.

  • "mean" — 평균의 변화 감지. 출력 인수 없이 findchangepts를 호출하면 이 함수는 신호, 변화 지점, 그리고 연속한 변화 지점들로 둘러싸인 각 세그먼트의 평균값을 플로팅합니다.

  • "rms" — RMS(제곱평균제곱근) 레벨의 변화 감지. 출력 인수 없이 findchangepts를 호출하면 이 함수는 신호와 변화 지점을 플로팅합니다.

  • "std" — 가우스 로그 가능도를 사용하여 표준편차의 변화 감지. 출력 인수 없이 findchangepts를 호출하면 이 함수는 신호, 변화 지점, 그리고 연속한 변화 지점들로 둘러싸인 각 세그먼트의 평균값을 플로팅합니다.

  • "linear" — 평균과 기울기의 변화 감지. 출력 인수 없이 findchangepts를 호출하면 이 함수는 신호, 변화 지점, 그리고 연속한 변화 지점들로 둘러싸인 신호의 각 부분에 가장 적합한 선을 플로팅합니다.

예: findchangepts([0 1 2 1],Statistic="mean")은 두 번째 샘플의 인덱스를 반환합니다.

예: findchangepts([0 1 2 1],Statistic="rms")는 세 번째 샘플의 인덱스를 반환합니다.

변화 지점 간의 최소 샘플 개수로, 정수 스칼라로 지정됩니다. 이 개수를 지정하지 않으면, 평균의 변화에 대한 디폴트 값은 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

각 변화 지점에 대한 총 잔차 오차의 최소 개선으로, 벌점을 나타내는 실수형 스칼라로 지정됩니다. 이 옵션은 각 변화 지점 후보에 추가 벌점을 적용하여, 반환되는 큰 변화의 개수를 제한합니다. MinThresholdMaxNumChanges를 동시에 지정할 수 없습니다.

예: findchangepts([0 1 2],MinThreshold=0)은 2개의 인덱스를 반환합니다.

예: findchangepts([0 1 2],MinThreshold=1)은 1개의 인덱스를 반환합니다.

예: findchangepts([0 1 2],MinThreshold=2)는 인덱스를 반환하지 않습니다.

데이터형: single | double

출력 인수

모두 축소

변화 지점 위치로, 정수 인덱스로 구성된 벡터로 반환됩니다.

모델링된 변화에 대한 신호의 잔차 오차로, 벡터로 반환됩니다.

세부 정보

모두 축소

변화 지점 감지

변화 지점은 신호의 일부 통계 속성이 급격히 변한 샘플 또는 시점을 말합니다. 이러한 속성에는 신호의 평균이나 분산 또는 스펙트럼 특징 등이 있을 수 있습니다.

findchangepts는 모수적 전역 방법을 사용하여 신호 변화 지점을 찾습니다. 이 함수는 다음을 수행합니다.

  1. 한 지점을 선택하고 신호를 두 섹션으로 나눕니다.

  2. 섹션마다 원하는 통계 속성에 대한 경험적 추정값을 계산합니다.

  3. 한 섹션 내의 각 지점에서 속성이 경험적 추정값에서 얼마나 벗어나는지 측정합니다. 모든 지점의 편차를 더합니다.

  4. 섹션 간 편차를 더하여 총 잔차 오차를 구합니다.

  5. 총 잔차 오차가 최소값을 가질 때까지 분할 지점의 위치를 바꿉니다.

이 절차는 평균을 통계량으로 선택할 때 가장 명확합니다. 이 경우 findchangepts는 각 섹션에 가장 "적합한" 수평 레벨의 총 잔차 오차를 최소화합니다. 신호 x1, x2, …, xN과 다음과 같은 부분 수열의 평균 및 분산이 주어지고

mean([xmxn])=1nm+1r=mnxr,var([xmxn])=1nm+1r=mn(xrmean([xmxn]))2Sxx|mnnm+1,

제곱합이 다음과 같으면

Sxy|mnr=mn(xrmean([xmxn]))(yrmean([ymyn])),

findchangepts는 다음 총 잔차 오차가 최소가 되도록 하는 k 값을 구합니다.

J=i=1k1(ximean([x1xk1]))2+i=kN(ximean([xkxN]))2=(k1)var([x1xk1])+(Nk+1)var([xkxN])

이 결과를 일반화하여 다른 통계량에도 사용할 수 있습니다. findchangepts는 섹션의 경험적 추정값 χ와 편차 측정값 Δ가 주어진 경우 다음 총 잔차 오차가 최소가 되도록 하는 k 값을 구합니다.

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

잔차 오차를 최소화하는 것은 로그 가능도를 최대화하는 것과 동일합니다. 평균 μ와 분산 σ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(ximean([xmxn]))2=(nm+1)var([xmxn]),

  • Statistic"std"로 지정하면, 평균이 고정되고 함수는 다음 식을 사용합니다.

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

  • Statistic"rms"로 지정하면, 총 편차는 "std"의 경우와 동일하지만 평균이 0으로 설정됩니다.

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

  • Statistic"linear"로 지정하면, 함수는 신호 값과 신호 값에서 얻은 최소제곱선 피팅 예측값의 차이제곱합을 총 편차로 사용합니다. 이 수량을 SSE(오차제곱합)라고 합니다. xm, xm+1, …, xn의 최적선은 다음과 같고

    x^(t)=Sxt|mnStt|mn(tmean([tmtn]))+mean([xmxn])

    SSE는 다음과 같습니다.

    i=mnΔ(xi;χ([xmxn]))=i=mn(xix^(ti))2=Sxx|mnSxt2|mnStt|mn=(nm+1)var([xmxn])(i=mn(ximean([xmxn]))(imean([mm+1n])))2(nm+1)var([mm+1n]).

관심 있는 신호에 변화 지점이 두 개 이상인 경우도 있습니다. 변화 지점 개수를 알고 있다면 이 절차를 간단히 일반화할 수 있습니다. 개수를 모를 경우에는 벌점 항을 잔차 오차에 추가해야 합니다. 변화 지점을 추가하면 항상 잔차 오차가 줄어들어 과적합이 발생하기 때문입니다. 극단적인 경우에는 모든 지점이 변화 지점이 되고 잔차 오차가 0이 됩니다. findchangepts는 변화 지점 개수에 따라 선형적으로 증가하는 벌점 항을 사용합니다. 변화점이 K개 발견되면 함수는 다음 식을 최소화합니다.

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

여기서 k0kK는 각각 신호의 첫 번째 샘플과 마지막 샘플입니다.

  • β로 나타내고 MinThreshold에 지정되는 비례 상수는 각 변화 지점에 추가되는 고정 벌점에 해당합니다. findchangepts는 잔차 오차의 감소로 임계값을 충족하지 못하면 변화 지점 추가를 거부합니다. 가능한 모든 변화를 반환하려면 MinThreshold를 0으로 설정하십시오.

  • 무슨 임계값을 사용할지 모르거나 신호의 변화 지점 개수를 대략적으로 안다면 MaxNumChanges를 대신 지정하십시오. 이 옵션은 지정된 값보다 함수가 찾는 변화 개수가 적을 때까지 임계값을 조금씩 증가시킵니다.

findchangepts는 자체적으로 최소화를 수행하기 위해 미리 버림(early abandonment)을 적용한 동적 계획법에 기반한 포괄적 알고리즘을 사용합니다.

참고 문헌

[1] 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.

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

확장 기능

버전 내역

R2016a에 개발됨

참고 항목