Mehmet Emin Sezgin
  • Yazılar
  • Araştırmalar
  • Politika Notları
  • Veri ve Grafikler
  • Demografi Lab
  • English
  • Hakkımda

Doğum Simülatörü

Toplam Doğurganlık Hızı ve Yıllık Doğum Sayısı Projeksiyonu (2025-2100)

Türkiye’nin demografik göstergelerini interaktif olarak keşfedin. Her model, bu araştırma programının özgün analitik çerçevesine dayanmaktadır — kaydırıcıları hareket ettirerek varsayımları değiştirebilir, sonuçları anlık olarak görebilirsiniz.

Nasıl kullanılır: Her modeldeki kaydırıcıları sürükleyerek parametreleri değiştirin. Grafikler ve göstergeler anlık güncellenir. Modellerin metodolojik detayları, ilgili Araştırmalar ve Politika Notları sayfalarında yer almaktadır.

1. Parite Geçiş Simülatörü (PPR₁, PPR₂, PPR₃)

Birinci çocuktan ikinciye (PPR₁), ikinciden üçüncüye (PPR₂) ve üçüncüden dördüncüye (PPR₃) geçiş oranlarının toplam doğurganlık hızı üzerindeki etkisi. PPR₁, toplam TDH kaybının %56,6’sını tek başına açıklayan en yüksek kaldıraçlı bileşendir.

Kod
viewof ppr1_slider = Inputs.range([0.50, 0.95], {
  value: 0.712, step: 0.005,
  label: "PPR₁ (1→2 geçiş oranı)"
})
viewof ppr2_slider = Inputs.range([0.30, 0.75], {
  value: 0.507, step: 0.005,
  label: "PPR₂ (2→3 geçiş oranı)"
})
viewof ppr3_slider = Inputs.range([0.50, 0.90], {
  value: 0.700, step: 0.005,
  label: "PPR₃ (3→4+ geçiş oranı)"
})
Kod
tdh1_sabit = 0.608    // 1. çocuk TDH bileşeni
ppr1_ref = 0.712
ppr2_ref = 0.507
ppr3_ref = 0.700

// TDH = TDH₁ × (1 + PPR₁ + PPR₁×PPR₂ + PPR₁×PPR₂×PPR₃)
function tdhHesapla(p1, p2, p3) {
  return tdh1_sabit * (1 + p1 + p1*p2 + p1*p2*p3)
}

tdh_hesap = tdhHesapla(ppr1_slider, ppr2_slider, ppr3_slider)
tdh_mevcut = tdhHesapla(ppr1_ref, ppr2_ref, ppr3_ref)
tdh_fark = tdh_hesap - tdh_mevcut

// Elastikiyet: her bir PPR'nin marjinal etkisi (kısmi türev, sayısal)
d_eps = 0.01
elastik_ppr1 = (tdhHesapla(ppr1_ref + d_eps, ppr2_ref, ppr3_ref) - tdh_mevcut) / d_eps
elastik_ppr2 = (tdhHesapla(ppr1_ref, ppr2_ref + d_eps, ppr3_ref) - tdh_mevcut) / d_eps
elastik_ppr3 = (tdhHesapla(ppr1_ref, ppr2_ref, ppr3_ref + d_eps) - tdh_mevcut) / d_eps

// PPR1 grafik dizisi (diğerleri referans değerde sabit, taban çizgi için)
ppr1_dizi = Array.from({length: 91}, (_, i) => 0.50 + i * 0.005)
tdh_dizi = ppr1_dizi.map(p => tdhHesapla(p, ppr2_ref, ppr3_ref))
Kod
html`<div style="display: grid; grid-template-columns: repeat(4, 1fr); gap: 12px; margin: 16px 0;">
  <div style="background: #f8f9fa; border-left: 4px solid #1F3864; padding: 12px; border-radius: 4px;">
    <div style="font-size: 0.8em; color: #666;">Hesaplanan TDH</div>
    <div style="font-size: 1.8em; font-weight: bold; color: #1F3864;">${tdh_hesap.toFixed(3)}</div>
  </div>
  <div style="background: #f8f9fa; border-left: 4px solid ${tdh_fark >= 0 ? '#2E7D32' : '#B33A3A'}; padding: 12px; border-radius: 4px;">
    <div style="font-size: 0.8em; color: #666;">Mevcut TDH'ye fark</div>
    <div style="font-size: 1.8em; font-weight: bold; color: ${tdh_fark >= 0 ? '#2E7D32' : '#B33A3A'};">${tdh_fark >= 0 ? '+' : ''}${tdh_fark.toFixed(3)}</div>
  </div>
  <div style="background: #f8f9fa; border-left: 4px solid #9E7A1A; padding: 12px; border-radius: 4px;">
    <div style="font-size: 0.8em; color: #666;">PPR₁ mesafe (0,70 eşiğine)</div>
    <div style="font-size: 1.8em; font-weight: bold; color: ${ppr1_slider > 0.70 ? '#2E7D32' : '#B33A3A'};">${ppr1_slider > 0.70 ? '+' : ''}${(ppr1_slider - 0.70).toFixed(3)}</div>
  </div>
  <div style="background: #f8f9fa; border-left: 4px solid #666; padding: 12px; border-radius: 4px;">
    <div style="font-size: 0.8em; color: #666;">Tek çocuklu anne payı</div>
    <div style="font-size: 1.8em; font-weight: bold; color: #1F3864;">%${((1 - ppr1_slider) * 100).toFixed(0)}</div>
  </div>
</div>`
Kod
Plot.plot({
  width: 700, height: 380,
  x: {label: "PPR₁ (1→2 geçiş oranı)", domain: [0.50, 0.95]},
  y: {label: "Toplam Doğurganlık Hızı (TDH)", domain: [0.9, 2.0]},
  marks: [
    Plot.ruleY([1.30], {stroke: "#B33A3A", strokeDasharray: "6,4", strokeWidth: 1}),
    Plot.ruleY([1.70], {stroke: "#2E7D32", strokeDasharray: "6,4", strokeWidth: 1}),
    Plot.ruleY([2.10], {stroke: "#888", strokeDasharray: "3,3", strokeWidth: 1}),
    Plot.text([{x: 0.52, y: 1.32}], {text: ["Lowest-low eşiği (1,30)"], fill: "#B33A3A", fontSize: 10}),
    Plot.text([{x: 0.52, y: 1.72}], {text: ["Sürdürülebilirlik bandı (1,70)"], fill: "#2E7D32", fontSize: 10}),
    Plot.text([{x: 0.52, y: 2.12}], {text: ["Yenilenme (2,10)"], fill: "#888", fontSize: 10}),
    Plot.line(ppr1_dizi.map((p, i) => ({x: p, y: tdh_dizi[i]})), {x: "x", y: "y", stroke: "#888", strokeWidth: 1.5, strokeDasharray: "3,3"}),
    Plot.dot([{x: 0.712, y: tdh_mevcut}], {x: "x", y: "y", r: 7, fill: "#B33A3A", tip: true, title: d => `Mevcut: PPR₁=0,712 → TDH=${tdh_mevcut.toFixed(3)}`}),
    Plot.dot([{x: ppr1_slider, y: tdh_hesap}], {x: "x", y: "y", r: 8, fill: "#2E7D32", tip: true, title: d => `Secilen: PPR₁=${ppr1_slider.toFixed(3)}, PPR₂=${ppr2_slider.toFixed(3)}, PPR₃=${ppr3_slider.toFixed(3)} → TDH=${tdh_hesap.toFixed(3)}`}),
    Plot.ruleX([0.70], {stroke: "#9E7A1A", strokeDasharray: "4,4", strokeWidth: 1.5})
  ]
})
Kod
Plot.plot({
  width: 700, height: 220,
  marginLeft: 100,
  x: {label: "TDH Üzerindeki Marjinal Etki (kısmi türev)"},
  y: {label: null, domain: ["PPR₃ (3→4+)", "PPR₂ (2→3)", "PPR₁ (1→2)"], type: "band"},
  marks: [
    Plot.barX([
      {gosterge: "PPR₁ (1→2)", deger: elastik_ppr1},
      {gosterge: "PPR₂ (2→3)", deger: elastik_ppr2},
      {gosterge: "PPR₃ (3→4+)", deger: elastik_ppr3}
    ], {x: "deger", y: "gosterge", fill: "#1F3864", sort: {y: null}}),
    Plot.text([
      {gosterge: "PPR₁ (1→2)", deger: elastik_ppr1},
      {gosterge: "PPR₂ (2→3)", deger: elastik_ppr2},
      {gosterge: "PPR₃ (3→4+)", deger: elastik_ppr3}
    ], {x: "deger", y: "gosterge", text: d => d.deger.toFixed(2), dx: 20, fontSize: 11, fontWeight: "bold"})
  ]
})

Formül: TDH = TDH₁ × (1 + PPR₁ + PPR₁ × PPR₂ + PPR₁ × PPR₂ × PPR₃). Sabit tutulan 2025 bileşeni: TDH₁ = 0,608. Üst grafikte kırmızı nokta Türkiye’nin mevcut konumunu (PPR₁=0,712, PPR₂=0,507, PPR₃=0,700 → TDH=1,419), yeşil nokta seçilen üç değerin bileşik sonucunu gösterir (gri kesikli çizgi yalnızca PPR₁ eksenindeki referans patikadır, diğer ikisi sabit tutulduğunda). Alt panel, her bir geçişteki eşit büyüklükte (0,01 birim) bir iyileşmenin TDH’ye marjinal katkısını karşılaştırır: PPR₁’deki bir birim iyileşme, PPR₃’tekinin yaklaşık 5 katı etki üretir — bu, “neden ikinci çocuğa odaklanmak üçüncü çocuğa teşvik vermekten daha etkili” tezinin sayısal kanıtıdır.

