Zum Hauptinhalt springen

Einführung in die Kundensegmentierung mit Python

In diesem Tutorial lernst du, wie du Kundensegmentierung mit der RFM-Analyse (Recency, Frequency, Monetary) von Grund auf in Python umsetzt.
· 8 Min. lesen

Entdecke KI

Im Einzelhandel erzeugen Filialketten täglich enorme Datenmengen. Diese Daten fallen in allen Stores an und wachsen von Tag zu Tag. Diese umfangreiche Datenbasis aus Transaktionen muss analysiert werden, um profitable Strategien zu entwickeln.

Alle Kundinnen und Kunden haben unterschiedliche Bedürfnisse. Mit wachsender Kundenbasis und mehr Transaktionen wird es immer schwieriger, die Anforderungen jeder einzelnen Person zu verstehen. Die Identifizierung potenzieller Käufergruppen verbessert Kampagnen und steigert letztlich den Umsatz. Segmentierung hilft, Kundinnen und Kunden in sinnvolle Gruppen einzuteilen.

Was ist Kundensegmentierung?

Kundensegmentierung ist die Einteilung von Kundinnen und Kunden in Gruppen oder Cluster anhand gemeinsamer Merkmale. Im B2C-Bereich können Marktforschende nach demografischen Merkmalen wie Beruf, Geschlecht, Alter, Standort und Familienstand segmentieren. Dazu kommen psychografische Merkmale wie soziale Schicht, Lebensstil und Persönlichkeit sowie Verhaltensmerkmale wie Ausgaben, Konsumgewohnheiten, Produkt-/Service-Nutzung und bisherige Käufe. Im B2B-Umfeld bieten sich Unternehmensmerkmale an, zum Beispiel Unternehmensgröße, Branche und Standort.

chart

Warum Kundensegmentierung?

  • Sie hilft, die vielversprechendsten Kundinnen und Kunden zu identifizieren.
  • Sie ermöglicht es, gezielt mit den richtigen Zielgruppen zu kommunizieren.
  • Sie unterstützt bei der Auswahl des effektivsten Kanals für jede Zielgruppe.
  • Sie verbessert Servicequalität, Loyalität und Bindung.
  • Sie stärkt die Kundenbeziehung durch ein besseres Verständnis der Segmentbedürfnisse.
  • Sie eröffnet Chancen für Upselling und Cross-Selling.
  • Sie erleichtert es, spezielle Angebote für Zielgruppen zu entwickeln, um Mehrkäufe zu fördern.
  • Sie hilft, der Konkurrenz einen Schritt voraus zu sein.
  • Sie zeigt potenzielle neue Produkte auf, die Kundinnen und Kunden interessieren könnten.

Arten der Segmentierung

types of segmentation

Kundensegmentierung mit RFM-Analyse

Die RFM-Analyse (Recency, Frequency, Monetary) ist ein verhaltensbasiertes Verfahren zur Gruppierung von Kundinnen und Kunden. Sie segmentiert anhand vergangener Käufe: Wie kürzlich, wie häufig und wie viel wurde eingekauft? RFM filtert Kundinnen und Kunden für bessere Betreuung in verschiedene Gruppen. So lassen sich besonders wertvolle Zielgruppen für profitableres Geschäft identifizieren. Es gibt zum Beispiel Großkundinnen und -kunden, aber was, wenn sie nur einmal oder schon lange her gekauft haben? Kaufen sie regelmäßig? Außerdem unterstützt RFM personalisierte und wirksame Promotions.

  • Recency (R): Wer hat kürzlich gekauft? Anzahl der Tage seit dem letzten Kauf (geringe Recency ist besser).
  • Frequency (F): Wer kauft häufig? Gemeint ist die Anzahl der Bestellungen (hohe Frequency ist besser).
  • Monetary (M): Wer hat hohe Umsätze? Gemeint ist der gesamte ausgegebene Betrag (hoher Monetary-Wert ist besser).

Jede der drei Variablen (Recency, Frequency, Monetary) wird in vier gleich große Gruppen unterteilt. So entstehen 64 (4x4x4) verschiedene Kundensegmente.

Schritte der RFM-Analyse (Recency, Frequency, Monetary):

  1. Berechne Recency-, Frequency- und Monetary-Werte für jede Kundin bzw. jeden Kunden.
  2. Füge der RFM-Tabelle Segment-Bins per Quartil hinzu.
  3. Sortiere die RFM-Scores aufsteigend.

1. Berechne Recency-, Frequency- und Monetary-Werte pro Kunde.

Recency, Frequency, Monetary values

2. Füge der RFM-Tabelle Segment-Bins per Quartil hinzu.

