Regression Model: Customer Purchasing Behaviors

1 Introduction

Regresi linier adalah teknik analisis statistik yang digunakan untuk memprediksi hubungan antara dua atau lebih variabel. Pada artikel ini kita akan membuat model regresi linier berganda menggunakan data Customer Purchasing Behaviors. Kita ingin mengetahui variabel apa saja yang mempengaruhi Loyalty Score dari nasabah yang nantinya akan digunakan sebagai tim data untuk mengevaluasi dan meningkatkan loyalitas nasabah.

2 Data Preparation

2.1 Importing Libraries

Langkah pertama adalah memanggil library yang akan digunakan dalam pemodelan.

library(tidyverse)
library(caret)
library(plotly)
library(data.table)
library(GGally)
library(car)
library(scales)
library(lmtest)
library(tidymodels)
library(gridExtra)
library(ggstatsplot)
library(dplyr)
library(grid)
library(performance)
library(MLmetrics)

2.2 Importing Datasets

Selanjutnya, dilakukan import data Customer Purchasing Behaviors dalam bentuk CSV yang disimpan dalam data frame yang disimpan dengan nama purchase_data.

purchase_data <- read.csv("Customer Purchasing Behaviors.csv", sep = ',', header = TRUE)
str(purchase_data)
#> 'data.frame':    238 obs. of  7 variables:
#>  $ user_id           : int  1 2 3 4 5 6 7 8 9 10 ...
#>  $ age               : int  25 34 45 22 29 41 36 27 50 31 ...
#>  $ annual_income     : int  45000 55000 65000 30000 47000 61000 54000 43000 70000 50000 ...
#>  $ purchase_amount   : int  200 350 500 150 220 480 400 230 600 320 ...
#>  $ loyalty_score     : num  4.5 7 8 3 4.8 7.8 6.5 4.2 9 5.5 ...
#>  $ region            : chr  "North" "South" "West" "East" ...
#>  $ purchase_frequency: int  12 18 22 10 13 21 19 14 25 17 ...

Data di atas memiliki 238 observasi dan 7 variables. Variabel user_id merupakan variabel dengan unique identifier untuk setiap nasabah. Target variabel dalam case ini adalah loyalty_score. Dalam case ini kita menggunakan variabel dependen yang bersifat numerik yaitu age,annual_income,purchase_amount,dan purchase_frequency.

3 Exploratory Data Analysis

Sebelum melakukan pemodelan, kita harus memastikan bahwa data yang digunakan adalah data yang bersih dan useful. ### 3.1 Duplicates Langkah pertama dilakukan pengecekan data duplikat.

dup <- sum(duplicated(purchase_data))
dup
#> [1] 0

Berdasarkan hasil pengecekan, data purchase_data tidak memiliki data duplikat.

3.2 Missing Values

Selanjutnya yaitu melakukan pengecekan missing values. Missing values akan menyebabkan data tidak valid saat dilakukan pemodelan. Terdapat beberapa uji yang tidak resisten terhadap missing values.

mv <- colSums(is.na(x=purchase_data))
mv
#>            user_id                age      annual_income    purchase_amount 
#>                  0                  0                  0                  0 
#>      loyalty_score             region purchase_frequency 
#>                  0                  0                  0

Berdasarkab hasil pengecekan missing values, data purchase_data tidak memiliki missing values untuk seluruh variabel, sehingga tidak perlu dilakukan penanganan missing values.

3.3 Data Types

Selanjutnya, dilakukan pengecekan untuk tipe variabel. Variabel yang memiliki tipe data tidak sesuai akan mempengaruhi hasil pemodelan bahkan tidak bisa diproses dalam pemodelan.

