#Versuch set.seed global zu setzen
set.seed(333)
knitr::opts_chunk$set(cache = T)
##Projekt Der Aufbau des Projektes erfolgt nach dem CRISP-DM. Im folgenden wird kurz das CRISP-Dm beschrieben.
Wir versuchen nicht mehrere Data Frames zu erstellen das es sonst zu einer Auslastung des Arbeitspeichers kommen könnte. ( Mein PC hat leider schon so genug Probleme und ich musste ihn während des Projektes einigemale neu starten)
Im folgenden werden wir eine Daten Analyse eines Datensatzes durchführen und die gegegeben Daten analysieren. Diese Analyse wird mit dem CRISP-DM Modell erfolgen und die einzelnen Punkte werden nach der Reihenfolge des Modells (Schritte 1. bis 6.) abgearbeitet. In der Inhaltsbeschreibung kann man entnehmen an welcher Stelle der Ausarbeitung wie unser aktuell befinden.
Hier müssen wir die gegebene Aufgabe definieren. In unserem Fall kommt diese aus der Aufgbabenstellung hervor und ist somit klar definiert. Wir befinden uns im Bereich des Bankwesens, genauer gesagt im Bereich Privatkunden.
Selektion und Exploration der Daten. Was sagen diese aus? -> Es handelt sich um Daten (in Tabellenform) eines Kreditinstitutes. Diese zeigt uns verschiedenste Angaben im Bezug auf einzelne Kunden (Privatkunden) wie zum Beispiel “Alter” und “Geschlecht” aber auch bankspezifische Angaben wie zum Beispiel “Kontostand” oder “hat Kreditprodukt”.
Da leider nicht alle der vorliegenden Daten das gewünschte Format haben oder vollständig sind, ist es unsere Aufgabe im Punkt “Data Preparation” genannte Fehler zu verbessern bzw. zu beseitigen.
In diesem Schritt versuchen wir die vorliegenden Daten dazu verwenden in ein Modell zu fassen. Es werden verschiedene Modelle wie “Random Forest” oder auch einfache “Neuronale Netze”. So können wir feststellen, welche Daten geeignete Modelle und welche das beste Modell ergeben.
Die zuvor im “Modelling” erstellten Modelle werden nun analysiert und bewertet.
Aus der Evaluation wissen wir nun welche Modelle für uns geeigente sind. Diese können nun in die Systeme und Prozesse des Unternehmens (Kreditinstitut) eingebunden werden. Desweiteren kann so die Umsetzung von Handlungsempfehlungen vorangetrieben werden.
##Alle verwendeten Bibliotheken
library(ggplot2)
library(tidyverse)
library(dplyr)
library(mice)
library(tidyr)
library(caret)
library(randomForest)
## randomForest 4.6-14
## Type rfNews() to see new features/changes/bug fixes.
##
## Attaching package: 'randomForest'
## The following object is masked from 'package:dplyr':
##
## combine
## The following object is masked from 'package:ggplot2':
##
## margin
Setzen des Work Directory
#Verzeichnis in dem die Datein liegen
work_dir <- "C:/Users/Phili/OneDrive/Desktop/Abgabe Klass"
#setzen des Arbeitsbereiches (Work Directory)
setwd(work_dir)
#Überprüfen des Working Directory (stimmt der Pfad)
getwd()
## [1] "C:/Users/Phili/OneDrive/Desktop/Abgabe Klass"
#In den CSV Datein feheln Werte, diese könnten wir schon auffüllen über den read.csv Befehl na.strings=c("")) könnten wir diese schon befüllen.
#Header = T, bedeutet das wir eine Überschrift in der CSV Datei haben
#Dec ist der Seperator, dieser ist der Trenner den wir in den Datein haben. Zum Beispiel im Amerikanschen trennt ein Punkt Kommazahlen. Im Deutschen das Komma.
df_train <- read.csv("train_credit_card_lead.csv",sep = ";", header = T, dec = ".")
df_test <- read.csv("to_predict_credit_card_lead.csv", sep = ";", header = T, dec = ".")
sample_sub <- read.csv("sample_submission_credit_card_lead.csv", sep = ";", header = T, dec = ".")
summary(df_train)
## customer_id sex cust_age region
## Length:233439 Length:233439 Min. : 23.00 Length:233439
## Class :character Class :character 1st Qu.: 30.00 Class :character
## Mode :character Mode :character Median : 43.00 Mode :character
## Mean : 43.87
## 3rd Qu.: 54.00
## Max. :121.00
## job_status channel vintage hast_credit_product
## Length:233439 Length:233439 Min. : 7.00 Length:233439
## Class :character Class :character 1st Qu.: 20.00 Class :character
## Mode :character Mode :character Median : 32.00 Mode :character
## Mean : 46.96
## 3rd Qu.: 73.00
## Max. :135.00
## mean_account_balance flag_active_customer sales_lead
## Min. : 20790 Length:233439 Min. :0.0000
## 1st Qu.: 604292 Class :character 1st Qu.:0.0000
## Median : 894832 Mode :character Median :0.0000
## Mean : 1128590 Mean :0.2372
## 3rd Qu.: 1366942 3rd Qu.:0.0000
## Max. :10352009 Max. :1.0000
#Da unsere Trainingsdaten nicht den Datentypen entsprechen die wir benötigen, werden diese in diesem Schritt umgewandelt.
df_train$sex = as.factor(df_train$sex)
df_train$region = as.factor(df_train$region)
df_train$job_status = as.factor(df_train$job_status)
df_train$channel = as.factor(df_train$channel)
df_train$hast_credit_product = as.factor(df_train$hast_credit_product)
df_train$flag_active_customer = as.factor(df_train$flag_active_customer)
df_train$sales_lead <- as.factor(df_train$sales_lead)
summary(df_train)
## customer_id sex cust_age region
## Length:233439 Female:105906 Min. : 23.00 RG268 : 34146
## Class :character Male :127533 1st Qu.: 30.00 RG283 : 28005
## Mode :character Median : 43.00 RG254 : 25515
## Mean : 43.87 RG284 : 18320
## 3rd Qu.: 54.00 RG277 : 12191
## Max. :121.00 RG280 : 12090
## (Other):103172
## job_status channel vintage hast_credit_product
## Entrepreneur : 2538 X1:98525 Min. : 7.00 : 27859
## Other :66575 X2:64271 1st Qu.: 20.00 No :137155
## Salaried :68391 X3:65334 Median : 32.00 Yes: 68425
## Self_Employed:95935 X4: 5309 Mean : 46.96
## 3rd Qu.: 73.00
## Max. :135.00
##
## mean_account_balance flag_active_customer sales_lead
## Min. : 20790 No :142796 0:178077
## 1st Qu.: 604292 Yes: 90643 1: 55362
## Median : 894832
## Mean : 1128590
## 3rd Qu.: 1366942
## Max. :10352009
##
#Um mit dem Datensatz weiter arbeiten zu können, schauen wir in welchen Variablen aktuell NA's enthalten sind. Im Trainingsdatensatz sind nur bei hast_credit_product Missing Values zu erkennen. Diese werden wir um mit den Daten arbeiten zu können auf Na setzen.
levels(df_train$hast_credit_product) <- c(NA, "No", "Yes")
summary(df_train)
## customer_id sex cust_age region
## Length:233439 Female:105906 Min. : 23.00 RG268 : 34146
## Class :character Male :127533 1st Qu.: 30.00 RG283 : 28005
## Mode :character Median : 43.00 RG254 : 25515
## Mean : 43.87 RG284 : 18320
## 3rd Qu.: 54.00 RG277 : 12191
## Max. :121.00 RG280 : 12090
## (Other):103172
## job_status channel vintage hast_credit_product
## Entrepreneur : 2538 X1:98525 Min. : 7.00 No :137155
## Other :66575 X2:64271 1st Qu.: 20.00 Yes : 68425
## Salaried :68391 X3:65334 Median : 32.00 NA's: 27859
## Self_Employed:95935 X4: 5309 Mean : 46.96
## 3rd Qu.: 73.00
## Max. :135.00
##
## mean_account_balance flag_active_customer sales_lead
## Min. : 20790 No :142796 0:178077
## 1st Qu.: 604292 Yes: 90643 1: 55362
## Median : 894832
## Mean : 1128590
## 3rd Qu.: 1366942
## Max. :10352009
##
#Nach der Umwandlung haben wir 27859 NA's.
#Der merge Befehl hängt Data Frames zusammen, dies passiert in unserem Fall über das angeben einer Variuablen die in beiden Data Franes vorhanden sind. In diesem Fall setzen wir die Daten über die Customer ID zusammen. (by) Wir geben in der Funktion auch die beiden Data Frames an die wir zusammenfügen, einaml der Test Datensatz und den Sample Datensatz. Somit können wir uns sicher sein das in beiden Datensätzen die gleichen Daten vorhanden sind.
df_test <- merge(df_test, sample_sub, by="customer_id")
summary(df_test)
## customer_id sex cust_age region
## Length:12286 Length:12286 Min. : 24.00 Length:12286
## Class :character Class :character 1st Qu.: 30.00 Class :character
## Mode :character Mode :character Median : 43.00 Mode :character
## Mean : 44.07
## 3rd Qu.: 54.00
## Max. :118.00
## NA's :5228
## job_status channel vintage hast_credit_product
## Length:12286 Length:12286 Min. : 7.00 Length:12286
## Class :character Class :character 1st Qu.: 20.00 Class :character
## Mode :character Mode :character Median : 32.00 Mode :character
## Mean : 46.89
## 3rd Qu.: 73.00
## Max. :135.00
##
## mean_account_balance flag_active_customer sales_lead
## Min. : 47526 Length:12286 Min. :0.0000
## 1st Qu.: 604810 Class :character 1st Qu.:0.0000
## Median : 889016 Mode :character Median :0.0000
## Mean :1124850 Mean :0.2442
## 3rd Qu.:1358215 3rd Qu.:0.0000
## Max. :9126917 Max. :1.0000
##
#Sales_lead ist dem Data Frame zugefügt worden. Jetzt müssen wir die Daten erneut betrachten.
#Zuerst wandeln wir die Daten wie bei dem Trainingsdatensatz um.
#Die selbe Umwandlung müssen wir auch für die Testdaten anwenden. Diese müssen aber noch zusätzlich mit den sample_sub Daten zusammengesetzt werden.
df_test$sex = as.factor(df_test$sex)
df_test$region = as.factor(df_test$region)
df_test$job_status = as.factor(df_test$job_status)
df_test$channel = as.factor(df_test$channel)
df_test$hast_credit_product = as.factor(df_test$hast_credit_product)
df_test$flag_active_customer = as.factor(df_test$flag_active_customer)
df_test$sales_lead <- as.factor(df_test$sales_lead)
summary(df_test)
## customer_id sex cust_age region
## Length:12286 Female:5622 Min. : 24.00 RG268 :1788
## Class :character Male :6664 1st Qu.: 30.00 RG283 :1411
## Mode :character Median : 43.00 RG254 :1325
## Mean : 44.07 RG284 :1000
## 3rd Qu.: 54.00 RG280 : 685
## Max. :118.00 RG277 : 635
## NA's :5228 (Other):5442
## job_status channel vintage hast_credit_product
## : 125 X1:5193 Min. : 7.00 :1466
## Entrepreneur : 126 X2:3455 1st Qu.: 20.00 No :7202
## Other :3555 X3:3378 Median : 32.00 Yes:3618
## Salaried :3577 X4: 260 Mean : 46.89
## Self_Employed:4903 3rd Qu.: 73.00
## Max. :135.00
##
## mean_account_balance flag_active_customer sales_lead
## Min. : 47526 No :7494 0:9286
## 1st Qu.: 604810 Yes:4792 1:3000
## Median : 889016
## Mean :1124850
## 3rd Qu.:1358215
## Max. :9126917
##
#Im Vergleich zum anderen Datensatz haben wir mehrere fehlende Werte. In der Imputation werden wir uns überlegen wie wir die fehlenden Daten behandeln. Jetzt schauen wir erstmal das wir job_status und has credict_product mit NA's füllen.
levels(df_test$job_status) <- c(NA, "Self_Employed", "Salaried", "Other", "Entrepreneur")
levels(df_test$hast_credit_product) <- c(NA, "No", "Yes")
summary(df_test)
## customer_id sex cust_age region
## Length:12286 Female:5622 Min. : 24.00 RG268 :1788
## Class :character Male :6664 1st Qu.: 30.00 RG283 :1411
## Mode :character Median : 43.00 RG254 :1325
## Mean : 44.07 RG284 :1000
## 3rd Qu.: 54.00 RG280 : 685
## Max. :118.00 RG277 : 635
## NA's :5228 (Other):5442
## job_status channel vintage hast_credit_product
## Self_Employed: 126 X1:5193 Min. : 7.00 No :7202
## Salaried :3555 X2:3455 1st Qu.: 20.00 Yes :3618
## Other :3577 X3:3378 Median : 32.00 NA's:1466
## Entrepreneur :4903 X4: 260 Mean : 46.89
## NA's : 125 3rd Qu.: 73.00
## Max. :135.00
##
## mean_account_balance flag_active_customer sales_lead
## Min. : 47526 No :7494 0:9286
## 1st Qu.: 604810 Yes:4792 1:3000
## Median : 889016
## Mean :1124850
## 3rd Qu.:1358215
## Max. :9126917
##
#Überprüfung ob die Füllung der fehlenden Daten mit Na's funktioniert hat.
head(df_train)
## customer_id sex cust_age region job_status channel vintage
## 1 7LLRHXTV Female 73 RG268 Other X3 43
## 2 YONNUG68 Female 30 RG277 Salaried X1 32
## 3 FOE54SW2 Female 56 RG268 Self_Employed X3 26
## 4 ZQ2QVMAN Male 34 RG270 Salaried X1 19
## 5 Y7PBNN9L Female 30 RG282 Salaried X1 33
## 6 DRGQHH6N Male 56 RG261 Self_Employed X1 32
## hast_credit_product mean_account_balance flag_active_customer sales_lead
## 1 No 1045696 No 0
## 2 No 581988 No 0
## 3 No 1484315 Yes 0
## 4 No 470454 No 0
## 5 No 886787 No 0
## 6 No 544163 Yes 0
#In der Tabelle erkennen wir das wir 11 verschiedene Variablen mir verschiedenen Ausprägungen haben. Nach den Kontoständen zu urteilen könnte es eine Bank für Reiche sein. Wenn wir alleine in der kurzen Übersicht den kleinsten Kontostand mit "nur" 470k.
Wenn wir die beiden Grafiken betrachten fällt uns eins sofort auf. Das die Daten nicht aus dem gleichen Datensatz stammen können. Eindeutig haben wir in dem df_test mehrere Missing Values. Im weiteren Missachten wir dies. Normalerweise würden wir hier die Daten wieder zusammensetzen und danach diese in eine gleichmäßige Datenmenge teilen. So hätten wir klar gestellt das wir eine zufällige Auswahl von Daten hätten.
Ein weiteres Problem das sich hier ergibt ist, das wir viele Werte haben die fehlende Werte beinhalten. Das ist bei dem Test Datensatz fast die Hälfte aller Daten.
#Hier kann man deutlich erkennen das wir nur NA Werte bei has_credit_product haben im train Satz.
md.pattern(df_train)
## customer_id sex cust_age region job_status channel vintage
## 205580 1 1 1 1 1 1 1
## 27859 1 1 1 1 1 1 1
## 0 0 0 0 0 0 0
## mean_account_balance flag_active_customer sales_lead hast_credit_product
## 205580 1 1 1 1
## 27859 1 1 1 0
## 0 0 0 27859
##
## 205580 0
## 27859 1
## 27859
#Bei diesem Datensatz können wir ganz klar feststellen das wir mehr fehlende Werte haben. Wir haben hast_credit_product, cust_age und job_status bei dem Werte fehlen die wir ersetzen müssen.
md.pattern(df_test)
## customer_id sex region channel vintage mean_account_balance
## 6231 1 1 1 1 1 1
## 4482 1 1 1 1 1 1
## 827 1 1 1 1 1 1
## 621 1 1 1 1 1 1
## 107 1 1 1 1 1 1
## 18 1 1 1 1 1 1
## 0 0 0 0 0 0
## flag_active_customer sales_lead job_status hast_credit_product cust_age
## 6231 1 1 1 1 1
## 4482 1 1 1 1 0
## 827 1 1 1 0 1
## 621 1 1 1 0 0
## 107 1 1 0 1 0
## 18 1 1 0 0 0
## 0 0 125 1466 5228
##
## 6231 0
## 4482 1
## 827 1
## 621 2
## 107 2
## 18 3
## 6819
summary(df_train)
## customer_id sex cust_age region
## Length:233439 Female:105906 Min. : 23.00 RG268 : 34146
## Class :character Male :127533 1st Qu.: 30.00 RG283 : 28005
## Mode :character Median : 43.00 RG254 : 25515
## Mean : 43.87 RG284 : 18320
## 3rd Qu.: 54.00 RG277 : 12191
## Max. :121.00 RG280 : 12090
## (Other):103172
## job_status channel vintage hast_credit_product
## Entrepreneur : 2538 X1:98525 Min. : 7.00 No :137155
## Other :66575 X2:64271 1st Qu.: 20.00 Yes : 68425
## Salaried :68391 X3:65334 Median : 32.00 NA's: 27859
## Self_Employed:95935 X4: 5309 Mean : 46.96
## 3rd Qu.: 73.00
## Max. :135.00
##
## mean_account_balance flag_active_customer sales_lead
## Min. : 20790 No :142796 0:178077
## 1st Qu.: 604292 Yes: 90643 1: 55362
## Median : 894832
## Mean : 1128590
## 3rd Qu.: 1366942
## Max. :10352009
##
customer_id | Fortlaufende Werte die immer einer Person zugeordnet werden können. | sex: | Eindeutige Unterteilung in Mann und Frau (2 Variable) | cust_age: | Das Alter der Kunden reicht von 23-121 Jahren, hier werden wir wohl nachher einige Werte beschneiden müssen. | region: | Die Region der Kunden ist in ein genaues Gebiet unterteilt. | job_status: | Es gibt vier verschiedene Job Bezeichnungen unter denen hier unterschieden werden. | channel: | Bei den Channel gibt es vier verschiedene, diese sind klar unterteilt und es gibt keine Ausreißer. | vintage: | Die Vetragslaufzeit reicht von 7-121 Monaten. Dies ist vollkommen in Ordnung da es immer Leute gibt die nicht dauerhast bei | einer Bank sind | hast_credit_product | Dieser Wert muss nachher überarbeitet werden, hier haben wir viele 27859 Werte die fehlen.
| mean_account_balance | Die Account Balance reicht von 20790 bis 10 Mio, der Durchschnitt ist bei rund 900 k. Daher können wir davon ausgehen das | die Bank wahrscheinlich für wolhabende Kunden ist. | flag_active_customer | Es gibt wie wir hier an den Zahlen erkennen können, einige nicht aktive Kunden. | sales_lead | Die Anzahl an verkauften Produkten liegt bei 55362. Wenn wir hier in betracht ziehen das nur 90643 aktive Kunden sind, würde | ich behaupten ist dies ein sehr guter Wert ist. Der Kunde verkauft über 50 Prozent seiner Kunden ein Produkt.
library(janitor)
tabyl(df_train, job_status, sales_lead)
## job_status 0 1
## Entrepreneur 853 1685
## Other 50241 16334
## Salaried 57500 10891
## Self_Employed 69483 26452
#Der Plot ist ergibt einige Intressante Dinge aus. Wir können erkennen das mehr der Entrepreneur ein Produkt kaufen als keins. Bei den Selbstständigen haben auch einige der Kunden ein Produkt gekauft. (ca 1/3) Die normal Angestellten sind leider eine der Gruppe die wir nicht sonderlich gut erreichen
#Nochmal ausführen lassen und schauern ob es dann geht
#ggplot(df_train, aes(job_status, n, fill = sales_lead))
#df_train %>%
# select(cust_age, sales_lead) %>%
# group_by(cust_age <=40) %>%
#count(sales_lead = 1)
#df_train %>%
# select(cust_age, sales_lead) %>%
#group_by(cust_age <=40) %>%
#count(sales_lead = 1) %>%
#ungroup() %>%
#select(cust_age, sales_lead)
Wie wir vorhin schon bei den Daten erkennen konnten habe wir Personen in unseren Data Frames die relativ alt sind. Es gibt einige Methoden dies zu bereinigen. Wir könnten diese ignorieren. In einem Boxplot haben wir Ausreißer festgestellt bei denen wir ebenso daraus folgern könnten die Daten der Personen von über 100 Jahre zu entfernen.
Unsere Entscheidung haben wir auf der Grundlage des erzählen einer Idee die eine andere Betrachtungsweise aufzeigt getätigt.
Wir nutzen Google um heraus zu finden wie alt die Ältester in Deutschland lebende Person aktuell ist. Hier könnten wir erkennen das diese aktuell eine Dame mit dem Alter von 112 Jahren ist. Im Datensatz sind viele Leute über diesem Alter.
Noch zu erwähnen ist das einige der Personen über 100 Jahre alt sind. Hier haben wir zusätzlich noch geprüft wie viele Personen in Deutschland über 100 Jahre als sind um bei einer zu hohen Anzahl das ganze erneut zu überdenken.
Da in Deutschland aktuell über 19000 Menschen im Alter von über 100 Jahre leben ist dies in umsere Datensatz kein Problem.
#Entfernung aller über 112 Jahre alten Personen im Data Frame
df_train$cust_age [df_train$cust_age >= 112] <- NA
#Durch diesen Befehl werden alle Na Werte aus dem Data Frame geworfen
df_train <- na.omit(df_train)
#Vorher hatten wir im Datensatz 233439 nun nach der Entfernung aller über 112 Jahren haben wir nur 205555 Daten. Wie wir im summary sehen ist das nun höchste Alter 111 Jahre.
summary(df_train)
## customer_id sex cust_age region
## Length:205555 Female: 95449 Min. : 23.00 RG268 :28793
## Class :character Male :110106 1st Qu.: 29.00 RG283 :23476
## Mode :character Median : 41.00 RG254 :22928
## Mean : 42.81 RG284 :15513
## 3rd Qu.: 53.00 RG277 :10751
## Max. :111.00 RG280 :10665
## (Other):93429
## job_status channel vintage hast_credit_product
## Entrepreneur : 1565 X1:95611 Min. : 7.00 No :137139
## Other :57709 X2:53034 1st Qu.: 20.00 Yes: 68416
## Salaried :64386 X3:52279 Median : 31.00
## Self_Employed:81895 X4: 4631 Mean : 44.28
## 3rd Qu.: 67.00
## Max. :135.00
##
## mean_account_balance flag_active_customer sales_lead
## Min. : 20790 No :128120 0:173938
## 1st Qu.: 595837 Yes: 77435 1: 31617
## Median : 881046
## Mean : 1115316
## 3rd Qu.: 1346854
## Max. :10352009
##
df_train %>%
select(cust_age) %>%
group_by(cust_age>=100)%>%
count()
## # A tibble: 2 x 2
## # Groups: cust_age >= 100 [2]
## `cust_age >= 100` n
## <lgl> <int>
## 1 FALSE 205506
## 2 TRUE 49
#Mit der Entfernung aller Daten über 112 Jahren haben wir 49 Kunden über dem Alter von 100 Jahren übrig.
summary(df_test)
## customer_id sex cust_age region
## Length:12286 Female:5622 Min. : 24.00 RG268 :1788
## Class :character Male :6664 1st Qu.: 30.00 RG283 :1411
## Mode :character Median : 43.00 RG254 :1325
## Mean : 44.07 RG284 :1000
## 3rd Qu.: 54.00 RG280 : 685
## Max. :118.00 RG277 : 635
## NA's :5228 (Other):5442
## job_status channel vintage hast_credit_product
## Self_Employed: 126 X1:5193 Min. : 7.00 No :7202
## Salaried :3555 X2:3455 1st Qu.: 20.00 Yes :3618
## Other :3577 X3:3378 Median : 32.00 NA's:1466
## Entrepreneur :4903 X4: 260 Mean : 46.89
## NA's : 125 3rd Qu.: 73.00
## Max. :135.00
##
## mean_account_balance flag_active_customer sales_lead
## Min. : 47526 No :7494 0:9286
## 1st Qu.: 604810 Yes:4792 1:3000
## Median : 889016
## Mean :1124850
## 3rd Qu.:1358215
## Max. :9126917
##
#Den Test Datensatz können wir momentan noch nicht bereinigen da wir im Alter noch einige NA's haben, diese müssen wir im nächsten Schritt erst einmal auffüllen.
split_dummy <- sample(c(rep(0, 0.8 * nrow(df_train)), # Create dummy for splitting
rep(1, 0.2 * nrow(df_train))))
table(split_dummy)
## split_dummy
## 0 1
## 164444 41111
#Hier teilen wir die Werte des Trainigsdatensatz in 80 % für den Training auf und 20 % nutzen wir später für die Validation
#Wir überschreiben hier nicht den Datensatz df_train, weil wir diesen nutzen können für log. Reg.
df_train_split <- df_train[split_dummy == 0, ]
df_validation <- df_train[split_dummy == 1,]
df_train <- mice(data = df_train, method = "cart", maxit = 1, m = 2)
##
## iter imp variable
## 1 1
## 1 2
## Warning: Number of logged events: 1
df_train <- complete(df_train)
summary(df_train)
## customer_id sex cust_age region
## Length:205555 Female: 95449 Min. : 23.00 RG268 :28793
## Class :character Male :110106 1st Qu.: 29.00 RG283 :23476
## Mode :character Median : 41.00 RG254 :22928
## Mean : 42.81 RG284 :15513
## 3rd Qu.: 53.00 RG277 :10751
## Max. :111.00 RG280 :10665
## (Other):93429
## job_status channel vintage hast_credit_product
## Entrepreneur : 1565 X1:95611 Min. : 7.00 No :137139
## Other :57709 X2:53034 1st Qu.: 20.00 Yes: 68416
## Salaried :64386 X3:52279 Median : 31.00
## Self_Employed:81895 X4: 4631 Mean : 44.28
## 3rd Qu.: 67.00
## Max. :135.00
##
## mean_account_balance flag_active_customer sales_lead
## Min. : 20790 No :128120 0:173938
## 1st Qu.: 595837 Yes: 77435 1: 31617
## Median : 881046
## Mean : 1115316
## 3rd Qu.: 1346854
## Max. :10352009
##
#Keine fehlende Werte mehr bei hast_credit_product.
df_train_split <- mice(data = df_train_split, method = "cart", maxit = 1, m = 2)
##
## iter imp variable
## 1 1
## 1 2
## Warning: Number of logged events: 1
df_train_split <- complete(df_train_split)
summary(df_train_split)
## customer_id sex cust_age region
## Length:164444 Female:76349 Min. : 23.0 RG268 :22979
## Class :character Male :88095 1st Qu.: 29.0 RG283 :18778
## Mode :character Median : 40.0 RG254 :18334
## Mean : 42.8 RG284 :12447
## 3rd Qu.: 53.0 RG277 : 8596
## Max. :111.0 RG280 : 8565
## (Other):74745
## job_status channel vintage hast_credit_product
## Entrepreneur : 1233 X1:76620 Min. : 7.00 No :109599
## Other :46253 X2:42414 1st Qu.: 20.00 Yes: 54845
## Salaried :51602 X3:41728 Median : 31.00
## Self_Employed:65356 X4: 3682 Mean : 44.24
## 3rd Qu.: 67.00
## Max. :135.00
##
## mean_account_balance flag_active_customer sales_lead
## Min. : 20790 No :102502 0:139235
## 1st Qu.: 595944 Yes: 61942 1: 25209
## Median : 879791
## Mean : 1114844
## 3rd Qu.: 1345947
## Max. :10352009
##
df_validation <- mice(data = df_validation, method = "cart", maxit = 1, m = 2)
##
## iter imp variable
## 1 1
## 1 2
## Warning: Number of logged events: 1
df_validation <- complete(df_validation)
summary(df_validation)
## customer_id sex cust_age region
## Length:41111 Female:19100 Min. : 24.00 RG268 : 5814
## Class :character Male :22011 1st Qu.: 29.00 RG283 : 4698
## Mode :character Median : 41.00 RG254 : 4594
## Mean : 42.87 RG284 : 3066
## 3rd Qu.: 53.00 RG277 : 2155
## Max. :111.00 RG280 : 2100
## (Other):18684
## job_status channel vintage hast_credit_product
## Entrepreneur : 332 X1:18991 Min. : 7.00 No :27540
## Other :11456 X2:10620 1st Qu.: 20.00 Yes:13571
## Salaried :12784 X3:10551 Median : 31.00
## Self_Employed:16539 X4: 949 Mean : 44.44
## 3rd Qu.: 67.00
## Max. :135.00
##
## mean_account_balance flag_active_customer sales_lead
## Min. : 45657 No :25618 0:34703
## 1st Qu.: 595205 Yes:15493 1: 6408
## Median : 886315
## Mean : 1117203
## 3rd Qu.: 1351478
## Max. :10007678
##
df_test <- mice(data = df_test, method = "cart", maxit = 1, m = 2)
##
## iter imp variable
## 1 1 cust_age job_status hast_credit_product
## 1 2 cust_age job_status hast_credit_product
## Warning: Number of logged events: 1
df_test <- complete(df_test)
summary(df_test)
## customer_id sex cust_age region
## Length:12286 Female:5622 Min. : 24.00 RG268 :1788
## Class :character Male :6664 1st Qu.: 30.00 RG283 :1411
## Mode :character Median : 43.00 RG254 :1325
## Mean : 44.19 RG284 :1000
## 3rd Qu.: 54.00 RG280 : 685
## Max. :118.00 RG277 : 635
## (Other):5442
## job_status channel vintage hast_credit_product
## Self_Employed: 127 X1:5193 Min. : 7.00 No :7979
## Salaried :3586 X2:3455 1st Qu.: 20.00 Yes:4307
## Other :3608 X3:3378 Median : 32.00
## Entrepreneur :4965 X4: 260 Mean : 46.89
## 3rd Qu.: 73.00
## Max. :135.00
##
## mean_account_balance flag_active_customer sales_lead
## Min. : 47526 No :7494 0:9286
## 1st Qu.: 604810 Yes:4792 1:3000
## Median : 889016
## Mean :1124850
## 3rd Qu.:1358215
## Max. :9126917
##
summary(df_test)
## customer_id sex cust_age region
## Length:12286 Female:5622 Min. : 24.00 RG268 :1788
## Class :character Male :6664 1st Qu.: 30.00 RG283 :1411
## Mode :character Median : 43.00 RG254 :1325
## Mean : 44.19 RG284 :1000
## 3rd Qu.: 54.00 RG280 : 685
## Max. :118.00 RG277 : 635
## (Other):5442
## job_status channel vintage hast_credit_product
## Self_Employed: 127 X1:5193 Min. : 7.00 No :7979
## Salaried :3586 X2:3455 1st Qu.: 20.00 Yes:4307
## Other :3608 X3:3378 Median : 32.00
## Entrepreneur :4965 X4: 260 Mean : 46.89
## 3rd Qu.: 73.00
## Max. :135.00
##
## mean_account_balance flag_active_customer sales_lead
## Min. : 47526 No :7494 0:9286
## 1st Qu.: 604810 Yes:4792 1:3000
## Median : 889016
## Mean :1124850
## 3rd Qu.:1358215
## Max. :9126917
##
#Alter der Kunden über 118 Jahre. Wir müssen diesen an den anderen anpassen und sagen das wir wieder alle Kunden >= 112 aus dem Datebsatz entfernen.
#Entfernung aller über 112 Jahre alten Personen im Data Frame
df_test$cust_age [df_test$cust_age >= 112] <- NA
#Durch diesen Befehl werden alle Na Werte aus dem Data Frame geworfen
df_test <- na.omit(df_test)
#Vorher hatten wir im Datensatz 12286 nun nach der Entfernung aller über 112 Jahren haben wir nur 12280 Daten. Wie wir im summary sehen ist das nun höchste Alter 110 Jahre.
summary(df_test)
## customer_id sex cust_age region
## Length:12280 Female:5622 Min. : 24.00 RG268 :1785
## Class :character Male :6658 1st Qu.: 30.00 RG283 :1411
## Mode :character Median : 43.00 RG254 :1325
## Mean : 44.16 RG284 : 999
## 3rd Qu.: 54.00 RG280 : 684
## Max. :110.00 RG277 : 634
## (Other):5442
## job_status channel vintage hast_credit_product
## Self_Employed: 126 X1:5192 Min. : 7.00 No :7976
## Salaried :3581 X2:3455 1st Qu.: 20.00 Yes:4304
## Other :3608 X3:3375 Median : 32.00
## Entrepreneur :4965 X4: 258 Mean : 46.89
## 3rd Qu.: 73.00
## Max. :135.00
##
## mean_account_balance flag_active_customer sales_lead
## Min. : 47526 No :7489 0:9283
## 1st Qu.: 604759 Yes:4791 1:2997
## Median : 888842
## Mean :1124769
## 3rd Qu.:1357686
## Max. :9126917
##
df_test %>%
select(cust_age) %>%
group_by(cust_age>=100)%>%
count()
## # A tibble: 2 x 2
## # Groups: cust_age >= 100 [2]
## `cust_age >= 100` n
## <lgl> <int>
## 1 FALSE 12268
## 2 TRUE 12
#Mit der Entfernung aller Daten über 112 Jahren haben wir 49 Kunden über dem Alter von 100 Jahren übrig.
##Up- und Downsampling
#Upsampling
df_train_upsample <- upSample(df_train, df_train$sales_lead)
#Downsampling
df_train_downsampling <- downSample(df_train, df_train$sales_lead)
#Logistische Regression
glm_fit <- glm(sales_lead ~ sex+cust_age+region+job_status+channel+vintage+hast_credit_product+mean_account_balance+flag_active_customer, family = binomial(link = 'logit'), data = df_train)
summary(glm_fit)
##
## Call:
## glm(formula = sales_lead ~ sex + cust_age + region + job_status +
## channel + vintage + hast_credit_product + mean_account_balance +
## flag_active_customer, family = binomial(link = "logit"),
## data = df_train)
##
## Deviance Residuals:
## Min 1Q Median 3Q Max
## -1.6964 -0.5582 -0.3665 -0.2233 2.9944
##
## Coefficients:
## Estimate Std. Error z value Pr(>|z|)
## (Intercept) -3.726e+00 9.633e-02 -38.683 < 2e-16 ***
## sexMale 3.532e-02 1.378e-02 2.563 0.01037 *
## cust_age 8.512e-03 7.571e-04 11.243 < 2e-16 ***
## regionRG251 2.084e-01 8.509e-02 2.449 0.01432 *
## regionRG252 2.315e-01 9.345e-02 2.478 0.01323 *
## regionRG253 7.004e-02 1.053e-01 0.665 0.50602
## regionRG254 8.733e-02 7.648e-02 1.142 0.25350
## regionRG255 2.507e-01 1.032e-01 2.430 0.01511 *
## regionRG256 4.219e-02 1.050e-01 0.402 0.68787
## regionRG257 2.804e-01 8.627e-02 3.251 0.00115 **
## regionRG258 1.819e-01 1.066e-01 1.707 0.08785 .
## regionRG259 6.595e-02 1.004e-01 0.657 0.51125
## regionRG260 2.011e-01 9.742e-02 2.064 0.03903 *
## regionRG261 1.233e-01 8.415e-02 1.465 0.14281
## regionRG262 7.004e-02 1.107e-01 0.632 0.52710
## regionRG263 3.595e-01 9.112e-02 3.946 7.96e-05 ***
## regionRG264 1.096e-01 1.041e-01 1.053 0.29230
## regionRG265 1.208e-01 1.101e-01 1.097 0.27281
## regionRG266 1.352e-02 1.202e-01 0.113 0.91042
## regionRG267 -1.738e-01 1.234e-01 -1.409 0.15879
## regionRG268 1.934e-01 7.553e-02 2.561 0.01044 *
## regionRG269 3.334e-01 8.285e-02 4.024 5.73e-05 ***
## regionRG270 2.096e-01 8.521e-02 2.460 0.01388 *
## regionRG271 1.065e-01 1.162e-01 0.917 0.35936
## regionRG272 1.776e-01 8.728e-02 2.035 0.04183 *
## regionRG273 2.616e-01 8.889e-02 2.943 0.00325 **
## regionRG274 3.764e-02 8.856e-02 0.425 0.67086
## regionRG275 5.303e-03 9.709e-02 0.055 0.95644
## regionRG276 2.075e-01 9.509e-02 2.182 0.02909 *
## regionRG277 3.122e-01 7.915e-02 3.944 8.01e-05 ***
## regionRG278 -5.144e-03 1.079e-01 -0.048 0.96199
## regionRG279 2.921e-01 9.025e-02 3.236 0.00121 **
## regionRG280 2.452e-01 7.902e-02 3.103 0.00192 **
## regionRG281 1.269e-01 8.718e-02 1.455 0.14563
## regionRG282 1.339e-01 8.721e-02 1.535 0.12468
## regionRG283 1.919e-01 7.593e-02 2.527 0.01149 *
## regionRG284 2.105e-01 7.699e-02 2.735 0.00624 **
## job_statusOther -9.287e-01 5.505e-02 -16.870 < 2e-16 ***
## job_statusSalaried 1.062e-01 5.681e-02 1.870 0.06147 .
## job_statusSelf_Employed -8.337e-01 5.361e-02 -15.551 < 2e-16 ***
## channelX2 9.970e-01 2.478e-02 40.244 < 2e-16 ***
## channelX3 8.437e-01 2.634e-02 32.029 < 2e-16 ***
## channelX4 8.465e-01 4.701e-02 18.007 < 2e-16 ***
## vintage 1.058e-02 2.729e-04 38.762 < 2e-16 ***
## hast_credit_productYes 1.617e+00 1.441e-02 112.204 < 2e-16 ***
## mean_account_balance -2.565e-08 8.297e-09 -3.091 0.00199 **
## flag_active_customerYes 3.738e-01 1.444e-02 25.892 < 2e-16 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## (Dispersion parameter for binomial family taken to be 1)
##
## Null deviance: 176476 on 205554 degrees of freedom
## Residual deviance: 146853 on 205508 degrees of freedom
## AIC: 146947
##
## Number of Fisher Scoring iterations: 5
require(caTools)
## Loading required package: caTools
rf_classifier = randomForest(sales_lead ~ ., data=df_train, ntree=100, mtry=2, importance=TRUE)
rf_classifier
##
## Call:
## randomForest(formula = sales_lead ~ ., data = df_train, ntree = 100, mtry = 2, importance = TRUE)
## Type of random forest: classification
## Number of trees: 100
## No. of variables tried at each split: 2
##
## OOB estimate of error rate: 13.93%
## Confusion matrix:
## 0 1 class.error
## 0 170975 2963 0.01703481
## 1 25673 5944 0.81199987
varImpPlot(rf_classifier)