segment bin values on RFM table

3. Fasse alle Scores in einer Spalte (RFM_Score) zusammen.

all scores in single column

Potenzielle Kundensegmente mit RFM in Python identifizieren

Benötigte Bibliotheken importieren

#import modules
import pandas as pd # for dataframes
import matplotlib.pyplot as plt # for plotting graphs
import seaborn as sns # for plotting graphs
import datetime as dt

Dataset laden

Lass uns zuerst das benötigte HR-Dataset mit der pandas-Funktion read_csv laden. Du kannst die Daten über diesen Link herunterladen.

data = pd.read_excel("Online_Retail.xlsx")
data.head()
dataset 1
data.tail()
dataset 2
data.info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 541909 entries, 0 to 541908
Data columns (total 8 columns):
InvoiceNo      541909 non-null object
StockCode      541909 non-null object
Description    540455 non-null object
Quantity       541909 non-null int64
InvoiceDate    541909 non-null datetime64[ns]
UnitPrice      541909 non-null float64
CustomerID     406829 non-null float64
Country        541909 non-null object
dtypes: datetime64[ns](1), float64(2), int64(1), object(4)
memory usage: 33.1+ MB
data= data[pd.notnull(data['CustomerID'])]

Duplikate entfernen

Manchmal sind Datensätze unaufgeräumt. Duplikate können die Analyse verzerren. In Python bietet pandas die Funktion drop_duplicates(), um doppelte Einträge zu entfernen.

filtered_data=data[['Country','CustomerID']].drop_duplicates()

Lass uns in die Daten eintauchen

#Top ten country's customer
filtered_data.Country.value_counts()[:10].plot(kind='bar')
<matplotlib.axes._subplots.AxesSubplot at 0x7fd81725dfd0>
data insights

Im vorliegenden Datensatz stammen die meisten Kundinnen und Kunden aus dem "United Kingdom". Du kannst also die Daten auf Kundinnen und Kunden aus dem Vereinigten Königreich filtern.

uk_data=data[data.Country=='United Kingdom']
uk_data.info()
<class 'pandas.core.frame.DataFrame'>
Int64Index: 361878 entries, 0 to 541893
Data columns (total 8 columns):
InvoiceNo      361878 non-null object
StockCode      361878 non-null object
Description    361878 non-null object
Quantity       361878 non-null int64
InvoiceDate    361878 non-null datetime64[ns]
UnitPrice      361878 non-null float64
CustomerID     361878 non-null float64
Country        361878 non-null object
dtypes: datetime64[ns](1), float64(2), int64(1), object(4)
memory usage: 24.8+ MB

Die describe()-Funktion in pandas liefert schnell diverse Kennzahlen. Sie gibt Anzahl, Mittelwert, Standardabweichung, Minimum und Maximum sowie die Quantile zurück.

uk_data.describe()
 QuantityUnitPriceCustomerID
count361878.000000361878.000000361878.000000
mean11.0770293.25600715547.871368
std263.12926670.6547311594.402590
min-80995.0000000.00000012346.000000
25%2.0000001.25000014194.000000
50%4.0000001.95000015514.000000
75%12.0000003.75000016931.000000
max80995.00000038970.00000018287.000000

Hier fällt auf, dass einige Bestellungen negative Mengen aufweisen – das ist nicht plausibel. Filtere daher Quantity größer als null.

uk_data = uk_data[(uk_data['Quantity']>0)]
In: # Change the name of columns
rfm.columns=['monetary','frequency','recency']
uk_data.info() 
<class 'pandas.core.frame.DataFrame'>
Int64Index: 354345 entries, 0 to 541893
Data columns (total 8 columns):
InvoiceNo      354345 non-null object
StockCode      354345 non-null object
Description    354345 non-null object
Quantity       354345 non-null int64
InvoiceDate    354345 non-null datetime64[ns]
UnitPrice      354345 non-null float64
CustomerID     354345 non-null float64
Country        354345 non-null object
dtypes: datetime64[ns](1), float64(2), int64(1), object(4)
memory usage: 24.3+ MB

Benötigte Spalten filtern

Für die RFM-Analyse reichen fünf Spalten: CustomerID, InvoiceDate, InvoiceNo, Quantity und UnitPrice. CustomerID identifiziert eindeutig, InvoiceDate ermöglicht die Recency-Berechnung, InvoiceNo zählt die Bestellungen (Frequency). Quantity pro Transaktion und UnitPrice je Einheit erlauben die Ermittlung des Gesamtumsatzes.