datypes <- str(purchase_data)
#> 'data.frame':    238 obs. of  7 variables:
#>  $ user_id           : int  1 2 3 4 5 6 7 8 9 10 ...
#>  $ age               : int  25 34 45 22 29 41 36 27 50 31 ...
#>  $ annual_income     : int  45000 55000 65000 30000 47000 61000 54000 43000 70000 50000 ...
#>  $ purchase_amount   : int  200 350 500 150 220 480 400 230 600 320 ...
#>  $ loyalty_score     : num  4.5 7 8 3 4.8 7.8 6.5 4.2 9 5.5 ...
#>  $ region            : chr  "North" "South" "West" "East" ...
#>  $ purchase_frequency: int  12 18 22 10 13 21 19 14 25 17 ...
datypes
#> NULL

Berdasarkan pengecekan tipe data, variabel yang dibutuhkan (age,annual_income,purchase_amount,purchase_frequency,loyalty_score) memiliki tipe yang sesuai sehingga variabel tidak perlu dilakukan perubahan tipe data.

3.4 Boxplot

Boxplot adalah grafik visualisasi data yang digunakan dalam statistik untuk menunjukkan distribusi data. Selain itu, kita bisa melihat apakah pada data terdapat outlier/pencilan.

# Boxplot
par(new=TRUE)
bp_age <- boxplot(purchase_data$age, col = "grey", xlab = "Age", ylab = "Value", main = "Age Var Boxplot")

bp_income <- boxplot(purchase_data$annual_income, col = "grey", xlab = "Annual Income", ylab = "Value", main = "Annual Income Var Boxplot")

bp_pcsamt <- boxplot(purchase_data$purchase_amount, col = "grey", xlab = "Purchase Amount", ylab = "Value", main = "Purchase Amount Var Boxplot")

bp_pcsfreq <- boxplot(purchase_data$purchase_frequency, col = "grey", xlab = "Purchase Frequency", ylab = "Value", main = "Purchase Frequency Var Boxplot")

bp_loyaltyscr <- boxplot(purchase_data$loyalty_score, col = "grey", xlab = "Loyalty Score", ylab = "Value", main = "Loyalty Score Var Boxplot")

Berdasarkan Boxplot seluruh variabel, tidak terdapat pengamatan yang keluar dari kotak distribusi data. Hal ini menunjukkan bahwa pada data purchase_data tidak terdapat outlier.

3.5 Descriptive Statistics

Statistika deskriptif adalah salah satu jenis statistik yang berfungsi untuk mendeskripsikan data yang fokus pada penyajian, managemen, dan klasifikasi data sehingga dapat memberikan informasi yang berguna.

desc_stats <- summary(purchase_data)
desc_stats 
#>     user_id            age        annual_income   purchase_amount
#>  Min.   :  1.00   Min.   :22.00   Min.   :30000   Min.   :150.0  
#>  1st Qu.: 60.25   1st Qu.:31.00   1st Qu.:50000   1st Qu.:320.0  
#>  Median :119.50   Median :39.00   Median :59000   Median :440.0  
#>  Mean   :119.50   Mean   :38.68   Mean   :57408   Mean   :425.6  
#>  3rd Qu.:178.75   3rd Qu.:46.75   3rd Qu.:66750   3rd Qu.:527.5  
#>  Max.   :238.00   Max.   :55.00   Max.   :75000   Max.   :640.0  
#>  loyalty_score      region          purchase_frequency
#>  Min.   :3.000   Length:238         Min.   :10.0      
#>  1st Qu.:5.500   Class :character   1st Qu.:17.0      
#>  Median :7.000   Mode  :character   Median :20.0      
#>  Mean   :6.794                      Mean   :19.8      
#>  3rd Qu.:8.275                      3rd Qu.:23.0      
#>  Max.   :9.500                      Max.   :28.0

3.6 Correlation

Korelasi digunakan untuk melihat hubungan antar variabel. Korelasi ini dapat digunakan sebagai filter awal dalam memilih variabel independen (X). Namun, korelasi memiliki beberapa kekurangan. Korelasi hanya dapat melihat seberapa besar kekuatan hubungan kedua variabel, namun tidak dapat melihat peran yang mempengaruhi dan dipengaruhi.

cols_2 <- c("age","annual_income","purchase_amount","loyalty_score","purchase_frequency")
boxdat <- purchase_data[cols_2]
corr_numvar <- ggcorrmat(
  data = boxdat,
  type = "parametric", # Person Correlation
  colors = c("darkred", "white", "steelblue")
)

