푸리에 모델 피팅하기
푸리에 급수 모델 소개
푸리에 급수는 사인 함수와 코사인 함수의 합으로 주기 함수를 설명합니다. 푸리에 급수를 사용하여 임의의 주기 함수를 단순한 성분으로 분리할 수 있습니다. 이러한 성분은 적분하고, 미분하고, 분석하기가 쉽습니다. 이런 이유로 푸리에 급수는 주기 신호를 대략적으로 파악하는 데 자주 사용됩니다.
푸리에 급수를 표현하는 형식은 몇 가지가 있습니다. Curve Fitting Toolbox™는 다음과 같은 삼각 푸리에 급수 형식을 사용합니다.
여기서 a0은 데이터의 상수(절편) 항을 모델링하고 i = 0 코사인 항과 연결되어 있으며, w는 신호의 기본주파수이고, n은 항(고조파)의 개수입니다. Curve Fitting Toolbox는 1 ≤ n ≤ 8인 경우 푸리에 급수 회귀를 지원합니다.
푸리에 급수에 대한 자세한 내용은 푸리에 해석과 필터링 항목을 참조하십시오.
곡선 피팅기 앱에서 대화형 방식으로 푸리에 모델 피팅하기
이 예제에서는 곡선 피팅기 앱을 사용하여 푸리에 모델을 데이터에 피팅하는 방법을 보여줍니다.
소리 신호 샘플 데이터를 불러옵니다.
load gong.mat
변수 y
및 변수 Fs
는 징 울림에 대한 소리 신호 데이터와 주파수 데이터를 각각 포함하고 있습니다. y
의 처음 1,000개 요소를 gongClip
이라는 이름의 벡터에 저장하여 소리 클립을 만듭니다.
gongClip = y(1:1000);
gongClip
의 각 요소에 대응하는 시간을 계산하기 위해 요소의 인덱스를 Fs
로 나눕니다.
t = [1:1000]./Fs;
명령줄에서 곡선 피팅기 앱을 엽니다.
curveFitter
또는 앱 탭의 수학, 통계학 및 최적화 그룹에서 곡선 피팅기를 클릭합니다.
곡선 피팅기 앱에서 피팅에 대한 데이터 변수를 선택합니다. 곡선 피팅기 탭의 데이터 섹션에서 데이터 선택을 클릭합니다. 피팅 데이터 선택 대화 상자에서 X 데이터 값으로 t
를 선택하고 Y 데이터 값으로 gongClip
를 선택합니다.
변수를 선택하면 앱이 데이터 점을 플로팅합니다. 기본적으로 앱은 다항식을 데이터에 피팅합니다. 푸리에 모델을 피팅하려면 곡선 피팅기 탭의 피팅 유형 섹션에서 Fourier
를 클릭합니다.
앱이 단일 항 푸리에 모델을 피팅합니다.
피팅된 1항 푸리에 모델은 단순한 진동 동작이 있는 주기 함수입니다. 결과 패널에는 모델의 일반 방정식, 95% 신뢰구간의 피팅된 계수 추정값, 기본주파수, 적합도 통계량이 표시됩니다.
피팅된 1항 푸리에 모델의 RMSE(RMS 오차)는 0.1996입니다. 1항 푸리에 모델을 4개 항을 가진 푸리에 모델과 비교하려면 피팅 옵션 패널의 항 개수에서 4
를 선택합니다. 앱이 4개 항을 가진 푸리에 모델을 데이터에 피팅합니다.
피팅된 4항 푸리에 모델은 1항 푸리에 모델보다 복잡한 진동 동작을 가지고 있습니다. 4항 모델의 RMSE는 0.1685이며, 이는 4개 항이 1개 항보다 소리 데이터를 더 정확하게 예측한다는 것을 나타냅니다. 한편, 플롯은 gongClip
의 일부 데이터 점이 4항 모델의 범위를 벗어났음을 보여줍니다.
내보내기 섹션에서 내보내기를 클릭한 다음 Export to Workspace
를 선택하여 피팅된 4항 푸리에 모델을 작업 공간으로 내보냅니다. 대화 상자에서 두 번째 옵션 및 세 번째 옵션의 선택을 취소합니다. 첫 번째 옵션 옆의 상자에 변수 이름으로 피팅을 저장합니다.
sound
함수를 사용하여 gongClip
의 소리 데이터를 들을 수 있습니다.
sound(gongClip,Fs)
pause(2) % Allow gongClip to play before executing next line
gongClip
의 푸리에 모델 근사에 대한 소리 데이터를 얻으려면 feval
을 사용하여 t
의 시간에 gongFourierModel
을 실행합니다. 근사된 소리 데이터를 재생합니다.
gongClipApprox = feval(gongFourierModel,t); sound(gongClipApprox,Fs)
두 클립은 근사 평균 톤이 동일합니다. 한편, 근사된 소리 데이터는 gongClip
의 소리 데이터만큼 톤의 변동이 많지 않습니다.
명령줄에서 푸리에 모델 피팅하기
이 예제에서는 fit
함수를 사용하여 푸리에 모델을 데이터에 피팅하는 방법을 보여줍니다.
2항 푸리에 모델 피팅하기
ENSO(El Niño-Southern Oscillation) 데이터를 불러옵니다.
load enso;
변수 pressure
는 이스터 섬, 칠레 및 다윈, 호주 간의 평균 대기압 차이에 대한 데이터를 포함하고 있습니다. 변수 month
는 각 기압 차이가 발생한 달에 대한 데이터를 포함하고 있습니다.
month
에 대해 pressure
를 플로팅합니다.
plot(month,pressure)
기압 데이터는 0과 18 사이에서 진동하는데, 이는 푸리에 급수에 의해 설명될 수 있음을 나타냅니다.
푸리에 라이브러리 모델을 사용하여 2항 푸리에 모델을 피팅합니다. fourier
에 항의 개수를 붙여서 모델 유형을 지정합니다. 나중에 비교할 수 있도록 적합도 통계량을 저장합니다.
[f2,gof2] = fit(month,pressure,"fourier2")
f2 = General model Fourier2: f2(x) = a0 + a1*cos(x*w) + b1*sin(x*w) + a2*cos(2*x*w) + b2*sin(2*x*w) Coefficients (with 95% confidence bounds): a0 = 10.63 (10.23, 11.03) a1 = 2.923 (2.27, 3.576) b1 = 1.059 (0.01593, 2.101) a2 = -0.5052 (-1.086, 0.07532) b2 = 0.2187 (-0.4202, 0.8576) w = 0.5258 (0.5222, 0.5294)
gof2 = struct with fields:
sse: 1.1230e+03
rsquare: 0.4279
dfe: 162
adjrsquare: 0.4103
rmse: 2.6329
f2
는 일반 공식, 95% 신뢰한계의 계수 추정값, 피팅 w
에 대한 기본주파수가 포함된 cfit
객체입니다. a2
와 b2
에 대한 신뢰한계는 영점을 교차하므로, 0과 다르거나 피팅된 모델이 1항 푸리에 모델과 다르다는 결론을 내릴 충분한 증거가 없습니다. RMSE(RMS 오차)는 2.6329이며, 이는 f2
의 정확도를 다른 피팅의 정확도와 비교하는 데 유용합니다.
기본주파수에서 주기를 계산하려면 공식 T = 2*pi/w
를 사용합니다.
w = f2.w
w = 0.5258
T = 2*pi/w
T = 11.9497
피팅된 2항 푸리에 모델의 주기는 약 12개월(즉, 1년)입니다.
데이터의 산점도 플롯으로 f2
를 플로팅합니다.
plot(f2,month,pressure)
f2
의 형태는 1항 푸리에 모델의 형태와 유사하며 진동은 약 12개월에 한 번 최고조에 달합니다.
7항 푸리에 모델 피팅하기
7항 푸리에 모델을 데이터에 피팅합니다. 적합도 통계량을 저장합니다.
[f7,gof7] = fit(month,pressure,"fourier7")
f7 = General model Fourier7: f7(x) = a0 + a1*cos(x*w) + b1*sin(x*w) + a2*cos(2*x*w) + b2*sin(2*x*w) + a3*cos(3*x*w) + b3*sin(3*x*w) + a4*cos(4*x*w) + b4*sin(4*x*w) + a5*cos(5*x*w) + b5*sin(5*x*w) + a6*cos(6*x*w) + b6*sin(6*x*w) + a7*cos(7*x*w) + b7*sin(7*x*w) Coefficients (with 95% confidence bounds): a0 = 10.63 (10.28, 10.97) a1 = 0.5669 (0.08285, 1.051) b1 = 0.1969 (-0.29, 0.6838) a2 = -1.203 (-1.687, -0.7189) b2 = -0.8085 (-1.307, -0.31) a3 = 0.9323 (0.4325, 1.432) b3 = 0.7599 (0.2622, 1.258) a4 = -0.6653 (-1.149, -0.1817) b4 = -0.2038 (-0.6995, 0.292) a5 = -0.02913 (-0.5129, 0.4547) b5 = -0.3701 (-0.8566, 0.1164) a6 = -0.04841 (-0.5437, 0.4469) b6 = -0.1367 (-0.6286, 0.3552) a7 = 2.812 (2.19, 3.433) b7 = 1.333 (0.4017, 2.264) w = 0.07527 (0.07478, 0.07576)
gof7 = struct with fields:
sse: 768.3656
rsquare: 0.6086
dfe: 152
adjrsquare: 0.5700
rmse: 2.2483
f7
은 영점을 교차하는 신뢰한계를 가진 여러 계수를 포함하고 있으므로, 대응하는 항이 피팅된 푸리에 모델의 정확도를 높인다고 결론을 내릴 충분한 증거가 없습니다. 이 경우의 RMSE는 2.2483으로 f2
의 RMSE보다 작은데, 이는 7항 푸리에 모델이 2항 푸리에 모델보다 정확하게 기압을 예측한다는 것을 입증합니다.
기본주파수에서 주기를 계산하려면 공식 T = 2*pi/w
를 사용하여 주기를 계산합니다.
w = f7.w
w = 0.0753
T = (2*pi)/w
T = 83.4745
피팅된 7항 푸리에 모델의 주기는 약 83개월(즉, 대략 7년)입니다. 피팅된 계수의 진폭은 기압 차이의 예측 값에 가장 크게 기여하는 항을 결정합니다.
형식 sin(Ax)
또는 형식 cos(Ax)
의 정현파 주기는 공식 T = 2*pi/|A|
로 지정됩니다. a7
과 b7
이 최대 계수입니다.
T = 2*pi/(w*7)
T = 11.9249
a7
과 b7
에 대응하는 항의 주기는 약 12개월이며, 이는 연간 주기가 가장 유력함을 나타냅니다.
동일한 공식을 사용하여 다음 항의 주기를 계산합니다.
항
a1
과 항b1
은 각각 7년의 주기를 가지고 있습니다.항
a2
와 항b2
는 각각 3.5(7/2)년의 주기를 가지고 있습니다.a2
계수 및b2
계수는 a1 계수 및 b1 계수보다 크기가 크므로, 3.5년 주기는 7년 주기보다 기압 차이의 예측 값에 더 많이 기여합니다.항
a3
과 항b3
이 유력하며, 이는 2.3년(7/3) 주기를 나타냅니다.
a6
, b6
, a5
, b5
와 같이 작은 항은 피팅에서 중요도가 낮습니다.
데이터의 산점도 플롯으로 f7
을 플로팅합니다.
plot(f7,month,pressure)
7항 푸리에 모델은 더 복잡한 패턴으로 진동하며 1항 푸리에 모델보다 기압 차이에서 더 넓은 범위의 값을 캡처합니다. 주기는 약 84개월(즉, 7년)마다 반복됩니다. 일반적으로 엘니뇨 온난화는 2~7년의 불규칙한 간격으로 발생하며 9개월에서 2년 동안 지속됩니다. 평균 주기 길이는 5년입니다. 모델 결과는 이러한 주기 중 일부를 반영합니다.
시작점 설정하기
fit
함수는 data
입력 인수를 사용하여 계수 및 기본주파수 계산을 위한 최적화된 시작점을 계산합니다. 푸리에 급수 모델은 특히 시작점에 민감하며, 최적화된 값은 관련 방정식에서 몇 개 항에 대해서만 정확할 수 있습니다. StartPoint
이름-값 인수를 지정하여 최적화된 시작점을 재정의할 수 있습니다.
데이터의 산점도 플롯에서의 극값은 4년 주기가 존재할 수 있음을 시사합니다. 이를 확인하려면 기본주파수의 시작점을 8년(즉, 96개월) 주기에 해당하는 값으로 설정합니다. 피팅된 푸리에 모델의 8년 주기는 항 a2
와 항 b2
의 주기를 3.5
에서 4
로 늘립니다.
w_8 = (2*pi)/96
w_8 = 0.0654
coeffnames
함수를 사용하여 f7
계수 이름으로 구성된 셀형 벡터에서 기본주파수의 인덱스를 구합니다.
coeffnames(f7)
ans = 16x1 cell
{'a0'}
{'a1'}
{'b1'}
{'a2'}
{'b2'}
{'a3'}
{'b3'}
{'a4'}
{'b4'}
{'a5'}
{'b5'}
{'a6'}
{'b6'}
{'a7'}
{'b7'}
{'w' }
기본주파수는 계수 이름으로 구성된 이 벡터의 마지막 요소입니다. f7
계수로부터 계수 값으로 구성된 벡터를 만들고, 기본주파수에 대한 값을 8년 주기에 해당하는 값으로 바꿉니다.
coeffs = coeffvalues(f7); coeffs(:,end) = w_8
coeffs = 1×16
10.6262 0.5669 0.1969 -1.2031 -0.8085 0.9323 0.7599 -0.6653 -0.2038 -0.0291 -0.3701 -0.0484 -0.1367 2.8120 1.3330 0.0654
기본주파수에 대한 새 값을 시작점으로 하는 계수를 사용하여 7항 푸리에 모델을 기압 차이 데이터에 피팅합니다. 적합도 통계량을 저장합니다.
[f7_8,gof7_8] = fit(month,pressure,"fourier7",StartPoint=coeffs)
f7_8 = General model Fourier7: f7_8(x) = a0 + a1*cos(x*w) + b1*sin(x*w) + a2*cos(2*x*w) + b2*sin(2*x*w) + a3*cos(3*x*w) + b3*sin(3*x*w) + a4*cos(4*x*w) + b4*sin(4*x*w) + a5*cos(5*x*w) + b5*sin(5*x*w) + a6*cos(6*x*w) + b6*sin(6*x*w) + a7*cos(7*x*w) + b7*sin(7*x*w) Coefficients (with 95% confidence bounds): a0 = 10.58 (10.05, 11.1) a1 = 0.3286 (-0.4339, 1.091) b1 = -0.05917 (-0.7884, 0.6701) a2 = -0.8667 (-1.738, 0.004258) b2 = 1.094 (0.2819, 1.906) a3 = -0.4524 (-1.232, 0.3272) b3 = -0.3117 (-1.099, 0.4753) a4 = 0.181 (-0.7949, 1.157) b4 = 0.5806 (-0.1796, 1.341) a5 = 0.03263 (-0.7174, 0.7827) b5 = -0.2299 (-0.9767, 0.5169) a6 = 0.3726 (-0.39, 1.135) b6 = -0.2745 (-1.165, 0.6161) a7 = 0.4309 (-0.491, 1.353) b7 = -0.3547 (-1.316, 0.6062) w = 0.06795 (0.06519, 0.0707)
gof7_8 = struct with fields:
sse: 1.6851e+03
rsquare: 0.1416
dfe: 152
adjrsquare: 0.0568
rmse: 3.3296
f7_8
계수가 f7
계수에서 약간 이동되었습니다. f7_8
에 대한 RMSE가 더 높을수록 이는 f7
이 데이터에 더 적합한 피팅임을 나타냅니다. 모델을 시각적으로 비교하기 위해 두 피팅을 모두 플로팅합니다.
plot(f7_8,month,pressure) hold on plot(f7, 'b') hold off legend("Data","f7_8","f7")
이 플롯은 f7
이 f7_8
보다 더 정확하게 기압 차이 데이터의 변동을 캡처함을 보여줍니다.
푸리에 피팅 반복 표시하기
이름-값 인수를 사용하여 추가 옵션을 지정하는 대신 fitoptions
객체를 fit
함수에 전달할 수 있습니다. 푸리에 모델 피팅에 사용 가능한 옵션을 보려면 모델 이름을 입력 인수로 fitoptions
함수에 전달합니다.
fitoptions("fourier7")
ans = nlsqoptions with properties: StartPoint: [] Lower: [] Upper: [] Algorithm: 'Trust-Region' DiffMinChange: 1.0000e-08 DiffMaxChange: 0.1000 Display: 'Notify' MaxFunEvals: 600 MaxIter: 400 TolFun: 1.0000e-06 TolX: 1.0000e-06 Robust: 'Off' Normalize: 'off' Exclude: [] Weights: [] Method: 'NonlinearLeastSquares'
fitoptions
객체를 만들고 각 반복 후에 출력값을 표시하도록 지정합니다.
optionsf7 = fitoptions("fourier7",Display="iter")
optionsf7 = nlsqoptions with properties: StartPoint: [] Lower: [] Upper: [] Algorithm: 'Trust-Region' DiffMinChange: 1.0000e-08 DiffMaxChange: 0.1000 Display: 'Iter' MaxFunEvals: 600 MaxIter: 400 TolFun: 1.0000e-06 TolX: 1.0000e-06 Robust: 'Off' Normalize: 'off' Exclude: [] Weights: [] Method: 'NonlinearLeastSquares'
optionsf7
은 7항 푸리에 모델 피팅에 대한 옵션이 포함된 fitoptions
객체입니다.
f7
생성과 관련된 반복 단계를 보기 위해 optionsf7
의 옵션을 사용하여 또 다른 7항 푸리에 모델을 피팅합니다.
f7_iter = fit(month,pressure,"fourier7",optionsf7)
Norm of First-order Iteration Func-count f(x) step optimality CG-iterations 0 2 768.41 1.93e+03 1 4 768.366 2.2176e-05 69.1 0 2 6 768.366 7.94962e-07 2.48 0 Success, but fitting stopped because change in residuals less than tolerance (TolFun).
f7_iter = General model Fourier7: f7_iter(x) = a0 + a1*cos(x*w) + b1*sin(x*w) + a2*cos(2*x*w) + b2*sin(2*x*w) + a3*cos(3*x*w) + b3*sin(3*x*w) + a4*cos(4*x*w) + b4*sin(4*x*w) + a5*cos(5*x*w) + b5*sin(5*x*w) + a6*cos(6*x*w) + b6*sin(6*x*w) + a7*cos(7*x*w) + b7*sin(7*x*w) Coefficients (with 95% confidence bounds): a0 = 10.63 (10.28, 10.97) a1 = 0.5669 (0.08285, 1.051) b1 = 0.1969 (-0.29, 0.6838) a2 = -1.203 (-1.687, -0.7189) b2 = -0.8085 (-1.307, -0.31) a3 = 0.9323 (0.4325, 1.432) b3 = 0.7599 (0.2622, 1.258) a4 = -0.6653 (-1.149, -0.1817) b4 = -0.2038 (-0.6995, 0.292) a5 = -0.02913 (-0.5129, 0.4547) b5 = -0.3701 (-0.8566, 0.1164) a6 = -0.04841 (-0.5437, 0.4469) b6 = -0.1367 (-0.6286, 0.3552) a7 = 2.812 (2.19, 3.433) b7 = 1.333 (0.4017, 2.264) w = 0.07527 (0.07478, 0.07576)
푸리에 모델 피팅을 더 자세히 조사하기 위해 NonlinearLeastSquares
피팅 알고리즘에 사용 가능한 다양한 옵션을 지정하여 시험할 수 있습니다. 자세한 내용은 fitoptions
항목을 참조하십시오.
참고 항목
앱
함수
fit
|fittype
|fitoptions