uk_data=uk_data[['CustomerID','InvoiceDate','InvoiceNo','Quantity','UnitPrice']]
uk_data['TotalPrice'] = uk_data['Quantity'] * uk_data['UnitPrice']
uk_data['InvoiceDate'].min(),uk_data['InvoiceDate'].max()
(Timestamp('2010-12-01 08:26:00'), Timestamp('2011-12-09 12:49:00'))
PRESENT = dt.datetime(2011,12,10)
uk_data['InvoiceDate'] = pd.to_datetime(uk_data['InvoiceDate'])
uk_data.head()
 CustomerIDInvoiceDateInvoiceNoQuantityUnitPriceTotalPrice
017850.02010-12-01 08:26:0053636562.5515.30
117850.02010-12-01 08:26:0053636563.3920.34
217850.02010-12-01 08:26:0053636582.7522.00
317850.02010-12-01 08:26:0053636563.3920.34
417850.02010-12-01 08:26:0053636563.3920.34

RFM-Analyse

Du führst folgende Schritte aus:

  • Recency: Anzahl der Tage zwischen Stichtag und letztem Kauf je Kunde.
  • Frequency: Anzahl der Bestellungen je Kunde.
  • Monetary: Summe der Kaufbeträge je Kunde.
rfm= uk_data.groupby('CustomerID').agg({'InvoiceDate': lambda date: (PRESENT - date.max()).days,
                                        'InvoiceNo': lambda num: len(num),
                                        'TotalPrice': lambda price: price.sum()})
rfm.columns
Index(['InvoiceDate', 'TotalPrice', 'InvoiceNo'], dtype='object')
# Change the name of columns rfm.columns=['recency', 'monetary', 'frequency'] 
rfm['recency'] = rfm['recency'].astype(int)
rfm.head()
 monetaryfrequencyrecency
CustomerID   
12346.032577183.601
12747.024196.01103
12748.0033719.734596
12749.034090.88199
12820.03942.3459

Quartile für RFM-Werte berechnen

Kundinnen und Kunden mit der niedrigsten Recency sowie der höchsten Frequency und dem höchsten Monetary-Wert gelten als Top-Kundschaft.

qcut() ist eine quantilbasierte Diskretisierungsfunktion. Sie teilt Daten anhand von Stichprobenquantilen in Bins ein. Beispiel: 1000 Werte in 4 Quantilen ergeben eine kategoriale Zuordnung der Quantil-Mitgliedschaft je Kundin bzw. Kunde.

rfm['r_quartile'] = pd.qcut(rfm['recency'], 4, ['1','2','3','4'])
rfm['f_quartile'] = pd.qcut(rfm['frequency'], 4, ['4','3','2','1'])
rfm['m_quartile'] = pd.qcut(rfm['monetary'], 4, ['4','3','2','1'])
rfm.head()
 monetaryfrequencyrecencyr_quartilef_quartilem_quartile
CustomerID      
12346.032577183.601111
12747.024196.01103414
12748.0033719.734596414
12749.034090.88199414
12820.03942.3459324

RFM-Ergebnisse interpretieren

Kombiniere alle drei Quartile (r_quartile, f_quartile, m_quartile) in einer Spalte. Dieser Rang hilft dir, Kundinnen und Kunden treffsicher zu segmentieren.

rfm['RFM_Score'] = rfm.r_quartile.astype(str)+ rfm.f_quartile.astype(str) + rfm.m_quartile.astype(str)
rfm.head()
 monetaryfrequencyrecencyr_quartilef_quartilem_quartileRFM_Score
CustomerID       
12346.032577183.601111111
12747.024196.01103414414
12748.0033719.734596414414
12749.034090.88199414414
12820.03942.3459324324
# Filter out Top/Best cusotmers
rfm[rfm['RFM_Score']=='111'].sort_values('monetary', ascending=False).head()
 monetaryfrequencyrecencyr_quartilef_quartilem_quartileRFM_Score
CustomerID       
16754.03722002.42111111
12346.032577183.61111111
15749.023544534.310111111
16698.02261998.05111111
13135.01963096.01111111

Fazit

Glückwunsch, du hast das Ende dieses Tutorials erreicht!

Du hast die wichtigsten Aspekte der Kundensegmentierung kennengelernt: Was Segmentierung ist, warum sie gebraucht wird, welche Arten es gibt, die RFM-Analyse und deren Umsetzung von Grund auf in Python. Außerdem hast du grundlegende pandas-Konzepte wie den Umgang mit Duplikaten, groupby und qcut() für quantilbasierte Bins wiederholt.

Idealerweise kannst du die Methoden nun auf eigene Datensätze anwenden. Danke fürs Lesen!

Wenn du mehr über Python lernen willst, starte mit DataCamps kostenlosem Kurs Intro to Python for Data Science.

Themen

Ähnlich