Miuul Araştırma

Power BI ile CRM Analitiği - III: CLTV Hesabı ile Müşteri Segmenti Oluşturma

CLTV sayesinde müşterilerin satın alma ve karlılık pattern'ları göz önünde bulundurularak müşteriye özel teklifte bulunulabilir. Bu makalede CLTV hesabı ile segmentasyon yapıyoruz.


Source: tetti. rd

Power BI’ da CRM analitiği çalışmalarımızın 3. serisi olan CLTV, müşteri segmentasyonu için oldukça önem taşıyan bir konudur. CLTV (Customer Lifetime Value) sayesinde müşterilerin satın alma, karlılık patternları göz önünde bulundurularak müşteriye özel teklifte bulunulabilir. Bu çalışmamızda CLTV hesabı ile segmentasyon yapacağız.

 

Hızlı bir şekilde CLTV hesaplamasından ve kullanılan kavramlardan bahsedelim. RFM hesaplarken elde ettiğimiz Frequency ve Monetary metrikleri CLTV hesaplarken kullandığımız girdilerden oluşuyor.

CLTV = (Customer Value / Churn Rate)  * Profit Margin
Customer Value = Avg Order Value * Purchase Frequency
Avg Order Value = Total Revenue / Total # of Orders
Purchase Frequency = Total # of Orders / Total # of Customers
Churn Rate = 1-Repeat Rate

--

Customer Value : Müşteri Değeri
Avg Order Value : Müşterinin sipariş başına bırakacağı ortalama para
Purchase Fequency : Satın alma sıklığı
Total # of Orders : Toplam sipariş miktarı
Total #of Customers : Toplam müşteri sayısı
Profit Margin : Karlılık
Churn Rate : Müşterinin bir daha alışveriş yapmaması
Repeat Rate : Birden fazla alışveriş yapan müşteri sayısı / Toplam müşteri sayısı

Veri setimizi artık tanıyoruz. PowerBI’ da python kodu çalıştırabilmek için “Get Data” — “More” tıklayıp arama çubuğuna python yazmamız yeterli. Bu kısma CLTV değerlerini elde ettiğimiz işlemleri, segmentlere atanmış final scriptimizi yapıştırıyoruz.

5 gruba ayrılmış CLTV hesaplaması için aşağıdaki kodu çalıştırabilirsiniz.

import datetime as dt
import pandas as pd
from sklearn.preprocessing import MinMaxScaler

import warnings
warnings.filterwarnings("ignore", category=DeprecationWarning)
warnings.filterwarnings("ignore", category=FutureWarning)

pd.set_option('display.max_columns', None)
pd.set_option('display.max_columns', None)

df_ = pd.read_excel("D:/online_retail_II.xlsx",sheet_name="Year 2010-2011")
df = df_.copy()

def outlier_thresholds(dataframe, variable):
    quartile1 = dataframe[variable].quantile(0.01)
    quartile3 = dataframe[variable].quantile(0.99)
    interquantile_range = quartile3 - quartile1
    up_limit = quartile3 + 1.5 * interquantile_range
    low_limit = quartile1 - 1.5 * interquantile_range
    return low_limit, up_limit


def replace_with_thresholds(dataframe, variable):
    low_limit, up_limit = outlier_thresholds(dataframe, variable)
    # dataframe.loc[(dataframe[variable] < low xss=removed>
    dataframe.loc[(dataframe[variable] > up_limit), variable] = up_limit


def crm_data_prep(dataframe):
    dataframe.dropna(axis=0, inplace=True)
    dataframe = dataframe[~dataframe["Invoice"].str.contains("C", na=False)]
    dataframe = dataframe[dataframe["Quantity"] > 0]
    replace_with_thresholds(dataframe, "Quantity")
    replace_with_thresholds(dataframe, "Price")
    dataframe["TotalPrice"] = dataframe["Quantity"] * dataframe["Price"]
    return dataframe


df_prep = crm_data_prep(df)

##########################################
# Creating RFM Segments
##########################################

def create_rfm(dataframe):
    today_date = dt.datetime(2011, 12, 11)
    rfm = dataframe.groupby('Customer ID').agg({'InvoiceDate': lambda date: (today_date - date.max()).days,
                                                'Invoice': lambda num: num.nunique(),
                                                "TotalPrice": lambda price: price.sum(),
                                                "Country": lambda country: country.min()})
    rfm.columns = ['recency', 'frequency', "monetary", "Country"]
    rfm = rfm[(rfm['monetary'] > 0)]

    rfm["recency_score"] = pd.qcut(rfm['recency'], 5, labels=[5, 4, 3, 2, 1])
    rfm["frequency_score"] = pd.qcut(rfm["frequency"].rank(method="first"), 5, labels=[1, 2, 3, 4, 5])

    rfm['rfm_segment'] = rfm['recency_score'].astype(str) + rfm['frequency_score'].astype(str)

    seg_map = {
        r'[1-2][1-2]': 'hibernating',
        r'[1-2][3-4]': 'at_risk',
        r'[1-2]5': 'cant_loose',
        r'3[1-2]': 'about_to_sleep',
        r'33': 'need_attention',
        r'[3-4][4-5]': 'loyal_customers',
        r'41': 'promising',
        r'51': 'new_customers',
        r'[4-5][2-3]': 'potential_loyalists',
        r'5[4-5]': 'champions'
    }

    rfm['rfm_segment'] = rfm['rfm_segment'].replace(seg_map, regex=True)
    rfm = rfm[["recency", "frequency", "monetary", "recency_score","frequency_score", "rfm_segment", "Country"]]
    return rfm