2. Nüfus Piramidi Projeksiyonu (2025 → 2060)

2025’in gerçek TÜİK yaş piramidinden başlayarak, seçilen senaryoya göre nüfus yapısının nasıl dönüştüğünü gösteren interaktif projeksiyon.

Kod
viewof secilen_yil = Inputs.range([2025, 2060], {value: 2025, step: 5, label: "Yıl"})
viewof secilen_senaryo = Inputs.radio(["S0 — Müdahalesiz", "S3 — Kapsamlı politika"], {value: "S0 — Müdahalesiz", label: "Senaryo"})
Kod
yas_gruplari = ["0-4","5-9","10-14","15-19","20-24","25-29","30-34","35-39",
                 "40-44","45-49","50-54","55-59","60-64","65-69","70-74","75-79","80-84","85+"]

erkek_2025_base = [2.894, 3.667, 3.885, 3.838, 3.724, 3.918, 3.715, 3.675, 3.758, 3.620,
                    3.192, 2.632, 2.522, 1.893, 1.422, 0.898, 0.468, 0.297]
kadin_2025_base = [2.747, 3.484, 3.687, 3.642, 3.557, 3.772, 3.620, 3.614, 3.713, 3.575,
                    3.204, 2.595, 2.620, 2.022, 1.667, 1.195, 0.696, 0.574]

hayatta_kalma = [0.998, 0.999, 0.999, 0.998, 0.997, 0.996, 0.995, 0.993, 0.990, 0.985,
                  0.978, 0.967, 0.950, 0.925, 0.885, 0.820, 0.720, 0.500]

taban_S0 = ({2025: 5.641, 2030: 4.9, 2040: 3.6, 2050: 2.6, 2060: 1.9})
taban_S3 = ({2025: 5.641, 2030: 5.5, 2040: 5.3, 2050: 5.6, 2060: 5.8})

function piramitHesapla(yil, senaryo) {
  let adim = (yil - 2025) / 5
  let erkek = [...erkek_2025_base]
  let kadin = [...kadin_2025_base]
  for (let s = 0; s < adim; s++) {
    let ye = new Array(18).fill(0)
    let yk = new Array(18).fill(0)
    for (let i = 17; i > 0; i--) { ye[i] = erkek[i-1]*hayatta_kalma[i-1]; yk[i] = kadin[i-1]*hayatta_kalma[i-1] }
    let yba = 2025 + (s+1)*5
    let tt = senaryo.startsWith("S0") ? taban_S0 : taban_S3
    let keys = Object.keys(tt).map(Number).sort((a,b)=>a-b)
    let lo = keys.filter(y => y <= yba).pop(), hi = keys.filter(y => y >= yba).shift()
    let td = lo===hi ? tt[lo] : tt[lo]+(tt[hi]-tt[lo])*(yba-lo)/(hi-lo)
    ye[0] = td*0.512; yk[0] = td*0.488; erkek = ye; kadin = yk
  }
  let t = erkek.reduce((a,b)=>a+b,0) + kadin.reduce((a,b)=>a+b,0)
  return {erkek: erkek.map(v=>v/t*100), kadin: kadin.map(v=>v/t*100)}
}

piramit_veri = piramitHesapla(secilen_yil, secilen_senaryo)
taban_pay = (piramit_veri.erkek[0] + piramit_veri.kadin[0]).toFixed(1)
tepe_pay = (piramit_veri.erkek.slice(13).reduce((a,b)=>a+b,0) + piramit_veri.kadin.slice(13).reduce((a,b)=>a+b,0)).toFixed(1)
Kod
html`<div style="display: grid; grid-template-columns: 1fr 1fr; gap: 12px; margin: 8px 0;">
  <div style="background: #f8f9fa; border-left: 4px solid #1F3864; padding: 10px; border-radius: 4px;">
    <span style="font-size: 0.8em; color: #666;">Taban (0-4 yaş) payı:</span>
    <span style="font-size: 1.3em; font-weight: bold; color: #1F3864;"> %${taban_pay}</span>
  </div>
  <div style="background: #f8f9fa; border-left: 4px solid #9E7A1A; padding: 10px; border-radius: 4px;">
    <span style="font-size: 0.8em; color: #666;">Tepe (65+) payı:</span>
    <span style="font-size: 1.3em; font-weight: bold; color: #9E7A1A;"> %${tepe_pay}</span>
  </div>
</div>`
Kod
Plot.plot({
  width: 700, height: 480, marginLeft: 60,
  x: {label: "Toplam Nüfusun Payı (%)", domain: [-5.5, 5.5]},
  y: {label: null, domain: yas_gruplari, type: "band"},
  color: {domain: ["Erkek", "Kadın"], range: ["#1F3864", "#9E7A1A"]},
  marks: [
    Plot.barX(yas_gruplari.map((yg,i) => ({yas: yg, deger: -piramit_veri.erkek[i], cinsiyet: "Erkek"})),
      {x: "deger", y: "yas", fill: "cinsiyet", sort: {y: null}}),
    Plot.barX(yas_gruplari.map((yg,i) => ({yas: yg, deger: piramit_veri.kadin[i], cinsiyet: "Kadın"})),
      {x: "deger", y: "yas", fill: "cinsiyet", sort: {y: null}}),
    Plot.ruleX([0])
  ]
})

Yöntem: 2025 gerçek TÜİK piramidi başlangıç noktası; her 5 yılda bir yaş grubu yukarı kaydırılır (TÜİK hayat tablosuna yakın hayatta kalma oranlarıyla), taban (0-4 yaş girişi) seçilen senaryonun TDH eğilimine göre değişir. Tam bir kohort-bileşen modeli değil, momentum analizinin temel mekanığını görünürleştiren bir göstergedir.

3. Kohort Yarılma ve Sürdürülebilirlik Hesaplayıcı

Üç kısıt çerçevesi: kohort yarılma süresi, yıllık küçülme oranı ve yaşlı bağımlılık oranı. Türkiye’nin mevcut TDH’si bu kısıtların neresinde?

Kod
viewof tdh_slider = Inputs.range([0.80, 2.50], {value: 1.42, step: 0.01, label: "Toplam Dogurganlik Hizi (TDH)"})
viewof mu_slider = Inputs.range([26, 32], {value: 29, step: 0.5, label: "Ortalama anne yasi (mu)"})
Kod
k_katsayi = 0.478
nrr_hesap = tdh_slider * k_katsayi

// Kısıt I: Kohort yarılma > 100 yıl
kohort_yarilma = nrr_hesap >= 1.0 ? Infinity : (Math.log(2) / (-Math.log(nrr_hesap))) * mu_slider
kisit1_ok = kohort_yarilma > 100

// Kısıt II: Yıllık küçülme < %0.5
yillik_kucilme = nrr_hesap >= 1.0 ? 0 : -(Math.log(nrr_hesap) / mu_slider) * 100
kisit2_ok = yillik_kucilme < 0.5

// Kısıt III: Prospektif OADR (70+/15-69) < 0.30 (Sanderson-Scherbov yaklaşımı)
// Sustainability-Level Fertility (Sezgin 2026) Table 3'ten: stabil nüfus, Lotka modeli, 70+ tanım
oadr_tahmin = nrr_hesap >= 1.0 ? 0.24 :
              tdh_slider >= 2.09 ? 0.24 :
              tdh_slider >= 2.00 ? 0.25 :
              tdh_slider >= 1.90 ? 0.27 :
              tdh_slider >= 1.80 ? 0.29 :
              tdh_slider >= 1.70 ? 0.31 :
              tdh_slider >= 1.60 ? 0.33 :
              tdh_slider >= 1.50 ? 0.36 :
              tdh_slider >= 1.48 ? 0.37 :
              tdh_slider >= 1.30 ? 0.43 :
              tdh_slider >= 1.00 ? 0.59 : 0.70
kisit3_ok = oadr_tahmin < 0.30

