← Bültene Dön
⏱️ 9 dk okuma

Python ile enflasyon tahmini denemem: SARIMAX’ı nasıl kullandım?

Bu çalışmada Türkiye’de aylık enflasyonu Python ile tahmin etmeyi denedim. Sadece geçmiş enflasyona bakmak yerine dolar kuru, petrol fiyatı ve faiz değişimini de modele ekledim. Burada hem yazdığım kodların mantığını hem de sonuçları yeniden kontrol ederken fark ettiğim sorunları anlatmak istiyorum.

Baştan sonucu söyleyeyim: kod çalışıyor ama bu, modelin iyi tahmin yaptığı anlamına gelmiyor. Benim modelim bazı basit yöntemleri geçemedi. Bence çalışmanın en öğretici kısmı da bunu görüp nedenini araştırmak oldu.

Bu yazıyı 27 Ağustos 2026’da güncelledim. İlk denemem ile sonradan yaptığımız kontrolleri ayrı ayrı anlattım. Böylece hangi sonucun ilk çalışmadan, hangisinin yeniden değerlendirmeden geldiği belli olsun istedim. Kodların incelenen sürümü GitHub’daki 79c01d5 kaydı.

Özgün Python kodları ve veri dosyaları →

Önce şu soruyu netleştirdim: neyi tahmin ediyorum?

Tahmin etmeye çalıştığım şey, fiyatların bir önceki aya göre yüzde kaç değiştiği: yani aylık enflasyon. Örneğin modelin %2 demesi, yıl sonu enflasyonunun %2 olacağı anlamına gelmiyor. Yıllık oran için ilgili 12 ayın değişimlerini bileşik olarak hesaplamak gerekiyor; aylık oranları toplamak yetmiyor.

Kullandığım SARIMAX, geçmiş değerlerden ve ek değişkenlerden yararlanan istatistiksel bir zaman serisi modeli. Burada bir sinir ağı ya da ChatGPT benzeri bir sistem kurmadım. Modelin adı biraz karmaşık görünse de temel sorum basit: geçmiş enflasyonun yanına başka bilgiler eklemek tahmini iyileştiriyor mu?

Hangi verileri kullandım?

Çalıştığım dosyada Ekim 2016 ile Temmuz 2026 arasında 118 aylık satır var. Önceki yazıda 120 demiştim; sayınca bunun doğru olmadığını gördük. Aylık değişimleri hesaplarken ilk satır kullanılamadığı için modele 117 gözlem giriyor. Dosyada eksik ay veya boş sayısal hücre yok; fakat bu, her hücrenin kaynağını doğruladığımız anlamına gelmiyor.

Değişkenler ve modeldeki karşılıkları
SeriKaynak / ölçümModel girdisi
Aylık enflasyonFRED TURCPIALLMINMEI ve elle tamamlanan TÜİK aylık oranlarıAylık yüzde değişim; hedef y
USD/TRYYahoo Finance TRY=X; aylık çubuğun kapanışı100 × (kur / önceki kur − 1)
BrentYahoo Finance BZ=F; vadeli işlem serisi, spot fiyat değil100 × (fiyat / önceki fiyat − 1)
Gecelik faizFRED IRSTCI01TRM156N; bankalararası gecelik oranBu ay − önceki ay; yüzde puan

Enflasyonun ilk bölümünü FRED’deki TÜFE serisinden aldım. Bu seri Nisan 2025’te bittiği için sonraki 15 ayın oranları elle eklenmişti. Yazıyı güncellerken bu oranları TCMB’nin TÜİK kaynaklı tablosuyla tek tek karşılaştırdık: hepsi eşleşiyor. Yine de ilk eklemede kullandığım bülten bağlantılarını ve verilerin o günkü sürümlerini saklamamış olmak bir eksik.

Kontrol kaynağı: TCMB tüketici fiyatları tablosu →

