LATAR BELAKANG

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.

PERBEDAAN LASSO DAN FUSED LASSO

LASSO

  • Tujuan: Lasso (Least Absolute Shrinkage and Selection Operator) bertujuan untuk mengurangi kompleksitas model dan melakukan seleksi variabel.
  • Regulasi: Menggunakan penalti L1, yang berarti menambahkan jumlah absolut dari koefisien ke fungsi biaya. Ini cenderung mengatur beberapa koefisien menjadi nol, sehingga menghasilkan model yang lebih sederhana.
  • Kegunaan: Cocok untuk situasi di mana banyak variabel mungkin tidak relevan, sehingga membantu dalam memilih variabel yang paling penting. Rumus untuk regresi Lasso adalah:

\[ \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.

Fused Lasso

  • Tujuan: Fused lasso merupakan pengembangan dari lasso yang tidak hanya melakukan seleksi variabel, tetapi juga mempertimbangkan struktur atau ketergantungan antar variabel.
  • Regulasi: Menggunakan kombinasi penalti L1 (seperti lasso) dan penalti L2, yang mengukur perubahan antara koefisien yang berdekatan. Ini mendorong koefisien yang berdekatan untuk memiliki nilai yang serupa, sehingga baik dalam seleksi variabel dan pemodelan data yang teratur.
  • Kegunaan: Bermanfaat dalam konteks di mana ada urutan atau struktur dalam data, seperti data spasial atau temporal, di mana perubahan mendadak dalam nilai koefisien dapat menunjukkan fenomena yang signifikan.

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

  • \(\lambda_2\) adalah penalti pada perbedaan antara koefisien \(\beta_j\) dan \(\beta_{j-1}\).

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.

Kesimpulan

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.

MEMBANGKITKAN DATA

# Import Library
library(glmnet)
## Loading required package: Matrix
## Loaded glmnet 4.1-8
library(penalized)
## Loading required package: survival
## Welcome to penalized. For extended examples, see vignette("penalized").
library(ggplot2)
library(Metrics)
library(reshape2)
library(gridExtra)
#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.

MODEL LASSO

# Melatih model Lasso
lasso_model <- glmnet(databangkit, res.y, alpha = 1)
lasso_model
## 
## 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
plot(lasso_model)

# 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
# Mengambil lambda terbaik dari cross-validation
best_lambda <- cv_lasso$lambda.min
best_lambda
## [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)
# Menghitung MSE untuk model Lasso
mse_lasso <- mean((res.y - predictions_lasso)^2)
mse_lasso
## [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

MODEL FUSED LASSO

# Melatih model Fused Lasso
fused_lasso_model <- penalized(res.y, databangkit, lambda1 = 1, lambda2 = 0.5, model = "linear", fused = TRUE)
fused_lasso_model
## 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

GABUNGAN UJI KEBAIKAN MODEL

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

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

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

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

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

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

  7. 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:"
print(head(lasso_importance, 10))
##  [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:"
print(head(fused_lasso_importance, 10))
##                                                                         
## 4.998414 4.998414 4.921590 4.909101 4.783474 4.767874 4.767874 4.767874 
##                   
## 4.722105 4.652445

PLOT HASIL

## membuat plot
pred_df <- data.frame(
  Actual =res.y,
  Lasso_Pred = as.vector(predictions_lasso),
  Fused_Pred = as.vector(predictions_fused_lasso )
)

PLOT HASIL 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'

PLOT HASIL FUSED LASSO

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

RESIDUAL PLOT

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_plot

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

MENGGABUNGKAN PLOT

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