Main Content

이 번역 페이지는 최신 내용을 담고 있지 않습니다. 최신 내용을 영문으로 보려면 여기를 클릭하십시오.

푸리에 모델 피팅하기

푸리에 급수 모델 소개

푸리에 급수는 사인 함수와 코사인 함수의 합으로 주기 함수를 설명합니다. 푸리에 급수를 사용하여 임의의 주기 함수를 단순한 성분으로 분리할 수 있습니다. 이러한 성분은 적분하고, 미분하고, 분석하기가 쉽습니다. 이런 이유로 푸리에 급수는 주기 신호를 대략적으로 파악하는 데 자주 사용됩니다.

푸리에 급수를 표현하는 형식은 몇 가지가 있습니다. Curve Fitting Toolbox™는 다음과 같은 삼각 푸리에 급수 형식을 사용합니다.

y=a0+i=1naicos(iwx)+bisin(iwx)

여기서 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를 선택합니다.

Select_Fitting_Data.png

변수를 선택하면 앱이 데이터 점을 플로팅합니다. 기본적으로 앱은 다항식을 데이터에 피팅합니다. 푸리에 모델을 피팅하려면 곡선 피팅기 탭의 피팅 유형 섹션에서 Fourier를 클릭합니다.

FourierGallery.png

앱이 단일 항 푸리에 모델을 피팅합니다.

fourier1.png

피팅된 1항 푸리에 모델은 단순한 진동 동작이 있는 주기 함수입니다. 결과 패널에는 모델의 일반 방정식, 95% 신뢰구간의 피팅된 계수 추정값, 기본주파수, 적합도 통계량이 표시됩니다.

resultsFourier1.png

피팅된 1항 푸리에 모델의 평균 제곱 오차의 제곱근(RMSE)은 0.1996입니다. 1항 푸리에 모델을 4개 항을 가진 푸리에 모델과 비교하려면 피팅 옵션 패널의 항 개수에서 4를 선택합니다. 앱이 4개 항을 가진 푸리에 모델을 데이터에 피팅합니다.

fourier4.png

피팅된 4항 푸리에 모델은 1항 푸리에 모델보다 복잡한 진동 동작을 가지고 있습니다. 4항 모델의 RMSE는 0.1685이며, 이는 4개 항이 1개 항보다 소리 데이터를 더 정확하게 예측한다는 것을 나타냅니다. 한편, 플롯은 gongClip의 일부 데이터 점이 4항 모델의 범위를 벗어났음을 보여줍니다.

내보내기 섹션에서 내보내기를 클릭한 다음 Export to Workspace를 선택하여 피팅된 4항 푸리에 모델을 작업 공간으로 내보냅니다. 대화 상자에서 두 번째 옵션 및 세 번째 옵션의 선택을 취소합니다. 첫 번째 옵션 옆의 상자에 변수 이름으로 피팅을 저장합니다.

ExportFitWindow.png

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 객체입니다. a2b2에 대한 신뢰한계는 영점을 교차하므로, 0과 다르거나 피팅된 모델이 1항 푸리에 모델과 다르다는 결론을 내릴 충분한 증거가 없습니다. 평균 제곱 오차의 제곱근(RMSE)은 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|로 지정됩니다. a7b7이 최대 계수입니다.

T = 2*pi/(w*7)
T = 11.9249

a7b7에 대응하는 항의 주기는 약 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 = 16×1 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")

이 플롯은 f7f7_8보다 더 정확하게 기압 차이 데이터의 변동을 캡처함을 보여줍니다.

푸리에 피팅 반복 표시하기

이름-값 인수를 사용하여 추가 옵션을 지정하는 대신 fitoptions 객체를 fit 함수에 전달할 수 있습니다. 푸리에 모델 피팅에 사용 가능한 옵션을 보려면 모델 이름을 입력 인수로 fitoptions 함수에 전달합니다.

fitoptions("fourier7")
ans =

        Normalize: 'off'
          Exclude: []
          Weights: []
           Method: 'NonlinearLeastSquares'
           Robust: 'Off'
       StartPoint: [1×0 double]
            Lower: [1×0 double]
            Upper: [1×0 double]
        Algorithm: 'Trust-Region'
    DiffMinChange: 1.0000e-08
    DiffMaxChange: 0.1000
          Display: 'Notify'
      MaxFunEvals: 600
          MaxIter: 400
           TolFun: 1.0000e-06
             TolX: 1.0000e-06

fitoptions 객체를 만들고 각 반복 후에 출력값을 표시하도록 지정합니다.

optionsf7 = fitoptions("fourier7",Display="iter")
options =

        Normalize: 'off'
          Exclude: []
          Weights: []
           Method: 'NonlinearLeastSquares'
           Robust: 'Off'
       StartPoint: [1×0 double]
            Lower: [1×0 double]
            Upper: [1×0 double]
        Algorithm: 'Trust-Region'
    DiffMinChange: 1.0000e-08
    DiffMaxChange: 0.1000
          Display: 'Iter'
      MaxFunEvals: 600
          MaxIter: 400
           TolFun: 1.0000e-06
             TolX: 1.0000e-06

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 항목을 참조하십시오.

참고 항목

함수

관련 항목