TÜFE endeksinden aylık değişimi tekrar hesaplayınca dosyadaki oranlarla fark 0,005 yüzde puanın altında kalıyor. Bu, iki ondalık basamağa yuvarlamayla uyumlu. Ama elle devam ettirilen endeksi, yeni bazlı resmî TÜFE endeksi gibi sunmamak gerekiyor. Ben burada endeksin düzeyini değil, aylık değişimini tahmin ediyorum.

Veriyi birleştiren ilk kodda ffill() var. Bu komut boş hücreye bir önceki değeri taşıyor; yeni veri bulmuyor. Mesela baktığımız FRED faiz serisi Mayıs 2026’da biterken dosyada Haziran ve Temmuz için de %35,5 yazıyor. Bu iki ayı yeni ölçülmüş faiz gözlemleri gibi kabul edemem. Bir sonraki sürümde doldurduğum hücreleri ayrıca işaretlemem gerekiyor.

Bir başka ayrıntı da zamanlama: aylık kur kapanışını ayın ilk günüyle etiketlemek, o fiyatı ay başında bildiğim anlamına gelmiyor. Tahmin yaparken gerçekten hangi bilginin elimde olduğunu düşünmeliyim. Ayrıca kullandığım bankalararası gecelik faiz, TCMB politika faiziyle birebir aynı seri değil.

Veriyi Python’da nasıl hazırladım?

Kur ve petrolün düzeyleri yerine aylık yüzde değişimlerini kullandım. Faizde ise bu ayın oranından geçen ayın oranını çıkardım. Burada önemli bir fark var: faiz %35’ten %36’ya çıkarsa değişim 1 yüzde puan. Bu işlem, yüzde değişim hesabıyla aynı değil. Dönüşümleri sadece sayıları küçültmek için değil, değişkenleri nasıl yorumlayacağıma göre seçmem gerekiyor.

Veri kontrolü ve dönüşümler · audit.py python
raw = pd.read_csv(path, parse_dates=["Tarih"]).set_index("Tarih")
# prepare() ayrıca ay sırasını, tekrarları ve boş değerleri denetler.
data = raw.assign(
    Kur_Degisim=raw.USD_TRY.pct_change(fill_method=None) * 100,
    Petrol_Degisim=raw.Brent_Petrol_USD.pct_change(fill_method=None) * 100,
    Faiz_Degisim=raw.Faiz_Orani.diff(),
).iloc[1:]

y = data["Enflasyon_Aylik_Yuzde"]
x = data[["Kur_Degisim", "Petrol_Degisim", "Faiz_Degisim"]]

Bu kısa kod, veri hazırlamanın ana kısmını gösteriyor. İndirilebilir tam kod ayrıca tarih sırasını, eksik ayları ve boş değerleri kontrol ediyor. Ancak dosyada önceden doldurulmuş hücreler varsa bunları kendiliğinden ayıramıyor. Temiz görünen bir tablo ile kaynağı iyi belgelenmiş bir tablo aynı şey değil.

SARIMAX modelini nasıl kurdum?

İlk kodda modelin derecelerini auto_arima ile seçtim. Bu araç, belirli seçenekleri adım adım deneyip AIC denilen ölçüte göre karşılaştırıyor; mümkün olan bütün modelleri taramıyor. Yeniden çalıştırınca aynı dereceler seçildi: (0,1,2) ve (0,0,0,12). Sabit terim seçilmedi. Bazı adaylarda yakınsama uyarısı çıktı, ama seçilen son model yakınsadı. Paket sürümlerini ilk çalışmada tam sabitlemediğim için başka bir ortamda aynı seçimin çıkacağını garanti edemem.

Burada benim de anlatırken dikkat etmem gereken bir nokta var: (0,0,0,12) yazınca model otomatik olarak yıllık mevsimsellik öğrenmiş olmuyor. Mevsimsel derecelerin hepsi sıfır. Yani son modelim, SARIMAX sınıfıyla kurulmuş ama aktif mevsimselliği olmayan bir ARIMAX(0,1,2). Depodaki eski, tek değişkenli (1,1,1) × (1,1,1,12) denemesi ise başka bir model.

