1 Data Understanding

1.1 Latar Belakang

Data tersebut merupakan data mengenai telemarketing dari sebuah bank di Portugal. Menggunakan data tersebut kita dapat memprediksi calon nasabah mana yang akan membeli product ketika di telepon oleh pihak bank.

1.2 Metadata

Deskripsi dari dataset Bank marketing :

  • age : umur klien.
  • job : jenis pekerjaan.
  • marital : status perkawinan.
  • education : ‘primary’, ‘secondary’, ‘tertiary’, ‘unknown’
  • default: memiliki kredit default?
  • housing: memiliki pinjaman perumahan?
  • balance: saldo bank.
  • loan: memiliki pinjaman pribadi?
  • contact: jenis komunikasi kontak (‘cellular’,‘telephone’)
  • month: bulan kontak terakhir dalam setahun.
  • day_of_week: hari kontak terakhir dalam seminggu.
  • duration: durasi kontak terakhir, dalam detik.
  • campaign: jumlah kontak yang dilakukan selama kampanye ini dan untuk klien ini (numeric, includes last contact).
  • pdays: jumlah hari yang berlalu setelah klien terakhir dihubungi dari kampanye sebelumnya.
  • previous: jumlah kontak yang dilakukan sebelum kampanye ini dan untuk klien ini.
  • poutcome: hasil dari kampanye pemasaran sebelumnya.
  • y : deposit

2 Exploratory Data Analysis (EDA)

2.1 Import Library

library(dplyr) # untuk transformasi data
library(plotly) # untuk membuat plot menjadi interaktif
library(glue) # untuk custom informasi saat plot interaktif
library(scales) # untuk custom keterangan axis atau lainnya
library(tidyr) # untuk custom keterangan axis atau lainnya
library(ggpubr) # untuk export plot
library(ggthemes)

2.2 Baca Data

bank <- read.csv("bank.csv", sep = ";")

2.3 Pemeriksaan Data

2.3.1 Menampilkan 5 data teratas dan terbawah

head(bank)
tail(bank)

2.3.2 Menampilkan Dimensi Data

dim(bank)
#> [1] 4521   17

2.3.3 Melihat variable Bank

names(bank)
#>  [1] "age"       "job"       "marital"   "education" "default"   "balance"  
#>  [7] "housing"   "loan"      "contact"   "day"       "month"     "duration" 
#> [13] "campaign"  "pdays"     "previous"  "poutcome"  "y"

Dari pemeriksaan data diatas didapatkan bahwa :

  • Dataset Bank Marketing terdiri dari 4521 baris dan 17 kolom
  • Nama variabel dari dataset tersebut adalah “age”, “job”, “marital”, “education”, “default”, “balance”, “housing”, “loan”, “contact”, “day”, “month”, duration”, “campaign”, “pdays”, “previous”, “poutcome”, “y”

2.4 Pembersihan Data (Data Cleaning)

2.4.1 Melihat dan Memperbaiki Tipe Data

