RFM Analizi ile Müşteri Segmentasyonu

Merhaba VBO okuyucuları!

Bu yazımda sizlere, müşteri segmentasyonu ve analizinde yaygın bir kullanımı olan RFM analizinden bahsedeceğim. Bir önceki yazımda yine e-ticaret verisi üzerinde belli analizler yapıp, veriyi incelemiştik. Yazıya buradan ulaşabilirsiniz: https://www.veribilimiokulu.com/e-ticaret-veri-analizi/

RFM nedir?

Recency, Frequency, Monetary kelimelerinin baş harflerinden oluşup, bu üç metriğin hesaplanmasından sonra birleştirilmesiyle meydana gelen bir skordur. Müşterilerin mevcut durumunun analiz edilip, bu skorlara göre segmentlere ayrılmasına yardımcı olur.

Recency: Müşterinin ne kadardır websitesinden/mağazadan hizmet aldığı, ne zamandır bize üye olduğu gibi bilgileri verir. Hesaplanması genellikle, bugünden son üyelik tarihi/son sipariş tarihinin çıkartılmasıyla elde edilir.

Frequency: Müşterinin ne sıklıkla alışveriş yaptığını, ne sıklıkla siteye giriş yaptığını gösteren metriktir. Genellikle sipariş numarası/sipariş kodunun saydırılmasıyla sonuç verir.

Monetary: Müşterinin harcamalarının toplamıdır. E-ticaret sitesine getirdiği ciro, aldığı hizmetler sonrası toplanan getiri olarak da tanımlanabilir. Ciro tanımı ne ise, müşteri bazında hayatı boyunca yapılan harcamalar toplanarak hesaplanır.

Son zamanlarda, ‘Tenure’ kavramına da yeni bir metrik olarak RFM analizlerinde yer verilmeye başlandı. Tenure ise, müşterinin e-ticaret sitesi/mağaza ile ilk kontağından bu yana geçen zaman olarak geçer. Bugünden minimum kontak tarihi çıkartılmasıyla bulunabilir.

Bu metrikler belirlendikten sonra, metrik bazında müşteri verisi 5 eşit parçaya ayrılır. Sonrasında bu rakamlar bir araya getirilerek bir RFM skoru atanır.

Şimdi bu analizin Python üzerinde uygulamasını gösterelim.

UCI Machine Learning Repository veritabanından ‘Online Retail II Data Set’ isimli veriyi yükleyip işleme başlıyoruz. https://archive.ics.uci.edu/ml/datasets/Online+Retail+II

#Kütüphaneleri yüklüyoruz
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import datetime as dt
import seaborn as sns

#Veriyi yüklüyoruz
data = pd.read_csv('data2.csv',encoding = 'unicode_escape')

#Toplam harcamayı sütun olarak ekliyoruz
data['TotalPrice'] = data['Price']*data['Quantity']

#Sipariş tarihinin veri tipini değiştiriyoruz
data['InvoiceDate'] = pd.to_datetime(data['InvoiceDate'])

#Bugünü/ analiz tarihini değişken olarak belirliyoruz
today = dt.datetime(2012,1,1)
print(today)

#0'dan büyük değerleri alıyoruz.
data = data[data['Quantity'] > 0]
data = data[data['TotalPrice'] > 0]
Müşteri verisi
#Recency ve Monetary değerleri buluyoruz.
data_x = data.groupby('Customer ID').agg({'TotalPrice': lambda x: x.sum(),
                                        'InvoiceDate': lambda x: (today - x.max()).days})
#Data StockCode bazında olduğu için, InvoiceNo'yu unique hale getiriyoruz.
data_y = data.groupby(['Customer ID','Invoice']).agg({'TotalPrice': lambda x: x.sum()})

#Saydırdığımızda InvoiceNo unique halde gelmiş oluyor.
data_z = data_y.groupby('Customer ID').agg({'TotalPrice': lambda x: len(x)})

#RFM tablosuna ulaşmış oluyoruz.
rfm_table= pd.merge(data_x,data_z, on='Customer ID')

#Sütun isimlerini belirliyoruz
rfm_table.rename(columns= {'InvoiceDate': 'Recency',
                          'TotalPrice_y': 'Frequency',
                          'TotalPrice_x': 'Monetary'}, inplace= True)
Müşteri metrikleri
#Frequency bulma
def RScore(x,p,d):
    if x <= d[p][0.20]:
        return 0
    elif x <= d[p][0.40]:
        return 1
    elif x <= d[p][0.60]: 
        return 2
    elif x <= d[p][0.80]:
        return 3
    else:
        return 4

