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.