Merhaba Veri Yolcusu! Üçüncü Durak: Kodlama ve Uygulama

Dostlara Bir Not:

Bölüm 2’ye gösterdiğiniz ilgiye ve yapıcı geri bildirimler için çok teşekkür ederim! Özellikle, kurduğumuz modelin Odds Ratio ve Marjinal Etkiler gibi daha derin yorumlama teknikleri hakkında gelen tavsiyeler, bizi ileriki paylaşımlar için motive etti. Merak etmeyin, bu değerli geri bildirimleri not ettik! Bu konulara özel, “İleri Seviye Model Yorumlama” adında yepyeni bir serinin tohumlarını şimdiden attık.

Şimdilik, mevcut serimizin akışına sadık kalarak, Bölüm 2’de tasarladığımız o akıllı prototipi, şimdi sağlam ve otomatize bir “motora” dönüştürmeye odaklanalım. Kemerleri bağlayın, atölyenin en teknik bölümüne giriyoruz!

1. Adım: Atölyeden Fabrikaya - Neden Temiz Koda İhtiyacımız Var?

Dostlar, Bölüm 2’de kullandığımız R Markdown (.Rmd) dosyası, analiz yapmak, notlar almak ve bir hikaye anlatmak için harikaydı. Tıpkı bir sanatçının eskiz defteri gibiydi. Ancak bir fabrikanın üretim hattı, eskiz defterleriyle çalışmaz; temiz, verimli ve hatasız çalışan mühendislik planlarına ihtiyaç duyar.

Bizim mühendislik planımız ise temiz bir R Script (.R) dosyası olacak. Bu dosyada sadece ve sadece motorumuzun çalışması için gerekli olan kemik kodlar yer alacak. Notlar, denemeler ve çıktılar olmayacak. Bu, “analiz” ile “üretim” dünyasını ayırmanın ilk ve en önemli adımıdır.

2. Adım: Kodumuzu Modüler Hale Getirmek - Fonksiyonların Gücü

Uzun, baştan sona akan bir kod yazmak yerine, kodumuzu yeniden kullanılabilir ve test edilebilir parçalara ayıracağız. İşte bu parçalara fonksiyon diyoruz. Bu, kodumuzu inanılmaz derecede temiz, okunaklı ve yönetilebilir hale getirecek.

Haydi, projemizin ana adımlarını fonksiyonlara dönüştürelim. Yeni bir R Script dosyası (fonksiyonlar.R) açıp içine bu fonksiyonları yazıyoruz:

# fonksiyonlar.R

# Gerekli kütüphaneleri yükleyen bir fonksiyon
kutuphaneleri_yukle <- function() {
  library(dplyr)
  library(caret)
}

# Yeni veriyi modele hazır hale getiren fonksiyon
veri_hazirla <- function(yeni_sikayet_dosyasi, yeni_musteri_dosyasi) {
  # Verileri oku
  sikayetler <- read.csv(yeni_sikayet_dosyasi)
  musteri_bilgileri <- read.csv(yeni_musteri_dosyasi)
  
  # Bölüm 2'de yaptığımız adımları tekrarla
  birlesik_veri <- left_join(sikayetler, musteri_bilgileri, by = "musteri_id")
  
  musteri_ozet <- birlesik_veri %>%
    group_by(musteri_id, uyelik_suresi_ay, aylik_harcama) %>% # Artık terk_durumu yok!
    summarise(toplam_sikayet_sayisi = n(), .groups = 'drop')
    
  return(musteri_ozet)
}

# Tahminleri üreten ve sonuçları hazırlayan fonksiyon
tahmin_yap <- function(model, hazir_veri) {
  # Olasılıkları tahmin et
  tahmin_olasikliklari <- predict(model, newdata = hazir_veri, type = "response")
  
  # Bölüm 2'de bulduğumuz en iyi stratejik eşiği (0.40) kullanalım!
  en_iyi_esik <- 0.40
  tahmin_siniflari <- ifelse(tahmin_olasikliklari > en_iyi_esik, "Terk Edecek", "Kalacak")
  
  # Sonuçları güzel bir tabloya dönüştür
  sonuclar <- data.frame(
    musteri_id = hazir_veri$musteri_id,
    terk_etme_olasiligi = round(tahmin_olasikliklari, 3),
    tahmin_durumu = tahmin_siniflari
  )
  
  return(sonuclar)
}

3. Adım: En Değerli Varlığımızı Korumak - Modeli Kaydetmek ve Yüklemek

Her tahmin yapmak istediğimizde, modeli sıfırdan eğitmek istemeyiz. Bu yüzden Bölüm 2’de eğittiğimiz o değerli modeli, daha sonra kullanmak üzere diskimize kaydediyoruz.

