LASSO (Least Absolute Shrinkage and Selection Operator) merupakan salah satu teknik regresi penalized yang populer digunakan dalam menangani masalah regresi dengan data berdimensi tinggi. Lasso tidak hanya melakukan pemilihan variabel, tetapi juga menghasilkan model yang lebih sederhana dan lebih mudah diinterpretasikan. Sehingga model lasso cocok untuk situasi di mana banyak variabel mungkin tidak relevan dan membantu pemilihan variabel yang paling penting. Namun model Lasso memiliki keterbatasan dalam situasi di mana ada struktur tertentu antar variabel, seperti ketika data bersifat spasial atau time series, di mana hubungan antar variabel tidak bisa dianggap independen. Maka dari itu, diperlukanlah pengembangan model yang diberi nama model Lasso untuk menangani kelemahan dari model Lasso yakni Fused Lasso Fused Lasso dikembangkan untuk menangani masalah tersebut dengan memperhitungkan korelasi antar variabel secara langsung, terutama dalam situasi di mana variabel saling berdekatan atau memiliki hubungan yang teratur. Teknik ini menggabungkan regularisasi LASSO dengan penalti tambahan untuk perbedaan antar koefisien variabel yang bertetangga.
\[ \hat{\beta} = \arg\min_\beta \left( \frac{1}{2n} \sum_{i=1}^{n} (y_i - X_i \beta)^2 + \lambda \sum_{j=1}^{p} |\beta_j| \right) \]
Dimana: - \(y_i\) adalah nilai observasi dari target.
\(X_i\) adalah vektor fitur.
\(\beta_j\) adalah koefisien regresi.
\(\lambda\) adalah parameter regulasi yang mengontrol kekuatan penalti.
Penalti L1 menyebabkan beberapa koefisien menjadi nol, sehingga Lasso juga berfungsi sebagai metode pemilihan fitur.
Rumus untuk Fused Lasso adalah:
\[ \hat{\beta} = \arg\min_\beta \left( \frac{1}{2n} \sum_{i=1}^{n} (y_i - X_i \beta)^2 + \lambda_1 \sum_{j=1}^{p} |\beta_j| + \lambda_2 \sum_{j=2}^{p} |\beta_j - \beta_{j-1}| \right) \]
Dimana: - \(\lambda_1\) adalah penalti L1 untuk koefisien \(\beta_j\).
Fused Lasso tidak hanya melakukan pemilihan fitur, tetapi juga memaksa koefisien yang berdekatan untuk mendekati satu sama lain, menciptakan solusi yang lebih halus dan berguna untuk data yang memiliki korelasi spasial atau temporal.
| Aspek | Lasso | Fused Lasso |
|---|---|---|
| Penalti | L1 (\(\sum |\beta_j|\)) | L1 + Penalti pada perbedaan antara koefisien (\(\sum |\beta_j - \beta_{j-1}|\)) |
| Pemilihan Fitur | Ya, menghasilkan beberapa koefisien nol | Ya, dan menjaga struktur yang halus antara koefisien yang berdekatan |
| Kegunaan | Cocok untuk data yang tidak memiliki korelasi antar variabel | Cocok untuk data dengan korelasi antar variabel yang berdekatan (misalnya data spasial/temporal) |
| Interpretasi Model | Lebih mudah karena pemilihan fitur yang jelas |
Lasso fokus pada pemilihan variabel, sedangkan fused lasso memperhatikan baik pemilihan variabel maupun hubungan antara variabel yang berdekatan. Keduanya memiliki aplikasi masing-masing tergantung pada struktur data dan tujuan analisis.
## Loading required package: Matrix
## Loaded glmnet 4.1-8
## Loading required package: survival
## Welcome to penalized. For extended examples, see vignette("penalized").
#Mengatur seed agar hasilnya dapat direproduksi
set.seed(123)
# Jumlah observasi (n) dan jumlah variabel prediktor (p)
n <- 50
p <- 100
# Membuat matriks X (n observasi, p variabel prediktor) dengan nilai acak dari distribusi normal
databangkit <- matrix(rnorm(n * p), nrow = n, ncol = p)
# Membuat koefisien beta yang sebagian besar nol (hanya 10 variabel pertama yang signifikan)
beta <- c(rep(5, 10), rep(0, 90))
# Membuat variabel respons Y dengan sedikit noise
res.y <- databangkit %*% beta + rnorm(n)Data simulasi yang digunakan sebanyak 50 observasi dan 100 variabel prediktor, di mana hanya 10 variabel pertama yang signifikan dalam memengaruhi respons \(Y\), dengan sedikit noise ditambahkan untuk membuat variabel respons lebih realistis.
##
## Call: glmnet(x = databangkit, y = res.y, alpha = 1)
##
## Df %Dev Lambda
## 1 0 0.00 5.7330
## 2 1 1.83 5.4720
## 3 2 4.53 5.2240
## 4 3 7.51 4.9860
## 5 3 10.57 4.7590
## 6 4 13.85 4.5430
## 7 4 16.95 4.3370
## 8 4 19.77 4.1400
## 9 6 23.09 3.9510
## 10 6 27.06 3.7720
## 11 6 30.67 3.6000
## 12 8 34.04 3.4370
## 13 9 37.25 3.2810
## 14 10 40.39 3.1310
## 15 10 43.60 2.9890
## 16 10 46.52 2.8530
## 17 10 49.18 2.7240
## 18 11 51.70 2.6000
## 19 12 54.25 2.4820
## 20 13 56.70 2.3690
## 21 14 59.10 2.2610
## 22 14 61.45 2.1580
## 23 15 63.76 2.0600
## 24 16 65.97 1.9670
## 25 17 68.12 1.8770
## 26 18 70.12 1.7920
## 27 18 71.98 1.7100
## 28 18 73.68 1.6330
## 29 20 75.36 1.5590
## 30 20 77.04 1.4880
## 31 21 78.57 1.4200
## 32 22 80.08 1.3560
## 33 22 81.49 1.2940
## 34 22 82.78 1.2350
## 35 22 83.95 1.1790
## 36 22 85.02 1.1250
## 37 23 85.99 1.0740
## 38 26 86.95 1.0250
## 39 26 87.94 0.9788
## 40 26 88.84 0.9343
## 41 26 89.66 0.8918
## 42 27 90.40 0.8513
## 43 27 91.12 0.8126
## 44 28 91.78 0.7757
## 45 28 92.37 0.7404
## 46 28 92.92 0.7068
## 47 28 93.42 0.6746
## 48 29 93.88 0.6440
## 49 30 94.33 0.6147
## 50 30 94.80 0.5868
## 51 30 95.24 0.5601
## 52 30 95.64 0.5346
## 53 30 96.00 0.5103
## 54 30 96.34 0.4871
## 55 30 96.64 0.4650
## 56 30 96.91 0.4439
## 57 30 97.16 0.4237
## 58 30 97.39 0.4044
## 59 30 97.60 0.3861
## 60 30 97.79 0.3685
## 61 31 97.97 0.3518
## 62 31 98.13 0.3358
## 63 31 98.27 0.3205
## 64 31 98.41 0.3059
## 65 31 98.53 0.2920
## 66 32 98.64 0.2788
## 67 32 98.74 0.2661
## 68 32 98.84 0.2540
## 69 33 98.92 0.2425
## 70 33 99.00 0.2314
## 71 33 99.07 0.2209
## 72 33 99.14 0.2109
## 73 33 99.20 0.2013
## 74 33 99.25 0.1921
## 75 33 99.30 0.1834
## 76 33 99.34 0.1751
## 77 35 99.39 0.1671
## 78 35 99.43 0.1595
## 79 37 99.47 0.1523
## 80 38 99.50 0.1453
## 81 38 99.54 0.1387
## 82 38 99.57 0.1324
## 83 39 99.60 0.1264
## 84 39 99.63 0.1207
## 85 39 99.66 0.1152
## 86 39 99.68 0.1099
## 87 41 99.70 0.1050
## 88 41 99.72 0.1002
## 89 41 99.74 0.0956
## 90 41 99.76 0.0913
## 91 41 99.77 0.0871
## 92 42 99.79 0.0832
## 93 42 99.80 0.0794
## 94 44 99.82 0.0758
## 95 45 99.83 0.0723
## 96 45 99.84 0.0690
## 97 45 99.85 0.0659
## 98 45 99.87 0.0629
## 99 45 99.87 0.0601
## 100 45 99.88 0.0573
# Cross-validation untuk memilih lambda terbaik
cv_lasso <- cv.glmnet(databangkit, res.y, alpha = 1)
cv_lasso##
## Call: cv.glmnet(x = databangkit, y = res.y, alpha = 1)
##
## Measure: Mean-Squared Error
##
## Lambda Index Measure SE Nonzero
## min 0.1152 85 53.96 20.86 39
## 1se 0.4439 56 74.35 21.16 30
## [1] 0.1151852
# Menampilkan koefisien yang dipilih dengan lambda terbaik
lasso_coefficients <- coef(cv_lasso, s = "lambda.min")
print(lasso_coefficients)## 101 x 1 sparse Matrix of class "dgCMatrix"
## s1
## (Intercept) 0.610666041
## V1 3.255840103
## V2 3.417384209
## V3 3.168281083
## V4 4.758433991
## V5 4.146259863
## V6 3.643707168
## V7 4.448818204
## V8 4.171173506
## V9 3.748820059
## V10 4.173667486
## V11 .
## V12 .
## V13 -0.464373128
## V14 0.600038619
## V15 0.146060383
## V16 .
## V17 .
## V18 .
## V19 .
## V20 0.344937929
## V21 -0.069934776
## V22 .
## V23 .
## V24 -0.766545005
## V25 .
## V26 .
## V27 0.057149645
## V28 .
## V29 .
## V30 .
## V31 .
## V32 .
## V33 -0.505757212
## V34 -0.102870319
## V35 .
## V36 .
## V37 -0.128805611
## V38 .
## V39 .
## V40 .
## V41 .
## V42 .
## V43 .
## V44 0.008973676
## V45 0.860154266
## V46 .
## V47 .
## V48 .
## V49 .
## V50 .
## V51 0.202475393
## V52 -0.463920093
## V53 0.240509670
## V54 .
## V55 .
## V56 .
## V57 .
## V58 0.265196903
## V59 .
## V60 .
## V61 -0.096929711
## V62 -0.247119053
## V63 .
## V64 .
## V65 .
## V66 .
## V67 .
## V68 0.219000482
## V69 .
## V70 .
## V71 .
## V72 .
## V73 .
## V74 -0.235785106
## V75 .
## V76 .
## V77 .
## V78 .
## V79 .
## V80 -0.299455486
## V81 0.040162583
## V82 0.515900881
## V83 -0.282952319
## V84 0.387052366
## V85 .
## V86 0.115805577
## V87 .
## V88 .
## V89 0.037639363
## V90 0.854867932
## V91 .
## V92 .
## V93 .
## V94 .
## V95 .
## V96 -0.775578180
## V97 .
## V98 .
## V99 .
## V100 .
# Menemukan variabel yang koefisiennya tidak nol
selected_variables <- which(lasso_coefficients != 0)
print(selected_variables) # Variabel-variabel yang terpilih## [1] 1 2 3 4 5 6 7 8 9 10 11 14 15 16 21 22 25 28 34 35 38 45 46 52 53
## [26] 54 59 62 63 69 75 81 82 83 84 85 87 90 91 97
Hasil ini menunjukkan bahwa model Lasso memilih 40 variabel yang memiliki koefisien tidak nol, yang berarti hanya variabel-variabel tersebut dianggap relevan dalam memprediksi respons \(Y\) di antara 100 variabel awal.
# Menghapus variabel yang disetel ke nol
filtered_X <- databangkit[, selected_variables[-1]] # -1 untuk tidak memasukkan intercept# Melakukan prediksi untuk model Lasso menggunakan predict()
predictions_lasso <- predict(cv_lasso, s = "lambda.min", newx = databangkit)## [1] 0.5485117
# Menghitung R-Squared untuk model Lasso
rs_res_lasso <- sum((res.y - predictions_lasso)^2) # Residual sum of squares (RSS)
rs_tot_lasso <- sum((res.y - mean(res.y))^2) # Total sum of squares (TSS)
r_squared_lasso <- 1 - (rs_res_lasso / rs_tot_lasso) # Hitung R-Squared
r_squared_lasso## [1] 0.996559
# Melatih model Fused Lasso
fused_lasso_model <- penalized(res.y, databangkit, lambda1 = 1, lambda2 = 0.5, model = "linear", fused = TRUE)## Penalized linear regression object
## 101 regression coefficients of which 57 are non-zero
##
## Loglikelihood = -13.74059
## L1 penalty = 52.5689 at lambda1 = 1
## L2 penalty = 5.749558 at lambda2 = 0.5
Melatih model Fused Lasso menggunakan penalti L1 dan penalti tambahan pada perbedaan antar-koefisien yang berdekatan, dengan tujuan menghasilkan koefisien yang halus untuk data prediktor, menggunakan parameter \(\lambda_1 = 1\) dan \(\lambda_2 = 0.5\).
# Mengambil koefisien dari model Fused Lasso
coefficients_fused_lasso <- coef(fused_lasso_model)
# Menemukan variabel yang koefisiennya tidak nol
selected_variables_fused <- which(coefficients_fused_lasso != 0)
# Menghapus variabel yang disetel ke nol
filtered_X_fused <- databangkit[, selected_variables_fused]
# Melakukan prediksi menggunakan model Fused Lasso
predictions_fused_lasso <- fitted(fused_lasso_model)
predictions_fused_lasso## 1 2 3 4 5 6
## 15.5686898 -5.8981006 -3.9951218 3.1124170 2.1726636 -6.2692894
## 7 8 9 10 11 12
## -8.7459625 -10.7124611 0.0150081 16.0451509 20.0282011 4.0483144
## 13 14 15 16 17 18
## -8.9687996 14.6019209 -7.2397451 25.2890488 9.3735827 -28.2890074
## 19 20 21 22 23 24
## 15.5682175 2.3836385 24.3337059 -12.0190290 -8.8682565 10.1904344
## 25 26 27 28 29 30
## -3.7990937 -15.7748084 17.9978838 -3.9396691 16.2145469 -20.2055702
## 31 32 33 34 35 36
## 9.9694794 10.9974548 9.8197549 -5.9128096 -3.1937666 -1.6729503
## 37 38 39 40 41 42
## 9.8903132 11.6310613 10.3260250 -2.3399766 1.9770031 5.0599942
## 43 44 45 46 47 48
## 22.7019528 -22.7319479 -3.9920391 1.8489008 13.4889852 -6.1438252
## 49 50
## -11.1837938 -18.1180699
# Menghitung MSE untuk model Fused Lasso
mse_fused_lasso <- mean((res.y - predictions_fused_lasso)^2)
mse_fused_lasso## [1] 0.1014435
# Menghitung R-Squared untuk model Fused Lasso
ss_res_fused <- sum((res.y - predictions_fused_lasso)^2)
ss_tot_fused <- sum((res.y - mean(res.y))^2)
r_squared_fused <- 1 - (ss_res_fused / ss_tot_fused)
r_squared_fused## [1] 0.9993636
## ADDITIONAL METRICS ##
# Function to calculate additional metrics
calculate_metrics <- function(actual, predicted) {
mae <- mae(actual, predicted)
rmse <- rmse(actual, predicted)
mape <- mape(actual, predicted)
aic <- AIC(lm(actual ~ predicted))
# Calculate adjusted R-squared
n <- length(actual)
p <- sum(coef(cv_lasso) != 0) - 1 # number of non-zero coefficients, excluding intercept
adj_r_squared <- 1 - ((1 - r_squared_lasso) * (n - 1) / (n - p - 1))
return(c(MAE = mae, RMSE = rmse, MAPE = mape, AIC = aic, Adj_R_Squared = adj_r_squared))
}
# Calculate metrics for Lasso
lasso_metrics <- calculate_metrics(res.y, predictions_lasso)
# Calculate metrics for Fused Lasso
fused_lasso_metrics <- calculate_metrics(res.y, predictions_fused_lasso)
# Combine results
results_extended <- data.frame(
Model = c("Lasso", "Fused Lasso"),
MSE = c(mse_lasso, mse_fused_lasso),
R_Squared = c(r_squared_lasso, r_squared_fused),
MAE = c(lasso_metrics["MAE"], fused_lasso_metrics["MAE"]),
RMSE = c(lasso_metrics["RMSE"], fused_lasso_metrics["RMSE"]),
MAPE = c(lasso_metrics["MAPE"], fused_lasso_metrics["MAPE"]),
AIC = c(lasso_metrics["AIC"], fused_lasso_metrics["AIC"]),
Adj_R_Squared = c(lasso_metrics["Adj_R_Squared"], fused_lasso_metrics["Adj_R_Squared"])
)
# Print extended results
print(results_extended)## Model MSE R_Squared MAE RMSE MAPE AIC
## 1 Lasso 0.5485117 0.9965590 0.5662305 0.7406158 0.14742066 95.63343
## 2 Fused Lasso 0.1014435 0.9993636 0.2546301 0.3185020 0.06454824 29.01590
## Adj_R_Squared
## 1 0.9911258
## 2 0.9911258
Mean Squared Error (MSE): Model Fused Lasso memiliki nilai MSE yang jauh lebih rendah (0.1014) dibandingkan Lasso (0.5485), menunjukkan bahwa Fused Lasso lebih akurat dalam memprediksi nilai data.
R-Squared: Nilai R-Squared Fused Lasso (0.9994) lebih tinggi dibandingkan Lasso (0.9966), yang menunjukkan bahwa model Fused Lasso lebih baik dalam menjelaskan variabilitas dalam data.
Mean Absolute Error (MAE): Fused Lasso juga memiliki nilai MAE yang lebih rendah (0.2546) dibandingkan Lasso (0.5662), yang berarti prediksi dari Fused Lasso lebih mendekati nilai sebenarnya.
Root Mean Squared Error (RMSE): Nilai RMSE Fused Lasso (0.3185) juga lebih rendah dibandingkan Lasso (0.7406), mengindikasikan bahwa Fused Lasso memiliki kesalahan prediksi yang lebih kecil.
Mean Absolute Percentage Error (MAPE): Model Fused Lasso memiliki nilai MAPE yang lebih kecil (0.0645) dibandingkan Lasso (0.1474), yang menunjukkan bahwa persentase kesalahan prediksi model Fused Lasso lebih rendah.
Akaike Information Criterion (AIC): Nilai AIC untuk Fused Lasso (29.0159) lebih rendah dari Lasso (95.6334), yang menunjukkan bahwa Fused Lasso adalah model yang lebih baik dalam hal keseimbangan antara kompleksitas model dan fit.
Adjusted R-Squared: Nilai Adjusted R-Squared untuk kedua model adalah sama (0.9911), menunjukkan bahwa keduanya memiliki kompleksitas yang seimbang dalam hal variabel bebas yang digunakan.
Kesimpulan Berdasarkan hasil evaluasi ini, model Fused Lasso menunjukkan performa yang lebih baik daripada model Lasso dalam berbagai metrik evaluasi. Dengan nilai MSE, MAE, RMSE, MAPE, dan AIC yang lebih rendah serta R-Squared yang lebih tinggi, Fused Lasso lebih akurat dan efisien dalam menangkap pola data.
# Calculate variable importance for Lasso
lasso_importance <- abs(coef(cv_lasso, s = "lambda.min"))[-1] # exclude intercept
lasso_importance <- sort(lasso_importance, decreasing = TRUE)
print("Top 10 most important variables for Lasso:")## [1] "Top 10 most important variables for Lasso:"
## [1] 4.758434 4.448818 4.173667 4.171174 4.146260 3.748820 3.643707 3.417384
## [9] 3.255840 3.168281
# Calculate variable importance for Fused Lasso
fused_lasso_importance <- abs(coefficients_fused_lasso)[-1] # exclude intercept
fused_lasso_importance <- sort(fused_lasso_importance, decreasing = TRUE)
print("Top 10 most important variables for Fused Lasso:")## [1] "Top 10 most important variables for Fused Lasso:"
##
## 4.998414 4.998414 4.921590 4.909101 4.783474 4.767874 4.767874 4.767874
##
## 4.722105 4.652445
## membuat plot
pred_df <- data.frame(
Actual =res.y,
Lasso_Pred = as.vector(predictions_lasso),
Fused_Pred = as.vector(predictions_fused_lasso )
)#lasso plot
ggplot(pred_df, aes(x = Actual, y = Lasso_Pred)) +
geom_point(color = "blue", alpha = 0.5) +
geom_smooth(method = "loess", color = "blue", se = FALSE) +
labs(title = "Prediksi Lasso vs Actual",
x = "Actual",
y = "Lasso Predicted") +
theme_minimal()## `geom_smooth()` using formula = 'y ~ x'
##fused lasso
ggplot(pred_df, aes(x = Actual, y = Fused_Pred)) +
geom_point(color = "red", alpha = 0.5) +
geom_smooth(method = "loess", color = "red", se = FALSE) +
labs(title = "Prediksi Fused Lasso vs Actual",
x = "Actual",
y = "Fused Lasso Predicted") +
theme_minimal()## `geom_smooth()` using formula = 'y ~ x'
residuals_lasso <- res.y - predictions_lasso
residuals_fused <- res.y - predictions_fused_lasso
residual_df <- data.frame(
Predicted = c(predictions_lasso, predictions_fused_lasso),
Residuals = c(residuals_lasso, residuals_fused),
Model = factor(rep(c("Lasso", "Fused Lasso"), each = length(res.y)))
)
residual_plot <- ggplot(residual_df, aes(x = Predicted, y = Residuals, color = Model)) +
geom_point(alpha = 0.7) +
geom_hline(yintercept = 0, linetype = "dashed", color = "black") +
facet_wrap(~ Model) +
labs(title = "Residual Plot", x = "Predicted Values", y = "Residuals") +
theme_minimal()
residual_plotBerdasarkan residual plot, model Fused Lasso menunjukkan distribusi residual yang lebih sempit dan terfokus di sekitar nol dibandingkan dengan model Lasso, yang memiliki penyebaran residual lebih lebar dan beberapa outlier ekstrem. Hal ini mengindikasikan bahwa Fused Lasso memberikan performa yang lebih stabil dengan prediksi yang lebih akurat dan kurang variabel, sementara Lasso lebih rentan terhadap prediksi ekstrem. Secara keseluruhan, Fused Lasso tampaknya lebih konsisten dalam menangkap pola data.
### Plot perbandingan prediksi
ggplot(pred_df) +
geom_point(aes(x = Actual, y = Lasso_Pred, color = "Lasso"), alpha = 0.5) +
geom_point(aes(x = Actual, y = Fused_Pred, color = "Fused Lasso"), alpha = 0.5) +
geom_line(aes(x = Actual, y = Actual, color = "Actual"), linetype = "dashed", size = 1) + # Menambahkan garis untuk data aktual
geom_smooth(aes(x = Actual, y = Lasso_Pred, color = "Lasso"), method = "loess", se = FALSE) +
geom_smooth(aes(x = Actual, y = Fused_Pred, color = "Fused Lasso"), method = "loess", se = FALSE) +
scale_color_manual(values = c("Lasso" = "purple", "Fused Lasso" = "red", "Actual" = "green")) + # Warna untuk masing-masing model
labs(title = "Perbandingan Prediksi Lasso, Fused Lasso, dan Data Aktual",
x = "Actual",
y = "Predicted",
color = "Model") + # Menambahkan keterangan untuk legend
theme_minimal()## Warning: Using `size` aesthetic for lines was deprecated in ggplot2 3.4.0.
## ℹ Please use `linewidth` instead.
## This warning is displayed once every 8 hours.
## Call `lifecycle::last_lifecycle_warnings()` to see where this warning was
## generated.
## `geom_smooth()` using formula = 'y ~ x'
## `geom_smooth()` using formula = 'y ~ x'
Berdasarkan plot perbandingan kedua model, didapatkan bahwa kedua model memiliki prediksi yang mendekati nilai aktual terlihat pada titik-titik yang menyebar mengikuti garis lurusnya pada masing-masing model. Semua garis (prediksi Lasso, Fused Lasso, dan data aktual) berada sangat dekat satu sama lain, mengikuti tren linear yang hampir sempurna. Ini menunjukkan bahwa kedua model memiliki performa yang baik dalam memprediksi nilai respons dengan kesalahan yang minimal meskipun pada plot terlihat bahwa Model Fused Lasso tampak lebih baik dibandingkan dengan Model Lasso karena terlihat bahwa pada model ini nilai prediksi lebih akurat dalam merepresentasikan nilai aktual (data yang dibangkitkan).