corr_numvar <- corr_numvar +  labs(title = NULL, subtitle = NULL) + theme(
  plot.margin = margin(0.15, 0, 0.1, 0.01, "npc")) 

corr_numvar

grid.text(
  "Correlation: Numeric Variable", 
  0, 
  0.900,
  just = c("left", "bottom"),
  gp = gpar(
    fontsize = 22,
    fontface = "bold",
    fontfamily = "Econ Sans Cnd"
  )
)

grid.lines(
  x = c(0, 1),
  y = 1,
  gp = gpar(col = "#e5001c", lwd = 4)
)

grid.rect(
  x = 0,
  y = 1,
  width = 0.05,
  height = 0.025,
  just = c("left", "top"),
  gp = gpar(fill = "#e5001c", lwd = 0)
)

Korelasi menunjukkan bahwa seluruh variabel, memiliki korelasi positif yang kuat satu sama lain (mendekati nilai 1). Dalam hal ini ketika satu variabel meningkat maka variabel lainnya juga akan mengalami peningkatan. Namun, dengan hasil korelasi yang tinggi akan menimbulkan multikolinieritas pada model regresi.

3.7 Scatter Plot

Scatter plot adalah jenis grafik yang digunakan dalam statistik dan analisis data untuk menampilkan serta menganalisis hubungan antara dua variabel numerik.

# 1. Loyalty Score dan Purchase Frequency
plot(purchase_data$loyalty_score, purchase_data$purchase_frequency)

# 2. Loyalty Score dan Age
plot(purchase_data$loyalty_score, purchase_data$age)

# 3. Loyalty Score dan Annual Income
plot(purchase_data$loyalty_score, purchase_data$annual_income)

# 4. Loyalty Score dan Purchase Amount
plot(purchase_data$loyalty_score, purchase_data$purchase_amount)

Hasil scatter plot align dengan hasil korelasi, dimana setiap penambahan variabel independen, variabel dependen juga akan meningkat.

4 Modeling : Linear Regression

Setelah dilakukan preprocessing data, selanjutnya dilakukan pemodelan regresi.

4.1 Initial Model

Pada model regresi, digunakan 4 variabel independen X yaitu (purchase_frequency,age,annual_income,purchase_amount) dan 1 variabel dependen Y yaitu loyalty_score

# Fungsi
model_ols <- lm(formula = loyalty_score ~ purchase_frequency + age + annual_income + purchase_amount,
                data = purchase_data)

# Hasil Model
model_ols
#> 
#> Call:
#> lm(formula = loyalty_score ~ purchase_frequency + age + annual_income + 
#>     purchase_amount, data = purchase_data)
#> 
#> Coefficients:
#>        (Intercept)  purchase_frequency                 age       annual_income  
#>         0.55540597         -0.05977776          0.00504367          0.00003465  
#>    purchase_amount  
#>         0.01230622

4.2 Assumption

Setelah dilakukan pemodelan, dari hasil model tersebut dilakukan uji asumsi regresi. #### Linearity Linearity artinya target variabel dengan prediktornya memiliki hubungan yang linear atau hubungannya bersifat garis lurus.

# Linearity
plot(model_ols, which = 1)
abline(h = 10, col = "green")
abline(h = -10, col = "green")

Dari plor dapat diluhat bahwa nilai residual berada di sekitar nilai 0, karena nilai residual berada di sekitar angka 0, maka uji asumsi linearity TERPENUHI.

Normality of Residuals

Uji Normalitas adalah sebuah uji yang dilakukan dengan tujuan untuk menilai sebaran data pada sebuah kelompok data atau variabel, apakah sebaran data tersebut berdistribusi normal atau tidak. Model linear regression diharapkan menghasilkan error yang berdistribusi normal. Dengan begitu, error lebih banyak berkumpul di sekitar angka nol. Pada uji ini digunakan pengujian menggunakan metode Shapiro Test.

  • H0: error berdistribusi normal
  • H1: error TIDAK berdistribusi normal

