Churn prediction

foto af Mantas Hesthaven på Unsplash

kundekurn, også kendt som kundeslidning, opstår, når kunder holder op med at handle med et firma. Virksomhederne er interesserede i at identificere segmenter af disse kunder, fordi prisen for at erhverve en ny kunde normalt er højere end at beholde den gamle. Kendte et segment af kunder, der var i fare for at kæmpe, kunne de proaktivt engagere dem med særlige tilbud i stedet for blot at miste dem.

i dette indlæg, vil vi skabe en simpel kunde churn forudsigelse model ved hjælp af Telco kunde Churn datasæt. Vi valgte et beslutningstræ til at modellere kærnede kunder, pandaer til dataknusning og matplotlib til visualiseringer. Vi vil gøre alt det ovenfor i Python.
koden kan bruges med et andet datasæt med et par mindre justeringer for at træne basismodellen. Vi giver også et par referencer og give ideer til nye funktioner og forbedringer.

Du kan køre denne kode ved at hente denne Jupyter-notesbog.

Her er et par links, der kan interessere 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

nogle af linkene ovenfor er tilknyttede links, og hvis du gennemgår dem for at foretage et køb, tjener jeg en provision. Husk, at jeg linker kurser på grund af deres kvalitet og ikke på grund af den provision, jeg modtager fra dine køb.

Vi bruger pandas til at læse datasættet og forarbejde det. Telco datasæt har en kunde pr linje med mange kolonner (funktioner). Der er ikke nogen rækker med alle manglende værdier eller dubletter (dette sker sjældent med virkelige datasæt). Der er 11 prøver, der har Totalafgifter indstillet til””, hvilket virker som en fejl i dataene. Vi fjerner disse prøver og indstiller typen til numerisk (flyde).

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ørste par prøver i Telco customer churn datasæt

sonderende dataanalyse

Vi har 2 typer funktioner i datasættet: kategorisk (to eller flere værdier og uden nogen rækkefølge) og numerisk. De fleste af funktionsnavnene er selvforklarende, bortset fra:

  • Partner: om kunden har en partner eller ej (ja, nej),
  • afhængige: uanset om kunden har pårørende eller ej (ja, nej),
  • OnlineBackup: om kunden har en online backup eller ej (ja, nej, ingen internet service),
  • uopsigelighed: antal måneder kunden har opholdt sig hos virksomheden,
  • Månedligtafgifter: det beløb, der opkræves til kunden månedligt,
  • Totalafgifter: det samlede beløb, der opkræves til kunden.

Der er 7032 kunder i datasættet og 19 funktioner uden customerID (ikke-informativ) og Churn kolonne (målvariabel). De fleste af de kategoriske funktioner har 4 eller mindre unikke værdier.

datasæt sammendrag

vi kombinerer funktioner i to lister, så vi kan analysere dem i fællesskab.

categorical_features = 
numerical_features =
target = "Churn”

numeriske funktioner distribution

numeriske opsummeringsteknikker (middelværdi, standardafvigelse osv.) vis os ikke pigge, former for distributioner, og det er svært at observere outliers med det. Det er derfor, vi bruger histogrammer.

df.describe()

oversigt over numeriske funktioner

Ved første øjekast er der ingen outliers i dataene. Intet datapunkt er afbrudt fra distribution eller for langt fra middelværdien. For at bekræfte, at vi bliver nødt til at beregne interkvartilinterval (IK) og vise, at værdierne for hver numerisk funktion ligger inden for 1,5 ik fra første og tredje kvartil.

Vi kunne konvertere numeriske funktioner til ordinære intervaller. For eksempel er ansættelse numerisk, men ofte er vi ligeglad med små numeriske forskelle og i stedet gruppetid til kunder med kort, mellemlang og lang sigt. En grund til at konvertere det ville være at reducere støj, ofte små svingninger er bare støj.

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

histogrammer af numeriske træk

Vi ser på distributioner af numeriske træk i forhold til målvariablen. Vi kan observere, at jo større Totalafgifter og uopsigelighed er, desto mindre er sandsynligheden for 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)

div>

numeriske funktioner i forhold til målvariablen

kategorisk funktionsfordeling

for at analysere kategoriske funktioner bruger vi søjlediagrammer. Vi bemærker, at ældre og kunder uden telefontjeneste er mindre repræsenteret i dataene.

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)

distribution af kategoriske træk

det næste trin er at se på kategoriske træk i forhold til målvariablen. Vi gør dette kun for kontrakt funktion. Brugere, der har en måned til måned kontrakt, er mere tilbøjelige til at churn end brugere med langsigtede kontrakter.

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’)

kontraktfunktion i forhold til målvariablen

målvariabelfordeling

