Müşteri yaşam döngüsü soruları
| Soru | Kalıp | Anahtar fonksiyon |
|---|---|---|
| Bu ay kaç yeni müşteri geldi? | Bu dönem − (dönem öncesi) | EXCEPT |
| Kaçı geri döndü? | Bu dönem ∩ (dönem öncesi) | INTERSECT |
| Kaçını kaybettik? | (önceki 12 ay) − bu dönem | DATESINPERIOD + EXCEPT |
| İlk ayın müşterileri ne kadar süre kalıyor? | Kohort matrisi | Hesaplanmış sütunlar + DISTINCTCOUNT |
| Hangi müşteri değerli, hangisi risk altında? | RFM skoru ve segmenti | DATEDIFF, SWITCH(TRUE()) |
Ortak teknik: tarih filtresini değiştirmek
Bu kalıpların hepsinde “bu dönem”in yanında “dönemden önceki her şey” ya da “son 12 ay” gibi ikinci bir zaman penceresi gerekir. Tarih tablosu işaretli olduğu için Tarih[Tarih] < DonemBasi filtresi Yıl, Ay gibi diğer tarih filtrelerinin yerine geçer. Tablo işaretli olmasaydı REMOVEFILTERS(Tarih) eklemen gerekirdi.
Geri Dönen Müşteri =
VAR DonemBasi = MIN(Tarih[Tarih])
VAR BuDonem =
CALCULATETABLE(VALUES(Satislar[MusteriNo]), Satislar[Durum] <> "İptal")
VAR Onceki =
CALCULATETABLE(
VALUES(Satislar[MusteriNo]),
Tarih[Tarih] < DonemBasi,
Satislar[Durum] <> "İptal"
)
RETURN COUNTROWS(INTERSECT(BuDonem, Onceki))
Kohort analizi
Kohort = aynı ayda ilk alışverişini yapan müşteriler. İki hesaplanmış sütun gerekir:
-- Musteriler tablosunda: IlkSiparis = CALCULATE(MIN(Satislar[Tarih]), Satislar[Durum] <> "İptal") KohortAy = FORMAT(Musteriler[IlkSiparis], "yyyy-MM") -- Satislar tablosunda: KohortAyFarki = DATEDIFF(RELATED(Musteriler[IlkSiparis]), Satislar[Tarih], MONTH)
Hesaplanmış sütunda CALCULATE bağlam geçişi yapar: müşteri satırı filtreye dönüşür ve yalnızca o müşterinin siparişleri arasında en küçük tarih bulunur. Matris: satırlar Musteriler[KohortAy], sütunlar Satislar[KohortAyFarki], değer “Kohort Tutma %”.
RFM
R (Recency, yenilik), F (Frequency, sıklık), M (Monetary, parasal değer). Her müşteri üç boyutta 1–5 puan alır; puan kombinasyonları iş dilinde segmentlere çevrilir. Ayrıntılı ölçüler Measure Lab'nda, sonuçlar RFM raporu'nda.
Aktif müşteri: tanımı sen seçersin
Pazarlama müdürü soruyor: “Şu anda kaç aktif müşterimiz var?” “Aktif” bir iş tanımıdır; raporu yazan kişi onu açıkça seçip belgeye yazar. Anadolu Market'te kullanılan tanım şu: son 90 günde en az bir iptal edilmemiş siparişi olan müşteri.
Aktif Müşteri (90 Gün) =
COUNTROWS(
CALCULATETABLE(
VALUES(Satislar[MusteriNo]),
DATESINPERIOD(Tarih[Tarih], MAX(Tarih[Tarih]), -90, DAY),
Satislar[Durum] <> "İptal"
)
)
Motor bunu nasıl değerlendirir?
MAX(Tarih[Tarih])dış bağlamda hesaplanır: 2024 hücresinde 31.12.2024.DATESINPERIODgeriye 90 günlük bir liste döndürür: 3 Ekim – 31 Aralık 2024.- CALCULATETABLE bu listeyi Tarih[Tarih] filtresinin yerine koyar; tarih tablosu işaretli olduğu için Yıl filtresi de kalkar. Hücre artık “son 90 günde alışveriş yapanlar”ı sayar.
| Hücre | Müşteri Sayısı (dönem içinde) | Aktif Müşteri (90 Gün) |
|---|---|---|
| 2022 | 32 | 28 |
| 2023 | 77 | 55 |
| 2024 | 123 | 89 |
| 2024-Ç4 | 90 | 89 |
2024-Ç4'teki 1 kişilik fark öğreticidir: çeyrek 92 gün, pencere 90 gün. 1–2 Ekim'de alışveriş yapıp sonra gelmeyen müşteri çeyreğin müşterisidir ama “aktif” değildir.
Kenar durumlar
- Toplam satırı: Kategori matrisinde satırlar 32, 32, 34, 5, 50, 46, 30 gösterir. Toplamları 229 eder, ama toplam satırı 89 der. Bir müşteri birden çok kategoriden alır. Bu doğrudur; araç ipucunda (tooltip) açıkla.
- Gün sayımı:
-90, DAYson günü de sayar ve tam 90 gün verir. “Son alımdan bu yana ≤ 90 gün” yazarsan 91 gün sayarsın: 2024 sonunda 90 müşteri çıkar, ölçü 89 der. Tanımı veri sözlüğüne yaz. - TODAY() tuzağı: Çapayı
TODAY()yaparsan veri 31.12.2024'te bittiği hâlde pencere bugünden geriye kayar ve sonuç boş gelir. Yenileme bir gün gecikirse de sayı sessizce düşer. Çapa her zaman verinin son günü olmalı:CALCULATE(MAX(Satislar[Tarih]), REMOVEFILTERS()).
Kayıp (churn) tanımını seçmek
| Tanım | Nasıl ölçülür? | Ne zaman doğru? |
|---|---|---|
| Sabit eşik | Son alımdan bu yana X günden fazla geçti | Abonelik olmayan perakende; kampanya listesi |
| Dönem karşılaştırma | Önceki 12 ayda vardı, bu dönemde yok ([Kayıp Müşteri]) | Yıllık yönetim raporu, bütçe |
| Olay tabanlı | Üyelik iptali, sözleşme bitişi | Abonelik işi; olay verisi gerekir |
Sabit eşiği tahminle seçme. Müşterilerin iki alışveriş arasında normalde ne kadar beklediğine bak. Aşağıdaki sorgu bunu motorda hesaplar:
EVALUATE
VAR T =
ADDCOLUMNS(
CALCULATETABLE(VALUES(Satislar[MusteriNo]), Satislar[Durum] <> "İptal"),
"Ilk", CALCULATE(MIN(Satislar[Tarih]), Satislar[Durum] <> "İptal"),
"Son", CALCULATE(MAX(Satislar[Tarih]), Satislar[Durum] <> "İptal"),
"N", CALCULATE(DISTINCTCOUNT(Satislar[SiparisNo]), Satislar[Durum] <> "İptal")
)
VAR Tekrar = ADDCOLUMNS(FILTER(T, [N] > 1), "Ara", DIVIDE(DATEDIFF([Ilk], [Son], DAY), [N] - 1))
RETURN
ROW(
"Medyan", MEDIANX(Tekrar, [Ara]),
"Yuzde90", PERCENTILEX.INC(Tekrar, [Ara], 0.9)
)
Sonuç: tekrar alan 127 müşteride medyan aralık 83 gün, %90'lık değer 155 gün (%80'lik değer 136). 90 günlük bir “kayıp” eşiği normal davranan müşterilerin neredeyse yarısını kayıp sayar; 180 gün, %90'ın olağan aralığının dışında kalır. 2024 sonunda son alımı 180 günden eski müşteri sayısı 27. Rapor hâli Vaka: müşteri kaybı dersinde.
Anti-kalıp: pencere uyuşmazlığı
“Önceki 12 ayda vardı, bu dönemde yok” mantığını çeyrek kırılımına koyarsan şu olur: 2024 yıl hücresinde oran %16,9 (77 müşterinin 13'ü). Çeyreklerde ise %30–39 görünür. Çünkü 12 aylık bir geçmiş, 3 aylık bir gözlemle karşılaştırılıyor. Üç ay alışveriş yapmamak kayıp değildir. Kural: gözlem penceresi karşılaştırma penceresinden kısa olmamalı; olursa ölçü BLANK dönsün.
Korumalı Yıllık Kayıp % =
VAR Gun = COUNTROWS(Tarih)
VAR DonemBasi = MIN(Tarih[Tarih])
VAR Onceki =
CALCULATETABLE(
VALUES(Satislar[MusteriNo]),
DATESINPERIOD(Tarih[Tarih], DonemBasi - 1, -12, MONTH),
Satislar[Durum] <> "İptal"
)
VAR Simdi = CALCULATETABLE(VALUES(Satislar[MusteriNo]), Satislar[Durum] <> "İptal")
RETURN
IF(Gun >= 365, DIVIDE(COUNTROWS(EXCEPT(Onceki, Simdi)) + 0, COUNTROWS(Onceki)))
+ 0 önemli: boş kümede COUNTROWS BLANK döner ve 2023'te (2022 müşterilerinin hepsi geri döndü) oran %0 yerine boş görünür.
CLV: müşteri yaşam boyu değeri
Finans direktörü soruyor: “Yeni bir müşteri kazanmak için en fazla ne harcayabiliriz?” Cevap CLV'dir (Customer Lifetime Value). Tek bir doğru formül yok. Olasılıksal modeller Python ya da Fabric not defterinde kurulur ve sonucu tabloya yazılır; DAX tarafında üç yaklaşım var.
| Yaklaşım | Hesap | Güçlü yanı | Zayıf yanı |
|---|---|---|---|
| Tarihsel | Bugüne kadarki brüt kâr ÷ müşteri | Kesin, denetlenebilir | Geleceği söylemez; yeni müşteriyi küçük gösterir |
| Basit formül | Yıllık müşteri başı kâr × beklenen ömür (≈ 1 ÷ yıllık kayıp oranı) | Anlaşılır, tek ölçü | Kayıp oranına çok duyarlı |
| Kohort temelli | Her kohortun ay ay birikimli kârı | En dürüst eğri | Uzun geçmiş ister |
Birikimli Müşteri Kârı =
VAR Son = MAX(Tarih[Tarih])
RETURN
DIVIDE(
CALCULATE([Brüt Kâr], REMOVEFILTERS(Tarih), Tarih[Tarih] <= Son),
CALCULATE([Müşteri Sayısı], REMOVEFILTERS(Tarih), Tarih[Tarih] <= Son)
)
Basit CLV =
VAR KarMusteri = DIVIDE([Brüt Kâr], [Müşteri Sayısı])
VAR Onceki = CALCULATE([Müşteri Sayısı], DATESINPERIOD(Tarih[Tarih], MIN(Tarih[Tarih]) - 1, -12, MONTH))
VAR Kayip = IF(COUNTROWS(Tarih) >= 365, DIVIDE([Kayıp Müşteri] + 0, Onceki))
VAR Omur = MIN(5, DIVIDE(1, Kayip))
RETURN IF(Kayip > 0, KarMusteri * Omur)
2024 için: müşteri başı yıllık brüt kâr 2.346 ₺, kayıp oranı %16,9. Ömür 1 ÷ 0,169 ≈ 5,9 yıl çıkar; 5 yıllık tavanla CLV 11.730 ₺ olur. Birikimli kâr ise 2024 sonunda müşteri başı 3.354 ₺ (2023 sonunda 2.176 ₺).
- Kayıp oranı 0: 2023'te 1 ÷ 0 sonsuz ömür demektir.
IF(Kayip > 0, …)bu hücreyi boş bırakır. Tavan (5 yıl) bir iş varsayımıdır; ölçü açıklamasına yaz. - Tek sayı verme: Bir aralık sun: ömür 3 yılsa 7.038 ₺, 5 yılsa 11.730 ₺. Karar alt uçla verilir.
- Segment farkı: Tüm dönemde müşteri başı brüt kâr Premium'da 5.866 ₺, Bireysel'de 1.961 ₺. Ortalama bir CLV, iki çok farklı kitleyi tek sayıda saklar.
Kohort matrisi: üretimde üç tuzak
1. Sağdan sansür
Son kohortların ileri ayları henüz yaşanmadı. [Kohort Tutma %] ölçüsü 12. ay sütununun toplamında %19,1 der (136 müşterinin 26'sı). Ama Ocak 2024'ten sonraki kohortlar 12. aya ulaşmadı; paydada olmamalılar. Yalnızca olgun kohortlarla oran %33,8 olur. 6. ayda fark %31,6'ya karşı %38,1.
Olgun Kohort Tutma % =
VAR Ay = SELECTEDVALUE(Satislar[KohortAyFarki])
VAR SonTarih = CALCULATE(MAX(Satislar[Tarih]), REMOVEFILTERS())
VAR Olgun =
FILTER(
VALUES(Musteriler[KohortAy]),
VAR Ilk = CALCULATE(MIN(Musteriler[IlkSiparis]))
RETURN NOT ISBLANK(Ilk) && DATEDIFF(Ilk, SonTarih, MONTH) >= Ay
)
VAR Aktif = CALCULATE(DISTINCTCOUNT(Satislar[MusteriNo]), Satislar[Durum] <> "İptal", REMOVEFILTERS(Tarih), Olgun)
VAR Boyut =
CALCULATE(
DISTINCTCOUNT(Satislar[MusteriNo]),
Satislar[KohortAyFarki] = 0, Satislar[Durum] <> "İptal", REMOVEFILTERS(Tarih), Olgun
)
RETURN IF(NOT ISBLANK(Ay) && Ay >= 0, DIVIDE(Aktif, Boyut))
2. Negatif ay farkı
Matriste −6 ile −1 arası sütunlar görünür. Kohort, ilk iptal edilmemiş siparişten hesaplanır. Ondan önce iptal edilmiş siparişi olan müşteri negatif fark üretir. Görsel filtresine KohortAyFarki ≥ 0 koy ve bu kararı belgeye yaz.
3. Küçük kohortlar
2023-09 kohortunda 1 müşteri var; hücreleri ya %100 ya %0 görünür. Kohort büyüklüğünü ilk sütuna koy, 5'ten küçük kohortları gri yap ya da çeyreklik kohorta geç. Kohort büyüklüğü ölçüsünde KohortAyFarki = 0 filtresi sütundan gelen ay farkının üzerine yazar; değer satırda sabit kalır.
RFM'yi üretime almak
Uygulamadaki [RFM Skoru] sabit eşikler kullanıyor (ör. son 12 ay satışı 12.000 ₺ ve üstü → M = 5). İki seçenek var:
Sabit eşik yıllar arası kıyası anlamlı tutar (“Şampiyon” her yıl aynı ölçüt) ama dağılım dengesiz olabilir: 2024'te 123 müşteriden yalnızca 16'sı M ≥ 12.000. Yüzdelik eşik her puana yaklaşık eşit müşteri koyar ama dağılım her yıl yeniden bölündüğü için yıl kıyası zayıflar. 2024 net satışında %20'lik sınırlar 2.030 / 3.735 / 5.372 / 9.305 ₺. Segment dağılımı 2023 sonundan 2024 sonuna şöyle değişti: Şampiyon 17 → 27, Potansiyel sadık 37 → 75, Kaybedilmiş 0 → 13.
Ölçü mü, anlık görüntü mü?
Ölçü dilimleyiciye tepki verir; keşif için iyidir. Ama CRM ekibi “1 Kasım'da Şampiyon olanlara kampanya gönderdik” dediğinde rapor aynı listeyi yeniden üretebilmelidir. Bunun için her ay sonunda bir anlık görüntü tablosu (Ay, MusteriNo, Segment) yazılır; segment geçişleri de bu tablodan basit bir sayımla çıkar. Milyonlarca müşteride ölçü her hücrede müşteri başına üç CALCULATE çalıştırır; o ölçekte anlık görüntü zorunludur (DAX optimizasyonu dersi).