Churn prediction

figcaption > foto av Mantas hesthaven på Unsplash

customer Churn, även känd som customer Attrition, uppstår när kunder slutar göra affärer med ett företag. Företagen är intresserade av att identifiera segment av dessa kunder eftersom priset för att förvärva en ny kund vanligtvis är högre än att behålla den gamla. Till exempel, om Netflix kände till ett segment av kunder som riskerade att churning kunde de proaktivt engagera dem med specialerbjudanden istället för att helt enkelt förlora dem.

i det här inlägget kommer vi att skapa en enkel kund churn förutsägelse modell med Telco kund Churn dataset. Vi valde ett beslutsträd för att modellera churned kunder, pandor för data crunching och matplotlib för visualiseringar. Vi kommer att göra allt detta ovan i Python.
koden kan användas med en annan dataset med några mindre justeringar för att träna baslinjemodellen. Vi ger också några referenser och ger förslag på nya funktioner och förbättringar.

Du kan köra den här koden genom att ladda ner den här Jupyter-anteckningsboken.

Här är några länkar som kan intressera dig:

- Labeling and Data Engineering for Conversational AI and Analytics- Data Science for Business Leaders - Intro to Machine Learning with PyTorch - Become a Growth Product Manager - Deep Learning (Adaptive Computation and ML series) - Free skill tests for Data Scientists & Machine Learning Engineers

några av länkarna ovan är affiliate länkar och om du går igenom dem för att göra ett köp tjänar jag en provision. Tänk på att jag länkar kurser på grund av deras kvalitet och inte på grund av den provision jag får från dina inköp.

vi använder pandor för att läsa datauppsättningen och förbehandla den. Telco dataset har en kund per rad med många kolumner (funktioner). Det finns inga rader med alla saknade värden eller dubbletter (detta händer sällan med verkliga datamängder). Det finns 11 prover som har Totaltladdningar inställda på””, vilket verkar som ett misstag i data. Vi tar bort dessa prover och ställer in typen till numerisk (float).

df = pd.read_csv('data/WA_Fn-UseC_-Telco-Customer-Churn.csv')df = df.dropna(how=”all”) # remove samples with all missing values
df = df # remove duplicatestotal_charges_filter = df.TotalCharges == " "
df = df
df.TotalCharges = pd.to_numeric(df.TotalCharges)

första exemplaren i telco kund Churn dataset

exploratory data analysis

Vi har 2 typer av funktioner i dataset: kategorisk (två eller flera värden och utan någon ordning) och numerisk. De flesta funktionsnamnen är självförklarande, förutom:

  • Partner: om kunden har en partner eller inte (ja, nej),
  • beroende: om kunden har anhöriga eller inte (ja, nej),
  • OnlineBackup: om kunden har en online backup eller inte (ja, nej, ingen internettjänst),
  • tenure: antal månader kunden har bott hos företaget,
  • MonthlyCharges: det belopp som debiteras kunden varje månad,
  • Totalavgifter: det totala belopp som debiteras kunden.

det finns 7032 kunder i datauppsättningen och 19 funktioner utan customerID (icke-informativ) och Churn kolumn (målvariabel). De flesta av de kategoriska funktionerna har 4 eller mindre unika värden.

Dataset sammanfattning

vi kombinerar funktioner i två listor så att vi kan analysera dem gemensamt.

categorical_features = 
numerical_features =
target = "Churn”

numeriska funktioner distribution

numeriska sammanfattningstekniker (medelvärde, standardavvikelse etc.) Visa oss inte spikar, former av fördelningar och det är svårt att observera avvikare med det. Det är därför vi använder histogram.

df.describe()

sammanfattning av numeriska funktioner

vid första anblicken finns det inga avvikelser i data. Ingen datapunkt kopplas bort från distributionen eller för långt från medelvärdet. För att bekräfta att vi skulle behöva beräkna interkvartilintervall (IQR) och visa att värdena för varje numerisk funktion ligger inom 1,5 IQR från första och tredje kvartilen.

Vi kan konvertera numeriska funktioner till ordinära intervall. Till exempel är besittningsrätt numerisk, men ofta bryr vi oss inte om små numeriska skillnader och grupperar istället besittningsrätt till kunder med kort, medellång och lång sikt. En anledning att konvertera det skulle vara att minska bullret, ofta små fluktuerar är bara buller.

df.hist(bins=30, figsize=(10, 7))

histogram av numeriska funktioner

vi tittar på fördelningar av numeriska funktioner i förhållande till målvariabeln. Vi kan konstatera att ju större Totalavgifter och besittningsrätt är desto mindre är sannolikheten för churn.

fig, ax = plt.subplots(1, 3, figsize=(14, 4))
df.hist(bins=30, color="blue", alpha=0.5, ax=ax)
df.hist(bins=30, color="red", alpha=0.5, ax=ax)

numeriska funktioner i förhållande till målvariabeln

kategorisk funktionsfördelning

för att analysera kategoriska funktioner använder vi stapeldiagram. Vi observerar att äldre och kunder utan telefontjänst är mindre representerade i uppgifterna.

ROWS, COLS = 4, 4
fig, ax = plt.subplots(ROWS, COLS, figsize=(18, 18))
row, col = 0, 0
for i, categorical_feature in enumerate(categorical_features):
if col == COLS - 1:
row += 1
col = i % COLS
df.value_counts().plot('bar', ax=ax).set_title(categorical_feature)