glimpse(bank)
#> Rows: 4,521
#> Columns: 17
#> $ age       <int> 30, 33, 35, 30, 59, 35, 36, 39, 41, 43, 39, 43, 36, 20, 31, …
#> $ job       <chr> "unemployed", "services", "management", "management", "blue-…
#> $ marital   <chr> "married", "married", "single", "married", "married", "singl…
#> $ education <chr> "primary", "secondary", "tertiary", "tertiary", "secondary",…
#> $ default   <chr> "no", "no", "no", "no", "no", "no", "no", "no", "no", "no", …
#> $ balance   <int> 1787, 4789, 1350, 1476, 0, 747, 307, 147, 221, -88, 9374, 26…
#> $ housing   <chr> "no", "yes", "yes", "yes", "yes", "no", "yes", "yes", "yes",…
#> $ loan      <chr> "no", "yes", "no", "yes", "no", "no", "no", "no", "no", "yes…
#> $ contact   <chr> "cellular", "cellular", "cellular", "unknown", "unknown", "c…
#> $ day       <int> 19, 11, 16, 3, 5, 23, 14, 6, 14, 17, 20, 17, 13, 30, 29, 29,…
#> $ month     <chr> "oct", "may", "apr", "jun", "may", "feb", "may", "may", "may…
#> $ duration  <int> 79, 220, 185, 199, 226, 141, 341, 151, 57, 313, 273, 113, 32…
#> $ campaign  <int> 1, 1, 1, 4, 1, 2, 1, 2, 2, 1, 1, 2, 2, 1, 1, 2, 5, 1, 1, 1, …
#> $ pdays     <int> -1, 339, 330, -1, -1, 176, 330, -1, -1, 147, -1, -1, -1, -1,…
#> $ previous  <int> 0, 4, 1, 0, 0, 3, 2, 0, 0, 2, 0, 0, 0, 0, 1, 0, 0, 2, 0, 1, …
#> $ poutcome  <chr> "unknown", "failure", "failure", "unknown", "unknown", "fail…
#> $ y         <chr> "no", "no", "no", "no", "no", "no", "no", "no", "no", "no", …

Dari hasil diatas diketahui bahwa ada beberapa variabel memiliki tipe data yang tidak sesuai, sehingga kita perbaiki sebagai berikut :

bank <- bank %>%
  mutate(
    job = as.factor(job),
    marital = as.factor(marital),
    education = as.factor(education),
    default = as.factor(default),
    housing = as.factor(housing),
    loan = as.factor(loan),
    contact = as.factor(contact),
    day = as.factor(day),
    month = as.factor(month),
    poutcome = as.factor(poutcome),
    y = as.factor(y)
  )

glimpse(bank)
#> Rows: 4,521
#> Columns: 17
#> $ age       <int> 30, 33, 35, 30, 59, 35, 36, 39, 41, 43, 39, 43, 36, 20, 31, …
#> $ job       <fct> unemployed, services, management, management, blue-collar, m…
#> $ marital   <fct> married, married, single, married, married, single, married,…
#> $ education <fct> primary, secondary, tertiary, tertiary, secondary, tertiary,…
#> $ default   <fct> no, no, no, no, no, no, no, no, no, no, no, no, no, no, no, …
#> $ balance   <int> 1787, 4789, 1350, 1476, 0, 747, 307, 147, 221, -88, 9374, 26…
#> $ housing   <fct> no, yes, yes, yes, yes, no, yes, yes, yes, yes, yes, yes, no…
#> $ loan      <fct> no, yes, no, yes, no, no, no, no, no, yes, no, no, no, no, y…
#> $ contact   <fct> cellular, cellular, cellular, unknown, unknown, cellular, ce…
#> $ day       <fct> 19, 11, 16, 3, 5, 23, 14, 6, 14, 17, 20, 17, 13, 30, 29, 29,…
#> $ month     <fct> oct, may, apr, jun, may, feb, may, may, may, apr, may, apr, …
#> $ duration  <int> 79, 220, 185, 199, 226, 141, 341, 151, 57, 313, 273, 113, 32…
#> $ campaign  <int> 1, 1, 1, 4, 1, 2, 1, 2, 2, 1, 1, 2, 2, 1, 1, 2, 5, 1, 1, 1, …
#> $ pdays     <int> -1, 339, 330, -1, -1, 176, 330, -1, -1, 147, -1, -1, -1, -1,…
#> $ previous  <int> 0, 4, 1, 0, 0, 3, 2, 0, 0, 2, 0, 0, 0, 0, 1, 0, 0, 2, 0, 1, …
#> $ poutcome  <fct> unknown, failure, failure, unknown, unknown, failure, other,…
#> $ y         <fct> no, no, no, no, no, no, no, no, no, no, no, no, no, yes, no,…

2.4.2 Memeriksa Missing Value

