Fourier bileşenleri beni faza sokmaz

Fourier bileşenleri beni faza sokmaz#

Rastlantı eseri regresyon modellerinde Fourier bileşenlerinin kullanımı bu hafta iki ayrı projede karşıma çıktı. Bu notebook, nasıl çalıştıklarını gösteren küçük bir örnek sunuyor.

Not: Özgün İngilizce başlık, “phase” ve “faze” eşseslilerine dayanan bir kelime oyunudur.

Bu notebook’u Colab’da çalıştırmak için buraya tıklayın

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt

np.printoptions(legacy='1.25')
plt.rcParams["figure.dpi"] = 100
plt.rcParams["figure.figsize"] = [6, 3.5]

Frekans f, genlik A ve faz kayması phi ile parametrelenen dönemsel bileşen içeren bir sinyalimiz olduğunu varsayın. Parametrelere keyfî değerler verip geri elde edip edemeyeceğimize bakacağız.

f = 1
A = 1.5
phi = 0.5

Sinyali sentezlemek için bu parametreli kosinüsü üç döngü boyunca değerlendireceğim.

ts = np.linspace(0, 3, endpoint=False)
ys = A * np.cos(2 * np.pi * f * ts + phi)
np.mean(ys)
np.float64(-2.220446049250313e-16)

Ardından ortalaması sıfır olan Gauss gürültüsü ekleyeceğim.

np.random.seed(1)
noise = np.random.normal(0, 0.5, size=len(ts))
ys += noise - noise.mean()

Sinyal şöyle görünür.

plt.plot(ts, ys)
plt.xlabel('t')
plt.ylabel('y');
_images/2a5b2c40fafeb8cc1db165d352f411665acba710fc2919ed2059c04d3927142d.png

Şimdi sinyalden parametreleri tahmin edip edemeyeceğimize bakalım. Temel fikir şu trigonometrik özdeşliktir:

\[ \cos(\omega t + \phi) = \cos\phi \cos(\omega t) - \sin\phi \sin(\omega t) \]

Faz kaymalı kosinüs, faz kayması olmayan sinüs ve kosinüsün ağırlıklı toplamı olarak yazılabilir. Dolayısıyla dönemsel bileşenin frekansını biliyorsanız sinüs ve kosinüsü öngörücü alan regresyonla genlik ile fazı tahmin edebilirsiniz.

Göstermek için verileri Fourier bileşenleriyle birlikte DataFrame içine koyacağım.

data = pd.DataFrame(dict(ys=ys, ts=ts))
data['cos'] = np.cos(2 * np.pi * f * ts)
data['sin'] = np.sin(2 * np.pi * f * ts)

Şimdi regresyon modelini çalıştırabiliriz (sentezlenen sinyale kesişim eklemediğimiz için burada da dışlıyoruz).

import statsmodels.formula.api as smf

res = smf.ols('ys ~ 0 + cos + sin', data=data).fit()
res.summary()
OLS Regression Results
Dep. Variable: ys R-squared (uncentered): 0.815
Model: OLS Adj. R-squared (uncentered): 0.808
Method: Least Squares F-statistic: 106.0
Date: Mon, 24 Aug 2026 Prob (F-statistic): 2.46e-18
Time: 15:20:03 Log-Likelihood: -34.513
No. Observations: 50 AIC: 73.03
Df Residuals: 48 BIC: 76.85
Df Model: 2
Covariance Type: nonrobust
coef std err t P>|t| [0.025 0.975]
cos 1.2602 0.098 12.794 0.000 1.062 1.458
sin -0.6846 0.098 -6.950 0.000 -0.883 -0.487
Omnibus: 0.306 Durbin-Watson: 2.389
Prob(Omnibus): 0.858 Jarque-Bera (JB): 0.244
Skew: 0.160 Prob(JB): 0.885
Kurtosis: 2.877 Cond. No. 1.00


Notes:
[1] R² is computed without centering (uncentered) since the model does not contain a constant.
[2] Standard Errors assume that the covariance matrix of the errors is correctly specified.

Uydurulan modelin verilerle karşılaştırması şöyledir.

data['yhat'] = res.fittedvalues

plt.plot(data['ts'], data['ys'], label='veri', alpha=0.6)
plt.plot(data['ts'], data['yhat'], label='uyum')
plt.xlabel('t')
plt.ylabel('y')
plt.legend();
_images/07464ce07e96d66eea628d9a58afbd3189ab2f3a1f78c7a6c1ffb69392b0eaa1.png

Uyum eğrisi dönemsel bileşenin fazını geri kazanmış gibi görünüyor. Tahmini genlik ile faz model parametrelerinde açıkça gösterilmez; Kartezyen koordinatlardan kutupsal koordinatlara dönüştürerek hesaplayabiliriz.

a = res.params['cos']
b = res.params['sin']

A_hat = np.hypot(a, b)     
phi_hat = np.arctan2(-b, a)

A_hat, phi_hat
(np.float64(1.4341371792799407), np.float64(0.49760870975866645))

Parametreleri en azından yaklaşık olarak geri elde ettik.

Fourier analizi hemen hemen aynı ilkeyle çalışır; sinüs ve kosinüs yerine karmaşık üstel kullanır.

ws = np.exp(2 * np.pi * 1j * f * ts)

Karmaşık üstel ile sinyalin nokta çarpımını —özünde korelasyonu— hesaplayarak parametreleri tahmin edebiliriz.

c = 2 / len(ts) * np.vdot(ws, ys)
c
np.complex128(1.2602143401738164+0.68455041144776j)

Sonuç sinyalin tahmini genlik ve fazını temsil eden karmaşık sayıdır.

A_hat = np.abs(c)
phi_hat = np.angle(c)

A_hat, phi_hat
(np.float64(1.4341371792799409), np.float64(0.49760870975866645))

Tahminler doğrusal regresyondan elde ettiklerimizle aynıdır.

Bu, \(e^{i\theta}=\cos\theta+i\sin\theta\) olduğu için çalışır. Sinyali karmaşık üstel tabana yansıttığımızda sinüs ve kosinüs bileşenlerini sıkıştırılmış biçimde hesaplarız.