
Einführung
In den letzten 10–15 Jahren haben sich mit dem Fortschritt digitaler Technologien Marketingstrategien grundlegend verändert. Bekannte Marken und Nischenanbieter sammeln heute riesige Datenmengen zu Transaktionen, Käufen, Präferenzen, Kaufkraft, Aktivität, Demografie, Bewertungen und mehr. All diese Daten helfen Marketerinnen und Marketern, das Verhalten ihrer Kundschaft entlang der gesamten Journey zu verstehen – vom Kaufinteresse bis zum tatsächlichen Kauf und zur langfristigen Bindung. Genau hier entfaltet Data Science ihr Potenzial.
Data Science verwandelt Marketing-Big-Data in umsetzbare Erkenntnisse – auch wenn diese auf den ersten Blick weniger intuitiv sind, etwa nicht offensichtliche Verhaltensmuster und Koinzidenzen. So entsteht ein klareres Bild der Zielgruppe: Neue Kundinnen und Kunden lassen sich gezielter gewinnen und bestehende besser halten, Strategien werden optimiert, die Sichtbarkeit steigt, Kampagnen werden treffsicherer, neue Kanäle kommen hinzu – und am Ende wächst der Umsatz deutlich.
Einer der typischsten Data-Science-Einsätze im Marketing ist die Vorhersage der Abwanderungsrate (Churn). Schauen wir uns dieses Thema genauer an.
Data-Science-Use-Case im Marketing: Vorhersage der Customer Churn Rate
Customer Churn beschreibt die Tendenz von Kundinnen und Kunden, ein genutztes Abo zu kündigen und damit nicht länger Kundschaft dieses Dienstes zu sein. Die Customer Churn Rate ist der prozentuale Anteil der Abgewanderten innerhalb eines definierten Zeitraums. Sie ist das Gegenstück zur Wachstumsrate, die neue Kundinnen und Kunden misst.
Die Churn Rate ist ein zentraler Indikator für Kundenzufriedenheit und die Gesundheit des Geschäfts insgesamt. Neben natürlicher Abwanderung, die es in jedem Business gibt, oder saisonalen Effekten, gibt es Faktoren, die darauf hindeuten, dass im Unternehmen etwas schiefläuft und behoben werden sollte. Dazu gehören:
- fehlender oder schlechter Kundensupport,
- negative Service-Erlebnisse,
- Wechsel zu einem Wettbewerber mit besseren Konditionen oder Preisen,
- veränderte Prioritäten der Kundschaft,
- langjährige Kundinnen und Kunden sind nicht mehr zufrieden,
- der Service erfüllt die Erwartungen nicht,
- finanzielle Gründe,
- Betrugsschutz bei Zahlungen der Kundschaft.
Eine hohe Churn Rate ist aus mehreren Gründen ein ernstes Problem:
- Sie korreliert mit Umsatzverlusten.
- Es kostet deutlich mehr, neue Kundinnen und Kunden zu gewinnen, als bestehende zu halten – insbesondere in stark umkämpften Märkten.
- Ist schlechter Service der Grund, leidet die Reputation: Negative Bewertungen ehemaliger Kundinnen und Kunden in sozialen Medien oder auf Bewertungsplattformen können großen Schaden anrichten.
Kundenbindung ist daher ein Kernbestandteil der Geschäftsstrategie aller abonnementbasierten Services. Um Churn vorherzusagen und rechtzeitig gegenzusteuern, musst du Verhaltensdaten sammeln und analysieren (Kaufintervalle, Gesamtdauer der Kundenbeziehung, Kündigungen, Follow-ups per Anruf und Nachricht, Online-Aktivität) und die Merkmale bzw. Merkmalskombinationen identifizieren, die Kundinnen und Kunden mit Abwanderungsrisiko kennzeichnen. Dieses Wissen – insbesondere bei umsatzstarken oder langjährigen Kundinnen und Kunden – ermöglicht es, gezielt Maßnahmen zu ergreifen: etwa proaktive Anrufe mit speziellen Angeboten wie Geschenken, Rabatten, Upgrades zum gleichen Preis oder anderen personalisierten Erlebnissen.
Technisch ist Churn Prediction ein klassisches Klassifikationsproblem im Machine Learning: Kundinnen und Kunden werden mit "Ja" oder "Nein" markiert – also abwanderungsgefährdet oder nicht. Untersuchen wir diesen Use Case in Python mit realen Daten.
Wir modellieren Churn im Telekommunikationsumfeld, in dem Kundinnen und Kunden mehrere Services unter einem Rahmenvertrag nutzen können. Der Datensatz enthält aufbereitete Aktivitätsmerkmale und ein Churn-Label, das angibt, ob jemand abgewandert ist oder nicht.
Werfen wir einen Blick auf die Daten und die Verteilung der Churn Rate:
import pandas as pd
telcom = pd.read_csv('telco.csv')
print(f'Number of customers: {telcom.shape[0]:,}\n'
f'Churn values: {set(telcom['Churn'])}\n\n'
f'Churn distribution, %:\n{round(telcom.groupby(['Churn']).size()/telcom.shape[0]*100).convert_dtypes()}')
Number of customers: 7,032
Churn values: {0, 1}
Churn distribution, %:
Churn
0 73
1 27
dtype: float64
27% der Kundschaft ist abgewandert – ein recht hoher Wert. Im Vergleich zum vorherigen Data-Science-Use-Case scheint hier jedoch kein gravierendes Klassenungleichgewicht vorzuliegen.
Als Nächstes bereiten wir die Daten für das Machine Learning vor. Dazu teilen wir in Trainings- und Testdaten und extrahieren Features und Zielvariable:
from sklearn.model_selection import train_test_split
target = ['Churn']
custid = ['customerID']
cols = [col for col in telcom.columns if col not in custid + target]
X = telcom[cols]
y = telcom[target]
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.25)
Als erstes Modell nutzen wir eine einfache logistische Regression zur Vorhersage der Churn-Labels und Bewertung der Genauigkeit:
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import accuracy_score
lr = LogisticRegression()
lr.fit(X_train, y_train)
predictions = lr.predict(X_test)
print(f'Test accuracy: {round(accuracy_score(y_test, predictions), 4)}')
Test accuracy: 0.8009
Nun erweitern wir die logistische Regression: Wir skalieren die Daten und nutzen L1-Regularisierung, um gleichzeitig Feature Selection zu betreiben. Unterschiedliche C-Werte (Kehrwert der Regularisierungsstärke) beeinflussen die Genauigkeit. Zunächst setzen wir C auf 0.025:
lr = LogisticRegression(penalty='l1', C=0.025, solver='liblinear')
lr.fit(X_train, y_train)
predictions = lr.predict(X_test)
print(f'Test accuracy: {round(accuracy_score(y_test, predictions), 4)}')
Test accuracy: 0.7969
Als Nächstes stimmen wir den C-Parameter der L1-Regularisierung ab, um den optimalen Wert zu finden, der die Modellkomplexität reduziert und gleichzeitig gute Performance liefert. Dazu iterieren wir über verschiedene C-Werte, trainieren jeweils eine logistische Regression und berechnen die Metriken.
Die Liste C mit möglichen Werten ist vorbereitet. Das Array l1_metrics umfasst 3 Spalten: C-Wert, Anzahl der Nicht-Null-Koeffizienten und Accuracy. Probieren wir es aus:
C Non-Zero Coeffs Accuracy
0 1.0000 23.0 0.801479
1 0.5000 22.0 0.799204
2 0.2500 21.0 0.802048
3 0.1000 20.0 0.802617
4 0.0500 18.0 0.802048
5 0.0250 13.0 0.796928
6 0.0100 5.0 0.790102
7 0.0050 3.0 0.783276
8 0.0025 2.0 0.745734
Wir sehen: Kleinere C-Werte verringern die Anzahl der Nicht-Null-Koeffizienten (also der genutzten Features) und damit die Komplexität, senken aber auch die Genauigkeit. C = 0,05 scheint optimal: Die Feature-Anzahl sinkt auf 18, während die Accuracy leicht über der der nicht regularisierten Variante liegt.
Als nächstes probieren wir einen anderen Algorithmus – ein Entscheidungsbaum-Modell:
from sklearn.tree import DecisionTreeClassifier
clf = DecisionTreeClassifier()
clf.fit(X_train, y_train)
predictions = clf.predict(X_test)
print(f'Test accuracy: {round(accuracy_score(y_test, predictions), 4)}')
Test accuracy: 0.7275
Um ein präziseres Modell zu wählen und Overfitting zu vermeiden, stimmen wir die Baumtiefe (max_depth) ab. Technisch ähnelt das der C-Abstimmung oben: Wir iterieren über mehrere max_depth-Werte, trainieren jeweils einen Baum und berechnen die Performance.
Die Liste depth_list mit Kandidaten ist vorbereitet. Das Array depth_tuning hat 2 Spalten: Tiefe und Accuracy. Wenden wir den Ansatz an und finden die optimale Tiefe:
depth_list = list(range(2, 15))
depth_tuning = np.zeros((len(depth_list), 2))
depth_tuning[:, 0] = depth_list
for index in range(len(depth_list)):
clf = DecisionTreeClassifier(max_depth=depth_list[index])
clf.fit(X_train, y_train)
predictions = clf.predict(X_test)
depth_tuning[index, 1] = accuracy_score(y_test, predictions)
col_names = ['Max_Depth', 'Accuracy']
print(pd.DataFrame(depth_tuning, columns=col_names))
Max_Depth Accuracy
0 2.0 0.756542
1 3.0 0.783276
2 4.0 0.782708
3 5.0 0.791809
4 6.0 0.778157
5 7.0 0.780432
6 8.0 0.757110
7 9.0 0.762230
8 10.0 0.763936
9 11.0 0.752560
10 12.0 0.745165
11 13.0 0.732651
12 14.0 0.727531
Die Accuracy steigt zunächst mit der Tiefe und fällt dann wieder. Bei max_depth = 5 erreicht der Baum den höchsten Wert – diesen können wir als optimal ansehen.
Nachdem wir die besten Parameter für beide Modelle gefunden haben, setzen wir sie neu auf und identifizieren die wichtigsten Treiber, die Churn erhöhen oder senken.
Für die logistische Regression betrachten wir die Exponenten der Koeffizienten:
# Bestes Modell rekonstruieren
lr = LogisticRegression(penalty='l1', C=0.05, solver='liblinear')
lr.fit(X_train, y_train)
predictions = lr.predict(X_test)
# Feature-Namen und Koeffizienten zusammenführen
feature_names = pd.DataFrame(X_train.columns, columns=['Feature'])
log_coef = pd.DataFrame(np.transpose(lr.coef_), columns=['Coefficient'])
coefficients = pd.concat([feature_names, log_coef], axis=1)
# Exponenten berechnen
coefficients['Exp_Coefficient'] = np.exp(coefficients['Coefficient'])
# Null-Koeffizienten entfernen
coefficients = coefficients[coefficients['Coefficient']!=0]
print(coefficients.sort_values(by=['Exp_Coefficient']))
Feature Coefficient Exp_Coefficient
21 tenure -0.907750 0.403431
4 PhoneService_Yes -0.820517 0.440204
17 Contract_Two year -0.595271 0.551413
8 TechSupport_Yes -0.418254 0.658195
16 Contract_One year -0.414158 0.660896
5 OnlineSecurity_Yes -0.412228 0.662173
6 OnlineBackup_Yes -0.143100 0.866667
3 Dependents_Yes -0.039299 0.961463
7 DeviceProtection_Yes -0.017465 0.982687
11 PaperlessBilling_Yes 0.071389 1.073999
1 SeniorCitizen_Yes 0.097904 1.102857
19 PaymentMethod_Electronic check 0.188533 1.207477
22 MonthlyCharges 0.901454 2.463182
Der stärkste Einflussfaktor auf die Abwanderungswahrscheinlichkeit ist tenure (Dauer der Kundenbeziehung). Allgemein gilt: Exponenten kleiner als 1 senken die Odds, größere als 1 erhöhen sie.
Für den Entscheidungsbaum extrahieren und visualisieren wir die If-Else-Regeln:
# Bestes Modell rekonstruieren
clf = DecisionTreeClassifier(max_depth=5)
clf.fit(X_train, y_train)
predictions = clf.predict(X_test)
from sklearn import tree
import graphviz
# Graphviz-Objekt aus dem trainierten Baum exportieren
exported = tree.export_graphviz(decision_tree=clf,
out_file=None,
feature_names=cols,
precision=1,
class_names=['Not churn', 'Churn'],
filled=True)
graph = graphviz.Source(exported)
display(graph)

Die Visualisierung lässt sich als Baum von If-Else-Regeln interpretieren. Wieder sehen wir: Die Dauer der Kundenbeziehung ist der wichtigste Treiber. Mit mehr Ebenen lassen sich zusätzliche Einblicke zu weiteren Variablen gewinnen.
Als nächste Schritte kannst du Parameter weiter verfeinern, andere Verfahren für das Train/Test-Splitting testen, zusätzliche Algorithmen vergleichen und verschiedene Metriken auswerten, um die Modellleistung ganzheitlich zu beurteilen.
Wenn du tiefer in Churn Prediction und andere Data-Science-Anwendungen im Marketing einsteigen willst, ist dieser Kurs ein guter Startpunkt: Machine Learning for Marketing in Python.