karsilanan = (kisit1_ok ? 1 : 0) + (kisit2_ok ? 1 : 0) + (kisit3_ok ? 1 : 0)
Kod
html`<div style="display: grid; grid-template-columns: repeat(3, 1fr); gap: 12px; margin: 16px 0;">
  <div style="background: ${kisit1_ok ? '#e8f5e9' : '#ffebee'}; border-left: 4px solid ${kisit1_ok ? '#2E7D32' : '#B33A3A'}; padding: 12px; border-radius: 4px;">
    <div style="font-size: 0.75em; color: #666;">Kısıt I: Kohort yarılanma</div>
    <div style="font-size: 1.5em; font-weight: bold; color: ${kisit1_ok ? '#2E7D32' : '#B33A3A'};">${kohort_yarilma === Infinity ? '∞' : kohort_yarilma.toFixed(0)} yıl</div>
    <div style="font-size: 0.7em; color: #888;">Eşik: >100 yıl ${kisit1_ok ? '✓' : '✗'}</div>
  </div>
  <div style="background: ${kisit2_ok ? '#e8f5e9' : '#ffebee'}; border-left: 4px solid ${kisit2_ok ? '#2E7D32' : '#B33A3A'}; padding: 12px; border-radius: 4px;">
    <div style="font-size: 0.75em; color: #666;">Kısıt II: Yıllık küçülme</div>
    <div style="font-size: 1.5em; font-weight: bold; color: ${kisit2_ok ? '#2E7D32' : '#B33A3A'};">%${yillik_kucilme.toFixed(2)}</div>
    <div style="font-size: 0.7em; color: #888;">Eşik: <%0,50 ${kisit2_ok ? '✓' : '✗'}</div>
  </div>
  <div style="background: ${kisit3_ok ? '#e8f5e9' : '#ffebee'}; border-left: 4px solid ${kisit3_ok ? '#2E7D32' : '#B33A3A'}; padding: 12px; border-radius: 4px;">
    <div style="font-size: 0.75em; color: #666;">Kısıt III: Prospektif OADR (70+/15-69)</div>
    <div style="font-size: 1.5em; font-weight: bold; color: ${kisit3_ok ? '#2E7D32' : '#B33A3A'};">${oadr_tahmin.toFixed(2)}</div>
    <div style="font-size: 0.7em; color: #888;">Eşik: <0,30 ${kisit3_ok ? '✓' : '✗'}</div>
  </div>
</div>

<div style="background: ${karsilanan === 3 ? '#e8f5e9' : karsilanan >= 1 ? '#fff3e0' : '#ffebee'}; padding: 14px; border-radius: 6px; text-align: center; margin: 8px 0;">
  <span style="font-size: 1.1em; font-weight: bold;">
    NRR = ${nrr_hesap.toFixed(3)} | TDH = ${tdh_slider.toFixed(2)} |
    ${karsilanan}/3 kısıt karşılanıyor |
    ${karsilanan === 3 ? 'SÜRDÜRÜLEBİLİR ✓' : karsilanan >= 1 ? 'KISMİ RİSK ⚠' : 'SÜRDÜRÜLEMEz ✗'}
  </span>
</div>

<div style="font-size: 0.85em; color: #666; margin-top: 6px;">
  Sürdürülebilirlik bandı: TDH ≥ 1,70 (minimum) | TDH ≥ 1,81 (üç kısıt birlikte) | Türkiye mevcut: TDH = 1,42 (bant dışında)
</div>`

Formül: NRR = TDH × k (k = 0,478). Kohort yarılanma = ln(2) / (−ln(NRR)) × μ. Yıllık küçülme = −ln(NRR) / μ. Prospektif OADR (70+/15-69): stabil nüfus modelinden (Lotka), Sanderson-Scherbov (2010) yaklaşımıyla — kalan yaşam beklentisi 15 yılın altındaki nüfusun çalışma çağı nüfusuna oranı. Değerler Sustainability-Level Fertility (Sezgin, 2026) Table 3’ten alınmıştır. Not: Bu, Türkiye’nin güncel (2024) OADR’si değil, seçilen TDH’nin sonsuza kadar sürmesi halinde nüfusun ulaşacağı uzun dönem denge durumundaki (stabil nüfus) değerdir.

μ (ortalama anne yaşı) neden bu yönde çalışıyor? Kaydırıcıda μ küçüldüğünde kohort yarılanma süresi de küçülür — bu ilk bakışta sezgiye aykırı görünebilir (“anneler daha genç doğuruyorsa nüfus daha mı hızlı çökermiş?”). Burada μ, NRR’yi sabit tutarak yalnızca nesil döngüsünün takvimde ne kadar sık tekrarlandığını gösterir: aynı küçülme oranı (NRR) daha kısa aralıklarla tekrarlanırsa, yıl bazında çöküş daha hızlı birikir — tıpkı aynı faiz oranının yıllık değil aylık bileşik olarak işlemesi gibi. Bu, μ’nün gerçek hayatta erken doğum üzerinden NRR’yi (çocuk sayısını) etkileme yolunu içermez — o ayrı ve genelde ters yönlü bir mekanizmadır (örn. erken evlenme/doğum, kalan doğurganlık penceresini uzatarak NRR’yi yükseltebilir). Bu araç, μ ve NRR’yi birbirinden bağımsız iki kaydırıcı olarak ele alır; ikisinin birbirini nasıl etkilediğini modellemez.

4. Toplam Nüfus Projeksiyon Simülatörü (2025–2225, 200 Yıl)

TDH farklı sabit değerlerde tutulsa, 200 yıl boyunca Türkiye nüfusu nasıl bir patika izler? Kısa vadeli momentum ile uzun vadeli küçülme arasındaki fark.

Kod
viewof tdh_momentum = Inputs.range([1.00, 2.50], {value: 1.42, step: 0.02, label: "TDH (sabit tutulursa):"})
Kod
nrr_mom = tdh_momentum * 0.478
mu_mom = 29
nufus_2025 = 86.1  // milyon

// Belgelenmiş senaryo projeksiyonları (milyon, göç hariç), 2025-2105 gerçek/doğrulanmış,
// 2105 sonrası 2080-2105 aralığındaki ortalama büyüme hızının (r) uzatılmasıyla 2225'e taşınmıştır.
// Kaynak: Görülmez Kriz, Sezgin (2026), Tablo 3.2 (2025-2105); yazar uzantısı (2125-2225).
proj_S0 = ({2025:86.1, 2030:88.0, 2040:89.3, 2050:86.5, 2060:80.7, 2080:63.2, 2105:39.5, 2125:27.1, 2150:17.0, 2175:10.6, 2200:6.6, 2225:4.1})
proj_S1 = ({2025:86.1, 2030:88.0, 2040:90.1, 2050:89.4, 2060:85.2, 2080:71.7, 2105:52.4, 2125:40.8, 2150:29.8, 2175:21.8, 2200:15.9, 2225:11.6})
proj_S2 = ({2025:86.1, 2030:90.2, 2040:96.6, 2050:100.1, 2060:101.1, 2080:101.2, 2105:100.8, 2125:100.5, 2150:100.1, 2175:99.7, 2200:99.3, 2225:98.9})
proj_S3 = ({2025:86.1, 2030:88.0, 2040:91.4, 2050:92.0, 2060:89.1, 2080:79.4, 2105:65.1, 2125:55.5, 2150:45.5, 2175:37.3, 2200:30.6, 2225:25.1})

function interpolateScenario(tdh_val) {
  let scenarios = [
    {tdh: 1.00, proj: proj_S0},
    {tdh: 1.40, proj: proj_S1},
    {tdh: 1.70, proj: proj_S3},
    {tdh: 2.10, proj: proj_S2}
  ]
  if (tdh_val <= 1.00) return proj_S0
  if (tdh_val >= 2.10) return proj_S2
  let lo = scenarios.filter(s => s.tdh <= tdh_val).pop()
  let hi = scenarios.filter(s => s.tdh >= tdh_val).shift()
  if (lo.tdh === hi.tdh) return lo.proj
  let alpha = (tdh_val - lo.tdh) / (hi.tdh - lo.tdh)
  let result = {}
  for (let y of Object.keys(lo.proj)) {
    result[y] = lo.proj[y] + alpha * (hi.proj[y] - lo.proj[y])
  }
  return result
}

secilen_proj = interpolateScenario(tdh_momentum)
proj_vals = Object.values(secilen_proj)
zirve_nufus = Math.max(...proj_vals)
zirve_yil_idx = proj_vals.indexOf(zirve_nufus)
zirve_yil = Object.keys(secilen_proj)[zirve_yil_idx]
Kod
html`<div style="display: grid; grid-template-columns: repeat(4, 1fr); gap: 12px; margin: 16px 0;">
  <div style="background: #f8f9fa; border-left: 4px solid #1F3864; padding: 12px; border-radius: 4px;">
    <div style="font-size: 0.75em; color: #666;">Zirve nüfusu</div>
    <div style="font-size: 1.5em; font-weight: bold; color: #1F3864;">${zirve_nufus.toFixed(1)}M</div>
    <div style="font-size: 0.7em; color: #888;">~${zirve_yil} civarında</div>
  </div>
  <div style="background: #f8f9fa; border-left: 4px solid #9E7A1A; padding: 12px; border-radius: 4px;">
    <div style="font-size: 0.75em; color: #666;">2060 projeksiyonu</div>
    <div style="font-size: 1.5em; font-weight: bold; color: #9E7A1A;">${secilen_proj[2060].toFixed(1)}M</div>
  </div>
  <div style="background: #f8f9fa; border-left: 4px solid #888; padding: 12px; border-radius: 4px;">
    <div style="font-size: 0.75em; color: #666;">2125 projeksiyonu (100 yıl)</div>
    <div style="font-size: 1.5em; font-weight: bold; color: #888;">${secilen_proj[2125].toFixed(1)}M</div>
  </div>
  <div style="background: #f8f9fa; border-left: 4px solid #B33A3A; padding: 12px; border-radius: 4px;">
    <div style="font-size: 0.75em; color: #666;">2225 projeksiyonu (200 yıl)</div>
    <div style="font-size: 1.5em; font-weight: bold; color: #B33A3A;">${secilen_proj[2225].toFixed(1)}M</div>
  </div>
</div>`
Kod
yillar_200 = [2025, 2030, 2040, 2050, 2060, 2080, 2105, 2125, 2150, 2175, 2200, 2225]

s0_200 = yillar_200.map(y => ({yil: y, nufus: proj_S0[y], senaryo: "S0 (düşüş devam)"}))
s2_200 = yillar_200.map(y => ({yil: y, nufus: proj_S2[y], senaryo: "S2 (anında yenilenme)"}))
secilen_200 = yillar_200.map(y => ({yil: y, nufus: secilen_proj[y], senaryo: `Seçilen (TDH=${tdh_momentum.toFixed(2)})`}))