colSums(is.na(bank))
#>       age       job   marital education   default   balance   housing      loan 
#>         0         0         0         0         0         0         0         0 
#>   contact       day     month  duration  campaign     pdays  previous  poutcome 
#>         0         0         0         0         0         0         0         0 
#>         y 
#>         0

Dari hasil diatas diketahui data tersebut tidak terdapat missing value dan dapat dibuktikan juga dengan fungsi dibawah ini :

anyNA(bank)
#> [1] FALSE
cor(bank[, sapply(bank, is.numeric)])
#>                   age      balance     duration     campaign        pdays
#> age       1.000000000  0.083820142 -0.002366889 -0.005147905 -0.008893530
#> balance   0.083820142  1.000000000 -0.015949918 -0.009976166  0.009436676
#> duration -0.002366889 -0.015949918  1.000000000 -0.068382000  0.010380242
#> campaign -0.005147905 -0.009976166 -0.068382000  1.000000000 -0.093136818
#> pdays    -0.008893530  0.009436676  0.010380242 -0.093136818  1.000000000
#> previous -0.003510917  0.026196357  0.018080317 -0.067832630  0.577561827
#>              previous
#> age      -0.003510917
#> balance   0.026196357
#> duration  0.018080317
#> campaign -0.067832630
#> pdays     0.577561827
#> previous  1.000000000

Setelah membersihkan dataset bank marketing dan mengubah tipe data agar sesuai, data siap untuk diproses dan dianalisis.


3 Penjelasan Data

3.1 Ringkasan Data

summary(bank)
#>       age                 job          marital         education    default   
#>  Min.   :19.00   management :969   divorced: 528   primary  : 678   no :4445  
#>  1st Qu.:33.00   blue-collar:946   married :2797   secondary:2306   yes:  76  
#>  Median :39.00   technician :768   single  :1196   tertiary :1350             
#>  Mean   :41.17   admin.     :478                   unknown  : 187             
#>  3rd Qu.:49.00   services   :417                                              
#>  Max.   :87.00   retired    :230                                              
#>                  (Other)    :713                                              
#>     balance      housing     loan           contact          day      
#>  Min.   :-3313   no :1962   no :3830   cellular :2896   20     : 257  
#>  1st Qu.:   69   yes:2559   yes: 691   telephone: 301   18     : 226  
#>  Median :  444                         unknown  :1324   19     : 201  
#>  Mean   : 1423                                          21     : 198  
#>  3rd Qu.: 1480                                          14     : 195  
#>  Max.   :71188                                          17     : 191  
#>                                                         (Other):3253  
#>      month         duration       campaign          pdays       
#>  may    :1398   Min.   :   4   Min.   : 1.000   Min.   : -1.00  
#>  jul    : 706   1st Qu.: 104   1st Qu.: 1.000   1st Qu.: -1.00  
#>  aug    : 633   Median : 185   Median : 2.000   Median : -1.00  
#>  jun    : 531   Mean   : 264   Mean   : 2.794   Mean   : 39.77  
#>  nov    : 389   3rd Qu.: 329   3rd Qu.: 3.000   3rd Qu.: -1.00  
#>  apr    : 293   Max.   :3025   Max.   :50.000   Max.   :871.00  
#>  (Other): 571                                                   
#>     previous          poutcome      y       
#>  Min.   : 0.0000   failure: 490   no :4000  
#>  1st Qu.: 0.0000   other  : 197   yes: 521  
#>  Median : 0.0000   success: 129             
#>  Mean   : 0.5426   unknown:3705             
#>  3rd Qu.: 0.0000                            
#>  Max.   :25.0000                            
#> 