# Bu kodu Bölüm 2'deki RMD dosyanızın sonunda bir kez çalıştırmanız yeterli!
# model <- glm(...) # Modelinizi eğittiniz...Bölüm2'de bu işlemi gerçekleştirmiştik.
# saveRDS(model, file = "churn_model.rds")

Artık churn_model.rds adında, içinde tüm bilgeliği barındıran sihirli bir dosyamız var.

4. Adım: Üretim Hattını Kurmak - Ana Tahmin Script’i (pipeline.R)

Şimdi tüm parçaları bir araya getiren “orkestra şefi” script’imizi (pipeline.R) yazalım. Bu script, bizim tam otomatize “motorumuz” olacak! Bu bizim ikinci R script dosyamız olacak.

# pipeline.R

# Adım 1: Fonksiyonlarımızı R ortamına çağır
source("fonksiyonlar.R")

# Adım 2: Gerekli kütüphaneleri yükle
kutuphaneleri_yukle()

# Adım 3: Eğitilmiş modelimizi diskten hafızaya yükle
print("Model yukleniyor...")
model <- readRDS("churn_model.rds")

# Adım 4: Yeni gelen veriyi hazırla (Normalde bu dosyalar her gün güncellenir)
print("Yeni veriler hazırlaniyor...")
hazir_veri <- veri_hazirla(yeni_sikayet_dosyasi = "data/yeni_sikayetler.csv",
                           yeni_musteri_dosyasi = "data/yeni_musteri_bilgileri.csv")

# Adım 5: Tahminleri üret
print("Tahminler yapiliyor...")
tahmin_sonuclari <- tahmin_yap(model = model, hazir_veri = hazir_veri)

# Adım 6: Sonuçları kaydet
write.csv(tahmin_sonuclari, "tahmin_sonuclari.csv", row.names = FALSE)

print("Islem tamamlandi! 'tahmin_sonuclari.csv' dosyasi olusturuldu.")

İşte bu kadar! Artık pipeline.R script’ini her çalıştırdığımızda, tüm süreç otomatik olarak işleyecek ve bize risk altındaki yeni müşterilerin listesini verecek.

5. Adım: Ufuk Turu - Motoru Zamanlamak

Dostlar, motorumuz pipeline.R başarıyla çalıştı ve bize en önemli çıktıyı verdi: tahmin_sonuclari.csv dosyası! Bu dosya, modelimizin daha önce hiç görmediği yeni müşteriler hakkında ne düşündüğünü gösteriyor.

Peki, bu tablodaki “Terk Edecek” ve “Kalacak” etiketleri tam olarak nereden geliyor? Sınır değeri neydi ve neden oydu?

Stratejimizi Hatırlayalım: Bölüm 2’deki en kritik anı hatırlayın. Standart 0.5 eşiğinin, bizim ana hedefimiz olan “kayıp önleme” (yüksek Recall) için yeterince iyi olmadığına karar vermiştik. Yaptığımız analiz sonucunda, Duyarlılık (Recall) oranını %80’den %86.7’ye çıkaran, buna karşılık Kesinlik (Precision) oranından sadece makul bir ödün veren “Stratejik Tatlı Nokta” olarak 0.40 eşiğini seçmiştik.

Yani kuralımız basit: Bir müşterinin terk etme olasılığı 0.40’tan büyükse, onu “riskli” olarak işaretle!

Şimdi, bu kuralın yeni sonuçlarımız üzerinde nasıl çalıştığını somut bir tabloyla görelim:

Stratejik 0.40 Eşiğinin Yeni Müşteriler Üzerindeki Somut Sonuçları
Müşteri ID Terk Etme Olasılığı Kural: > 0.40? Tahmin Durumu Yorum
1501 0.396 Hayır Kalacak Doğru, 0.40’tan küçük.
1502 0.262 Hayır Kalacak Doğru, 0.40’tan küçük.
1506 0.674 Evet Terk Edecek Doğru, 0.40’tan büyük.
1508 0.482 Evet Terk Edecek Doğru, 0.40’tan büyük.
1509 0.490 Evet Terk Edecek Doğru, 0.40’tan büyük.
1515 0.515 Evet Terk Edecek Doğru, 0.40’tan büyük.
1521 0.447 Evet Terk Edecek Doğru, 0.40’tan büyük.
1524 0.493 Evet Terk Edecek Doğru, 0.40’tan büyük.
1530 0.793 Evet Terk Edecek Doğru, 0.40’tan büyük.

İşte stratejimizin gücü tam olarak burada ortaya çıkıyor!

Tablodaki 1508, 1509, 1521 ve 1524 gibi müşterilere dikkat edin. Bu müşterilerin terk etme olasılıkları %40 ile %50 arasında. Eğer standart 0.5 eşiğini kullansaydık, bu kritik müşterileri “riskli” olarak etiketlemeyecek ve potansiyel olarak gözden kaçıracaktık! Ancak Bölüm 2’de aldığımız bilinçli karar sayesinde, motorumuz bu “gri bölgedeki” müşterileri başarıyla tespit edebiliyor.