proj_data_200 = [...s0_200, ...secilen_200, ...s2_200]

Plot.plot({
  width: 700, height: 400,
  x: {label: "Yıl", domain: [2025, 2225]},
  y: {label: "Nüfus (milyon)", domain: [0, 110]},
  color: {domain: ["S0 (düşüş devam)", `Seçilen (TDH=${tdh_momentum.toFixed(2)})`, "S2 (anında yenilenme)"],
          range: ["#B33A3A", "#1F3864", "#888888"]},
  marks: [
    Plot.ruleX([2105], {stroke: "#ccc", strokeDasharray: "2,2"}),
    Plot.text([{x: 2105, y: 105}], {text: ["80 yıl"], fill: "#aaa", fontSize: 9}),
    Plot.ruleX([2225], {stroke: "#ccc", strokeDasharray: "2,2"}),
    Plot.text([{x: 2200, y: 105}], {text: ["200 yıl"], fill: "#aaa", fontSize: 9}),
    Plot.line(proj_data_200, {x: "yil", y: "nufus", stroke: "senaryo",
      strokeWidth: d => d.senaryo.startsWith("Seçilen") ? 2.5 : 1.5,
      strokeDasharray: d => d.senaryo.startsWith("S2") ? "4,4" : null}),
    Plot.dot(proj_data_200.filter(d => d.senaryo.startsWith("Seçilen")),
      {x: "yil", y: "nufus", fill: "#1F3864", r: 4, tip: true,
       title: d => `${d.yil}: ${d.nufus.toFixed(1)}M`})
  ]
})

Yöntem: 2025–2105 değerleri belgelenmiş S0/S1/S2/S3 senaryo projeksiyonlarından (kohort-bileşen modeli, göç hariç); kullanıcının seçtiği TDH’ye göre bu dört sabit nokta arasında lineer interpolasyon yapılır. 2105 sonrası (2125–2225), 2080–2105 aralığındaki ortalama büyüme/küçülme hızının sabit tutularak ileri taşınmasıdır — bu kısım doğrulanmış bir kohort-bileşen çıktısı değil, basitleştirilmiş bir uzantıdır ve yalnızca büyüklüğün mertebesini göstermek içindir. NRR=1 (TDH≈2,10) senaryosunda nüfus ~100M civarında stabilize olur (Keyfitz momentum, M=1,180); altındaki her TDH değeri süresiz küçülmeye gider.

5. Göç Senaryosu Simülatörü

Doğurganlık açığı net göçle kapatılabilir mi? Göçmen TDH’sinin (2,1) doğurganlık çarpanıyla birlikte hesaplanan kohort-bileşen modeli.

Kod
viewof goc_slider = Inputs.range([0, 500], {value: 0, step: 10, label: "Yıllık net göç (bin kişi)"})
Kod
goc_senaryolari = ([
  {goc: 0,   nufus2100: 53,  azalma: 13.2, kumulatif: 0,  oadr: 59},
  {goc: 100, nufus2100: 69,  azalma: 8.8,  kumulatif: 8,  oadr: 51},
  {goc: 250, nufus2100: 89,  azalma: 4.4,  kumulatif: 19, oadr: 44},
  {goc: 300, nufus2100: 96,  azalma: 3.4,  kumulatif: 23, oadr: 43},
  {goc: 500, nufus2100: 123, azalma: 0.2,  kumulatif: 38, oadr: 39}
])

function gocInterpolate(g) {
  let pts = goc_senaryolari
  if (g <= 0) return pts[0]
  if (g >= 500) return pts[pts.length-1]
  let lo = pts.filter(p => p.goc <= g).pop()
  let hi = pts.filter(p => p.goc >= g).shift()
  if (lo.goc === hi.goc) return lo
  let alpha = (g - lo.goc) / (hi.goc - lo.goc)
  return {
    goc: g,
    nufus2100: lo.nufus2100 + alpha*(hi.nufus2100-lo.nufus2100),
    azalma: lo.azalma + alpha*(hi.azalma-lo.azalma),
    kumulatif: lo.kumulatif + alpha*(hi.kumulatif-lo.kumulatif),
    oadr: lo.oadr + alpha*(hi.oadr-lo.oadr)
  }
}

goc_secilen = gocInterpolate(goc_slider)
azalma_ok = goc_secilen.azalma < 5.0   // Kısıt II eşiği (binde 5)
oadr_ok = goc_secilen.oadr < 30
Kod
html`<div style="display: grid; grid-template-columns: repeat(4, 1fr); gap: 12px; margin: 16px 0;">
  <div style="background: #f8f9fa; border-left: 4px solid #1F3864; padding: 12px; border-radius: 4px;">
    <div style="font-size: 0.75em; color: #666;">2100 nüfusu</div>
    <div style="font-size: 1.5em; font-weight: bold; color: #1F3864;">${goc_secilen.nufus2100.toFixed(0)}M</div>
  </div>
  <div style="background: ${azalma_ok ? '#e8f5e9' : '#ffebee'}; border-left: 4px solid ${azalma_ok ? '#2E7D32' : '#B33A3A'}; padding: 12px; border-radius: 4px;">
    <div style="font-size: 0.75em; color: #666;">Yıllık azalma (Kısıt II)</div>
    <div style="font-size: 1.5em; font-weight: bold; color: ${azalma_ok ? '#2E7D32' : '#B33A3A'};">‰${goc_secilen.azalma.toFixed(1)}</div>
    <div style="font-size: 0.7em; color: #888;">Eşik: <‰5,0 ${azalma_ok ? '✓' : '✗'}</div>
  </div>
  <div style="background: ${oadr_ok ? '#e8f5e9' : '#ffebee'}; border-left: 4px solid ${oadr_ok ? '#2E7D32' : '#B33A3A'}; padding: 12px; border-radius: 4px;">
    <div style="font-size: 0.75em; color: #666;">2100 OADR (Kısıt III)</div>
    <div style="font-size: 1.5em; font-weight: bold; color: ${oadr_ok ? '#2E7D32' : '#B33A3A'};">%${goc_secilen.oadr.toFixed(0)}</div>
    <div style="font-size: 0.7em; color: #888;">Eşik: <%30 ${oadr_ok ? '✓' : '✗'}</div>
  </div>
  <div style="background: #f8f9fa; border-left: 4px solid #9E7A1A; padding: 12px; border-radius: 4px;">
    <div style="font-size: 0.75em; color: #666;">Kümülatif göç (75 yıl)</div>
    <div style="font-size: 1.5em; font-weight: bold; color: #9E7A1A;">${goc_secilen.kumulatif.toFixed(0)}M</div>
  </div>
</div>`
Kod
Plot.plot({
  width: 700, height: 380,
  x: {label: "Yıllık net göç (bin kişi)", domain: [0, 500]},
  y: {label: "2100 Nüfusu (milyon)", domain: [40, 130]},
  marks: [
    Plot.line(goc_senaryolari, {x: "goc", y: "nufus2100", stroke: "#1F3864", strokeWidth: 2.5}),
    Plot.dot(goc_senaryolari, {x: "goc", y: "nufus2100", fill: "#1F3864", r: 5, tip: true,
      title: d => `${d.goc}K/yıl → ${d.nufus2100}M (2100), OADR %${d.oadr}`}),
    Plot.dot([{x: goc_slider, y: goc_secilen.nufus2100}], {x: "x", y: "y", r: 7, fill: "#2E7D32"}),
    Plot.ruleX([250], {stroke: "#9E7A1A", strokeDasharray: "4,4"}),
    Plot.text([{x: 260, y: 125}], {text: ["Kısıt II eşiği (~250K/yıl)"], fill: "#9E7A1A", fontSize: 10})
  ]
})

Kritik sınır: Göç, yalnızca nüfus düşüş hızı kısıtını (Kısıt II, <binde 5) karşılayabilir — 250 bin/yıl net göç ile bu eşik karşılanır. Ancak OADR kısıtı (Kısıt III, <%30) hiçbir göç senaryosunda karşılanmaz: 500 bin/yıl ile bile 2100 OADR’si %39’da kalır. Göç, doğurganlık davranışının kendisini (NRR) değiştirmez; yaş yapısını iyileştirir ama yeterli ölçekte değil. Göçmen TDH=2,1 varsayımıyla kohort-bileşen modeli kullanılmıştır (basit g=r+m formülü reddedilmiştir — bkz. yöntem notu).

Kaynak: Göç Projeksiyonu Devamlılık Notu, 19 Haziran 2026 — doğrulanmış senaryo tablosu.

6. SGK Aktif/Pasif Baskı Testi

Çalışma çağı nüfusu daraldıkça ve emekli nüfus büyüdükçe, sosyal güvenlik sisteminin çöken dengesi.

Kod
viewof tdh_sgk = Inputs.range([0.80, 2.10], {value: 1.42, step: 0.05, label: "TDH senaryosu"})
viewof emeklilik_yasi = Inputs.range([58, 68], {value: 62, step: 1, label: "Fiili emeklilik yaşı"})
Kod
sgk_yillar = [2022, 2025, 2030, 2035, 2040, 2045, 2050, 2055, 2060]