quantiles = rfm_table.quantile(q=[0.20,0.40,0.60,0.80])
quantiles = quantiles.to_dict()
rfm_table['Freq_Tile'] = rfm_table['Frequency'].apply(RScore, args=('Frequency',quantiles,))

#Recency bulma
rfm_table = rfm_table.sort_values('Recency',ascending=True)
rfm_table['Rec_Tile'] = pd.qcut(rfm_table['Recency'],5,labels=False)

#Monetary bulma
#rfm_table.sort_values('Monetary',ascending=False)
rfm_table['Mone_Tile'] = pd.qcut(rfm_table['Monetary'],5,labels=False)

#'Sıfır' değeri yer almasın istiyorsak, bulduğumuz değerleri 1 arttırıyoruz
rfm_table['Rec_Tile'] = rfm_table['Rec_Tile'] + 1
rfm_table['Freq_Tile'] = rfm_table['Freq_Tile'] + 1
rfm_table['Mone_Tile'] = rfm_table['Mone_Tile'] + 1

#Bulduğumuz değerleri birleştirip tek bir skor elde ediyoruz
rfm_table['RFM Score'] = rfm_table['Rec_Tile'].map(str) + rfm_table['Freq_Tile'].map(str) + rfm_table['Mone_Tile'].map(str)
rfm_table.head()
Müşteri analiz verisi
#Değerlerin içeriklerini inceliyoruz.
rfm_table.groupby('RFM Score').agg({
'Recency': ['mean','min','max','count'],
'Frequency': ['mean','min','max','count'],
'Monetary': ['mean','min','max','count'] }).round(1).head()
Müşteri segmentasyonu

Bu şekilde, segmentasyon işlemi aslında sonlanmış oluyor. Örneğin 121 segmentini yorumlayacak olursak,

  • bu segmentte 22 kişi bulunmakta,
  • ortalama olarak en son alışverişleri 31 gün önce gerçekleşmiş,
  • alışveriş sıklıkları 2, yani 2 alışverişleri var,
  • 209 dolar/TL harcamaları olmuş.

Kimi zaman bu metrikler arasında ağırlıklandırma yapıldığını görüyoruz. Bir şirket için parasal değer daha önemli olabilir, bu durumda mesela, %60 parasal değer, %20 recency değeri, %20 frequency değeri ile çarpıp, ortak bir skor elde edilebilir. Ya da, bu skorlar ile kmeans yapılıp, daha akıllı segmentler elde edilebilir. Bunun gibi kararlar şirketteki ilgili kişiler ile tartışılıp ortak bir karara varılması gereken durumlardır. Bazı kabuller, kurallar belirlenerek, segmentasyon kuralları dönüştürülebilir.

Yorumlarınız ve sorularınız için şimdiden teşekkürler!

Yazar Hakkında
Toplam 9 yazı
Sena Merter Dereli
Sena Merter Dereli
Pazarlama & Müşteri Analitiği Araştırmacısı / n11.com'da Pazarlama Analitiği Yöneticisi
Yorumlar (2 yorum)
fırat
fırat Yanıtla
- 21:00

Merhabalar;
Kimi zaman bu metrikler arasında ağırlıklandırma yapıldığını görüyoruz. Bir şirket için parasal değer daha önemli olabilir, bu durumda mesela, %60 parasal değer, %20 recency değeri, %20 frequency değeri ile çarpıp, ortak bir skor elde edilebilir. Ya da, bu skorlar ile kmeans yapılıp, daha akıllı segmentler elde edilebilir. Bunun gibi kararlar şirketteki ilgili kişiler ile tartışılıp ortak bir karara varılması gereken durumlardır. Bazı kabuller, kurallar belirlenerek, segmentasyon kuralları dönüştürülebilir.

Burda %60 parasal değer, dediğimizde monetary değeri mi çarpılır? yoksa monetary skoru u çarpılır?

fırat
fırat Yanıtla
- 21:02

R, F, M değerlerinin çeyreklerini bulurken neden buluruz? Biz burada hangi koşullara dayanarak [.2 , .4 , .6 , .8] bu şekilde böldük?
[0,25 , 0,50 , 0,75 ,1]’ e bölmedik?

Yardımlarınız için teşekkür ederim.

Bir yanıt yazın

E-posta adresiniz yayınlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir

×

Bir Şeyler Ara