målvariabelfordeling viser, at vi har at gøre med et ubalanceret problem, da der er mange flere ikke-churned som churned brugere. Modellen ville opnå høj nøjagtighed, da det for det meste ville forudsige majoritetsklassebrugere, der ikke churn i vores eksempel.

få ting, vi kan gøre for at minimere indflydelsen af ubalanceret datasæt:
– resample data (ubalanceret-Lær),
– Saml flere prøver,
– brug præcision og tilbagekaldelse som nøjagtighedsmålinger.

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

target variabel fordeling

funktioner

telco datasæt er allerede grupperet efter customerid, så det er svært at tilføje nye funktioner. Når vi arbejder på churn-forudsigelsen, får vi normalt et datasæt, der har en post pr. Derefter kunne vi tilføje funktioner som:

  • antal sessioner, før du køber noget,
  • gennemsnitlig tid pr.session,
  • tidsforskel mellem sessioner (hyppig eller mindre hyppig kunde),
  • er kun kunde i et land.

Nogle gange har vi endda kundehændelsesdata, som gør det muligt for os at finde mønstre for kundeadfærd i forhold til resultatet (churn).

Kodningsfunktioner

for at forberede datasættet til modellering af churn skal vi kode kategoriske funktioner til tal. Dette betyder kodning af “ja”, ” nej ” til 0 og 1, så algoritmen kan arbejde med dataene. Denne proces kaldes onehot-kodning.

one hot kodede kategoriske funktioner

klassifikator

vi bruger sklearn, et maskinlæringsbibliotek i Python, til at oprette en klassifikator.den sklearn måde er at bruge rørledninger, der definerer funktionen behandling og klassifikatoren. I vores eksempel tager rørledningen et datasæt i input, det forarbejder funktioner og træner klassifikatoren.
når det trænes, tager det samme input og returnerer forudsigelser i output.

i pipelinen behandler vi separat kategoriske og numeriske funktioner. Vi onehot koder kategoriske funktioner og skalerer numeriske funktioner ved at fjerne middelværdien og skalere dem til enhedsvarians.
vi valgte en beslutningstræmodel på grund af dens fortolkningsevne og satte maksimal dybde til 3 (vilkårligt).

rørledningen tager et datasæt i input, det forarbejder funktioner og træner klassifikatoren

træning af modellen

Vi deler datasættet til at træne (75% prøver) og test (25% prøver).
vi træner (passer) rørledningen og gør forudsigelser. Med classification_report beregner vi præcision og tilbagekaldelse med faktiske og forudsagte værdier.

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)

test af modellen

med classification_report beregner vi præcision og husker med faktiske og forudsagte værdier.

For klasse 1 (churned brugere) model opnår 0,67 præcision og 0,37 tilbagekaldelse. Præcision fortæller os, hvor mange churned brugere gjorde vores klassifikator forudsagt korrekt. På den anden side, recall fortælle os, hvor mange churned brugere det gik glip af.

i lægmandsbetingelser er klassificeringsenheden ikke særlig nøjagtig for kærnede brugere.

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

div>

klassifikationsrapport for beslutningstræmodellen

modelfortolkelighed

beslutningstræmodel bruger kontrakt, månedligtafgifter, Internetservice, totalafgifter og ansættelsesfunktioner til at træffe en beslutning, om en kunde vil churn eller ej. Disse funktioner adskiller churned kunder fra andre Godt baseret på de opdelte kriterier i beslutningstræet.

hver kundeprøve krydser træet, og den endelige node giver forudsigelsen.
For eksempel, hvis Contract_Month-to-month er:

  • lig med 0, fortsæt med at krydse træet med True branch,
  • lig med 1, fortsæt med at krydse træet med False branch,
  • ikke defineret, det udsender klassen 0.

dette er en fantastisk tilgang til at se, hvordan modellen træffer en beslutning, eller om der er nogen funktioner, der sneg sig i vores model, der ikke burde være der.

decision tree model

yderligere læsning

  1. håndtering klasse ubalance i kunde churn forudsigelse — hvordan kan vi bedre håndtere klasse ubalance i churn forudsigelse.
  2. a Survey on Customer Churn Prediction using Machine Learning Technologies] — dette papir gennemgår de mest populære maskinlæringsalgoritmer, der bruges af forskere til at forudsige churn.
  3. Telco kunde churn på Kaggle — Churn analyse på Kaggle.
  4. Vi-RNN-Hackless-churn-modeling — Event baseret churn forudsigelse.

før du går

Følg mig på kvidre, hvor jeg jævnligt kvidrer om datalogi og maskinlæring.

foto af Courtney hedger on Unsplash

Skriv et svar

Din e-mailadresse vil ikke blive publiceret.