function sgkProj(tdh_val, em_yas) {
  let nrr = tdh_val * 0.478
  let r = nrr >= 1.0 ? 0 : Math.log(nrr) / 29
  
  // Baz oran 2025: 1.59
  // Yaşlanan nüfus + küçülen çalışma çağı → oran düşer
  // Emeklilik yaşı yükseldikçe oran iyileşir (daha az pasif)
  let baz = 1.59
  let em_etki = (em_yas - 62) * 0.04 // her yıl emeklilik yaşı artışı ~ +0.04 oran
  
  return sgk_yillar.map(y => {
    let t = y - 2025
    // Demografik bozulma: yaş yapısı yaşlanıyor
    let dem_bozulma = t * 0.015 * (1 - nrr) // NRR düşükse bozulma hızlanır
    let oran = Math.max(0.5, baz + em_etki - dem_bozulma)
    return {yil: y, oran: oran, senaryo: `TDH=${tdh_val.toFixed(2)}, Em.yası=${em_yas}`}
  })
}

sgk_gercek = [{yil: 2022, oran: 2.01}, {yil: 2023, oran: 1.73}, {yil: 2024, oran: 1.63}, {yil: 2025, oran: 1.59}]
sgk_proj = sgkProj(tdh_sgk, emeklilik_yasi)
sgk_proj_ref = sgkProj(1.40, 62) // referans S0

// 1.0 eşiğine varılma yılı
esik_yil = sgk_proj.find(d => d.oran <= 1.0)
Kod
html`<div style="display: grid; grid-template-columns: repeat(3, 1fr); gap: 12px; margin: 16px 0;">
  <div style="background: #f8f9fa; border-left: 4px solid #1F3864; padding: 12px; border-radius: 4px;">
    <div style="font-size: 0.75em; color: #666;">Mevcut oran (2025)</div>
    <div style="font-size: 1.8em; font-weight: bold; color: #1F3864;">1,591</div>
  </div>
  <div style="background: #f8f9fa; border-left: 4px solid #9E7A1A; padding: 12px; border-radius: 4px;">
    <div style="font-size: 0.75em; color: #666;">Projeksiyon 2060</div>
    <div style="font-size: 1.8em; font-weight: bold; color: ${sgk_proj[sgk_proj.length-1].oran <= 1.0 ? '#B33A3A' : '#9E7A1A'};">${sgk_proj[sgk_proj.length-1].oran.toFixed(2)}</div>
  </div>
  <div style="background: ${esik_yil ? '#ffebee' : '#e8f5e9'}; border-left: 4px solid ${esik_yil ? '#B33A3A' : '#2E7D32'}; padding: 12px; border-radius: 4px;">
    <div style="font-size: 0.75em; color: #666;">1,0 eşiğine varış</div>
    <div style="font-size: 1.8em; font-weight: bold; color: ${esik_yil ? '#B33A3A' : '#2E7D32'};">${esik_yil ? `~${esik_yil.yil}` : '>2060'}</div>
  </div>
</div>`
Kod
sgk_all = [
  ...sgk_gercek.map(d => ({...d, senaryo: "Gerçekleşen"})),
  ...sgk_proj.map(d => ({...d, senaryo: "Seçilen senaryo"})),
  ...sgk_proj_ref.map(d => ({...d, senaryo: "S0 referans (TDH=1.40, Em=62)"}))
]

Plot.plot({
  width: 700, height: 380,
  x: {label: "Yıl", tickFormat: d => d.toString()},
  y: {label: "Aktif/Pasif Oranı", domain: [0.5, 2.2]},
  color: {domain: ["Gerçekleşen", "Seçilen senaryo", "S0 referans (TDH=1.40, Em=62)"], range: ["#1F3864", "#2E7D32", "#B33A3A"]},
  marks: [
    Plot.ruleY([1.0], {stroke: "#B33A3A", strokeDasharray: "6,4", strokeWidth: 2}),
    Plot.text([{x: 2035, y: 1.05}], {text: ["Sistemik çöküş eşiği (1,0)"], fill: "#B33A3A", fontSize: 10}),
    Plot.line(sgk_all, {x: "yil", y: "oran", stroke: "senaryo", strokeWidth: 2}),
    Plot.dot(sgk_all.filter(d => d.senaryo === "Gerçekleşen"), {x: "yil", y: "oran", fill: "#1F3864", r: 5, tip: true,
      title: d => `${d.yil}: ${d.oran.toFixed(2)}`})
  ]
})

Uyarı: Bu model basitleştirilmiş bir demografik-aktüaryal projeksiyondur; gerçek SGK dengesini belirleyen kayıt dışı istihdam oranı, prim gün sayısı, asıl-tali sigortalılık dağılımları ve emeklilik yaş kademesi gibi kurumsal değişkenler dahil edilmemiştir. Gösterdiği şey: demografik yapı değişmezse, kurumsal parametreleri ne kadar düzeltirseniz düzeltin, aktif/pasif oranının düşüş yönünün değişmeyeceğidir. SGK gerçek aktif/pasif oranı: 2022 = 2,01 (zirve); Ocak 2026 = 1,591.

7. İstenen vs Gerçekleşen Doğurganlık Makası

“Kriz bir istek eksikliği değil, bir güvence eksikliğidir” tezinin doğrudan sayısal kanıtı: TNSA 2018’e göre hiç çocuğu olmayan kadınlar dahi ortalama 2,6 çocuğu ideal görüyor — ama gerçekleşen TDH bunun çok altında kalıyor.

Kod
viewof mevcut_cocuk = Inputs.radio(["0 (henüz çocuksuz)", "1 (bir çocuklu)", "2 (iki çocuklu)", "3+ (üç ve üzeri)"], {value: "0 (henüz çocuksuz)", label: "Mevcut çocuk sayısı"})
Kod
ideal_tablo = ({
  "0 (henüz çocuksuz)": 2.6,
  "1 (bir çocuklu)": 2.8,
  "2 (iki çocuklu)": 3.2,
  "3+ (üç ve üzeri)": 3.8
})

tdh_gerceklesen = 1.419  // 2025 TÜİK
tdh_istihdamda = 1.38
tdh_istihdam_disi = 1.72

ideal_secilen = ideal_tablo[mevcut_cocuk]
makas = ideal_secilen - tdh_gerceklesen
Kod
html`<div style="display: grid; grid-template-columns: repeat(3, 1fr); gap: 12px; margin: 16px 0;">
  <div style="background: #f8f9fa; border-left: 4px solid #9E7A1A; padding: 12px; border-radius: 4px;">
    <div style="font-size: 0.75em; color: #666;">İdeal çocuk sayısı (TNSA 2018)</div>
    <div style="font-size: 1.8em; font-weight: bold; color: #9E7A1A;">${ideal_secilen.toFixed(1)}</div>
  </div>
  <div style="background: #f8f9fa; border-left: 4px solid #1F3864; padding: 12px; border-radius: 4px;">
    <div style="font-size: 0.75em; color: #666;">Gerçekleşen TDH (2025)</div>
    <div style="font-size: 1.8em; font-weight: bold; color: #1F3864;">${tdh_gerceklesen.toFixed(2)}</div>
  </div>
  <div style="background: #ffebee; border-left: 4px solid #B33A3A; padding: 12px; border-radius: 4px;">
    <div style="font-size: 0.75em; color: #666;">Makas (İdeal - Gerçekleşen)</div>
    <div style="font-size: 1.8em; font-weight: bold; color: #B33A3A;">${makas.toFixed(2)}</div>
  </div>
</div>`
Kod
makas_veri = [
  {kategori: "İdeal", deger: ideal_secilen},
  {kategori: "Gerçekleşen", deger: tdh_gerceklesen}
]

Plot.plot({
  width: 700, height: 380,
  x: {label: null, domain: ["İdeal", "Gerçekleşen"]},
  y: {label: "Çocuk Sayısı", domain: [0, 4.2]},
  color: {domain: ["İdeal", "Gerçekleşen"], range: ["#9E7A1A", "#1F3864"]},
  marks: [
    Plot.barY(makas_veri, {x: "kategori", y: "deger", fill: "kategori"}),
    Plot.text(makas_veri, {x: "kategori", y: d => d.deger + 0.15, text: d => d.deger.toFixed(2), fontSize: 12, fontWeight: "bold"}),
    Plot.ruleY([2.1], {stroke: "#888", strokeDasharray: "4,4"}),
    Plot.text([{x: "Gerçekleşen", y: 2.25}], {x: "x", y: "y", text: ["Yenilenme (2,1)"], fill: "#888", fontSize: 9, dx: 40})
  ]
})

İstihdam durumuna göre makas: Çalışan kadınlarda gerçekleşen TDH 1,38; istihdam dışı kadınlarda 1,72’dir (fark: 0,34 çocuk). Her iki grup da kendi TNSA idealinin (2,6-3,8 bandı) çok altında kalmaktadır — istihdamda olmak makası biraz daraltsa da, hiçbir grup idealine yaklaşamamaktadır. Bu, krizin yalnızca “kariyer odaklı erteleme” olmadığını, tüm toplumsal kesimlere yayılmış sistemik bir güvence sorunu olduğunu göstermektedir.

Kaynak: TNSA 2018 (Hacettepe Üniversitesi Nüfus Etütleri Enstitüsü) ideal çocuk sayısı tablosu; TÜİK 2025 TDH; istihdam durumuna göre TDH (Demografik Güvenlik araştırma notu, Sezgin 2026). Bu makas, herhangi bir kaydırıcı değişmeden bile (mevcut çocuk sayısı 0 seçili) zaten ~1,2 çocukluk bir açıktır — kriz bir istek eksikliği değil, bir güvence eksikliğidir.

8. Doğum Sırasına Göre TDH Ayrıştırıcısı

Başlangıç yılını kaydırın: toplam doğurganlık hızındaki o yıldan 2025’e kadarki değişimin hangi doğum sırasından (1., 2., 3., 4+. çocuk) kaynaklandığını görün.