Özgün son modeli yeniden kurmak · audit.py python
model = SARIMAX(
    y, exog=x,
    order=(0, 1, 2),
    seasonal_order=(0, 0, 0, 12),
    enforce_stationarity=False,
    enforce_invertibility=False,
).fit(disp=False, maxiter=50)

if not model.mle_retvals.get("converged"):
    raise RuntimeError("Model yakınsamadı; sonuçları onaylamayın.")

Bu yapıda enflasyonu ek değişkenlerle açıklamaya çalışıyorum; kalan hata sürecinin birinci farkında iki hareketli ortalama terimi var. Yalnız, çıkan katsayıya bakıp “faizi şu kadar değiştirirsek enflasyon kesin şu kadar düşer” diyemem. Tahmin ilişkisi kurmak ile neden-sonuç ilişkisi göstermek farklı işler.

Bir teknik not: ilk akışta auto_arima’nın seçtiği dereceleri statsmodels ile farklı kısıtlar altında yeniden kurmuşum. Aramadaki AIC 456,29, son uyumda 446,20 çıkıyor; ayarlar farklı olduğu için bunu doğrudan bir iyileşme diye okumuyorum. Aşağıdaki yeni denemede, seçilen modeli yeniden değiştirmeden kullanıyorum.

Modeli kontrol ederken neye baktım?

Tekrar hesapladığımız kontrol sonuçları
KontrolSonuçYorum
Aylık enflasyon ADF p0,0067Birim kök sıfır hipotezi reddediliyor; d=1 seçimi ayrıca incelenmeli.
Faiz farkı ADF p0,0903%5 düzeyinde birim kök reddedilemiyor; “tüm dönüşümler durağan” denemez.
Özgün Ljung–Box, 12 gecikmep = 0,7390Otokorelasyona karşı yeterli kanıt yok; beyaz gürültü veya doğruluk kanıtı değil.
Başlangıç 4 artık çıkarılmış LBp = 0,6199; model_df=2ARMA derece düzeltmeli ek kontrol; tek başına kapsamlı tanı değil.
Aynı ay kur değişimi ↔ enflasyonPearson r = 0,0502Bu örneklemde çok zayıf doğrusal ilişki; “çok güçlü pozitif” ifadesi kaldırıldı.
Petrol / faiz farkı ↔ enflasyonr = 0,2166 / 0,3233Örneklem korelasyonu; etki büyüklüğü veya nedensellik değil.
Aylık enflasyonla eşanlı korelasyon: kur değişimi 0,0502; petrol değişimi 0,2166; faiz farkı 0,3233.
Aynı ayın değişimlerine bakınca kurla ilişki bu örneklemde çok zayıf görünüyor. Bu grafik gecikmeli etkileri ölçmüyor ve neden-sonuç ilişkisi göstermiyor.

Bu testleri birer kontrol sorusu gibi düşünmek daha doğru. Örneğin ADF’de p değerinin 0,05’ten büyük olması, serinin kesinlikle durağan olmadığını kanıtlamıyor. Aylık enflasyonda düşük p değeri bulmamıza rağmen modelin d=1 seçmesi de ayrıca araştırılmalı. d=0 ve d=1 seçeneklerini yalnız eğitim verisinde karşılaştırmadan birine kesin doğru diyemem.

İlk VIF ve Breusch–Pagan kontrollerini de fazla güçlü yorumlamışım. VIF, dönüştürülmüş model girdilerinde değil ham düzeylerde hesaplanmış; değerler 3,40 / 1,22 / 3,05. Breusch–Pagan ise son SARIMAX’ın değil, ayrı bir OLS regresyonunun hatalarına bakıyor. Bunlardan “modelim krizlerde de güvenilir” sonucunu çıkaramam.

Peki modelim gerçekten iyi tahmin yapıyor mu?

