├── README.md └── RFM.py /README.md: -------------------------------------------------------------------------------- 1 | # RFM-Analysis-for-Customer-Segmentation 2 | 3 | I segmented the customers according to their behavior and thus more comfortable marketing strategies can be made. 4 | 5 | For those who want to access the data set: https://archive.ics.uci.edu/ml/datasets/Online+Retail+II 6 | -------------------------------------------------------------------------------- /RFM.py: -------------------------------------------------------------------------------- 1 | import datetime as dt 2 | import pandas as pd 3 | import matplotlib.pyplot as plt 4 | 5 | pd.set_option('display.max_columns', None) 6 | pd.set_option('display.float_format', lambda x: '%.5f' % x) 7 | df_ = pd.read_excel("online_retail_II.xlsx", sheet_name="Year 2010-2011") 8 | df = df_.copy() 9 | 10 | df.info() 11 | df.isnull().sum() 12 | 13 | # boş değerleri kaldırmak 14 | df.dropna(inplace=True) 15 | 16 | # ürünlerin adet sayıları 17 | df["Description"].value_counts().head() 18 | 19 | # essiz ürün sayısı 20 | df["Description"].nunique() 21 | 22 | # ürünlerin toplam satıs miktarını çoktan aza doğru sıralamak 23 | df.groupby("Description").agg({"Quantity": "sum"}).sort_values("Quantity", ascending=False).head() 24 | 25 | # kesilen fatura adedi 26 | df["Invoice"].nunique() 27 | 28 | # iade ürünleri işlemlere dahil etmemek için eledik 29 | df = df[~df["Invoice"].str.contains("C", na=False)] 30 | 31 | # her bir üründen kazanılan ücreti hesaplamak için bir değişken atadık 32 | df["TotalPrice"] = df["Quantity"] * df["Price"] 33 | 34 | # veri setinin son halinde bir aykırılık olup olmadığını kontrol ediyoruz 35 | df.describe([0.01, 0.05, 0.10, 0.25, 0.50, 0.75, 0.90, 0.95, 0.99]).T 36 | 37 | # veri setindeki son tarihe baktık 38 | df["InvoiceDate"].max() 39 | """ 40 | Recency değerini hesaplamak için today_date adlı bir değişken tanımladık. 41 | Bu değişkenin verideki son tarihten 2 gün fazla yaptık. Bunu yapma amacımız veri setindeki 42 | son tarihte alışveriş yapanların Recency değerinin 0 olmasını engellemekti. 43 | """ 44 | today_date = dt.datetime(2011, 12, 11) 45 | 46 | # gruplama ile rfm değerlerini elde ettik 47 | rfm = df.groupby('Customer ID').agg({'InvoiceDate': lambda date: (today_date - date.max()).days, 48 | 'Invoice': lambda num: len(num), 49 | 'TotalPrice': lambda TotalPrice: TotalPrice.sum()}) 50 | 51 | rfm.columns = ['Recency', 'Frequency', 'Monetary'] 52 | 53 | # satın alma olduğu halde ücret gözükmeyen problemli verileri kaldırdık. 54 | rfm = rfm[(rfm["Monetary"]) > 0 & (rfm["Frequency"] > 0)] 55 | 56 | """ 57 | Recency değerini segmentlere ayırdık. 58 | Recency değerinin yüksek olması müşterinin bizden uzaklaşması anlamına geliyor. 59 | Bu karışıklığı önlemek adına labellerini azalan şekilde yaptık 60 | """ 61 | rfm["RecencyScore"] = pd.qcut(rfm["Recency"], 5, labels=[5, 4, 3, 2, 1]) 62 | rfm["FrequencyScore"] = pd.qcut(rfm["Frequency"], 5, labels=[1, 2, 3, 4, 5]) 63 | rfm["MonetaryScore"] = pd.qcut(rfm["Monetary"], 5, labels=[1, 2, 3, 4, 5]) 64 | 65 | # rfm değerini tek noktada görmek adına rfm_score adlı değişken tanımladık 66 | rfm["RFM_SCORE"] = (rfm['RecencyScore'].astype(str) + 67 | rfm['FrequencyScore'].astype(str) + 68 | rfm['MonetaryScore'].astype(str)) 69 | 70 | seg_map = { 71 | r'[1-2][1-2]': 'Hibernating', 72 | r'[1-2][3-4]': 'At_Risk', 73 | r'[1-2]5': 'Cant_Loose', 74 | r'3[1-2]': 'About_to_Sleep', 75 | r'33': 'Need_Attention', 76 | r'[3-4][4-5]': 'Loyal_Customers', 77 | r'41': 'Promising', 78 | r'51': 'New_Customers', 79 | r'[4-5][2-3]': 'Potential_Loyalists', 80 | r'5[4-5]': 'Champions' 81 | } 82 | # regex kullanarak rfm değerlerine karşılıkları olan segmentleri verdik 83 | rfm["Segment"] = (rfm['RecencyScore'].astype(str) + rfm['FrequencyScore'].astype(str)) 84 | rfm["Segment"] = rfm["Segment"].replace(seg_map, regex=True) 85 | 86 | # rfm değerlerini segmentlere göre gruplayıp değerlerinin ortalamasını ve sayısını aldık. 87 | rfm[["Segment", "Recency", "Frequency", "Monetary"]].groupby("Segment").agg(["mean", "count"]) 88 | 89 | # Loyal_Customers segmentindeki kişilerin değerlerini alıp csv dosyası olarak export ettik. 90 | rfm[rfm["Segment"] == "Loyal_Customers"].index 91 | 92 | new_df = pd.DataFrame() 93 | new_df["Loyal_Customers"] = rfm[rfm["Segment"] == "Loyal_Customers"].index 94 | new_df.to_csv("Loyal_Customers.csv") 95 | 96 | --------------------------------------------------------------------------------