Kod
viewof yil_a = Inputs.range([2013, 2024], {value: 2013, step: 1, label: "Baslangic yili (bitis: 2025)"})
Kod
yillar_tdh_ayristirma = [2013,2014,2015,2016,2017,2018,2019,2020,2021,2022,2023,2024,2025]
tdh1_seri = [0.767,0.786,0.787,0.774,0.765,0.728,0.692,0.661,0.619,0.633,0.616,0.624,0.611]
tdh2_seri = [0.694,0.710,0.695,0.680,0.668,0.649,0.609,0.572,0.558,0.508,0.468,0.457,0.435]
tdh3_seri = [0.369,0.399,0.396,0.389,0.381,0.371,0.348,0.319,0.313,0.287,0.252,0.239,0.220]
tdh4_seri = [0.277,0.290,0.278,0.271,0.267,0.257,0.241,0.220,0.222,0.205,0.181,0.168,0.154]

yil_b = 2025

idx_a = yillar_tdh_ayristirma.indexOf(yil_a)
idx_b = yillar_tdh_ayristirma.indexOf(yil_b)

deger_a = ({
  cocuk1: tdh1_seri[idx_a], cocuk2: tdh2_seri[idx_a],
  cocuk3: tdh3_seri[idx_a], cocuk4: tdh4_seri[idx_a]
})
deger_b = ({
  cocuk1: tdh1_seri[idx_b], cocuk2: tdh2_seri[idx_b],
  cocuk3: tdh3_seri[idx_b], cocuk4: tdh4_seri[idx_b]
})

tdh_a_toplam = deger_a.cocuk1 + deger_a.cocuk2 + deger_a.cocuk3 + deger_a.cocuk4
tdh_b_toplam = deger_b.cocuk1 + deger_b.cocuk2 + deger_b.cocuk3 + deger_b.cocuk4
fark_toplam = tdh_b_toplam - tdh_a_toplam

fark_1 = deger_b.cocuk1 - deger_a.cocuk1
fark_2 = deger_b.cocuk2 - deger_a.cocuk2
fark_3 = deger_b.cocuk3 - deger_a.cocuk3
fark_4 = deger_b.cocuk4 - deger_a.cocuk4

// En büyük katkıyı (mutlak değer) bulan yardımcı
katkilar = [
  {ad: "1. Çocuk", deger: fark_1},
  {ad: "2. Çocuk", deger: fark_2},
  {ad: "3. Çocuk", deger: fark_3},
  {ad: "4+ Çocuk", deger: fark_4}
]
en_buyuk_katki = katkilar.slice().sort((a,b) => Math.abs(b.deger) - Math.abs(a.deger))[0]
Kod
html`<div style="display: grid; grid-template-columns: repeat(3, 1fr); gap: 12px; margin: 16px 0;">
  <div style="background: #f8f9fa; border-left: 4px solid #888; padding: 12px; border-radius: 4px;">
    <div style="font-size: 0.75em; color: #666;">TDH ${yil_a}</div>
    <div style="font-size: 1.6em; font-weight: bold; color: #888;">${tdh_a_toplam.toFixed(2)}</div>
  </div>
  <div style="background: #f8f9fa; border-left: 4px solid #1F3864; padding: 12px; border-radius: 4px;">
    <div style="font-size: 0.75em; color: #666;">TDH ${yil_b}</div>
    <div style="font-size: 1.6em; font-weight: bold; color: #1F3864;">${tdh_b_toplam.toFixed(2)}</div>
  </div>
  <div style="background: ${fark_toplam < 0 ? '#ffebee' : '#e8f5e9'}; border-left: 4px solid ${fark_toplam < 0 ? '#B33A3A' : '#2E7D32'}; padding: 12px; border-radius: 4px;">
    <div style="font-size: 0.75em; color: #666;">En büyük katkı: ${en_buyuk_katki.ad}</div>
    <div style="font-size: 1.6em; font-weight: bold; color: ${fark_toplam < 0 ? '#B33A3A' : '#2E7D32'};">${en_buyuk_katki.deger >= 0 ? '+' : ''}${en_buyuk_katki.deger.toFixed(3)}</div>
  </div>
</div>`
Kod
bar_veri = [
  {yil: String(yil_a), siralama: "1. Çocuk", deger: deger_a.cocuk1, fark: 0},
  {yil: String(yil_a), siralama: "2. Çocuk", deger: deger_a.cocuk2, fark: 0},
  {yil: String(yil_a), siralama: "3. Çocuk", deger: deger_a.cocuk3, fark: 0},
  {yil: String(yil_a), siralama: "4+ Çocuk", deger: deger_a.cocuk4, fark: 0},
  {yil: String(yil_b), siralama: "1. Çocuk", deger: deger_b.cocuk1, fark: fark_1},
  {yil: String(yil_b), siralama: "2. Çocuk", deger: deger_b.cocuk2, fark: fark_2},
  {yil: String(yil_b), siralama: "3. Çocuk", deger: deger_b.cocuk3, fark: fark_3},
  {yil: String(yil_b), siralama: "4+ Çocuk", deger: deger_b.cocuk4, fark: fark_4}
]

siralama_renkleri = ["#1F3864","#9E7A1A","#5B8C5A","#B33A3A"]

Plot.plot({
  width: 700, height: 420,
  marginRight: 60,
  x: {label: null, domain: [String(yil_a), String(yil_b)]},
  y: {label: "TDH Bileşeni (çocuk sayısı)", domain: [0, Math.max(tdh_a_toplam, tdh_b_toplam) + 0.15]},
  color: {domain: ["1. Çocuk","2. Çocuk","3. Çocuk","4+ Çocuk"], range: siralama_renkleri, legend: true},
  marks: [
    Plot.barY(bar_veri, {x: "yil", y: "deger", fill: "siralama", order: ["4+ Çocuk","3. Çocuk","2. Çocuk","1. Çocuk"]}),
    Plot.text(bar_veri, {x: "yil", y: "deger", text: d => d.deger.toFixed(2),
      fill: "white", fontSize: 11, fontWeight: "bold"
    }),
    Plot.text(bar_veri.filter(d => d.yil === String(yil_b)), {x: "yil", y: "deger",
      text: d => d.fark === 0 ? "" : (d.fark > 0 ? `+${d.fark.toFixed(2)}` : d.fark.toFixed(2)),
      dx: 45, fontSize: 11, fontWeight: "bold",
      fill: d => d.fark < 0 ? "#B33A3A" : "#2E7D32"})
  ]
})
Kod
html`<div style="font-size: 0.9em; color: #444; background: #FAFAF8; border-left: 4px solid #9E7A1A; padding: 10px 14px; margin: 10px 0;">
<strong>Nasıl okunur:</strong> Sol sütun <strong>${yil_a}</strong>, sağ sütun <strong>2025</strong> yılına ait TDH'nin doğum sırasına göre bileşenlerini gösterir (her renk bir doğum sırası). Sağ sütunun yanında, ${yil_a}'dan 2025'e o bileşendeki değişim (kırmızı=azalma, yeşil=artma) etiketlenmiştir.
</div>`

Kaynak: TÜİK Doğum İstatistikleri, doğum sırasına göre TDH bileşenleri (TDHₙ = TDH × (n. sıra payı/100)), 2013-2025 tam seri (resmi TDH serisine tam toplanacak şekilde ölçeklenmiştir). Varsayılan seçimde (2013→2025), toplam TDH kaybının (-0,68) en büyük tek kaynağı 2. çocuktur (1→2 geçişi) — diğer üç bileşenin her biri ayrı ayrı daha az katkı yapar. Kaydırıcıyı değiştirerek son dönemdeki hızlanmayı da gözlemleyebilirsiniz (örn. 2021’den başlatıp 2025’e kadarki değişime bakın).

9. HWP Ayrıştırma Simülatörü

2013’ten 2024’e TDH kaybının (−0,626) hangi bileşenlerden geldiğini gösteren HWP ayrıştırmasını tersine çevirin: her bir bileşendeki kaybın ne kadarını “geri kazansak” TDH ne olurdu?

Kod
viewof iyilesme_evlilik = Inputs.range([0, 100], {value: 0, step: 5, label: "Evlilik etkisi iyilesme (%)"})
viewof iyilesme_ppr1 = Inputs.range([0, 100], {value: 0, step: 5, label: "1→2 gecis (PPR₁) iyilesme (%)"})
viewof iyilesme_ppr2plus = Inputs.range([0, 100], {value: 0, step: 5, label: "2→3 ve sonrasi gecisler iyilesme (%)"})
Kod
tdh_2013_hwp = 2.110
tdh_2024_hwp = 1.484

katki_evlilik = -0.019 + -0.077 + -0.066 + -0.056  // dort evlilik yas grubu toplami
katki_ppr1 = -0.354
katki_ppr2plus = -0.006 + -0.021 + -0.027  // 2->3, 3->4, 4+ gecisleri toplami

toplam_kayip_dogrulama = katki_evlilik + katki_ppr1 + katki_ppr2plus

// Kullanıcının seçtiği iyileşme oranlarına göre kalan kayıp
kalan_kayip_evlilik = katki_evlilik * (1 - iyilesme_evlilik/100)
kalan_kayip_ppr1 = katki_ppr1 * (1 - iyilesme_ppr1/100)
kalan_kayip_ppr2plus = katki_ppr2plus * (1 - iyilesme_ppr2plus/100)