Bunu görmek için veriyi tarihe göre üç kez eğitim ve test bölümüne ayırdım. Eğitim kısmı 30, sonra 59, sonra 88 ay oldu; her test 29 ay sürdü. Yani geçmişi giderek büyüten bir düzen kullandım. Test dönemleri Mayıs 2019–Eylül 2021, Ekim 2021–Şubat 2024 ve Mart 2024–Temmuz 2026.

Özgün testin kritik satırı · gerçek zamanlı test değildir python
# X_test, test aylarında SONRADAN gerçekleşmiş kur/petrol/faizdir.
prediction = results.get_forecast(
    steps=len(Y_test),
    exog=X_test,
)
# Bu sonuç: "gelecekteki X bilinseydi" koşullu performansıdır.

İlk testteki en önemli sorun bu satırda: X_test içinde gelecekte gerçekleşmiş kur, petrol ve faiz değerleri var. Oysa gerçek bir tahmin yaparken bunları henüz bilmiyorum. Bir de modelin derecelerini test aylarını da içeren bütün veriden seçmişim. Yani sonucu, “geleceği hiç görmeden elde ettiğim başarı” olarak anlatmam doğru değil.

İlk test dönemleriyle yaptığım karşılaştırma
YöntemMAE · yüzde puanOrtalama test RMSE · yüzde puan
Özgün model; gerçekleşmiş gelecek X1,91592,3476
Aynı sabit model; yalnız eğitimden X senaryosu1,88592,3416
Yalnız eğitim dönemi enflasyon ortalaması1,59732,0608
Son enflasyon değerini tekrarlama2,06552,5275
Son 12 ayı döngüsel tekrarlama2,35713,2454
Aynı 29 aylık testlerde MAE: geçmiş ortalaması 1,5973; ilk model 1,9159; son değer 2,0655; mevsimsel referans 2,3571 yüzde puan.
Çubuk ne kadar kısa olursa hata o kadar düşük. İlk model, sonradan gerçekleşmiş X bilgisiyle test edildiği halde geçmiş ortalamasını geçemiyor. Karşılaştırma aynı test dönemlerine ait.

Hata için MAE kullandım: tahmin ile gerçek değer arasındaki farkların mutlak değerlerini alıp ortalamasını hesaplıyor. Gerçek enflasyon %3, tahmin %1 ise hata 2 yüzde puan. İlk üç testte MAE sırasıyla 0,5249 / 3,4550 / 1,7678 çıktı. Özellikle zor dönemde hata belirgin şekilde büyüyor. Tablodaki RMSE sütunu da üç testin RMSE değerlerinin ortalaması; bütün hataları birleştirip hesaplanan tek bir RMSE değil.

Bu tablo benim için çalışmanın asıl kontrolü oldu. Modelimin MAE’si yaklaşık 1,92; sadece eğitim döneminin ortalamasını kullanan yönteminki ise 1,60. Yani daha karmaşık bir model kurmuş olmam daha iyi sonuç aldığım anlamına gelmemiş. Gelecek X’i sadece geçmişten oluşturunca hata burada biraz azalıyor; bilgi sızıntısı her zaman skoru iyileştirmek zorunda değil. Asıl mesele, testin gerçek kullanım koşuluna uyması. Bu ikinci satırda model derecelerini hâlâ bütün veriden seçtiğimizi de unutmamak gerekiyor.

Daha adil bir test yapınca ne oldu?

Yazıyı güncellerken ayrı bir deney daha ekledik. Bu kez her eğitim bölümünde model seçimini yeniden yaptık; gelecekteki X değerlerini de yalnız geçmişten oluşturduk. validate.py bunu yapıyor. Aday aralığını küçük tuttuk: mevsimsellik yok, p ve q en fazla 2, d en fazla 1. İlk testte (0,1,0), diğer ikisinde (0,1,2) seçildi. Üç son model de yakınsadı. Bu deney, ilk çalışmamın sonucu değil; sonradan eklediğimiz bir kontrol.