Bu tablo, Bölüm 2’de aldığımız teorik ve stratejik bir kararın, Bölüm 3’te kurduğumuz motor sayesinde nasıl pratiğe döküldüğünün ve gerçek iş değeri yarattığının en somut kanıtıdır.

Peki ya bu sonuçları bir CSV dosyasında görmek yerine, bir pazarlama yöneticisinin kullanabileceği interaktif bir web arayüzünde (dashboard) sunmak isteseydik? İşte o zaman R Shiny gibi araçlar devreye girer. Bu, modelimizi bir “vitrine” koymanın en şık yoludur. Belki de bu, serimizin sonunda bizi bekleyen sürpriz bir bonus durağı olur, ne dersiniz?

Üçüncü Duraktan Notlar ve Final Durağına Çağrı

Bu önemli duraktan ayrılırken, sadece kod yazmadık; bir fikri, yaşayan bir sisteme dönüştürmenin temelini attık. Gelin, fabrikada attığımız adımları ve ne anlama geldiklerini bir kez daha hatırlayalım:

  1. Atölyeyi Fabrikadan Ayırdık (Analizden Üretime Geçiş): İlk işimiz, Bölüm 2’deki notlarımızla, denemelerimizle dolu, dağınık ama yaratıcı “eskiz defterimizi” (.Rmd dosyası) bir kenara koymak oldu. Onun yerine, içinde sadece motorun çalışması için gereken, hatasız ve net komutların olduğu bir “mühendislik planı” (.R dosyası) hazırladık. Bu, bir projenin sürdürülebilirliği için en kritik adımdır: Keşif ve üretim süreçlerini birbirinden ayırmak.

  2. Montaj Hattı İstasyonları Kurduk (Fonksiyonların Gücü): Tüm işi tek bir uzun hatta yapmak yerine, fabrikamızı modüler istasyonlara böldük. “Veri Hazırlama İstasyonu” (veri_hazirla() fonksiyonu) ve “Tahmin Yapma İstasyonu” (tahmin_yap() fonksiyonu) gibi. Bu sayede, gelecekte bir adımda değişiklik yapmak istediğimizde tüm fabrikayı durdurmak yerine sadece ilgili istasyonu güncellememiz yeterli olacak. Bu, kodumuza esneklik, okunabilirlik ve bakım kolaylığı kazandırdı.

  3. En Değerli Parçamızı Mühürledik (Modeli Kaydetme): Bölüm 2’de onca emekle ürettiğimiz o akıllı “beyni”, yani modelimizi, her seferinde yeniden üretmek zorunda kalmamak için özel bir kasaya (churn_model.rds) kilitleyip mühürledik. Artık fabrikamız, bu hazır ve test edilmiş beyni raftan alıp anında kullanabilir. Bu, bize hız ve tutarlılık kazandırdı.

  4. Montaj Hattını Çalıştırdık (Üretim Pipeline’ı): Tüm bu istasyonları ve hazır parçaları, doğru sırayla çalıştıran bir “ana şalter” (pipeline.R script’i) oluşturduk. Bu şalteri indirdiğimizde, yeni ham veriler bir uçtan giriyor, tüm istasyonlardan geçiyor ve diğer uçtan “riskli müşteriler” listesi olarak çıkıyor. Artık bir prototipimiz değil, otomatize, tekrarlanabilir ve güvenilir bir motorumuz var.

  5. Stratejimizin Çalıştığını Kanıtladık (Sonuçları Yorumlama): Son olarak, motorumuzun ürettiği çıktıları inceledik. Bölüm 2’de aldığımız o stratejik 0.40 eşiği kararının, yeni müşteriler üzerinde tam olarak beklediğimiz gibi çalıştığını ve potansiyel müşteri kayıplarını başarıyla yakaladığını somut kanıtlarla gördük. Bu, teorinin pratiğe döküldüğü ve projemizin gerçek iş değeri yarattığı andı.

Artık elimizde sadece çalışan bir kod parçası değil; test edilmiş, iş mantığıyla optimize edilmiş ve bir sonraki adıma hazır, akıllı bir prototip var.

Peki sırada ne var?

Motorumuz her gün tıkır tıkır çalışıyor ve bize risk altındaki müşterilerin bir listesini veriyor. Peki, bu teknik çıktıyı pazarlama direktörüne veya CEO’ya nasıl sunacağız? Bu rakamları, aksiyon alınabilir içgörülere, etkileyici grafiklere ve ikna edici bir hikayeye nasıl dönüştürürüz?

İşte bu soruların cevabı, yolculuğumuzun son ve en önemli durağı olan İletişim ve Sunum’da!