Kondisi yang diharapkan: H0 - p_value > alpha -> gagal tolak h0 (terima h0) - p_value < alpha -> tolak h0 (terima h1)

# Normality by Shapiro Test
shapiro.test(model_ols$residuals)
#> 
#>  Shapiro-Wilk normality test
#> 
#> data:  model_ols$residuals
#> W = 0.92044, p-value = 0.0000000005476

Kesimpulan: Karena p-value < alpha, maka: - Tolak h0 - Terima h1 - Error tidak berdistribusi normal

Status: Uji asumsi Normality of Residuals [TIDAK TERPENUHI].

Homoscedasticity of Residuals

Pengujian homoskedastisitas dilakukan dengan melihat grafik residual vs fitted values untuk mengetahui apakah dalam model regresi terdapat ketidaksamaan variabs dari residual pengamatan ke pengamatan lain. Diharapkan error yang dihasilkan oleh model menyebar secara acak atau dengan variasi konstan. Apabila divisualisasikan maka error tidak berpola.

Breusch-Pagan hypothesis test:

  • H0: error menyebar konstan atau homoscedasticity
  • H1: error menyebar TIDAK konstan atau heteroscedasticity

Kondisi yang diharapkan: H0 p_value > alpha -> gagal tolak h0 (terima h0) p_value < alpha -> tolak h0 (terima h1)

# Homoscedasticity by BP Test
bptest(model_ols)
#> 
#>  studentized Breusch-Pagan test
#> 
#> data:  model_ols
#> BP = 24.828, df = 4, p-value = 0.00005447

Kesimpulan: Karena p-value < alpha, maka: - Tolak h0 - Terima h1

Status: Uji asumsi Homoscedasticity of Residuals [TIDAK TERPENUHI].

Non Multicollinearity

Pengujian multikolinieritas adalah uji yang dilakukan untuk memastikan apakah di dalam sebuah model regresi ada interkorelasi atau kolinieritas antar variabel bebas.

Uji VIF (Variance Inflation Factor) dengan fungsi vif() dari package car: * nilai VIF > 10: terjadi multicollinearity pada model * nilai VIF < 10: tidak terjadi multicollinearity pada model

Kondisi yang diharapkan: VIF < 10

# Non Multicollinearity
vif(model_ols)
#> purchase_frequency                age      annual_income    purchase_amount 
#>           83.37844           37.10974           34.74720          116.89244

Kesimpulan: Terdapat prediktor yang memiliki skor VIF > 10. Artinya, model ols terjadi Multicollinearity.

Status: Uji asumsi No Multicollinearity [TIDAK TERPENUHI].

4.3 Metrics Evaluation

Metrics Evaluation menggunakan residual model dalam perhitungannya.

Error/Residual

Error/residual adalah selisih antara hasil prediksi dengan nilai aktual.

\[ Error = prediction - actual = \hat y - y \] Metrics Evaluation

Metriks evaluation yang digunakan adalah Ajdusted R-squared dan MAPE

Adjusted R-squared - Rentang nilai 0 sampai 1 - Semakin mendekati 1, semakin baik prediktor dalam menjelaskan target

# Goodness of Fit : Ajdusted R-squared
summary(model_ols)$adj.r.squared
#> [1] 0.9895279

Model OLS memiliki nilai Adjusted R-squared sebesar 0.9895279 artinya prediktor yang digunakan sangat baik dalam menjelaskan target yaitu loyalty_score.

Mean Absolute Percentage Error (MAPE) MAPE menunjukkan seberapa besar penyimpangannya dalam bentuk persentase. \[ MAPE = \frac{1}{n} \sum\frac{|\hat y - y|}{y} \] Digunakan 10% (di bawah 10% dianggap baik)

# MAPE
MAPE(model_ols$fitted.values, purchase_data$loyalty_score)
#> [1] 0.02403834

Interpretasi MAPE: Hasil prediksi menyimpang sejauh 2,4% dari nilai aktualnya. MAPE memiliki range dalam bentuk persen, semakin kecil nilai MAPE, semakin bagus model yang kita miliki.