Eğitim içinde seçim, eğitimden senaryo · validate.py python
model = pm.auto_arima(
    y_train, X=x_train,
    seasonal=False, start_p=0, start_q=0,
    max_p=2, max_q=2, max_d=1,
    information_criterion="aic", stepwise=True,
    maxiter=200, suppress_warnings=False,
    error_action="warn", with_intercept="auto",
)
# future_scenario yalnız x_train kullanır; X_test kullanılmaz.
future_x = future_scenario(x_train, held_out.index)
prediction = model.predict(n_periods=len(held_out), X=future_x)
Yeni deney · üç adet 17 aylık test
YöntemMAE · yüzde puanOrtalama test RMSE · yüzde puan
Eğitim içinde seçilen ARIMAX + X senaryosu2,07042,2935
Eğitim dönemi ortalaması1,46781,9656
Son değeri tekrarlama2,21412,4542
Son 12 ayı döngüsel tekrarlama1,98572,7345

Bu yeni testler Mayıs 2022–Eylül 2023, Ekim 2023–Şubat 2025 ve Mart 2025–Temmuz 2026 dönemlerini kapsıyor. Önceki tabloyla dönemler farklı; iki tabloyu doğrudan karşılaştırıp “şu kadar iyileşti” diyemem. Ama bu deneyin kendi içinde de geçmiş ortalaması daha düşük hata veriyor. Buradan “SARIMAX işe yaramaz” değil, “benim bu kurulumum üstünlük göstermedi” sonucunu çıkarıyorum.

Yeni deney, model seçimini testten ayırıyor ve gelecek X’i kullanmıyor. Fakat verilerin geçmişte tam hangi gün yayımlandığını ve sonradan nasıl revize edildiğini yeniden kurmuyor. Gerçek zamanlı başarı iddiası için bu kayıtlar ve model seçimine hiç karışmamış yeni bir test dönemi gerekiyor.

17 aylık tahmin grafiğini nasıl okumalıyım?

İlk modelle Ağustos 2026–Aralık 2027 için 17 aylık bir yol çizdim. Bunun için gelecekteki kur, petrol ve faizi varsaymam gerekiyordu. Kur değişimini her ay son altı ayın ortalaması olan yaklaşık %1,4952; petrol değişimini yaklaşık %7,4709 aldım. Faiz değişimini sıfır kabul ettim, yani faiz düzeyi sabit kaldı. Bunlar doğrulanmış gelecek değerler değil, senaryo varsayımları. Petrolde her ay aynı pozitif yüzde değişimini kullanmak, fiyatın bileşik biçimde artması demek.

Gelecek açıklayıcı değişkenler ve koşullu aralık · audit.py python
future_x = pd.DataFrame({
    "Kur_Degisim": [x.Kur_Degisim.tail(6).mean()] * 17,
    "Petrol_Degisim": [x.Petrol_Degisim.tail(6).mean()] * 17,
    "Faiz_Degisim": [0.0] * 17,
}, index=forecast_dates)

forecast = model.get_forecast(steps=17, exog=future_x)
point = forecast.predicted_mean
conditional_interval = forecast.conf_int(alpha=0.05)
Ağustos 2026–Aralık 2027 aylık enflasyon senaryosu. Nokta tahmini 1,9694 ile başlayıp 2,2911 olur. Son ay koşullu yüzde 95 aralığı −2,5237 ile 7,1058 arasındadır.
Altın çizgi aylık nokta tahmini, gölgeli alan koşullu %95 tahmin aralığı. Bu bir yıllık enflasyon tahmini değil; gelecekteki kur, petrol ve faiz yolunu varsayan bir senaryo.
Grafikteki birkaç ayın sayısal karşılığı
AyAylık tahmin (%)Koşullu %95 alt–üst (%)
Ağustos 20261,9694−1,2611 – 5,1999
Eylül 20262,2911−1,5770 – 6,1591
Aralık 20272,2911−2,5237 – 7,1058

