Customer Segmentation with RFM Analysis (in Python Programming Language)
1
library(keras)
Background
Dalam transaksi jual beli, customer memiliki peran penting dalam eksistensi dan kemajuan sebuah industri. Oleh karenanya berbagai strategi marketing dilakukan untuk menarik perhatian customer baru atau untuk mempertahankan loyalitas customer.
Cara yang paling umum dilakukan adalah pemberian diskon pada product tertentu atau pemberian free product untuk customer tertentu. Strategi marketing ini diterapkan sesuai dengan value yang dimiliki oleh customer. Beberapa value dapat dikategorikan menjadi low-value customer (customer dengan frekuensi transaksi rendah dan spend money rendah), medium-value customer (customer dengan frekuensi transaksi tinggi namun spend money rendah atau sebaliknya), dan high-value customer (customer dengan frekuensi transaksi tinggi dan spend money yang tinggi pula).
Dalam melakukan segmentasi customer ada beberapa faktor yang harus dipertimbangkan. Faktor tersebut umumnya dianalisis berdasarkan data historical transaksi yang dimiliki oleh customer. Dari data historical tersebut dilakukan analisis lebih lanjut untuk mengetahui pattern data dan kemudian dilakukan modelling dengan bantuan algoritma machine learning agar menghasilkan output yang dapat dipertanggungjawabkan. Rangkaian proses ini nantinya diharapkan dapat menjawab beberapa pertanyaan bisnis seperti :
Siapakah customer yang berpotensi untuk *churn*, Siapakah loyal customer, Siapakah potential customer, dan lain-lain.
Metode segmentasi yang paling umum digunakan untuk melakukan segmentasi customer adalah RFM analysis. RFM akan melakukan segmentasi berdasarkan 3 poin penting yaitu :
Recency : Waktu transaksi terakhir yang dilakukan customer
Frequency : Banyak transaksi yang dilakukan oleh customer
Monetary : Banyak uang yang dikeluarkan ketika melakukan transaksi
Dalam artikel ini, akan dibahas lebih lanjut tentang proses segmentasi customer menggunakan metode RFM dengan bantuan machine learning clustering algorithm. Bahasa yang digunakan adalah bahasa pemrograman python.
Modelling Analysis
Pada artikel ini data yang digunakan adalah data online retail di UK yang dapat ditemukan pada link berikut. Data ini adalah data transaksi yang terjadi pada 01/12/2010 sampai 09/12/2011.
Import Library and Read Data
1
2
3
4
5
6
7
importpandasaspdimportseabornassnsimportmatplotlib.pyplotaspltpd.options.mode.chained_assignment=None# Suppress the warning (not recommended for general use)importwarningswarnings.simplefilter(action='ignore',category=pd.errors.SettingWithCopyWarning)
#> InvoiceNo StockCode ... CustomerID Country
#> 0 536365 85123A ... 17850.0 United Kingdom
#> 1 536365 71053 ... 17850.0 United Kingdom
#>
#> [2 rows x 8 columns]
1
ecom.shape
#> (541909, 8)
Dataframe ini mengandung 541909 observasi dengan jumlah kolom sebanyak 8 yang antara lain adalah :
InvoiceNo : Nomor invoice yang terdiri dari 6 digit angka unik. Ketika InvoiceNo diawali dengan character C maka mengindikasikan cancellation transaction.
StockCode : Kode product yang terdiri dari 5 digit angka unik.
Description : Deskripsi nama product.
Quantity : Jumlah product yang dibeli pada setiap transaksi.
InvoiceDate : Tanggal transaksi berlangsung.
UnitPrice : Harga satuan product.
CustomerID : ID Customer yang berisi 5 digit angka unik dan berbeda pada setiap customer.
Country : Nama negara.
Get only transaction in UK
Dikarenakan terdapat beberapa data yang tidak berada pada country United Kingdom (UK), maka perlu dilakukan filter data hanya untuk country daerah UK.
#> InvoiceNo StockCode ... CustomerID Country
#> 0 536365 85123A ... 17850.0 United Kingdom
#> 1 536365 71053 ... 17850.0 United Kingdom
#>
#> [2 rows x 8 columns]
Handle Missing Values
Missing value adalah masalah yang umum dihadapi ketika melakukan proses pengolahan data. Missing value terjadi ketika terdapat obeservasi kosong pada sebuah data.
Pada hasil di bawah ini dapat diketahui informasi bahwa beberapa variable pada data menggandung nilai missing, variable tersebut antara lain adalah Description dan CustomerID. CustomerID adalah variable penting dalam RFM analisis, dikarenakan CustomerID mengandung informasi unik ID member. Sedangkan Description mengandung informasi terkait deskripsi produk. Jika ditelaah lebih jauh, untuk menangani missing values pada kedua variable tersebut dapat dilakukan dengan cara deletion, dikarenakan proses imputasi pada kedua variable tersebut akan menghasilkan informasi yang tidak akurat.
Berikut ini adalah proses penghapusan missing values pada data :
1
ecom_uk.dropna(inplace=True)
Select Unique Transaction
Duplicated values atau duplikasi data adalah nilai berulang pada satu atau lebih observasi. Untuk menangani data yang duplikat dapat dilakukan penghapusan dan hanya mempertahankan salah satu observasi.
Dalam pengolahan data transformasi tipe data pada format yang sesuai sangat penting untuk dilakukan, hal ini agar nantinya data-data tersebut siap untuk dilakukan manipulasi lebih lanjut.
Karakter pertama “C” pada InvoiceNo menunjukkan bahwa customer melakukan pembatalan terhadap transaksi yang dilakukan. Sehingga data akan kurang relevan jika tetap dipertahankan, maka dari itu perlu dilakukan penghapusan pada observasi tersebut.
#> InvoiceNo StockCode ... CustomerID Country
#> 0 536365 85123A ... 17850 United Kingdom
#> 7 536366 22633 ... 17850 United Kingdom
#> 9 536367 84879 ... 13047 United Kingdom
#> 21 536368 22960 ... 13047 United Kingdom
#> 25 536369 21756 ... 13047 United Kingdom
#>
#> [5 rows x 8 columns]
Exploratory Data Analysis
Tahapan Exploratory Data Analysis digunakan untuk mengetahui pattern dari data.
Recency
Recency adalah faktor yang menyimpan informasi tentang berapa lama sejak customer melakukan pembelian. Untuk melakukan perhitungan recency pada masing-masing customer dapat dilakukan dengan cara memanipulasi tanggal transaksi customer dan kemudian dikurangi dengan tanggal maksimum yang terdapat pada data. Berikut di bawah ini adalah detail langkah-langkahnya :
Manipulasi tanggal transaksi dengan mengekstrak informasi tanggal, bulan dan tahun transaksi.
1
ecom_uk['Date']=ecom_uk['InvoiceDate'].dt.date
1
ecom_uk.head(2)
#> InvoiceNo StockCode ... Country Date
#> 0 536365 85123A ... United Kingdom 2010-12-01
#> 7 536366 22633 ... United Kingdom 2010-12-01
#>
#> [2 rows x 9 columns]
Mengambil tanggal transaksi maksimum pada keseluruhan observasi
1
2
last_trans=ecom_uk['Date'].max()last_trans
#> datetime.date(2011, 12, 9)
Mengekstrak informasi tanggal transaksi maksimum pada tiap customer.
Menghitung selisih tanggal transaksi maksimum dengan tanggal transaksi terakhir pada tiap customer, kemudian menyimpan jumlah hari pada kolom Days Recent.
Frequency mengandung infromasi tentang seberapa sering customer melakukan transaksi pembelian dalam kurun waktu tertentu. Nilai frequency dapat diperoleh dengan cara menghitung jumlah transkasi pada setiap unik customer.
1
temp=ecom_uk[['CustomerID','InvoiceNo']]
1
2
trans_cust=temp.groupby(by=['CustomerID']).count()trans_cust.rename(columns={'InvoiceNo':'Number of Transaction'})
Ouptut di atas menunjukkan jumlah transaksi yang dilakukan pada masing-masing customer. CustomerID 12346 melakukan transaksi sebanyak 1 kali saja, CustomerID 12747 melakukan transaksi sebanyak 11 kali, dan seterusnya.
Berikut dibawah ini adalah detail informasi InvoiceNo pada setiap transaksi yang dilakukan oleh customer.
Monetary adalah faktor yang menyimpan jumlah pengeluaran customer dalam transaksi. Nilai monetary dapat dihitung dari harga barang yang dibeli oleh masing-masing customer pada transaksi tertentu dan kemudian dikalkulasikan dengan jumlah barang yang dibeli.
Proses clustering bertujuan untuk membagi level customer kedalam beberapa segment tertentu meliputi low-value customer, medium-value customer or high-value customer.
Recency
Pada faktor Recency, customer yang memiliki recent trasaksi akan di kategorikan pada high-value customer. Kenapa? Karena customer tersebut berpotensi untuk melakukan pembelian lagi dibanding dengan customer yang sudah lama tidak melakukan pembelian.
1
new_data['Recency'].describe()
#> count 3921.000000
#> mean 91.722265
#> std 99.528532
#> min 0.000000
#> 25% 17.000000
#> 50% 50.000000
#> 75% 142.000000
#> max 373.000000
#> Name: Recency, dtype: float64
Teknik elbow mwthod untuk menentukan jumlah cluster yang terbentuk.
1
2
3
4
5
6
7
8
9
10
11
12
13
fromsklearn.clusterimportKMeanssse={}recency=new_data[['Recency']]forkinrange(1,10):kmeans=KMeans(n_clusters=k,max_iter=1000).fit(recency)recency["clusters"]=kmeans.labels_sse[k]=kmeans.inertia_plt.figure()plt.plot(list(sse.keys()),list(sse.values()))plt.xlabel("Number of cluster")plt.show()
In a Jupyter environment, please rerun this cell to show the HTML representation or trust the notebook. On GitHub, the HTML representation is unable to render, please try loading this page with nbviewer.org.
Berdasarkan visualisasi grafik elbow, maka jumlah cluster ideal yang dapat dibentuk adalah sebanyak 3 cluster. Pada hasil di atas menunjukkan bahwa cluster 1 mengandung informasi customer yang melakukan transaksi paling baru (most recent) sedangkan cluster 0 mengandung informasi customer yang sudah lama tidak melakukan transaksi pembelian.
Untuk keperluan standarisasi, maka perlu dilakukan re-order cluster sehingga cluster 0 akan memuat informasi low-value customer, cluster 1 medium-value customer dan cluster 2 high-value customer.
Dikarenakan step ini adalah step Recency, maka cluster yang memiliki nilai recency rendah akan dikategorikan pada cluster 2.
Dibawah ini adalah fungsi untuk melakukan reorder cluster :
1
2
3
4
5
6
7
8
9
10
#function for ordering cluster numbersdeforder_cluster(cluster_field_name,target_field_name,df,ascending):new_cluster_field_name='new_'+cluster_field_namedf_new=df.groupby(cluster_field_name)[target_field_name].mean().reset_index()df_new=df_new.sort_values(by=target_field_name,ascending=ascending).reset_index(drop=True)df_new['index']=df_new.indexdf_final=pd.merge(df,df_new[[cluster_field_name,'index']],on=cluster_field_name)df_final=df_final.drop([cluster_field_name],axis=1)df_final=df_final.rename(columns={"index":cluster_field_name})returndf_final
Factor penting selanjutnya adalah Frequency. Pada step frequency, customer yang memiliki banyak transaksi pembelian akan dikategorikan pada level high-value customer.
1
new_data['Frequency'].describe()
#> count 3921.000000
#> mean 4.246111
#> std 7.205750
#> min 1.000000
#> 25% 1.000000
#> 50% 2.000000
#> 75% 5.000000
#> max 210.000000
#> Name: Frequency, dtype: float64
1
2
3
4
5
6
7
8
9
10
sse={}frequency=new_data[['Frequency']]forkinrange(1,10):kmeans=KMeans(n_clusters=k,max_iter=1000).fit(frequency)frequency["clusters"]=kmeans.labels_sse[k]=kmeans.inertia_plt.figure()plt.plot(list(sse.keys()),list(sse.values()))plt.xlabel("Number of cluster")plt.show()
In a Jupyter environment, please rerun this cell to show the HTML representation or trust the notebook. On GitHub, the HTML representation is unable to render, please try loading this page with nbviewer.org.
Sama halnya dengan tahapan pada step Recency, pada step ini juga perlu dilakukan standarisasi cluster dengan melakukan reorder pada cluster. Sehingga cluster 0 dengan nilai frequency yang rendah akan dikategorikan pada level low-value customer sedangkan cluster 2 dengan nilai frequency tinggi akan dikategorikan pada level high-values customer.
Faktor penting terakhir pada RFM analysis adalah Monetary. Customer dengan nilai monetary yang tinggi akan dikategorikan pada level high-value customer dikarenakan berkontribusi besar dalam pendapatan yang dihasilkan industry.
1
new_data['Monetary'].describe()
#> count 3921.000000
#> mean 293.299913
#> std 3261.756525
#> min 0.000000
#> 25% 17.700000
#> 50% 45.400000
#> 75% 124.500000
#> max 168471.250000
#> Name: Monetary, dtype: float64
1
2
3
4
5
6
7
8
9
10
sse={}monetary_=new_data[['Monetary']]forkinrange(1,10):kmeans=KMeans(n_clusters=k,max_iter=1000).fit(monetary_)monetary_["clusters"]=kmeans.labels_sse[k]=kmeans.inertia_plt.figure()plt.plot(list(sse.keys()),list(sse.values()))plt.xlabel("Number of cluster")plt.show()
In a Jupyter environment, please rerun this cell to show the HTML representation or trust the notebook. On GitHub, the HTML representation is unable to render, please try loading this page with nbviewer.org.
Reorder cluster untuk standarisasi cluster sehingga cluster 0 dengan nilai monetary rendah akan dikategorikan dalam low-value customer sedangkan cluster 2 dengan nilai monetary tinggi akan dikelompokkan pada high-values customer.
Setelah memperoleh nilai cluster terurut pada setiap observasi data, langkah selanjutnya adalah memberikan label pada masing-masing observasi. Label ini bertujuan untuk mengidentifikasi level pada masing-masing customer apakah tergolong pada low-value customer, medium-value customer atau high-value customer.
Proses pelabelan terdiri dari beberapa tahapan yang antara lain adalah :
Dari hasil di atas diperoleh informasi bahwa minimum score pada data adalah 0, sedangkan maksimum value pada data adalah 4. Sehingga untuk segmentasi label dapat dikategorikan berdasarkan ketentuan berikut :
Customer dengan score <= 1 akan masuk dalam kategori low-value customer
Customer dengan score <= 3 akan masuk dalam kategori medium-value customer
Customer dengan score > 3 akan masuk dalam kategori high-value customer
Customer’s behavior in each factor based on their label
Setelah memberikan label pada masing-masing customer, apakah sudah cukup membantu untuk tim management dalam menentukan strategi marketing yang tepat? Jawabannya dapat Ya atau Tidak. Tidak dikarenakan management perlu untuk mengetahui informasi detail dari behavior (kebiasaan) customer pada setiap level dalam melakukan pembelanjaan. Oleh karena itu, sebelum melangkah lebih jauh, terlebih dahulu lakukan behavior analisis sebagai berikut :
#> CustomerID Label Metrics Value
#> 0 12346 Low Recency 1.389971
#> 1 15098 Medium Recency 0.996792
#> 2 16029 High Recency -0.064790
#> 3 17450 High Recency -1.121628
#> 4 17949 High Recency -2.530970
#> ... ... ... ... ...
#> 11758 15311 High Monetary 2.967380
#> 11759 16013 High Monetary 3.836427
#> 11760 16422 High Monetary 2.977145
#> 11761 17841 High Monetary 2.165383
#> 11762 16446 High Monetary 5.296556
#>
#> [11763 rows x 4 columns]
Visualisasi behavior customer pada setiap level.
1
2
3
4
5
6
7
importseabornassns# a snake plot with RFMsns.lineplot(x='Metrics',y='Value',hue='Label',data=rfm_melted)plt.title('Customer Behavior based on their Label')plt.legend(loc='upper right')plt.show()
Berdasarkan visualisasi di atas diperoleh detail informasi bahwa :
Customer dengan high-value labels memiliki kecenderungan untuk menghabiskan banyak uang dalam berbelanja (high monetary) dan sering melakukan pembelanjaan (high frequency)
Customer dengan medium-value labels tidak terlalu sering melakukan pembelian dan juga tidak banyak menghabiskan uang selama transaksi.
Customer dengan low-value labels hanya menghabiskan sedikit uang selama berbelanja, tidak terlalu sering berbelanja, tetapi memiliki nilai recency yang cukup tinggi dibandingkan level lainnya.
Berdasarkan rules di atas, pihak management dapat mempertimbangkan melakukan strategi marketing dengan cara :
Memberikan special promotion atau discount untuk low-value customer yang baru-baru saja berkunjung untuk berbelanja, sehingga mereka tertarik untuk berbelanja lagi di lain waktu.
Mempertahankan medium-value customer dengan cara memberikan cashback pada pembeliannya.
Memberikan reward pada loyal customer (high-value) dengan cara memberikan free product atau cashback pada pembelanjaannya.
Conclusion
RFM analysis adalah teknik yang umum digunakan untuk melakukan segmentasi terhadap customer berdasarkan value dan behavior selama bertransaksi. Teknik ini sangat membantu pihak management khususnya marketing team dalam menentukan strategi bisnis yang cocok untuk mempertahankan loyal customer dan menarik customer baru.