Insight

  • Usia nasabah bank memiliki rentang minimal 19 tahun dan maksimal 87 tahun, dengan rata-rata usia nasabah sebesar 41 tahun.
  • Pekerjaan yang paling banyak dimiliki oleh nasabah adalah “manajemen”. Mayoritas nasabah sudah menikah.
  • Sekolah menengah merupakan pendidikan terakhir yang paling banyak dimiliki oleh nasabah.
  • Sebagian besar nasabah sudah memiliki kartu kredit dengan status default.
  • Terdapat 2559 nasabah yang sudah memiliki pinjaman perumahan.
  • Mayoritas nasabah sudah memiliki pinjaman pribadi.
  • Jenis komunikasi yang paling banyak digunakan oleh nasabah adalah “seluler”.
  • Rata-rata durasi kontak dengan nasabah adalah 264 detik.
  • Banyak hasil dari kampanye pemasaran sebelumnya yang belum diketahui (unknown)

3.2 Analisis variabel Kategorik

bank %>%
  count(y) %>%
  ggplot(aes(x = y, y = n)) +
  geom_bar(stat = "identity") +
  xlab("Y") +
  ylab("Jumlah") +
  ggtitle("Distribusi Variabel Y")

bank %>%
  count(marital) %>%
  ggplot(aes(x = marital, y = n)) +
  geom_bar(stat = "identity") +
  xlab("Marital") +
  ylab("Jumlah") +
  ggtitle("Distribusi Variabel Marital")

bank %>%
  count(education) %>%
  ggplot(aes(x = education, y = n)) +
  geom_bar(stat = "identity") +
  xlab("Education") +
  ylab("Jumlah") +
  ggtitle("Distribusi Variabel Education")

bank %>%
  count(default) %>%
  ggplot(aes(x = default, y = n)) +
  geom_bar(stat = "identity") +
  xlab("Default") +
  ylab("Jumlah") +
  ggtitle("Distribusi Variabel Default")

bank %>%
  count(default) %>%
  ggplot(aes(x = default, y = n)) +
  geom_bar(stat = "identity") +
  xlab("Default") +
  ylab("Jumlah") +
  ggtitle("Distribusi Variabel Default")

Insight dari Analisis variabel kategorik:

  • Mayoritas nasabah tidak melakukan deposit (nilai “no”) daripada yang melakukan (nilai “yes”).
  • Mayoritas nasabah sudah menikah (nilai “married”) dibandingkan dengan single dan divorced.
  • Hampir semua nasabah tidak memiliki kredit default (nilai “no”) dibandingkan dengan yang memiliki (nilai “yes”).
  • Kontak terakhir paling banyak dilakukan pada bulan Mei dan jumlahnya sedikit pada bulan Desember.

3.3 Analisis Variabel Numerik

bank %>%
  ggplot(aes(x = age)) +
  geom_histogram(fill = "steelblue", color = "black") +
  xlab("Usia") +
  ylab("Frekuensi") +
  ggtitle("Histogram Usia")

bank %>%
  ggplot(aes(x = age)) +
  geom_boxplot(fill = "steelblue", color = "black") +
  xlab("Usia") +
  ggtitle("Boxplot Usia")

bank %>%
  ggplot(aes(x = balance)) +
  geom_histogram(fill = "steelblue", color = "black") +
  xlab("Saldo") +
  ylab("Frekuensi") +
  ggtitle("Histogram Saldo")

bank %>%
  ggplot(aes(x = balance)) +
  geom_boxplot(fill = "steelblue", color = "black") +
  xlab("Saldo") +
  ggtitle("Boxplot Saldo")

bank %>%
  ggplot(aes(x = duration)) +
  geom_histogram(fill = "steelblue", color = "black") +
  xlab("Durasi") +
  ylab("Frekuensi") +
  ggtitle("Histogram Durasi")

bank %>%
  ggplot(aes(x = duration)) +
  geom_boxplot(fill = "steelblue", color = "black") +
  xlab("Durasi") +
  ggtitle("Boxplot Durasi")

bank %>%
  ggplot(aes(x = duration)) +
  geom_histogram(fill = "steelblue", color = "black") +
  xlab("Durasi") +
  ylab("Frekuensi") +
  ggtitle("Histogram Durasi")

