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

Aufgaben

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.

1. Business Understanding

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.

2. Data Understanding

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”.

3. Data Preparation

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.

4. Modelling

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.

5. Evaluation

Die zuvor im “Modelling” erstellten Modelle werden nun analysiert und bewertet.

6. Deployment

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

Daten einlesen

Einlesen der Daten

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"

CSV einlesen

#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

Ändern der Datentypen des Traningdatensatzes

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

NA’s setzen bei fehlenden Werten

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.

Zusammenführen von df_test und sample_sub

#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.

Ändern der Datentypen des Testdatensatzes

#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.

Data Exploration

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.

Anschauen der Missing Values

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.

Fehlende Werte Trainingsdatensatz

#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

Fehlende Werte bei Testdatenatz

#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

Betrachtung aller Variablen

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.

Wie viele Leute kaufen in welcher Gruppe?

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

Wie viele Leute kaufen in welcher Altersgruppe?

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

Data Cleaning

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.

Bereinigung des Alter des Training Datensatz

#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.

Trennung der Test-, Trainingsdaten und Valdiation

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,]

Imputation

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                                     
## 

Anpassung der Age Variable im Testdatensatz

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.

Data Science

##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

Random Forest

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)