Ana içeriğe geç
Kesit Power BI
İleri · Vaka Çalışmaları

Vaka: müşteri kaybı (churn)

Pazarlama ekibi hangi müşterileri kaybettiğini ve kimi geri kazanmaya çalışacağını soruyor. Kayıp tanımını koyar, oranı segment, yaş, şehir ve kanala göre kırar, risk altındaki müşteri listesini çıkarırsın.

Uygulamada aç, 5 alıştırmayı çözÜcretsiz, hesap gerekmez, kurulum yok.

Bu sayfa dersin okuma sürümüdür. Metin bir kutuyu çalıştırmanı ya da adıma geçmeni söylüyorsa dersi uygulamada aç.

1. Şirketin sorusu ve brif

Kim soruyor? Pazarlama müdürü. Önümüzdeki çeyrekte bir “geri kazanma” (win-back) kampanyası yapılacak. Bütçe sınırlı: herkese indirim kodu gönderilmeyecek.

Hangi karar? Kampanya kime gidecek, hangi segment ve şehre öncelik verilecek? Brif üç soruya iniyor:

  1. Kaç müşteriyi kaybettik ve bu oran hangi grupta yüksek?
  2. Kaybettiğimiz müşteriler geçmişte ne kadar harcamıştı?
  3. Henüz kaybetmediğimiz ama kaybetmek üzere olduğumuz müşteriler kim?

Bu vaka, Müşteri analitiği: yeni, geri dönen, kayıp, kohort, RFM dersindeki tekniklere dayanır. Oradaki [Kayıp Müşteri] ölçüsü dönem bazlıdır: “geçen 12 ayda alıp bu dönemde almayan”. Burada kampanya için farklı bir tanım gerekiyor: müşteri bazında, son siparişten bu yana geçen gün sayısı.

2. Veri ve model

TabloKullanım
SatislarSipariş tarihi, durum (İptal hariç), kanal, tutar.
MusterilerSegment, şehir, bölge, yaş grubu. 150 kayıtlı müşteri.
TarihTarih filtresini kaldırmak ve “tarihe göre” sürüm için.

Veri sınırları:

3. Analiz adımları

Adım 1: Kayıp tanımı. Kural: iptal edilmemiş son siparişinden bu yana 180 gün veya daha fazla geçen müşteri kayıptır; 90–179 gün arası “risk altında”dır. Önce yapı taşları:

Son Sipariş =
CALCULATE(
    MAX(Satislar[Tarih]),
    REMOVEFILTERS(Tarih),
    REMOVEFILTERS(Satislar[Kanal]),
    Satislar[Durum] <> "İptal"
)
Veri Sonu = MAXX(ALL(Satislar), Satislar[Tarih])
Sessiz Gün =
VAR Son = [Son Sipariş]
RETURN IF(NOT ISBLANK(Son), DATEDIFF(Son, [Veri Sonu], DAY))

REMOVEFILTERS(Tarih) önemli: rapor sayfasında bir yıl seçilse bile müşterinin gerçek son siparişini buluruz. REMOVEFILTERS(Satislar[Kanal]) ise kanal kırılımında “bu kanaldaki son sipariş” yerine “herhangi bir kanaldaki son sipariş”i verir. Veri Sonu için ALL(Satislar) üzerinde yineleriz; hiçbir dilimleyici bu tarihi değiştirmez.

Bulgu: Sipariş vermiş 136 müşterinin 89’u aktif (90 günden az), 20’si risk altında (90–179 gün), 27’si kayıp (180+ gün).

Adım 2: Kayıp sayısı ve oranı.

Son Sipariş =
CALCULATE(MAX(Satislar[Tarih]), REMOVEFILTERS(Tarih), REMOVEFILTERS(Satislar[Kanal]), Satislar[Durum] <> "İptal")
Veri Sonu = MAXX(ALL(Satislar), Satislar[Tarih])
Sessiz Gün =
VAR Son = [Son Sipariş]
RETURN IF(NOT ISBLANK(Son), DATEDIFF(Son, [Veri Sonu], DAY))
Kaybedilen Müşteri =
COUNTROWS(
    FILTER(
        CALCULATETABLE(VALUES(Satislar[MusteriNo]), REMOVEFILTERS(Tarih), Satislar[Durum] <> "İptal"),
        [Sessiz Gün] >= 180
    )
)
Alışveriş Yapmış Müşteri = CALCULATE([Müşteri Sayısı], REMOVEFILTERS(Tarih))
Kayıp Oranı % = DIVIDE([Kaybedilen Müşteri], [Alışveriş Yapmış Müşteri])