rfm = create_rfm(df_prep)

##########################################
# Creating CLTV
##########################################

def create_cltv_c(dataframe):
    dataframe['avg_order_value'] = dataframe['monetary'] / dataframe['frequency']
    dataframe["purchase_frequency"] = dataframe['frequency'] / dataframe.shape[0]

    repeat_rate = dataframe[dataframe.frequency > 1].shape[0] / dataframe.shape[0]
    churn_rate = 1 - repeat_rate

    dataframe['profit_margin'] = dataframe['monetary'] * 0.05

    dataframe['cv'] = (dataframe['avg_order_value'] * dataframe["purchase_frequency"])

    dataframe['cltv'] = (dataframe['cv'] / churn_rate) * dataframe['profit_margin']

    scaler = MinMaxScaler(feature_range=(1, 100))
    scaler.fit(dataframe[["cltv"]])
    dataframe["cltv_c"] = scaler.transform(dataframe[["cltv"]])

    dataframe["cltv_c_segment"] = pd.qcut(dataframe["cltv_c"], 5, labels=["E", "D", "C", "B", "A"])

    dataframe = dataframe[["recency", "frequency", "monetary","recency_score","frequency_score", "rfm_segment",
                          "cltv_c", "cltv_c_segment", "Country"]]

    return dataframe

rfm_cltv = create_cltv_c(rfm)

Kodu script olarak aşağıdaki gibi yapıştıralım.

metin içeren bir resim

Açıklama otomatik olarak oluşturuldu

Görselleştirmede kullanacağımız final datayı seçelim ve load’a basarak yüklenmesini sağlayalım.

tablo içeren bir resim

Açıklama otomatik olarak oluşturuldu

Yükleme olduktan sonra datada sayısal değerlerin text değer olarak yüklendiğine ve nokta virgül uyumsuzlukları olduğunu göreceksiniz. Bunları görmek için “Queries” sekmesindeki “Transform Data” ya basalım ve değiştirilmesi gereken sütunu tamamen seçip “Any Columns” ta yer alan “Replace Values” e basarak noktayı virgüle çevirelim. Fakat bu haliyle bazı sütunlar hala text yapıda, sütunların hepsini seçip Data Type kısmından Decimal Number’ a dönüştürebiliriz.  Close & Apply demeden önceki son hali aşağıdaki gibi olmaktadır.

tablo içeren bir resim

Açıklama otomatik olarak oluşturuldu

 

Data hazırlık aşamamız bitti.

İlk görselleştirme çalışması olarak ülkeleri ortalama Recency skor değerlerine göre renklendirelim. Bunun için “format” kısmında “Data colors” için default renk değil, kurala göre renklendirme yapmasını seçiyoruz. Müşterilerin son alışveriş yaptığı skor değeri 3 ve 5 arasında ise turuncuya 3 ten küçük ise sarıya boyayacak şekilde renklendiriyoruz.

Bir diğer görselleştirme ise tüm müşteriler için Country, Recency, Frequency, RFM Segment ve CLTV segmentleri ve CLTV hesaplama değerlerini “Visualization” kısmındaki “Table” seçerek görselleştirelim.

 

tablo içeren bir resim

Açıklama otomatik olarak oluşturuldu

 

Son görsel olarak “Insert” kısmında “Elements” te yer alan “Shapes” içinden 3 adet Rectangle seçelim. Her birine Text Box ekleyelim. Format shape’ te yer alan Fill kısmında gri rengi seçerek arka planı renklendirebilriz. CLTV Segmentlerine göre ortalama Receny, Frequency ve Monetary metriklerini görselleştirelim. 

metin içeren bir resim

Açıklama otomatik olarak oluşturuldu

Bunun için “Visualizations” kısmındaki “Clustered Bar Chart” seçebilirsiniz. Axis kısmına cltv_c_segment’ i, Values kısmına ise Recency, Monetary, Frequency değerlerini her görsel için ayrı ayrı sürükleyip bırakalım. Ortalama değeri için ok tuşuna basarak Average değerlerini seçelim.

Son olarak Slicer seçerek Field alanıa Country değerini koyabiliriz. Böyle ülkelere göre filtreleme kolayca yapabiliriz.

 

Bu yazıda ülkelerin müşteri yaşam boyu değerini hesaplamış ve rfm segmentine göre dağılımlarını incelemiş olduk.

Okuduğunuz için teşekkürler.

Referanslar: I

BigQuery ML ile Çok Terimli Regresyon

Cem İstanbullu

Power BI ile CRM Analitiği - IV: Müşteri Yaşam Boyu Değeri (CLTV) Tahmini

Melda Özdin

R ile Yüksek Performanslı Programlama - I

Onur Boyar

SON ARAŞTIRMALAR

GİRİŞ

Aşağıya kaydolduğunuz e-postayı girin. Şifrenizi sıfırlamanız için size bir bağlantı göndereceğiz.

Giriş Ekranına Dön
Şifre sıfırlama talimatları
adresine gönderildi.