4.4 Variable Interpretation

Setelah dilakukan pengujian asumsi dan evaluasi metriks model, selanjutnya dapat dilakukan interpretasi hasil pemodelan.

Formula Regresi

\[\hat{y} = \beta_0 + \beta_1 x_1 + ... + \beta_n x_n\]

summary(model_ols)
#> 
#> Call:
#> lm(formula = loyalty_score ~ purchase_frequency + age + annual_income + 
#>     purchase_amount, data = purchase_data)
#> 
#> Residuals:
#>     Min      1Q  Median      3Q     Max 
#> -0.4216 -0.1309 -0.0278  0.1051  1.1361 
#> 
#> Coefficients:
#>                        Estimate   Std. Error t value             Pr(>|t|)    
#> (Intercept)         0.555405970  0.200656408   2.768              0.00609 ** 
#> purchase_frequency -0.059777759  0.025261920  -2.366              0.01879 *  
#> age                 0.005043673  0.008223550   0.613              0.54026    
#> annual_income       0.000034651  0.000006525   5.310          0.000000255 ***
#> purchase_amount     0.012306224  0.000974502  12.628 < 0.0000000000000002 ***
#> ---
#> Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
#> 
#> Residual standard error: 0.1943 on 233 degrees of freedom
#> Multiple R-squared:  0.9897, Adjusted R-squared:  0.9895 
#> F-statistic:  5600 on 4 and 233 DF,  p-value: < 0.00000000000000022

Formula regresi untuk model di atas:

\[ Loyalty Score = 0.5554 - 0.0597 * Purchase Frequency + 0.0050 * Age + 0.0001 * \\ Annual Income + 0.0123 * Purchase Amount \] Interpretasi dari model linear regression:

1. Intercept

Nilai variable target ketika semua nilai prediktor sama dengan nol. Loyalty_Score = 0.5554 - 0.0597*Purchase_Frequency + 0.0050*Age + 0.0001*Annual_Income + 0.0123*Purchase_Amount

Arti: Ketika seluruh prediktor = 0, maka loyalty score bernilai 0.5554. -> Naik sebesar 0.5554.

2. Coefficient/Slope

Besarnya perubahan nilai variable target ketika nilai prediktor bertambah 1 satuan. + Koefisien yang positif = meningkatkan nilai variable target + Koefisien yang negatif = menurunkan nilai variable target

Target: Loyalty_Score Prediktor: - Age : memiliki koef. positif ; semakin berumur akan semakin loyal - Purchase_Frequency : memiliki koef. negatif ; semakin banyak frekuensi pembelian maka akan semakin tidak loyal - Annual_Income : memiliki koef. positif ; semakin banyak annual income maka semakin loyal - Purchase_Amount : memiliki koef. positif ; semakin banyak jumlah uang yang dikeluarkan untuk belanja maka semakin loyal

3. Signifikansi Prediktor

Mengetahui apakah setiap prediktor berpengaruh signifikan terhadap variable targetnya. + Sebuah prediktor dikatakan signifikan ketika p-value < 0.05 (alpha)

Uji hipotesis yang digunakan:

  • H0: Prediktor tidak signifikan berpengaruh (Estimate = 0)
  • H1: Prediktor signifikan berpengaruh (Estimate != 0)

Hasil Uji Signifikansi: - Hanya tiga prediktor (purchase_frequency,annual_income,purchase_amount) yang signifikan terhadap variabel target (loyalty_score).

5 Conclusion

Model regresi pada case loyalty_score memiliki metriks evaluasi yang baik ditunjukkan dengan nilai Adjusted R-squared yang tinggi dan MAPE yang rendah. Hanya terdapat tiga prediktor yang signifikan mempengaruhi loyalty_score secara positif yaitu (purchase_frequency,annual_income,purchase_amount). Namun, untuk uji asumsi seluruhnya tidak memenuhi. Hal ini perlu dilakukan penanganan uji asumsi agar hasil pemodelan lebih valid.