Grafikte çizginin Eylül 2026’dan sonra yataylaşması, ekonominin kesin olarak dengeleneceği anlamına gelmiyor. Bu, seçtiğim modelin ve sabit tuttuğum X yolunun ürettiği sonuç. Aralık 2027 için görülen yaklaşık %2,29 da yıllık değil, o ayın aylık enflasyon tahmini.

Gölgeli alanı da “her krizi kapsayan güvenlik alanı” gibi düşünmemeliyim. Bu aralık, modele verdiğim gelecek X yolu doğru kabul edilerek hesaplanıyor. Kur veya petrol senaryosu değişirse belirsizlik de değişebilir. Parametre belirsizliğinin tamamını veya yeni bir ekonomik rejimi otomatik olarak içine almıyor. Alt sınırın negatif olması da silinecek bir hata değil; modelin kullandığı dağılımın bir sonucu.

Yöntem kaynağı: ARIMA hatalı regresyonda senaryolar ve tahmin aralıkları →

Kodları kendin denemek istersen

Yukarıdaki kısa kodlar, neyi nasıl yaptığımı göstermek için seçilmiş parçalar. Tam çalışmayı tekrar etmek için aşağıdaki Python dosyalarını ve requirements.txt dosyasını aynı klasöre indirebilirsin. Python 3.12 kullandık. audit.py ilk modeli yeniden hesaplıyor; validate.py ise model seçiminin eğitim içinde yapıldığı yeni deneyi çalıştırıyor. Ham veri için özgün GitHub deposunun aşağıdaki sürümü gerekiyor.

audit.py · tam yeniden hesaplama kodunu aç / indir →

validate.py · eğitim içinde model seçimi yapılan deneyi aç / indir →

requirements.txt · denetimde kullanılan sabit paket sürümleri →

results.json · özgün model denetiminin sayısal çıktısı →

validation-results.json · yeni deneyin fold bazında çıktısı →

Temiz ortamda yeniden üretim bash
python3.12 -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt

git clone https://github.com/ShayCorma/inflation-forecast.git
git -C inflation-forecast checkout 79c01d5173322e6e25f7c95e88d83aeb810fc021

python audit.py ./inflation-forecast
python audit.py ./inflation-forecast --auto
python validate.py ./inflation-forecast

Hangi dosyayla çalıştığımız belli olsun diye veri dosyasının SHA-256 özeti sonuç kaydında duruyor. Farklı bir veri sürümü indirirsen sonuçlar değişebilir. Bu sayfada ham piyasa verisini yeniden dağıtmıyorum; kodları, hesaplanan kontrol sonuçlarını ve kaynak bağlantılarını paylaşıyorum.

Bu denemeden ne öğrendim?

Bir sonraki sürümde önce veri kayıtlarını düzeltmek istiyorum: yayın tarihi, kaynak ve doldurulan hücreler belli olmalı. Sonra kur ve petrolün gecikmeli etkilerini, farklı mevsimsellik seçeneklerini ve gelecek X senaryolarını denemeliyim. Her modeli aynı dönemlerde basit yöntemlerle karşılaştırmak ve tahmin aralıklarının gerçekleşmeleri ne kadar kapsadığını ölçmek de önemli.

Bu çalışmadan çıkardığım en önemli ders şu: güzel bir grafik ve çalışan bir kod, tek başına iyi bir tahmin modeli demek değil. Sonucu nerede yanlış yorumladığımı görmek de öğrenmenin bir parçası. Şimdilik bunu, geleceği bildiğini iddia eden bir araç değil; nasıl kurulduğu ve nerede sınırlı kaldığı açık olan bir enflasyon tahmini denemesi olarak görüyorum.

Finansal Uyarı: Bu analiz genel bilgilendirme ve eğitim amaçlıdır; kişiye özel yatırım danışmanlığı, alım-satım teklifi veya getiri garantisi değildir. Veriler gecikmeli ya da revize edilmiş olabilir. Tüm risk ve sınırlamaları okuyun.
Python ile enflasyon tahmini denemem: SARIMAX’ı nasıl kullandım? | Avvenge