bank %>%
  ggplot(aes(x = duration)) +
  geom_boxplot(fill = "steelblue", color = "black") +
  xlab("Durasi") +
  ggtitle("Boxplot Durasi")

Insight Analisis variabel numerik:

  • Variabel “age” memiliki skewness positif, tidak berdistribusi normal, dan terdapat outlier di atas batas atasnya.
  • Variabel “balance” memiliki skewness positif, tidak berdistribusi normal, dan terdapat outliers.
  • Variabel “duration” memiliki skewness positif, tidak berdistribusi normal, dan terdapat outlier di atas batas atasnya dengan outliers terjauh di atas 3000.
  • Variabel “campaign” memiliki skewness positif, tidak berdistribusi normal, dan terdapat outlier di atas batas atasnya dengan outliers terjauh di atas 50.

4 Studi Kasus

  1. Dari kategori (education) : “primary”, “secondary”, “tertiary” apakah terdapat hubungan antara saldo dan durasi?
data1 <- bank %>% 
  filter(education != "unknown" )

viz1 <- ggplot(data1, aes(x = balance, y = duration, col = education, text = paste("Saldo:", balance, "<br>Durasi:", duration, "<br>Pendidikan:", education))) +
  geom_point(shape = 16) +
  geom_smooth(method = "lm", se = FALSE) +
  labs(title = "Hubungan Saldo dan Durasi",
       x = "Saldo",
       y = "Durasi") +
  theme(plot.title = element_text(size = 14))+
  theme_fivethirtyeight()
viz1

Answer : Dari gambar diatas menunjukkan adanya hubungan negatif yang sangat lemah antara kedua variabel tersebut.

  1. Bagaimana profil pendidikan nasabah yang belum menikah dibandingkan dengan nasabah yang telah menikah dalam hal jumlah saldo?
ggplot(data = data1, mapping = aes(x = balance, y = reorder(marital, balance))) +
  geom_col(aes(fill = education), position = "dodge") +
  labs(title = "Distribusi Saldo berdasarkan Status Pernikahan",
       x = "Saldo",
       y = "Status Pernikahan",
       fill = "Pendidikan") +
  theme_fivethirtyeight()

Answer : Ternyata mayoritas nasabah yang telah menikah memiliki tingkat pendidikan primary, hal ini dapat dilihat dari besarnya jumlah saldo nasabah yang sudah menikah sangat besar.

  1. Apa kategori pekerjaan yang memiliki durasi paling banyak? Dan jenis kontak apa yang paling umum digunakan untuk berkomunikasi dengan nasabah?
data3 <- bank %>% 
  select(contact, job, duration) %>% 
  group_by(contact,job) %>% 
  summarise(sum_duration = sum(duration)) %>% 
  arrange(desc(sum_duration))

data3
ggplot(data = data3, mapping = aes(x = sum_duration, y = reorder(job, sum_duration))) +
  geom_col(aes(fill = contact), position = "stack") +
  labs(title = "Distribusi Durasi Pekerjaan",
       x = "Durasi",
       y = "Pekerjaan",
       fill = "Kontak") +
  theme_fivethirtyeight()

Answer : Pekerjaan dengan durasi terbanyak adalah dalam bidang blue-collar, yang sebagian besar menggunakan kontak cellular. Namun, kategori pekerjaan menggunakan kontak cellular terbanyak adalah management.


5 Rekomendasi Bisnis

Berdasarkan insight di atas, rekomendasi bisnis yang dapat diberikan adalah fokus pada pelayanan dan penawaran produk yang sesuai dengan kebutuhan dan preferensi nasabah dengan tingkat pendidikan primary. Selain itu, strategi pemasaran dan komunikasi yang lebih intens menggunakan kontak cellular dapat diimplementasikan untuk memperluas jangkauan dan meningkatkan interaksi dengan nasabah. Selain itu, perhatian khusus dapat diberikan pada pekerjaan dalam bidang blue-collar, dengan menyediakan produk dan layanan yang relevan dengan kebutuhan mereka.