tdh_simulasyon = tdh_2013_hwp + kalan_kayip_evlilik + kalan_kayip_ppr1 + kalan_kayip_ppr2plus
tdh_kazanc = tdh_simulasyon - tdh_2024_hwp
Kod
html`<div style="display: grid; grid-template-columns: repeat(3, 1fr); gap: 12px; margin: 16px 0;">
  <div style="background: #f8f9fa; border-left: 4px solid #888; padding: 12px; border-radius: 4px;">
    <div style="font-size: 0.75em; color: #666;">TDH 2024 (gerçekleşen)</div>
    <div style="font-size: 1.6em; font-weight: bold; color: #888;">${tdh_2024_hwp.toFixed(3)}</div>
  </div>
  <div style="background: #f8f9fa; border-left: 4px solid #1F3864; padding: 12px; border-radius: 4px;">
    <div style="font-size: 0.75em; color: #666;">TDH (simulasyon)</div>
    <div style="font-size: 1.6em; font-weight: bold; color: #1F3864;">${tdh_simulasyon.toFixed(3)}</div>
  </div>
  <div style="background: ${tdh_kazanc > 0 ? '#e8f5e9' : '#f8f9fa'}; border-left: 4px solid ${tdh_kazanc > 0 ? '#2E7D32' : '#888'}; padding: 12px; border-radius: 4px;">
    <div style="font-size: 0.75em; color: #666;">Kazanc</div>
    <div style="font-size: 1.6em; font-weight: bold; color: ${tdh_kazanc > 0 ? '#2E7D32' : '#888'};">+${tdh_kazanc.toFixed(3)}</div>
  </div>
</div>`
Kod
waterfall_veri = [
  {asama: "TDH 2013", deger: tdh_2013_hwp, tip: "baz"},
  {asama: "Evlilik etkisi", deger: kalan_kayip_evlilik, tip: kalan_kayip_evlilik < 0 ? "kayip" : "kazanc"},
  {asama: "1→2 gecis", deger: kalan_kayip_ppr1, tip: kalan_kayip_ppr1 < 0 ? "kayip" : "kazanc"},
  {asama: "2→3+ gecisler", deger: kalan_kayip_ppr2plus, tip: kalan_kayip_ppr2plus < 0 ? "kayip" : "kazanc"},
  {asama: "TDH (simulasyon)", deger: tdh_simulasyon, tip: "sonuc"}
]

// Kümülatif başlangıç noktalarını hesapla (waterfall için)
kumulatif = {
  let aradeger = tdh_2013_hwp
  const sonuc = []
  for (let i = 1; i < waterfall_veri.length - 1; i++) {
    sonuc.push({asama: waterfall_veri[i].asama, baslangic: Math.min(aradeger, aradeger + waterfall_veri[i].deger),
                    bitis: Math.max(aradeger, aradeger + waterfall_veri[i].deger), tip: waterfall_veri[i].tip})
    aradeger += waterfall_veri[i].deger
  }
  return sonuc
}

renk_skala = ({baz: "#888888", kayip: "#B33A3A", kazanc: "#2E7D32", sonuc: "#1F3864"})

Plot.plot({
  width: 700, height: 400,
  x: {label: null, domain: ["TDH 2013", "Evlilik etkisi", "1→2 gecis", "2→3+ gecisler", "TDH (simulasyon)"]},
  y: {label: "TDH", domain: [1.3, 2.2]},
  marks: [
    Plot.barY([{asama: "TDH 2013", y0: 0, y1: tdh_2013_hwp}], {x: "asama", y1: "y1", y2: "y0", fill: renk_skala.baz}),
    Plot.barY(kumulatif, {x: "asama", y1: "baslangic", y2: "bitis", fill: d => renk_skala[d.tip]}),
    Plot.barY([{asama: "TDH (simulasyon)", y0: 0, y1: tdh_simulasyon}], {x: "asama", y1: "y1", y2: "y0", fill: renk_skala.sonuc}),
    Plot.text([{asama: "TDH 2013", y: tdh_2013_hwp + 0.05, t: tdh_2013_hwp.toFixed(2)}], {x: "asama", y: "y", text: "t", fontWeight: "bold"}),
    Plot.text([{asama: "TDH (simulasyon)", y: tdh_simulasyon + 0.05, t: tdh_simulasyon.toFixed(2)}], {x: "asama", y: "y", text: "t", fontWeight: "bold"}),
    Plot.text(kumulatif, {x: "asama", y: d => Math.max(d.baslangic, d.bitis) + 0.04,
      text: d => (d.bitis - d.baslangic === 0 ? "0.000" : ((d.tip === "kazanc" ? "+" : "") + (d.bitis - d.baslangic).toFixed(3))),
      fontSize: 10, fontWeight: "bold"})
  ]
})

Nasıl çalışır: Her kaydırıcı, ilgili HWP bileşenindeki gerçek 2013-2024 kaybının ne kadarının “geri kazanıldığını” (%0=hiç, %100=tam 2013 seviyesine dönüş) simüle eder. Gerçek 2013-2024 kayıpları: Evlilik etkisi −0,218 (dört yaş grubunun toplamı), 1→2 geçiş (PPR₁) −0,354, 2→3+ geçişler −0,054. PPR₁’i tek başına %100 iyileştirmek (diğer ikisi sabit), TDH’yi 1,484’ten 1,838’e çıkarır — bu, tüm toplam kaybın (−0,626) %56,5’ini tek başına temsil eder ve bütün diğer üç kategorinin toplamından daha büyüktür.

Kaynak: HWP (Horiuchi-Wilmoth-Pletcher) ayrıştırma analizi, 2013-2024, doğrulanmış TÜİK verisi (toplam kontrolü: 2,110 + (−0,626) = 1,484 ✓).

İpucu

Planlanan ek modeller: Stok-Akış Paradoksu, Bongaarts-Feeney Tempo Hesaplayıcı, Nesil Uzunluğu Hızlandırıcısı, Sürdürülebilirlik Düzey Kontrol Paneli ve daha fazlası bu bölüme eklenecektir. Tam liste için proje yol haritasına bakınız.

NotModel Hakkında

Bu simülatör, kullanıcının belirlediği TDH senaryosu altında Türkiye’de yılda kaç çocuk doğacağını 2100’e kadar projekte eder. Model, kadın nüfus piramidini yıldan yıla ileriye taşıyarak geri besleme döngüsünü canlı biçimde gösterir: düşük TDH, daha az kız doğumuna yol açar; bu kız çocukları 25 yıl sonra üreme çağına girdiğinde kadın havuzu küçülmüş olacağından, aynı TDH düzeyinde bile toplam doğum sayısı düşmeye devam eder.

Yöntem: Basitleştirilmiş kuşak-bileşenleri (Leslie matrisi). Baz yıl kadın nüfusu TÜİK ADNKS 2025 tek yaş × cinsiyet tablosundan (0-74 yaş birebir, 75+ dağıtımlı; toplam 43.032.734, 15-49 kadın havuzu 21.948.521). Yaşa özel doğurganlık hızları (YÖDH) TÜİK 2025 değerleridir. Ölümlülük, Türkiye kadın yaşam tablosu (e₀ ≈ 81) ile uyumlu yaş-spesifik hayatta kalma oranlarına dayanır. Göç modele dahil edilmemiştir (kapalı nüfus varsayımı). Baz yıl (2025) hesaplanan doğum sayısı: 894.542 (TÜİK gerçek: ~895.000, fark %0,1).

Kaynak: TÜİK, Doğum İstatistikleri 2009-2025; TÜİK, ADNKS 2025; TÜİK, Yaşa Özel Doğurganlık Hızı 2025.

Kod
viewof tdh_hedef = Inputs.range([0.5, 3.5], {
  value: 1.42,
  step: 0.01,
  label: "Hedef TDH"
})

viewof gecis_modu = Inputs.radio(
  ["Sabit (2025'ten itibaren)", "Kademeli (2040'a kadar)", "Kademeli (2050'ye kadar)"],
  {value: "Sabit (2025'ten itibaren)", label: "Geçiş modu"}
)
Kod
femPop2025 = {
  const p = [
    423378, 450710, 466064, 501245, 523734,   // 0-4
    542375, 577042, 609676, 629835, 640178,   // 5-9
    649365, 655835, 630003, 630141, 608604,   // 10-14
    614525, 617468, 639521, 640049, 624261,   // 15-19
    616124, 605665, 594495, 602515, 643773,   // 20-24
    655143, 660255, 654493, 649291, 628480,   // 25-29
    623089, 644615, 630459, 609583, 609184,   // 30-34
    610763, 623886, 625664, 622686, 628321,   // 35-39
    624627, 627433, 617648, 630676, 696265,   // 40-44
    671171, 639621, 618367, 597456, 550949,   // 45-49
    524228, 592506, 578661, 547468, 515570,   // 50-54
    499702, 479844, 439664, 383287, 431781,   // 55-59
    535570, 501331, 431925, 421111, 365411,   // 60-64
    428281, 380808, 319936, 283091, 328935,   // 65-69
    395180, 319521, 270031, 247080, 203208,   // 70-74
    264142, 232445, 204551, 180005, 158404,   // 75-79
    139396, 122668, 107948, 94994, 83595,     // 80-84
    73563, 64736, 56967, 50131, 44115,        // 85-89
    38822, 34163, 30063, 26456, 23281,        // 90-94
    20487, 18029, 15865, 13961, 12286,        // 95-99
    10825                                      // 100
  ];
  return p;
}