Müşteri listesini Satislar üzerinden alıyoruz (VALUES(Satislar[MusteriNo])). Böylece kanal ve kategori gibi olgu tablosundaki filtreler de listeyi daraltır. FILTER içindeki [Sessiz Gün] çağrısı her müşteri için bağlam geçişi yapar.

Bulgu: 27 / 136 = %19,9 kayıp oranı. Her beş müşteriden biri altı aydır sipariş vermiyor.

Adım 3: Segment, yaş, şehir ve kanal kırılımı. Aynı ölçüyü matriste satırlara koymak yeter.

KırılımKayıp / alışveriş yapanKayıp oranı
Premium8 / 30%26,7
Bireysel15 / 77%19,5
Kurumsal4 / 29%13,8
Yaş 35-448 / 29%27,6
Yaş 45-547 / 26%26,9
Yaş 18-244 / 18%22,2
Yaş 25-345 / 34%14,7
Yaş 55+3 / 29%10,3
Marmara bölgesi13 / 36%36,1
İç Anadolu bölgesi6 / 44%13,6
Kanal: Mağaza17 / 70%24,3
Kanal: Mobil23 / 117%19,7
Kanal: Web22 / 113%19,5

Şehir düzeyinde İstanbul öne çıkıyor: 27 müşteriden 10’u kayıp (%37,0). Bursa 3/9, Konya 2/5. Ancak Konya’da yalnızca 5 müşteri var; küçük gruplarda oran tek bir müşteriyle %20 oynar. Raporda oranın yanına mutlaka müşteri sayısını yaz.

Kanal kırılımı nasıl okunur?Bir müşteri birden fazla kanaldan alışveriş yapmış olabilir. Kanal satırı “bu kanalı en az bir kez kullanmış müşteriler arasında kayıp oranı”dır. Bu yüzden kanal satırlarının toplamı (17 + 23 + 22 = 62) toplam kayıptan (27) büyüktür. Toplam satırı ise doğru sonucu verir; DAX müşteriyi bir kez sayar.

Adım 4: Kaybedilen müşterilerin geçmiş harcaması.

Son Sipariş =
CALCULATE(MAX(Satislar[Tarih]), REMOVEFILTERS(Tarih), REMOVEFILTERS(Satislar[Kanal]), Satislar[Durum] <> "İptal")
Sessiz Gün =
VAR Son = [Son Sipariş]
RETURN IF(NOT ISBLANK(Son), DATEDIFF(Son, MAXX(ALL(Satislar), Satislar[Tarih]), DAY))
Kaybedilen Ciro =
CALCULATE(
    [Net Satış],
    REMOVEFILTERS(Tarih),
    FILTER(VALUES(Musteriler[MusteriNo]), [Sessiz Gün] >= 180)
)

Bulgu: Kaybedilen 27 müşteri, tüm dönemde 185.576 ₺ harcamış. Bu, toplam net satışın (1.250.772 ₺) %14,8’i. Kaybedilen müşteri başına geçmiş harcama 6.873 ₺; kalan müşterilerde 9.772 ₺. Yani genelde daha az harcayanları kaybediyoruz. Ama Premium istisna: kaybedilen cironun 82.328 ₺’si (%44) yalnızca 8 Premium müşteriden geliyor. Premium müşteri ortalama 11,1 sipariş veren, 16.271 ₺ harcayan bir müşteri; böyle birinin altı ay sessiz kalması güçlü bir sinyaldir.

Adım 5: Zaman içinde kayıp. Brif “şu an” soruyor, ama yönetim “artıyor mu?” diye de soracak. Veri sonu yerine bağlamdaki son tarihi kullanan bir sürüm:

Son Sipariş (Tarihe Kadar) =
VAR Gun = MAX(Tarih[Tarih])
RETURN CALCULATE(MAX(Satislar[Tarih]), REMOVEFILTERS(Tarih), Satislar[Tarih] <= Gun, Satislar[Durum] <> "İptal")
Kayıp (Tarihe Göre) =
VAR Gun = MAX(Tarih[Tarih])
VAR Musteriler180 =
    FILTER(
        CALCULATETABLE(VALUES(Satislar[MusteriNo]), REMOVEFILTERS(Tarih), Satislar[Tarih] <= Gun, Satislar[Durum] <> "İptal"),
        DATEDIFF([Son Sipariş (Tarihe Kadar)], Gun, DAY) >= 180
    )
RETURN COUNTROWS(Musteriler180)