fördelning av kategoriska funktioner

nästa steg är att titta på kategoriska funktioner i förhållande till målvariabeln. Vi gör detta endast för kontrakt funktion. Användare som har en månad till månad kontrakt är mer benägna att churn än användare med långsiktiga kontrakt.

feature = ‘Contract’
fig, ax = plt.subplots(1, 2, figsize=(14, 4))
df.value_counts().plot(‘bar’, ax=ax).set_title(‘not churned’)
df.value_counts().plot(‘bar’, ax=ax).set_title(‘churned’)

kontraktsfunktion i förhållande till målvariabeln

målvariabelfördelning

målvariabelfördelning visar att vi har att göra med ett obalanserat problem eftersom det finns många fler icke-churned som churned användare. Modellen skulle uppnå hög noggrannhet eftersom det för det mesta skulle förutsäga majoritetsklassanvändare som inte churn i vårt exempel.

några saker vi kan göra för att minimera påverkan av obalanserad dataset:
– sampla data (obalanserad-lär),
– samla in fler prover,
– Använd precision och återkalla som noggrannhetsmått.

df.value_counts().plot('bar').set_title('churned')

målvariabel distribution

funktioner

telco dataset är redan grupperat efter CustomerID så det är svårt att lägga till nya funktioner. När vi arbetar med churn-förutsägelsen får vi vanligtvis en dataset som har en post per kundsession (kundaktivitet under en viss tid). Då kan vi lägga till funktioner som:

  • antal sessioner innan du köper något,
  • genomsnittlig tid per session,
  • tidsskillnad mellan sessioner (frekvent eller mindre frekvent kund),
  • är en kund endast i ett land.

Ibland har vi till och med kundhändelsedata, vilket gör att vi kan hitta mönster för kundbeteende i förhållande till resultatet (churn).

Kodningsfunktioner

för att förbereda datauppsättningen för modellering av churn måste vi koda kategoriska funktioner till siffror. Detta innebär att koda ”ja”, ” nej ” till 0 och 1 så att algoritmen kan arbeta med data. Denna process kallas onehot-kodning.

en het kodade kategoriska funktioner

klassificerare

vi använder sklearn, ett maskininlärningsbibliotek i Python, för att skapa en klassificerare.
Den sklearn sätt är att använda rörledningar som definierar funktionen bearbetning och klassificerare. I vårt exempel tar rörledningen en dataset i ingången, den förbehandlar funktioner och tränar klassificeraren.
när det tränas tar det samma ingång och returnerar förutsägelser i utmatningen.

i rörledningen behandlar vi separat kategoriska och numeriska funktioner. Vi onehot koda kategoriska funktioner och skala numeriska funktioner genom att ta bort medelvärdet och skala dem till enhet varians.
vi valde en beslutsträdsmodell på grund av dess tolkningsförmåga och satte maxdjup till 3 (godtyckligt).

rörledningen tar en dataset i ingången, den förbehandlar funktioner och tränar klassificeraren

träna modellen

vi delar upp datasetet för att träna (75% prover) och testa (25% prover).
vi tränar (passar) rörledningen och gör förutsägelser. Med classification_report beräknar vi precision och återkallelse med faktiska och förutsagda värden.

from sklearn.model_selection import train_test_splitdf_train, df_test = train_test_split(df, test_size=0.25, random_state=42)pipeline.fit(df_train, df_train)
pred = pipeline.predict(df_test)

testa modellen

med classification_report beräknar vi precision och minns med faktiska och förutsagda värden.

För klass 1 (churned users) modell uppnår 0.67 precision och 0.37 minns. Precision berättar hur många churned användare gjorde vår klassificerare förutspådde korrekt. På andra sidan, minns berätta hur många churned användare det missade.

i lekman termer är klassificeraren inte särskilt exakt för churned användare.

from sklearn.metrics import classification_reportprint(classification_report(df_test, pred))

klassificeringsrapport för beslutsträdsmodellen

modelltolkningsbarhet

beslutsträdsmodell använder kontrakt, månadsavgifter, Internetservice, totalavgifter och besittningsfunktioner för att fatta beslut om en kund kommer att churn eller inte. Dessa funktioner separerar churned kunder från andra väl baserat på delningskriterierna i beslutsträdet.

varje kundprov går igenom trädet och den slutliga noden ger förutsägelsen.
till exempel, om Contract_Month-to-month är:

  • lika med 0, fortsätt att korsa trädet med sann gren,
  • lika med 1, fortsätt att korsa trädet med falsk gren,
  • inte definierad, det matar ut klassen 0.

detta är ett bra sätt att se hur modellen fattar ett beslut eller om några funktioner smög i vår modell som inte borde vara där.

tolkning av beslut träd modell

vidare läsning

  1. hantering klass obalans i kund Churn förutsägelse — hur kan vi bättre hantera klass obalans i Churn förutsägelse.
  2. a Survey on Customer Churn Prediction using Machine Learning Techniques] – detta dokument granskar de mest populära maskininlärningsalgoritmerna som används av forskare för att förutsäga churn.
  3. Telco kund churn på Kaggle — Churn analys på Kaggle.
  4. WTTE-RNN-Hackless-churn-modellering-händelse baserad churn förutsägelse.

innan du går

Följ mig på Twitter, där jag regelbundet tweetar om datavetenskap och maskininlärning.

foto av Courtney häck på Unsplash

Lämna ett svar

Din e-postadress kommer inte publiceras.