// 2025 ASFR deseni (kadın başına, tek yaş -- grup oranı her yaşa uygulanır)
// TÜİK 2025: 15-19: 9.15‰, 20-24: 53.25‰, 25-29: 95.86‰,
//             30-34: 79.59‰, 35-39: 36.70‰, 40-44: 8.45‰, 45-49: 0.71‰
// TDH = Σ(ASFR×5)/1000 = 1.419
asfrBase = {
  const a = new Array(101).fill(0);
  const rates = [0.009150, 0.053249, 0.095859, 0.079586, 0.036697, 0.008451, 0.000714];
  const starts = [15, 20, 25, 30, 35, 40, 45];
  for (let g = 0; g < 7; g++) {
    for (let i = 0; i < 5; i++) {
      a[starts[g] + i] = rates[g];
    }
  }
  return a;
}

baseTDH = {
  let s = 0;
  for (let a = 15; a <= 49; a++) s += asfrBase[a];
  return s;  // = TDH/5 × 7_groups... actually = TDH since sum of per-woman rates
}

// Hayatta kalma oranları (kadın, tek yaş, yaklaşık Türkiye e₀≈81)
survival = {
  const s = new Array(101).fill(0);
  for (let a = 0; a < 101; a++) {
    if (a === 0) s[a] = 0.9950;
    else if (a < 5) s[a] = 0.9985;
    else if (a < 15) s[a] = 0.9997;
    else if (a < 40) s[a] = 0.9993;
    else if (a < 50) s[a] = 0.9985;
    else if (a < 60) s[a] = 0.9965;
    else if (a < 70) s[a] = 0.9920;
    else if (a < 80) s[a] = 0.9800;
    else if (a < 90) s[a] = 0.9400;
    else s[a] = 0.8500;
  }
  return s;
}

// Kız doğum oranı (toplam doğumda kadın payı)
kizOrani = 0.4868
Kod
// ========== SİMÜLASYON ==========
simulasyon = {
  const startYear = 2025;
  const endYear = 2100;
  const nYears = endYear - startYear + 1;

  // Geçiş parametreleri
  let gecisYili;
  if (gecis_modu === "Sabit (2025'ten itibaren)") gecisYili = 2025;
  else if (gecis_modu === "Kademeli (2040'a kadar)") gecisYili = 2040;
  else gecisYili = 2050;

  // Başlangıç nüfusu kopyala
  const pop = femPop2025.slice();

  const sonuclar = [];

  for (let t = 0; t < nYears; t++) {
    const yil = startYear + t;

    // Bu yılın TDH'si
    let tdh_yil;
    if (yil <= 2025) {
      tdh_yil = 1.419;
    } else if (yil >= gecisYili) {
      tdh_yil = tdh_hedef;
    } else {
      const frac = (yil - 2025) / (gecisYili - 2025);
      tdh_yil = 1.419 + (tdh_hedef - 1.419) * frac;
    }

    // ASFR ölçekle
    const scale = tdh_yil / baseTDH;

    // Doğumları hesapla
    let toplam_dogum = 0;
    for (let a = 15; a <= 49; a++) {
      toplam_dogum += asfrBase[a] * scale * pop[a];
    }

    // 15-49 kadın havuzu
    let havuz = 0;
    for (let a = 15; a <= 49; a++) havuz += pop[a];

    sonuclar.push({
      yil: yil,
      dogum: Math.round(toplam_dogum),
      kiz_dogum: Math.round(toplam_dogum * kizOrani),
      havuz: Math.round(havuz),
      tdh: Math.round(tdh_yil * 1000) / 1000
    });

    // Nüfusu yaşlandır (sondan başa)
    for (let a = 100; a >= 1; a--) {
      pop[a] = pop[a - 1] * survival[a - 1];
    }
    // Yeni kız doğumları yaş 0'a ekle
    pop[0] = toplam_dogum * kizOrani;
  }

  return sonuclar;
}
Kod
dogum2025 = simulasyon[0].dogum

// Yenilenme düzeyinde doğum (TDH=2.09 ile aynı havuzda)
yenilenme_dogum = {
  const scale = 2.094 / baseTDH;
  let d = 0;
  for (let a = 15; a <= 49; a++) d += asfrBase[a] * scale * femPop2025[a];
  return Math.round(d);
}

Plot.plot({
  width: Math.min(900, window.innerWidth - 40),
  height: 420,
  marginLeft: 70,
  marginRight: 20,
  marginBottom: 50,
  style: {
    fontFamily: "Inter, system-ui, sans-serif",
    fontSize: 12
  },
  x: {
    label: null,
    tickFormat: d => String(d)
  },
  y: {
    label: "Yıllık doğum sayısı",
    tickFormat: d => (d / 1e6).toFixed(1) + "M",
    grid: true
  },
  color: {
    legend: false
  },
  marks: [
    // Yenilenme çizgisi (referans)
    Plot.ruleY([yenilenme_dogum], {
      stroke: "#B2182B",
      strokeDasharray: "6,4",
      strokeWidth: 1
    }),
    Plot.text([{x: 2030, y: yenilenme_dogum}], {
      x: "x", y: "y",
      text: d => `Yenilenme düzeyinde 2025 doğumu (~${(yenilenme_dogum/1e6).toFixed(2)}M)`,
      fill: "#B2182B",
      fontSize: 10,
      dy: -10
    }),
    // 2025 seviyesi
    Plot.ruleY([dogum2025], {
      stroke: "#888888",
      strokeDasharray: "3,3",
      strokeWidth: 1
    }),
    Plot.text([{x: 2080, y: dogum2025}], {
      x: "x", y: "y",
      text: d => `2025 seviyesi (${(dogum2025/1e3).toFixed(0)}K)`,
      fill: "#888888",
      fontSize: 10,
      dy: -10
    }),
    // Ana çizgi
    Plot.line(simulasyon, {
      x: "yil",
      y: "dogum",
      stroke: "#1F3864",
      strokeWidth: 2.5
    }),
    // Noktalar (her 5 yılda bir)
    Plot.dot(simulasyon.filter(d => d.yil % 10 === 0), {
      x: "yil",
      y: "dogum",
      fill: "#1F3864",
      r: 3.5
    }),
    // Tooltip
    Plot.tip(simulasyon, Plot.pointerX({
      x: "yil",
      y: "dogum",
      title: d => `${d.yil}\nDoğum: ${(d.dogum / 1e3).toFixed(0)}K\nTDH: ${d.tdh.toFixed(2)}\n15-49 havuz: ${(d.havuz / 1e6).toFixed(2)}M`
    }))
  ]
})
Kod
// ========== 15-49 KADIN HAVUZU ==========

Plot.plot({
  width: Math.min(900, window.innerWidth - 40),
  height: 280,
  marginLeft: 70,
  marginRight: 20,
  marginBottom: 50,
  style: {
    fontFamily: "Inter, system-ui, sans-serif",
    fontSize: 12
  },
  x: {
    label: null,
    tickFormat: d => String(d)
  },
  y: {
    label: "15-49 yaş kadın nüfusu",
    tickFormat: d => (d / 1e6).toFixed(0) + "M",
    grid: true
  },
  marks: [
    Plot.line(simulasyon, {
      x: "yil",
      y: "havuz",
      stroke: "#9E7A1A",
      strokeWidth: 2.5
    }),
    Plot.dot(simulasyon.filter(d => d.yil % 10 === 0), {
      x: "yil",
      y: "havuz",
      fill: "#9E7A1A",
      r: 3.5
    }),
    Plot.tip(simulasyon, Plot.pointerX({
      x: "yil",
      y: "havuz",
      title: d => `${d.yil}\n15-49: ${(d.havuz / 1e6).toFixed(2)}M\nDoğum: ${(d.dogum / 1e3).toFixed(0)}K`
    }))
  ]
})
Kod
md`**Seçili TDH:** ${tdh_hedef.toFixed(2)} | **Geçiş:** ${gecis_modu}`
Kod
Inputs.table(
  simulasyon.filter(d => [2025, 2030, 2035, 2040, 2050, 2060, 2070, 2080, 2090, 2100].includes(d.yil)),
  {
    columns: ["yil", "tdh", "dogum", "kiz_dogum", "havuz"],
    header: {
      yil: "Yıl",
      tdh: "TDH",
      dogum: "Toplam Doğum",
      kiz_dogum: "Kız Doğum",
      havuz: "15-49 Kadın"
    },
    format: {
      dogum: d => (d / 1000).toFixed(0) + "K",
      kiz_dogum: d => (d / 1000).toFixed(0) + "K",
      havuz: d => (d / 1e6).toFixed(2) + "M",
      tdh: d => d.toFixed(2)
    },
    width: {yil: 60, tdh: 60, dogum: 100, kiz_dogum: 100, havuz: 100}
  }
)
UyarıModelin Sınırları

Bu simülatör kapalı nüfus varsayımı altında çalışır: uluslararası göç dahil edilmemiştir. Gerçek doğum sayıları, göçle gelen/giden üreme çağı kadın nüfusundan etkilenecektir. YÖDH yaş deseni 2025 değerlerinde sabit tutulmuştur (yalnızca düzey, yani TDH değişir). Ortalama doğum yaşındaki olası kaymalar modele yansıtılmamıştır. Hayatta kalma oranları zaman içinde sabit varsayılmıştır (gerçekte iyileşme beklenir). 75 yaş ve üzeri nüfus, TÜİK’in yayımladığı toplam değerden (2.121.898) üstel dağıtım ile tek yaşa açılmıştır.

 

© 2026 Mehmet Emin Sezgin