Bulgu: Çeyrek sonlarında kayıp müşteri sayısı: 2023-Ç4 7, 2024-Ç1 12, Ç2 15, Ç3 20, Ç4 27. Bir yılda dört katına yakın arttı. Müşteri tabanı da büyüyor, ama artış hızı ciddi.

Adım 6: Risk altındaki müşteriler listesi. Kampanyanın asıl hedefi bu liste: henüz kaybedilmemiş, 90–179 gündür sessiz müşteriler.

EVALUATE
VAR Liste =
    ADDCOLUMNS(
        VALUES(Musteriler[MusteriNo]),
        "Müşteri", CALCULATE(MAX(Musteriler[Musteri])),
        "Segment", CALCULATE(MAX(Musteriler[Segment])),
        "Son", CALCULATE(MAX(Satislar[Tarih]), REMOVEFILTERS(Tarih), Satislar[Durum] <> "İptal"),
        "Ciro", CALCULATE([Net Satış], REMOVEFILTERS(Tarih))
    )
VAR Riskli =
    FILTER(Liste, NOT ISBLANK([Son]) && DATEDIFF([Son], DATE(2024, 12, 31), DAY) >= 90 && DATEDIFF([Son], DATE(2024, 12, 31), DAY) < 180)
RETURN TOPN(10, Riskli, [Ciro], DESC)
CALCULATE’i unutmaADDCOLUMNS içinde MAX(Musteriler[Segment]) yazarsan satır bağlamı filtreye dönüşmez ve her satıra tüm tablonun en büyük değeri (“Premium”) gelir. Bu vakayı hazırlarken ilk denemede tam olarak bu oldu ve liste “hep Premium” göründü. CALCULATE(MAX(...)) bağlam geçişi yapar.

Bulgu: 20 risk altındaki müşteri, geçmişte toplam 122.492 ₺ harcamış. 18’i Bireysel, 2’si Kurumsal; risk listesinde hiç Premium müşteri yok. Premium’daki sorun 180+ gün grubunda: 8 kayıp. İlk üç: 97 no.lu Mehmet Doğan (90 gün, 19.457 ₺), 24 no.lu Gamze Kaya (Kurumsal, 97 gün, 16.354 ₺), 51 no.lu Eren Çelik (109 gün, 11.573 ₺).

4. Rapor sayfası taslağı

KonumGörselAlanlar
Üst şerit4 kartAlışveriş yapmış müşteri (136), Kaybedilen (27), Kayıp oranı (%19,9), Kaybedilen ciro (185.576 ₺)
Sol ortaÇizgi grafikX: Tarih[YilCeyrek], Y: Kayıp (Tarihe Göre)
Sağ ortaÇubuk grafik (yatay)Segment ve yaş grubu; değer: Kayıp Oranı %, araç ipucunda müşteri sayısı
Sol altDoldurulmuş harita veya tabloŞehir; Kayıp Oranı % ve Alışveriş Yapmış Müşteri yan yana
Sağ altTabloRisk listesi: MusteriNo, ad, segment, son sipariş, sessiz gün, geçmiş ciro; ciroya göre azalan
Sayfa notuMetin kutusu“Kayıp: veri sonu (31.12.2024) itibarıyla 180+ gün sipariş yok.”

Risk tablosuna bir dilimleyici (Slicer) olarak “sessiz gün eşiği” eklemek istersen Segmentasyon dersindeki ne olur (what-if) parametresini kullan: 180 sabiti parametre değerine dönüşür.

5. Bulgu özeti ve öneri

  1. Kayıp oranı %19,9 (27 / 136) ve bir yılda 7’den 27’ye çıktı. Kayıp takibi aylık KPI olmalı.
  2. Premium en yüksek orana sahip (%26,7) ve kaybedilen cironun %44’ü bu segmentten. Premium için 180 gün yerine daha kısa bir uyarı eşiği (ör. 60 gün) tanımla; bu müşteriler ortalama 11 sipariş veriyor, uzun sessizlik normal değil.
  3. Marmara ve özellikle İstanbul (%37,0) öne çıkıyor. Bölge ekibiyle teslimat ve rakip etkisini konuş; küçük şehirlerde oranı müşteri sayısıyla birlikte oku.
  4. Kampanya önce risk listesine gitsin: 20 müşteri, 122.492 ₺ geçmiş ciro. Kaybedilmişlere göre geri kazanmak daha ucuzdur.
  5. 35-54 yaş grubunda oran %27 civarında, 55+ grubunda %10,3. Mesaj ve kanal seçimini yaş grubuna göre ayır.
Alıştırmalara geç (5)