1 Setup Package

Sebelum memasuki tahap pengolahan data dan pemodelan, dilakukan persiapan lingkungan analisis menggunakan perangkat lunak R. Tahap ini mencakup pengaturan konfigurasi code chunk, penetapan nilai random seed, serta instalasi dan pemanggilan package yang dibutuhkan selama proses analisis.

Pengaturan awal dilakukan untuk memastikan proses analisis berjalan secara konsisten, meminimalkan gangguan pada tampilan output, serta mempermudah penyajian hasil dalam dokumen R Markdown.

1.1 Konfigurasi Analisis

Konfigurasi awal dilakukan melalui fungsi knitr::opts_chunk$set() untuk mengatur perilaku setiap code chunk dalam dokumen. Pada analisis ini, kode secara default ditampilkan, sedangkan pesan dan peringatan dari package disembunyikan agar hasil analisis terlihat lebih ringkas.

Selain itu, digunakan set.seed(2026) untuk menjaga konsistensi hasil dari proses yang melibatkan bilangan acak, seperti pembagian data menjadi data latih dan data uji.

1.2 Instalasi dan Pemanggilan Package

Analisis ini memanfaatkan beberapa package R yang memiliki fungsi berbeda, mulai dari pengolahan data, visualisasi, hingga pembentukan model Support Vector Regression (SVR).

Berikut merupakan package yang digunakan beserta fungsinya.

Package Fungsi
e1071 Membentuk model Support Vector Regression (SVR).
ggplot2 Membuat visualisasi data dan hasil analisis.
dplyr Melakukan manipulasi dan pengolahan data.
knitr Mendukung penyajian tabel dan output dalam dokumen R Markdown.
readr Membaca dan mengimpor data.
janitor Membersihkan dan merapikan nama kolom serta struktur data.
corrplot Memvisualisasikan matriks korelasi antarvariabel.

Sebelum digunakan, dilakukan pemeriksaan ketersediaan package pada sistem. Apabila terdapat package yang belum terpasang, R akan menginstalnya secara otomatis. Selanjutnya, seluruh package dipanggil menggunakan fungsi library() agar dapat digunakan dalam tahapan analisis berikutnya.

# Package yang digunakan
paket <- c(
  "e1071",
  "ggplot2",
  "dplyr",
  "knitr",
  "readr",
  "janitor",
  "corrplot"
)

# Instalasi package jika belum tersedia
belum <- paket[
  !vapply(paket, requireNamespace, logical(1), quietly = TRUE)
]

if (length(belum) > 0) {
  install.packages(belum, repos = "https://cloud.r-project.org")
}

# Memanggil package
library(e1071)
library(ggplot2)
library(dplyr)
library(knitr)
library(janitor)
library(corrplot)

2 Tujuan

  1. Menerapkan metode Support Vector Regression (SVR) untuk memprediksi nilai Human Development Index (HDI) berdasarkan enam variabel prediktor yang berasal dari indikator World Happiness.
  2. Melakukan eksplorasi dan analisis deskriptif untuk memahami karakteristik data yang digunakan dalam pemodelan SVR.
  3. Membangun dan membandingkan model SVR menggunakan kernel linear dan radial.
  4. Melakukan optimasi hyperparameter SVR menggunakan metode 5-Fold Cross Validation untuk memperoleh kombinasi parameter yang menghasilkan nilai kesalahan prediksi terkecil.
  5. Mengevaluasi dan membandingkan kinerja model SVR berdasarkan nilai Mean Absolute Error (MAE), Root Mean Squared Error (RMSE), dan koefisien determinasi (R²).

3 Import Data

3.1 Dataset Happiness

setwd("C:\\Users\\Lenovo\\Downloads\\output")

data <- read.csv("data_preprocessed.csv",
                     header = TRUE)


head(data)
##   Overall.rank Country.or.region Score GDP.per.capita Social.support
## 1            1           Finland 7.769          1.340          1.587
## 2            2           Denmark 7.600          1.383          1.573
## 3            3            Norway 7.554          1.488          1.582
## 4            4           Iceland 7.494          1.380          1.624
## 5            5       Netherlands 7.488          1.396          1.522
## 6            6       Switzerland 7.480          1.452          1.526
##   Healthy.life.expectancy Freedom.to.make.life.choices Generosity
## 1                   0.986                        0.596      0.153
## 2                   0.996                        0.592      0.252
## 3                   1.028                        0.603      0.271
## 4                   1.026                        0.591      0.354
## 5                   0.999                        0.557      0.322
## 6                   1.052                        0.572      0.263
##   Perceptions.of.corruption hdi_name    join_key   hdi
## 1                     0.393     <NA>     Finland 0.948
## 2                     0.410     <NA>     Denmark 0.962
## 3                     0.341     <NA>      Norway 0.970
## 4                     0.118     <NA>     Iceland 0.972
## 5                     0.298     <NA> Netherlands 0.955
## 6                     0.343     <NA> Switzerland 0.970
tail(data)
##     Overall.rank        Country.or.region Score GDP.per.capita Social.support
## 148          151                    Yemen 3.380          0.287          1.163
## 149          152                   Rwanda 3.334          0.359          0.711
## 150          153                 Tanzania 3.231          0.476          0.885
## 151          154              Afghanistan 3.203          0.350          0.517
## 152          155 Central African Republic 3.083          0.026          0.000
## 153          156              South Sudan 2.853          0.306          0.575
##     Healthy.life.expectancy Freedom.to.make.life.choices Generosity
## 148                   0.463                        0.143      0.108
## 149                   0.614                        0.555      0.217
## 150                   0.499                        0.417      0.276
## 151                   0.361                        0.000      0.158
## 152                   0.105                        0.225      0.235
## 153                   0.295                        0.010      0.202
##     Perceptions.of.corruption hdi_name                 join_key   hdi
## 148                     0.077     <NA>                    Yemen 0.470
## 149                     0.411     <NA>                   Rwanda 0.578
## 150                     0.147     <NA>                 Tanzania 0.555
## 151                     0.025     <NA>              Afghanistan 0.496
## 152                     0.035     <NA> Central African Republic 0.414
## 153                     0.091     <NA>              South Sudan 0.388
summary(data)
##   Overall.rank    Country.or.region      Score       GDP.per.capita  
##  Min.   :  1.00   Length:153         Min.   :2.853   Min.   :0.0000  
##  1st Qu.: 40.00   Class :character   1st Qu.:4.534   1st Qu.:0.5780  
##  Median : 80.00   Mode  :character   Median :5.339   Median :0.9600  
##  Mean   : 79.16                      Mean   :5.394   Mean   :0.8999  
##  3rd Qu.:118.00                      3rd Qu.:6.182   3rd Qu.:1.2210  
##  Max.   :156.00                      Max.   :7.769   Max.   :1.6840  
##  Social.support  Healthy.life.expectancy Freedom.to.make.life.choices
##  Min.   :0.000   Min.   :0.0000          Min.   :0.0000              
##  1st Qu.:1.055   1st Qu.:0.5380          1st Qu.:0.3050              
##  Median :1.274   Median :0.7890          Median :0.4170              
##  Mean   :1.207   Mean   :0.7217          Mean   :0.3921              
##  3rd Qu.:1.454   3rd Qu.:0.8810          3rd Qu.:0.5080              
##  Max.   :1.624   Max.   :1.1410          Max.   :0.6310              
##    Generosity     Perceptions.of.corruption   hdi_name        
##  Min.   :0.0000   Min.   :0.000             Length:153        
##  1st Qu.:0.1080   1st Qu.:0.047             Class :character  
##  Median :0.1770   Median :0.085             Mode  :character  
##  Mean   :0.1839   Mean   :0.111                               
##  3rd Qu.:0.2470   3rd Qu.:0.141                               
##  Max.   :0.5660   Max.   :0.453                               
##    join_key              hdi        
##  Length:153         Min.   :0.3880  
##  Class :character   1st Qu.:0.6170  
##  Mode  :character   Median :0.7760  
##                     Mean   :0.7455  
##                     3rd Qu.:0.8890  
##                     Max.   :0.9720
str(data)
## 'data.frame':    153 obs. of  12 variables:
##  $ Overall.rank                : int  1 2 3 4 5 6 7 8 9 10 ...
##  $ Country.or.region           : chr  "Finland" "Denmark" "Norway" "Iceland" ...
##  $ Score                       : num  7.77 7.6 7.55 7.49 7.49 ...
##  $ GDP.per.capita              : num  1.34 1.38 1.49 1.38 1.4 ...
##  $ Social.support              : num  1.59 1.57 1.58 1.62 1.52 ...
##  $ Healthy.life.expectancy     : num  0.986 0.996 1.028 1.026 0.999 ...
##  $ Freedom.to.make.life.choices: num  0.596 0.592 0.603 0.591 0.557 0.572 0.574 0.585 0.584 0.532 ...
##  $ Generosity                  : num  0.153 0.252 0.271 0.354 0.322 0.263 0.267 0.33 0.285 0.244 ...
##  $ Perceptions.of.corruption   : num  0.393 0.41 0.341 0.118 0.298 0.343 0.373 0.38 0.308 0.226 ...
##  $ hdi_name                    : chr  NA NA NA NA ...
##  $ join_key                    : chr  "Finland" "Denmark" "Norway" "Iceland" ...
##  $ hdi                         : num  0.948 0.962 0.97 0.972 0.955 0.97 0.959 0.938 0.939 0.93 ...

Berdasarkan hasil pemeriksaan awal, dataset yang digunakan terdiri atas 153 observasi dan 12 variabel. Variabel tersebut mencakup informasi peringkat negara, skor kebahagiaan, enam indikator prediktor, serta nilai HDI.

Hasil summary() menunjukkan bahwa nilai HDI memiliki rata-rata sebesar 0,7455, median sebesar 0,776, nilai minimum sebesar 0,388, dan maksimum sebesar 0,972. Hal ini menunjukkan bahwa nilai HDI pada observasi yang digunakan memiliki rentang yang cukup beragam.

Sementara itu, hasil str() menunjukkan bahwa keenam variabel prediktor dan variabel HDI memiliki tipe data numerik. Dengan demikian, variabel-variabel tersebut dapat digunakan dalam pemodelan SVR yang merupakan metode regresi untuk memprediksi respons numerik.

4 Pemeriksaan Data

# Mengecek Missing Value
colSums(is.na(data))
##                 Overall.rank            Country.or.region 
##                            0                            0 
##                        Score               GDP.per.capita 
##                            0                            0 
##               Social.support      Healthy.life.expectancy 
##                            0                            0 
## Freedom.to.make.life.choices                   Generosity 
##                            0                            0 
##    Perceptions.of.corruption                     hdi_name 
##                            0                          147 
##                     join_key                          hdi 
##                            0                            0
# Mengecek Duplikasi
sum(duplicated(data))
## [1] 0
# Dimensi data
dim(data)
## [1] 153  12
# Struktur data
str(data)
## 'data.frame':    153 obs. of  12 variables:
##  $ Overall.rank                : int  1 2 3 4 5 6 7 8 9 10 ...
##  $ Country.or.region           : chr  "Finland" "Denmark" "Norway" "Iceland" ...
##  $ Score                       : num  7.77 7.6 7.55 7.49 7.49 ...
##  $ GDP.per.capita              : num  1.34 1.38 1.49 1.38 1.4 ...
##  $ Social.support              : num  1.59 1.57 1.58 1.62 1.52 ...
##  $ Healthy.life.expectancy     : num  0.986 0.996 1.028 1.026 0.999 ...
##  $ Freedom.to.make.life.choices: num  0.596 0.592 0.603 0.591 0.557 0.572 0.574 0.585 0.584 0.532 ...
##  $ Generosity                  : num  0.153 0.252 0.271 0.354 0.322 0.263 0.267 0.33 0.285 0.244 ...
##  $ Perceptions.of.corruption   : num  0.393 0.41 0.341 0.118 0.298 0.343 0.373 0.38 0.308 0.226 ...
##  $ hdi_name                    : chr  NA NA NA NA ...
##  $ join_key                    : chr  "Finland" "Denmark" "Norway" "Iceland" ...
##  $ hdi                         : num  0.948 0.962 0.97 0.972 0.955 0.97 0.959 0.938 0.939 0.93 ...
# Variabel Data
names(data)
##  [1] "Overall.rank"                 "Country.or.region"           
##  [3] "Score"                        "GDP.per.capita"              
##  [5] "Social.support"               "Healthy.life.expectancy"     
##  [7] "Freedom.to.make.life.choices" "Generosity"                  
##  [9] "Perceptions.of.corruption"    "hdi_name"                    
## [11] "join_key"                     "hdi"
# Inspeksi Awal Data
glimpse(data)
## Rows: 153
## Columns: 12
## $ Overall.rank                 <int> 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13…
## $ Country.or.region            <chr> "Finland", "Denmark", "Norway", "Iceland"…
## $ Score                        <dbl> 7.769, 7.600, 7.554, 7.494, 7.488, 7.480,…
## $ GDP.per.capita               <dbl> 1.340, 1.383, 1.488, 1.380, 1.396, 1.452,…
## $ Social.support               <dbl> 1.587, 1.573, 1.582, 1.624, 1.522, 1.526,…
## $ Healthy.life.expectancy      <dbl> 0.986, 0.996, 1.028, 1.026, 0.999, 1.052,…
## $ Freedom.to.make.life.choices <dbl> 0.596, 0.592, 0.603, 0.591, 0.557, 0.572,…
## $ Generosity                   <dbl> 0.153, 0.252, 0.271, 0.354, 0.322, 0.263,…
## $ Perceptions.of.corruption    <dbl> 0.393, 0.410, 0.341, 0.118, 0.298, 0.343,…
## $ hdi_name                     <chr> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, N…
## $ join_key                     <chr> "Finland", "Denmark", "Norway", "Iceland"…
## $ hdi                          <dbl> 0.948, 0.962, 0.970, 0.972, 0.955, 0.970,…

Berdasarkan pemeriksaan missing value, ditemukan bahwa variabel hdi_name memiliki 147 nilai yang hilang. Namun, variabel tersebut tidak digunakan dalam analisis SVR sehingga tidak memengaruhi proses pemodelan. Seluruh variabel yang digunakan, yaitu enam variabel prediktor dan satu variabel respons HDI, tidak memiliki missing value.

Selain itu, hasil pemeriksaan duplikasi menunjukkan bahwa tidak terdapat observasi yang terduplikasi. Dataset juga memiliki dimensi 153 baris dan 12 kolom. Setelah dilakukan pemilihan variabel untuk pemodelan, diperoleh 153 observasi dengan tujuh variabel analisis.

Dengan demikian, data yang digunakan dalam pemodelan tidak memerlukan penanganan missing value maupun penghapusan data duplikat.

5 Membersihkan Nama Variabel

data <- data %>%
  clean_names()

names(data)
##  [1] "overall_rank"                 "country_or_region"           
##  [3] "score"                        "gdp_per_capita"              
##  [5] "social_support"               "healthy_life_expectancy"     
##  [7] "freedom_to_make_life_choices" "generosity"                  
##  [9] "perceptions_of_corruption"    "hdi_name"                    
## [11] "join_key"                     "hdi"

Tahapan ini dilakukan untuk menyeragamkan penamaan variabel agar lebih mudah digunakan dalam penulisan syntax R. Fungsi clean_names() mengubah nama variabel menjadi format huruf kecil dengan pemisah garis bawah (snake_case).

Sebagai contoh, variabel GDP.per.capita diubah menjadi gdp_per_capita. Proses ini tidak mengubah isi maupun nilai data, tetapi hanya mengubah format penamaan variabel.

6 Menentukan Variabel Prediktor dan Respons

6.1 Variabel Respons

Y <- data[, 
          c("hdi"
            )]

# Memeriksa dimensi
length(Y)
## [1] 153
# Melihat data
head(Y)
## [1] 0.948 0.962 0.970 0.972 0.955 0.970

6.2 Variabel Prediktor

X <- data[, c(
  "gdp_per_capita",
  "social_support",
  "healthy_life_expectancy",
  "freedom_to_make_life_choices",
  "generosity",
  "perceptions_of_corruption"
)]

dim(X)
## [1] 153   6
head(X)
##   gdp_per_capita social_support healthy_life_expectancy
## 1          1.340          1.587                   0.986
## 2          1.383          1.573                   0.996
## 3          1.488          1.582                   1.028
## 4          1.380          1.624                   1.026
## 5          1.396          1.522                   0.999
## 6          1.452          1.526                   1.052
##   freedom_to_make_life_choices generosity perceptions_of_corruption
## 1                        0.596      0.153                     0.393
## 2                        0.592      0.252                     0.410
## 3                        0.603      0.271                     0.341
## 4                        0.591      0.354                     0.118
## 5                        0.557      0.322                     0.298
## 6                        0.572      0.263                     0.343

7 Membentuk Dataset Variabel

data_svr <- data.frame(X,
                       hdi=Y)

# Melihat dataset analisis
head(data_svr)
##   gdp_per_capita social_support healthy_life_expectancy
## 1          1.340          1.587                   0.986
## 2          1.383          1.573                   0.996
## 3          1.488          1.582                   1.028
## 4          1.380          1.624                   1.026
## 5          1.396          1.522                   0.999
## 6          1.452          1.526                   1.052
##   freedom_to_make_life_choices generosity perceptions_of_corruption   hdi
## 1                        0.596      0.153                     0.393 0.948
## 2                        0.592      0.252                     0.410 0.962
## 3                        0.603      0.271                     0.341 0.970
## 4                        0.591      0.354                     0.118 0.972
## 5                        0.557      0.322                     0.298 0.955
## 6                        0.572      0.263                     0.343 0.970
# Melihat dimensi data
dim(data_svr)
## [1] 153   7
# Memeriksa struktur data
str(data_svr)
## 'data.frame':    153 obs. of  7 variables:
##  $ gdp_per_capita              : num  1.34 1.38 1.49 1.38 1.4 ...
##  $ social_support              : num  1.59 1.57 1.58 1.62 1.52 ...
##  $ healthy_life_expectancy     : num  0.986 0.996 1.028 1.026 0.999 ...
##  $ freedom_to_make_life_choices: num  0.596 0.592 0.603 0.591 0.557 0.572 0.574 0.585 0.584 0.532 ...
##  $ generosity                  : num  0.153 0.252 0.271 0.354 0.322 0.263 0.267 0.33 0.285 0.244 ...
##  $ perceptions_of_corruption   : num  0.393 0.41 0.341 0.118 0.298 0.343 0.373 0.38 0.308 0.226 ...
##  $ hdi                         : num  0.948 0.962 0.97 0.972 0.955 0.97 0.959 0.938 0.939 0.93 ...

Pada penelitian ini, variabel respons yang digunakan adalah HDI (hdi), sedangkan variabel prediktor terdiri atas enam indikator dari World Happiness, yaitu GDP per capita, Social support, Healthy life expectancy, Freedom to make life choices, Generosity, dan Perceptions of corruption.

Pemilihan HDI sebagai variabel respons didasarkan pada tujuan analisis, yaitu membangun model yang dapat memprediksi nilai HDI berdasarkan indikator-indikator tersebut. Keenam prediktor digunakan secara bersamaan untuk menangkap informasi yang berpotensi berkaitan dengan variasi nilai HDI.

Selanjutnya, seluruh variabel digabungkan ke dalam satu dataset analisis yang terdiri atas 153 observasi dan tujuh variabel.

8 Pemeriksaan Tipe Data dan Missing Value

# Memastikan seluruh variabel numerik
sapply(data_svr, is.numeric)
##               gdp_per_capita               social_support 
##                         TRUE                         TRUE 
##      healthy_life_expectancy freedom_to_make_life_choices 
##                         TRUE                         TRUE 
##                   generosity    perceptions_of_corruption 
##                         TRUE                         TRUE 
##                          hdi 
##                         TRUE
# Menghitung missing value
colSums(is.na(data_svr))
##               gdp_per_capita               social_support 
##                            0                            0 
##      healthy_life_expectancy freedom_to_make_life_choices 
##                            0                            0 
##                   generosity    perceptions_of_corruption 
##                            0                            0 
##                          hdi 
##                            0
# Menghitung persentase missing value
round(
  colMeans(is.na(data_svr)) * 100,
  2
)
##               gdp_per_capita               social_support 
##                            0                            0 
##      healthy_life_expectancy freedom_to_make_life_choices 
##                            0                            0 
##                   generosity    perceptions_of_corruption 
##                            0                            0 
##                          hdi 
##                            0
# Menghitung total missing value
sum(is.na(data_svr))
## [1] 0
# Menghapus observasi yang memiliki missing value
data_svr <- data_svr[
  complete.cases(data_svr),
]

# Memeriksa kembali missing value
colSums(is.na(data_svr))
##               gdp_per_capita               social_support 
##                            0                            0 
##      healthy_life_expectancy freedom_to_make_life_choices 
##                            0                            0 
##                   generosity    perceptions_of_corruption 
##                            0                            0 
##                          hdi 
##                            0
# Memeriksa dimensi setelah pembersihan
dim(data_svr)
## [1] 153   7

Berdasarkan hasil pemeriksaan tipe data, seluruh variabel yang digunakan dalam analisis memiliki tipe numerik. Hal ini sesuai dengan kebutuhan metode SVR karena variabel respons yang diprediksi berupa data kontinu.

Hasil pemeriksaan lanjutan juga menunjukkan bahwa tidak terdapat missing value pada ketujuh variabel analisis. Oleh karena itu, seluruh 153 observasi dapat dipertahankan dan digunakan dalam tahapan analisis selanjutnya tanpa perlu melakukan imputasi atau penghapusan observasi.

9 Analisis Deskriptif dan Eksplorasi Data

9.1 Statistik Deskriptif

# Ringkasan statistik
summary(data_svr)
##  gdp_per_capita   social_support  healthy_life_expectancy
##  Min.   :0.0000   Min.   :0.000   Min.   :0.0000         
##  1st Qu.:0.5780   1st Qu.:1.055   1st Qu.:0.5380         
##  Median :0.9600   Median :1.274   Median :0.7890         
##  Mean   :0.8999   Mean   :1.207   Mean   :0.7217         
##  3rd Qu.:1.2210   3rd Qu.:1.454   3rd Qu.:0.8810         
##  Max.   :1.6840   Max.   :1.624   Max.   :1.1410         
##  freedom_to_make_life_choices   generosity     perceptions_of_corruption
##  Min.   :0.0000               Min.   :0.0000   Min.   :0.000            
##  1st Qu.:0.3050               1st Qu.:0.1080   1st Qu.:0.047            
##  Median :0.4170               Median :0.1770   Median :0.085            
##  Mean   :0.3921               Mean   :0.1839   Mean   :0.111            
##  3rd Qu.:0.5080               3rd Qu.:0.2470   3rd Qu.:0.141            
##  Max.   :0.6310               Max.   :0.5660   Max.   :0.453            
##       hdi        
##  Min.   :0.3880  
##  1st Qu.:0.6170  
##  Median :0.7760  
##  Mean   :0.7455  
##  3rd Qu.:0.8890  
##  Max.   :0.9720
# Statistik deskriptif
stat_deskriptif <- data.frame(
  Variabel = names(data_svr),

  Mean = sapply(data_svr, mean),

  Median = sapply(data_svr, median),

  SD = sapply(data_svr, sd),

  Minimum = sapply(data_svr, min),

  Maksimum = sapply(data_svr, max)
)

# Membulatkan hasil
stat_deskriptif[, -1] <- round(
  stat_deskriptif[, -1],
  4
)

# Menampilkan tabel
kable(
  stat_deskriptif,
  caption = "Statistik Deskriptif Variabel Penelitian"
)
Statistik Deskriptif Variabel Penelitian
Variabel Mean Median SD Minimum Maksimum
gdp_per_capita gdp_per_capita 0.8999 0.960 0.3995 0.000 1.684
social_support social_support 1.2069 1.274 0.3016 0.000 1.624
healthy_life_expectancy healthy_life_expectancy 0.7217 0.789 0.2426 0.000 1.141
freedom_to_make_life_choices freedom_to_make_life_choices 0.3921 0.417 0.1444 0.000 0.631
generosity generosity 0.1839 0.177 0.0959 0.000 0.566
perceptions_of_corruption perceptions_of_corruption 0.1110 0.085 0.0950 0.000 0.453
hdi hdi 0.7455 0.776 0.1596 0.388 0.972

Secara keseluruhan, nilai rata-rata dan median pada beberapa variabel memiliki perbedaan yang relatif kecil. Namun, pada variabel tertentu, seperti GDP per capita, terdapat perbedaan antara rata-rata sebesar 0,8999 dan median sebesar 0,9600. Hal ini memberikan gambaran bahwa distribusi data tidak selalu simetris.

Nilai standar deviasi juga menunjukkan tingkat keragaman masing-masing variabel. Semakin besar standar deviasi, semakin besar variasi data terhadap nilai rata-ratanya. Pada data ini, GDP per capita memiliki standar deviasi sebesar 0,3995, sedangkan Generosity memiliki standar deviasi sebesar 0,0959.

9.2 Visualisasi Distribusi Data

par(mfrow = c(2, 4))

for (i in 1:ncol(data_svr)) {
  hist(
    data_svr[[i]],
    main = names(data_svr)[i],
    xlab = names(data_svr)[i],
    col = "skyblue",
    border = "white"
  )
}

par(mfrow = c(1, 1))

Histogram digunakan untuk melihat bagaimana nilai setiap variabel tersebar dalam dataset. Melalui histogram, dapat diamati konsentrasi data, bentuk distribusi, serta kemungkinan adanya kemencengan distribusi (skewness).

Visualisasi ini membantu memberikan gambaran awal mengenai karakteristik data sebelum dilakukan pemodelan SVR. Namun, bentuk distribusi setiap variabel tidak harus mengikuti distribusi normal karena SVR tidak mensyaratkan asumsi normalitas seperti beberapa metode statistik parametrik.

9.3 Identifikasi Outlier

par(mfrow = c(2, 4))

for (i in 1:ncol(data_svr)) {
  boxplot(
    data_svr[[i]],
    main = names(data_svr)[i],
    ylab = "Nilai",
    col = "lightgreen"
  )
}

par(mfrow = c(1, 1))

Boxplot digunakan untuk mengidentifikasi kemungkinan adanya pencilan (outlier) pada masing-masing variabel. Pencilan ditunjukkan melalui titik-titik yang berada di luar batas whisker boxplot.

Keberadaan pencilan perlu diperhatikan karena nilai ekstrem dapat memengaruhi proses pembentukan model dan hasil prediksi. Meskipun demikian, pencilan tidak secara otomatis harus dihapus, melainkan perlu dipertimbangkan berdasarkan karakteristik dan konteks datanya.

9.4 Analisis Korelasi

cor_matrix <- cor(
  data_svr,
  method = "pearson",
  use = "complete.obs"
)

# Menampilkan matriks korelasi
round(cor_matrix, 3)
##                              gdp_per_capita social_support
## gdp_per_capita                        1.000          0.755
## social_support                        0.755          1.000
## healthy_life_expectancy               0.834          0.721
## freedom_to_make_life_choices          0.384          0.450
## generosity                           -0.085         -0.052
## perceptions_of_corruption             0.300          0.184
## hdi                                   0.948          0.771
##                              healthy_life_expectancy
## gdp_per_capita                                 0.834
## social_support                                 0.721
## healthy_life_expectancy                        1.000
## freedom_to_make_life_choices                   0.394
## generosity                                    -0.034
## perceptions_of_corruption                      0.296
## hdi                                            0.903
##                              freedom_to_make_life_choices generosity
## gdp_per_capita                                      0.384     -0.085
## social_support                                      0.450     -0.052
## healthy_life_expectancy                             0.394     -0.034
## freedom_to_make_life_choices                        1.000      0.269
## generosity                                          0.269      1.000
## perceptions_of_corruption                           0.446      0.335
## hdi                                                 0.396     -0.083
##                              perceptions_of_corruption    hdi
## gdp_per_capita                                   0.300  0.948
## social_support                                   0.184  0.771
## healthy_life_expectancy                          0.296  0.903
## freedom_to_make_life_choices                     0.446  0.396
## generosity                                       0.335 -0.083
## perceptions_of_corruption                        1.000  0.287
## hdi                                              0.287  1.000
# Visualisasi
library(corrplot)

corrplot(
  cor_matrix,
  method = "color",
  type = "upper",
  addCoef.col = "black",
  tl.col = "black",
  tl.srt = 45,
  number.cex = 0.7
)

Dari hasil tersebut, GDP per capita memiliki hubungan linear positif paling kuat dengan HDI, yaitu sebesar 0,948, diikuti oleh Healthy life expectancy sebesar 0,903. Hal ini menunjukkan bahwa pada dataset yang digunakan, negara dengan nilai GDP per capita dan harapan hidup sehat yang lebih tinggi cenderung memiliki nilai HDI yang lebih tinggi pula.

Sebaliknya, Generosity memiliki korelasi sebesar -0,083, yang menunjukkan hubungan linear negatif sangat lemah dengan HDI. Sementara itu, Perceptions of corruption memiliki korelasi positif sebesar 0,287.

Perlu diperhatikan bahwa korelasi hanya menggambarkan kekuatan dan arah hubungan linear antarvariabel, sehingga tidak dapat langsung diartikan sebagai hubungan sebab-akibat. Selain itu, korelasi yang rendah tidak serta-merta menunjukkan bahwa suatu variabel tidak berguna dalam pemodelan SVR karena SVR juga dapat menangkap pola hubungan nonlinier.

9.5 Scatterplot Prediktor terhadap HDI

par(mfrow = c(2, 3))

for (i in 1:ncol(X)) {
  plot(
    X[[i]],
    Y,
    main = paste(names(X)[i], "vs HDI"),
    xlab = names(X)[i],
    ylab = "HDI",
    pch = 19,
    col = "steelblue"
  )

  # Menambahkan garis regresi linear
  abline(
    lm(Y ~ X[[i]]),
    col = "red",
    lwd = 2
  )
}

par(mfrow = c(1, 1))

Scatterplot digunakan untuk mengamati pola hubungan antara setiap variabel prediktor dengan HDI secara visual. Garis merah pada masing-masing grafik merupakan garis regresi linear yang membantu menunjukkan arah kecenderungan hubungan.

Visualisasi ini dapat digunakan untuk melihat apakah hubungan antara prediktor dan HDI cenderung meningkat, menurun, atau memiliki pola yang tidak sepenuhnya linear. Hasil eksplorasi ini menjadi salah satu pertimbangan awal dalam membandingkan penggunaan kernel linear dan radial pada SVR.

10 Pemodelan SVR

10.1 Menentukan Formula Model

# Formula enam prediktor
vars_x <- c(
  "gdp_per_capita",
  "social_support",
  "healthy_life_expectancy",
  "freedom_to_make_life_choices",
  "generosity",
  "perceptions_of_corruption"
)

form6 <- reformulate(
  vars_x,
  response = "hdi"
)

form6
## hdi ~ gdp_per_capita + social_support + healthy_life_expectancy + 
##     freedom_to_make_life_choices + generosity + perceptions_of_corruption

Formula model digunakan untuk mendefinisikan HDI sebagai variabel respons yang diprediksi berdasarkan enam variabel prediktor. Dengan demikian, seluruh indikator Happiness dimasukkan secara bersamaan ke dalam model SVR.

10.2 Membagi Data Training dan Testing

set.seed(123)

# Menentukan jumlah data training
n <- nrow(data_svr)

# Membagi data dengan promosi 80 : 20
index_train <- sample(
  seq_len(n),
  size = floor(0.8 * n)
)

# Membentuk data training dan testing
train_hdi <- data_svr[index_train, ]
test_hdi <- data_svr[-index_train, ]

# Memeriksa jumlah observasi
cat("Jumlah data training:", nrow(train_hdi), "\n")
## Jumlah data training: 122
cat("Jumlah data testing:", nrow(test_hdi), "\n")
## Jumlah data testing: 31

Dataset dibagi menjadi dua bagian dengan proporsi 80:20. Sebanyak 122 observasi digunakan sebagai data training untuk membentuk model, sedangkan 31 observasi digunakan sebagai data testing untuk mengevaluasi kemampuan model dalam memprediksi data yang belum digunakan pada proses pelatihan.

Pembagian ini dilakukan agar evaluasi model dapat memberikan gambaran mengenai kemampuan generalisasi model terhadap data baru.

10.3 Membentuk Model SVR Linear

fit_linear6 <- svm(
  hdi ~ gdp_per_capita + social_support +
    healthy_life_expectancy + freedom_to_make_life_choices +
    generosity + perceptions_of_corruption,
  data = train_hdi,
  type = "eps-regression",
  kernel = "linear",
  cost = 1,
  epsilon = 0.05,
  scale = TRUE
)

# Melihat hasil model
summary(fit_linear6)
## 
## Call:
## svm(formula = hdi ~ gdp_per_capita + social_support + healthy_life_expectancy + 
##     freedom_to_make_life_choices + generosity + perceptions_of_corruption, 
##     data = train_hdi, type = "eps-regression", kernel = "linear", 
##     cost = 1, epsilon = 0.05, scale = TRUE)
## 
## 
## Parameters:
##    SVM-Type:  eps-regression 
##  SVM-Kernel:  linear 
##        cost:  1 
##       gamma:  0.1666667 
##     epsilon:  0.05 
## 
## 
## Number of Support Vectors:  102

Model SVR Linear dibangun menggunakan kernel linear dengan parameter cost = 1 dan epsilon = 0.05. Kernel linear digunakan untuk membentuk model berdasarkan pola hubungan yang bersifat linear dalam ruang fitur.

Berdasarkan hasil ringkasan model, diperoleh jumlah support vectors sebanyak 102. Support vectors merupakan observasi yang berperan dalam menentukan fungsi regresi SVR. Dengan kata lain, observasi tersebut menjadi bagian penting dalam pembentukan model.

10.4 Membangun SVR Radial

fit_radial6 <- svm(
  hdi ~ gdp_per_capita + social_support +
    healthy_life_expectancy + freedom_to_make_life_choices +
    generosity + perceptions_of_corruption,
  data = train_hdi,
  type = "eps-regression",
  kernel = "radial",
  cost = 1,
  epsilon = 0.05,
  scale = TRUE
)

# Melihat hasil model
summary(fit_radial6)
## 
## Call:
## svm(formula = hdi ~ gdp_per_capita + social_support + healthy_life_expectancy + 
##     freedom_to_make_life_choices + generosity + perceptions_of_corruption, 
##     data = train_hdi, type = "eps-regression", kernel = "radial", 
##     cost = 1, epsilon = 0.05, scale = TRUE)
## 
## 
## Parameters:
##    SVM-Type:  eps-regression 
##  SVM-Kernel:  radial 
##        cost:  1 
##       gamma:  0.1666667 
##     epsilon:  0.05 
## 
## 
## Number of Support Vectors:  100

Model SVR Radial dibangun menggunakan kernel radial atau Radial Basis Function (RBF), dengan nilai parameter cost = 1 dan epsilon = 0.05.

Berbeda dengan kernel linear, kernel radial memungkinkan model menangkap pola hubungan nonlinier antara variabel prediktor dan respons. Berdasarkan hasil ringkasan model, diperoleh jumlah support vectors sebanyak 100 observasi.

Jumlah support vectors pada kedua model tidak secara langsung menunjukkan model mana yang lebih baik. Kinerja keduanya perlu dibandingkan melalui hasil prediksi dan metrik evaluasi pada data testing.

11 Evaluasi Model Baseline

11.1 Membuat Fungsi Evaluasi

metrik_svr <- function(actual, predicted) {

  MAE <- mean(abs(actual - predicted))

  RMSE <- sqrt(mean((actual - predicted)^2))

  R2 <- if (sum((actual - mean(actual))^2) > 0) {
    1 - sum((actual - predicted)^2) /
      sum((actual - mean(actual))^2)
  } else {
    NA_real_
  }

  return(c(
    MAE = MAE,
    RMSE = RMSE,
    R2 = R2
  ))
}

11.2 Melakukan Prediksi

# Prediksi SVR Linear
pred_linear <- predict(
  fit_linear6,
  newdata = test_hdi
)

# Prediksi SVR Radial
pred_radial <- predict(
  fit_radial6,
  newdata = test_hdi
)

# Membandingkan nilai aktual dan prediksi
hasil_prediksi <- data.frame(
  Aktual = test_hdi$hdi,
  Prediksi_Linear = as.numeric(pred_linear),
  Prediksi_Radial = as.numeric(pred_radial)
)

head(hasil_prediksi)
##   Aktual Prediksi_Linear Prediksi_Radial
## 1  0.948       0.9304751       0.8822071
## 2  0.962       0.9439617       0.9230815
## 3  0.970       0.9777317       0.9457098
## 4  0.958       0.9496924       0.9522328
## 5  0.951       0.9331535       0.9252848
## 6  0.938       0.9248696       0.9253091

11.3 Evaluasi Model Baseline

# Evaluasi model linear
eval_linear <- metrik_svr(
  test_hdi$hdi,
  pred_linear
)

# Evaluasi model radial
eval_radial <- metrik_svr(
  test_hdi$hdi,
  pred_radial
)

# Membuat tabel perbandingan
hasil_evaluasi <- data.frame(
  Model = c("SVR Linear", "SVR Radial"),

  MAE = c(
    eval_linear["MAE"],
    eval_radial["MAE"]
  ),

  RMSE = c(
    eval_linear["RMSE"],
    eval_radial["RMSE"]
  ),

  R2 = c(
    eval_linear["R2"],
    eval_radial["R2"]
  )
)

kable(
  hasil_evaluasi,
  digits = 4,
  caption = "Perbandingan Kinerja Model SVR Baseline"
)
Perbandingan Kinerja Model SVR Baseline
Model MAE RMSE R2
SVR Linear 0.0286 0.0372 0.9213
SVR Radial 0.0312 0.0384 0.9163

Interpretasinya: - MAE (Mean Absolute Error) menunjukkan rata-rata selisih absolut antara nilai HDI aktual dan hasil prediksi. Model SVR Linear menghasilkan MAE sebesar 0,0286, yang berarti rata-rata kesalahan absolut prediksinya sekitar 0,0286. - RMSE (Root Mean Squared Error) mengukur besarnya kesalahan prediksi dengan memberikan penalti lebih besar terhadap kesalahan yang besar. Model SVR Linear menghasilkan RMSE sebesar 0,0372, lebih rendah dibandingkan model radial sebesar 0,0384. - R² (Koefisien Determinasi) menggambarkan kemampuan model dalam menjelaskan variasi nilai respons pada data testing. Model SVR Linear menghasilkan R² sebesar 0,9213, sedangkan SVR Radial menghasilkan 0,9163. Berdasarkan ketiga metrik tersebut, model SVR Linear memberikan kinerja yang sedikit lebih baik dibandingkan SVR Radial pada kondisi baseline. Hal ini ditunjukkan oleh nilai MAE dan RMSE yang lebih rendah serta nilai R² yang lebih tinggi.

Hasil ini menunjukkan bahwa penggunaan kernel radial yang lebih fleksibel untuk menangkap pola nonlinier belum tentu menghasilkan prediksi yang lebih baik.

12 Tuning Hyperparameter Menggunakan 5-Fold Cross Validation

12.1 Menentukan Fold Cross-Validation

Data training dibagi menjadi lima kelompok (fold) dengan jumlah observasi masing-masing sebanyak 25, 25, 24, 24, dan 24. Proses ini dilakukan untuk mengevaluasi kombinasi hyperparameter secara berulang sehingga penilaian model tidak hanya bergantung pada satu pembagian data training dan validasi.

Pada setiap iterasi, empat fold digunakan untuk melatih model, sedangkan satu fold lainnya digunakan untuk validasi. Proses tersebut dilakukan sebanyak lima kali sehingga setiap fold memperoleh kesempatan menjadi data validasi.

set.seed(123)

# Membagi training set menjadi 5 fold
fold_id <- sample(
  rep(1:5, length.out = nrow(train_hdi))
)

# Melihat jumlah observasi setiap fold
table(fold_id)
## fold_id
##  1  2  3  4  5 
## 25 25 24 24 24

12.2 Menentukan Kombinasi Hyperparameter

Tuning dilakukan dengan menguji beberapa kombinasi nilai cost, epsilon, dan gamma untuk kernel yang sesuai. - cost: mengatur besarnya penalti terhadap kesalahan prediksi yang berada di luar epsilon tube. - epsilon: menentukan lebar toleransi kesalahan prediksi yang tidak dikenai penalti dalam fungsi loss SVR. - gamma: mengatur jangkauan pengaruh observasi pada kernel radial. Parameter ini tidak digunakan untuk kernel linear. Dalam penelitian ini, terdapat sembilan kombinasi parameter untuk kernel linear dan 27 kombinasi untuk kernel radial. Dengan demikian, total terdapat 36 kombinasi hyperparameter yang dievaluasi.

# Grid untuk kernel linear
grid_linear <- expand.grid(
  kernel = "linear",
  cost = c(0.1, 1, 10),
  epsilon = c(0.02, 0.05, 0.1),
  gamma = NA_real_
)

# Grid untuk kernel radial
grid_radial <- expand.grid(
  kernel = "radial",
  cost = c(0.1, 1, 10),
  epsilon = c(0.02, 0.05, 0.1),
  gamma = c(0.05, 0.2, 1)
)

# Menggabungkan seluruh kombinasi
grid <- rbind(
  grid_linear,
  grid_radial
)

# Melihat jumlah kombinasi
nrow(grid)
## [1] 36
# Melihat kombinasi parameter
head(grid)
##   kernel cost epsilon gamma
## 1 linear  0.1    0.02    NA
## 2 linear  1.0    0.02    NA
## 3 linear 10.0    0.02    NA
## 4 linear  0.1    0.05    NA
## 5 linear  1.0    0.05    NA
## 6 linear 10.0    0.05    NA

12.3 Membuat Fungsi Cross-Validation

cv_rmse <- function(
  kernel,
  cost,
  epsilon,
  gamma,
  formula,
  dataset
) {

  hasil_fold <- vapply(1:5, function(k) {

    # Membagi data training dan validasi
    d_train <- dataset[fold_id != k, ]
    d_valid <- dataset[fold_id == k, ]

    # Menentukan parameter model
    args <- list(
      formula = formula,
      data = d_train,
      type = "eps-regression",
      kernel = kernel,
      cost = cost,
      epsilon = epsilon,
      scale = TRUE
    )

    # Gamma hanya digunakan untuk kernel radial
    if (kernel == "radial") {
      args$gamma <- gamma
    }

    # Membentuk model
    fit <- do.call(
      e1071::svm,
      args
    )

    # Prediksi data validasi
    pred <- predict(
      fit,
      newdata = d_valid
    )

    # Menghitung RMSE
    sqrt(mean(
      (d_valid$hdi - pred)^2
    ))

  }, numeric(1))

  return(hasil_fold)
}

12.4 Melakukan Tuning Hyperparameter

# Menghitung rata-rata RMSE untuk setiap kombinasi
grid$CV_RMSE <- vapply(
  seq_len(nrow(grid)),
  function(i) {

    hasil <- cv_rmse(
      kernel = grid$kernel[i],
      cost = grid$cost[i],
      epsilon = grid$epsilon[i],
      gamma = grid$gamma[i],
      formula = form6,
      dataset = train_hdi
    )

    mean(hasil)

  },
  numeric(1)
)

# Mengurutkan berdasarkan RMSE terkecil
grid <- grid[
  order(grid$CV_RMSE),
]

# Menampilkan 10 kombinasi terbaik
kable(
  head(grid, 10),
  digits = 4,
  caption = "10 Kombinasi Hyperparameter Terbaik Berdasarkan 5-Fold CV"
)
10 Kombinasi Hyperparameter Terbaik Berdasarkan 5-Fold CV
kernel cost epsilon gamma CV_RMSE
7 linear 0.1 0.10 NA 0.0407
8 linear 1.0 0.10 NA 0.0409
5 linear 1.0 0.05 NA 0.0409
9 linear 10.0 0.10 NA 0.0409
6 linear 10.0 0.05 NA 0.0410
2 linear 1.0 0.02 NA 0.0411
3 linear 10.0 0.02 NA 0.0412
1 linear 0.1 0.02 NA 0.0412
4 linear 0.1 0.05 NA 0.0412
18 radial 10.0 0.10 0.05 0.0429

Berdasarkan hasil 5-Fold Cross Validation, sepuluh kombinasi terbaik didominasi oleh kernel linear. Kombinasi dengan nilai RMSE validasi terkecil adalah kernel linear dengan cost = 0.1 dan epsilon = 0.1, yang menghasilkan rata-rata CV RMSE sebesar 0,0407.

Hasil ini menunjukkan bahwa berdasarkan kombinasi parameter yang diuji, kernel linear memberikan kesalahan prediksi validasi yang lebih kecil dibandingkan kombinasi kernel radial yang tercantum dalam sepuluh peringkat terbaik.

12.5 Menentukan Model Terbaik

# Mengambil kombinasi parameter terbaik
best <- grid[1, ]

# Menampilkan parameter terbaik
best
##   kernel cost epsilon gamma    CV_RMSE
## 7 linear  0.1     0.1    NA 0.04073721
# Menyiapkan parameter model
args_best <- list(
  formula = form6,
  data = train_hdi,
  type = "eps-regression",
  kernel = best$kernel,
  cost = best$cost,
  epsilon = best$epsilon,
  scale = TRUE
)

# Menambahkan gamma jika menggunakan radial
if (best$kernel == "radial") {
  args_best$gamma <- best$gamma
}

# Membentuk model terbaik
best_fit <- do.call(
  e1071::svm,
  args_best
)

# Melihat ringkasan model
summary(best_fit)
## 
## Call:
## svm(formula = hdi ~ gdp_per_capita + social_support + healthy_life_expectancy + 
##     freedom_to_make_life_choices + generosity + perceptions_of_corruption, 
##     data = structure(list(gdp_per_capita = c(1.609, 1.05, 0.512, 
##     1.258, 0.306, 0.35, 1.029, 0.741, 0.619, 0.813, 0.755, 0.393, 
##     1.155, 0.8, 1.387, 0.366, 1.067, 0.983, 0.476, 0.96, 0.308, 1.183, 
##     1.124, 0, 0.274, 1.365, 1.238, 1.015, 1.07, 1.403, 1.201, 1.237, 
##     0.35, 0.562, 0.094, 0.569, 1.231, 0.931, 0.794, 0.549, 1.044, 
##     0.489, 0.811, 1.221, 1.276, 0.696, 0.446, 1.041, 1.159, 0.332, 
##     1.503, 1.181, 0.949, 1.263, 0.191, 1.043, 0.611, 1.499, 1.092, 
##     1.452, 0.331, 0.801, 0.323, 1.206, 1.004, 0.275, 0.026, 0.38, 
##     1.38, 0.82, 0.85, 0.96, 1.301, 1.3, 0.336, 0.45, 1.294, 0.745, 
##     1.149, 1.034, 0.886, 0.945, 0.677, 0.359, 1.004, 0.385, 1.246, 
##     1.303, 1.187, 1.376, 1.043, 0.985, 0.694, 0.574, 0.493, 0.948, 
##     0.268, 1.269, 1.162, 1.373, 1.12, 1.221, 0.138, 0.204, 1.1, 1.333, 
##     1.324, 0.685, 0.578, 0.921, 1.286, 0.912, 0.879, 0.274, 0.947, 
##     0.764, 0.855, 0.57, 1.396, 0.657, 0.287, 0.673), social_support = c(1.479, 
##     1.409, 0.983, 1.523, 0.575, 0.517, 1.125, 1.346, 0.378, 1.321, 
##     0.765, 0.437, 1.266, 1.269, 1.487, 1.114, 1.465, 1.294, 0.885, 
##     1.351, 0.939, 1.36, 1.465, 0.698, 0.757, 1.505, 1.515, 1.401, 
##     1.323, 1.357, 1.41, 1.528, 0.766, 0.928, 1.125, 0.808, 1.477, 
##     1.203, 1.242, 0.91, 1.303, 1.169, 1.149, 1.431, 1.455, 1.111, 
##     1.226, 1.145, 1.369, 1.069, 1.31, 1.156, 1.265, 1.223, 0.56, 
##     0.98, 0.868, 1.553, 1.513, 1.526, 1.056, 0.782, 0.688, 1.438, 
##     1.439, 0.572, 0, 0.829, 1.624, 1.39, 1.055, 1.427, 1.219, 1.52, 
##     1.033, 1.134, 1.488, 1.529, 1.442, 1.441, 0.666, 1.212, 0.886, 
##     0.711, 1.383, 1.105, 1.504, 1.557, 1.465, 1.475, 1.147, 1.41, 
##     1.325, 1.122, 1.098, 1.531, 0.841, 1.487, 1.232, 1.454, 1.402, 
##     1.171, 0.774, 0.986, 0.842, 1.538, 1.472, 1.328, 1.058, 1, 1.484, 
##     1.312, 1.313, 0.916, 0.848, 1.03, 1.475, 1.167, 1.522, 1.247, 
##     1.163, 0.799), healthy_life_expectancy = c(1.012, 0.828, 0.581, 
##     0.953, 0.295, 0.361, 0.893, 0.851, 0.44, 0.604, 0.588, 0.397, 
##     0.914, 0.746, 1.009, 0.433, 0.789, 0.838, 0.499, 0.469, 0.428, 
##     0.808, 0.891, 0.268, 0.505, 1.039, 0.818, 0.779, 0.861, 0.795, 
##     0.828, 0.874, 0.192, 0.723, 0.357, 0.232, 0.713, 0.66, 0.789, 
##     0.331, 0.673, 0.168, 0, 0.999, 1.029, 0.245, 0.677, 0.538, 0.92, 
##     0.443, 0.825, 0.999, 0.831, 1.042, 0.495, 0.574, 0.486, 0.999, 
##     0.815, 1.052, 0.38, 0.782, 0.449, 0.884, 0.802, 0.41, 0.105, 
##     0.375, 1.026, 0.739, 0.815, 0.805, 1.036, 0.999, 0.532, 0.571, 
##     1.039, 0.756, 0.91, 0.963, 0.752, 0.845, 0.535, 0.614, 0.854, 
##     0.308, 0.881, 1.026, 0.812, 1.016, 0.769, 0.841, 0.835, 0.637, 
##     0.718, 0.667, 0.242, 0.92, 0.825, 0.987, 0.798, 0.828, 0.366, 
##     0.39, 0.785, 0.996, 1.045, 0.739, 0.426, 0.815, 1.062, 0.868, 
##     0.477, 0.555, 0.874, 0.551, 0.777, 0.489, 0.999, 0.672, 0.463, 
##     0.508), freedom_to_make_life_choices = c(0.526, 0.557, 0.431, 
##     0.564, 0.01, 0, 0.521, 0.543, 0.013, 0.457, 0.498, 0.349, 0.296, 
##     0.535, 0.574, 0.361, 0.235, 0.345, 0.417, 0.389, 0.382, 0.195, 
##     0.523, 0.559, 0.142, 0.584, 0.291, 0.497, 0.433, 0.439, 0.199, 
##     0.495, 0.174, 0.527, 0.269, 0.352, 0.489, 0.491, 0.43, 0.381, 
##     0.416, 0.359, 0.313, 0.508, 0.371, 0.426, 0.439, 0.455, 0.357, 
##     0.356, 0.598, 0.067, 0.47, 0.406, 0.443, 0.241, 0.381, 0.516, 
##     0.311, 0.572, 0.255, 0.418, 0.026, 0.483, 0.39, 0.293, 0.225, 
##     0.332, 0.591, 0.178, 0.283, 0.154, 0.159, 0.564, 0.344, 0.292, 
##     0.231, 0.631, 0.516, 0.558, 0.346, 0.212, 0.313, 0.555, 0.282, 
##     0.327, 0.334, 0.585, 0.264, 0.532, 0.351, 0.47, 0.435, 0.609, 
##     0.389, 0.317, 0.309, 0.457, 0.462, 0.495, 0.498, 0.508, 0.318, 
##     0.494, 0.305, 0.45, 0.436, 0.245, 0.431, 0.167, 0.362, 0.498, 
##     0.401, 0.148, 0.383, 0.547, 0.514, 0.066, 0.557, 0.225, 0.143, 
##     0.372), generosity = c(0.194, 0.359, 0.372, 0.144, 0.202, 0.158, 
##     0.058, 0.147, 0.331, 0.37, 0.2, 0.175, 0.119, 0.175, 0.267, 0.151, 
##     0.094, 0.185, 0.276, 0.13, 0.269, 0.083, 0.127, 0.243, 0.275, 
##     0.285, 0.043, 0.113, 0.074, 0.08, 0.081, 0.103, 0.198, 0.166, 
##     0.212, 0.154, 0.185, 0.498, 0.093, 0.187, 0.133, 0.107, 0.074, 
##     0.047, 0.261, 0.215, 0.285, 0.025, 0.187, 0.252, 0.262, 0, 0.244, 
##     0.19, 0.218, 0.148, 0.245, 0.298, 0.081, 0.263, 0.177, 0.036, 
##     0.419, 0.117, 0.099, 0.177, 0.235, 0.207, 0.354, 0.187, 0.095, 
##     0.064, 0.175, 0.375, 0.209, 0.153, 0.158, 0.322, 0.109, 0.144, 
##     0.043, 0.263, 0.22, 0.217, 0.137, 0.153, 0.121, 0.33, 0.075, 
##     0.244, 0.035, 0.099, 0.2, 0.232, 0.23, 0.235, 0.252, 0.046, 0.083, 
##     0.261, 0.215, 0.26, 0.188, 0.197, 0.27, 0.348, 0.111, 0.181, 
##     0.247, 0.059, 0.153, 0.126, 0.07, 0.169, 0.178, 0.266, 0.184, 
##     0.106, 0.322, 0.103, 0.108, 0.105), perceptions_of_corruption = c(0.316, 
##     0.028, 0.053, 0.057, 0.091, 0.025, 0.1, 0.073, 0.141, 0.167, 
##     0.085, 0.082, 0.022, 0.078, 0.373, 0.089, 0.142, 0.034, 0.147, 
##     0.055, 0.167, 0.106, 0.15, 0.27, 0.078, 0.308, 0.042, 0.101, 
##     0.073, 0.132, 0.02, 0.161, 0.078, 0.143, 0.053, 0.09, 0.016, 
##     0.028, 0.074, 0.037, 0.152, 0.093, 0.135, 0.025, 0.082, 0.041, 
##     0.089, 0.1, 0.056, 0.06, 0.182, 0.034, 0.047, 0.041, 0.089, 0.089, 
##     0.04, 0.31, 0.004, 0.343, 0.113, 0.076, 0.11, 0.05, 0.086, 0.085, 
##     0.035, 0.086, 0.118, 0.01, 0.064, 0.047, 0.056, 0.151, 0.1, 0.072, 
##     0.03, 0.24, 0.054, 0.093, 0.164, 0.006, 0.098, 0.411, 0.039, 
##     0.052, 0.014, 0.38, 0.064, 0.226, 0.182, 0.034, 0.127, 0.062, 
##     0.144, 0.038, 0.045, 0.036, 0.005, 0.265, 0.06, 0.024, 0.102, 
##     0.138, 0.125, 0.278, 0.183, 0, 0.087, 0.055, 0.079, 0.087, 0.056, 
##     0.041, 0.027, 0.164, 0.08, 0.088, 0.298, 0.066, 0.077, 0.093), 
##         hdi = c(0.922, 0.798, 0.628, 0.931, 0.388, 0.496, 0.797, 
##         0.766, 0.564, 0.698, 0.685, 0.515, 0.889, 0.662, 0.959, 0.598, 
##         0.824, 0.815, 0.555, 0.741, 0.524, 0.853, 0.862, 0.404, 0.603, 
##         0.939, 0.895, 0.776, 0.789, 0.9, 0.87, 0.905, 0.416, 0.685, 
##         0.522, 0.582, 0.807, 0.728, 0.678, 0.588, 0.721, 0.55, 0.695, 
##         0.89, 0.919, 0.56, 0.622, 0.731, 0.878, 0.582, 0.94, 0.908, 
##         0.776, 0.913, 0.517, 0.695, 0.628, 0.949, 0.845, 0.97, 0.459, 
##         0.71, 0.554, 0.906, 0.786, 0.571, 0.414, 0.5, 0.972, 0.779, 
##         0.811, 0.709, 0.937, 0.924, 0.497, 0.53, 0.915, 0.74, 0.839, 
##         0.833, 0.844, 0.804, 0.544, 0.578, 0.833, 0.419, 0.88, 0.938, 
##         0.889, 0.93, 0.789, 0.788, 0.706, 0.606, 0.691, 0.747, 0.467, 
##         0.915, 0.845, 0.959, 0.806, 0.819, 0.419, 0.493, 0.799, 0.946, 
##         0.92, 0.785, 0.595, 0.746, 0.918, 0.777, 0.665, 0.487, 0.81, 
##         0.617, 0.756, 0.563, 0.955, 0.674, 0.47, 0.649)), row.names = c(14L, 
##     50L, 118L, 43L, 153L, 151L, 90L, 91L, 146L, 92L, 137L, 99L, 72L, 
##     26L, 7L, 143L, 78L, 81L, 150L, 103L, 117L, 76L, 32L, 109L, 139L, 
##     9L, 41L, 74L, 23L, 27L, 60L, 53L, 129L, 122L, 124L, 96L, 38L, 
##     89L, 34L, 93L, 69L, 141L, 132L, 63L, 13L, 82L, 97L, 145L, 25L, 
##     133L, 21L, 79L, 127L, 47L, 147L, 123L, 95L, 16L, 94L, 6L, 112L, 
##     86L, 144L, 39L, 31L, 136L, 152L, 115L, 4L, 130L, 113L, 105L, 
##     52L, 22L, 131L, 108L, 35L, 40L, 30L, 12L, 116L, 75L, 64L, 149L, 
##     67L, 125L, 37L, 8L, 51L, 10L, 87L, 42L, 44L, 106L, 71L, 80L, 
##     126L, 20L, 46L, 17L, 55L, 77L, 111L, 120L, 114L, 15L, 24L, 68L, 
##     135L, 121L, 29L, 48L, 110L, 140L, 104L, 102L, 61L, 119L, 5L, 
##     107L, 148L, 100L), class = "data.frame"), type = "eps-regression", 
##     kernel = structure(1L, levels = c("linear", "radial"), class = "factor"), 
##     cost = 0.1, epsilon = 0.1, scale = TRUE)
## 
## 
## Parameters:
##    SVM-Type:  eps-regression 
##  SVM-Kernel:  linear 
##        cost:  0.1 
##       gamma:  0.1666667 
##     epsilon:  0.1 
## 
## 
## Number of Support Vectors:  78

Jumlah support vectors pada model terbaik adalah 78 observasi. Nilai ini lebih sedikit dibandingkan model linear baseline yang menggunakan 102 support vectors. Namun, kualitas model tetap ditentukan berdasarkan kemampuan prediksi dan hasil evaluasi, bukan hanya jumlah support vectors.

12.6 Evaluasi Model Terbaik pada Testing Set

# Prediksi menggunakan model terbaik
pred_best <- predict(
  best_fit,
  newdata = test_hdi
)

# Membandingkan tiga model
result_hdi <- rbind(

  data.frame(
    Model = "SVR Linear Baseline",
    t(metrik_svr(test_hdi$hdi, pred_linear))
  ),

  data.frame(
    Model = "SVR Radial Baseline",
    t(metrik_svr(test_hdi$hdi, pred_radial))
  ),

  data.frame(
    Model = "SVR Terbaik (Tuned)",
    t(metrik_svr(test_hdi$hdi, pred_best))
  )
)

# Menampilkan hasil
kable(
  result_hdi,
  digits = 4,
  caption = "Perbandingan Kinerja Model SVR pada Testing Set"
)
Perbandingan Kinerja Model SVR pada Testing Set
Model MAE RMSE R2
SVR Linear Baseline 0.0286 0.0372 0.9213
SVR Radial Baseline 0.0312 0.0384 0.9163
SVR Terbaik (Tuned) 0.0270 0.0347 0.9315

Berdasarkan hasil evaluasi, model SVR terbaik setelah proses tuning menghasilkan nilai MAE sebesar 0,0270 dan RMSE sebesar 0,0347. Kedua nilai tersebut merupakan yang terkecil dibandingkan model baseline. Sementara itu, nilai R² sebesar 0,9315 merupakan nilai tertinggi di antara ketiga model.

Hal tersebut menunjukkan bahwa proses tuning hyperparameter berhasil meningkatkan kinerja model SVR Linear. Dibandingkan model linear baseline, nilai MAE mengalami penurunan dari 0,0286 menjadi 0,0270, sedangkan RMSE menurun dari 0,0372 menjadi 0,0347. Nilai R² juga meningkat dari 0,9213 menjadi 0,9315.

Dengan demikian, model SVR Linear dengan parameter cost = 0.1 dan epsilon = 0.1 menjadi model dengan kinerja terbaik di antara model yang diuji pada penelitian ini.

12.7 Visualisasi Aktual dan Prediksi

plot_hdi <- data.frame(
  Aktual = test_hdi$hdi,
  Prediksi = as.numeric(pred_best)
)

ggplot(
  plot_hdi,
  aes(x = Aktual, y = Prediksi)
) +

  geom_point(
    color = "steelblue",
    size = 2.5
  ) +

  geom_abline(
    intercept = 0,
    slope = 1,
    linetype = "dashed",
    color = "red"
  ) +

  coord_equal() +

  labs(
    title = "Perbandingan HDI Aktual dan Prediksi SVR",
    subtitle = "Model terbaik berdasarkan 5-Fold Cross Validation",
    x = "HDI Aktual",
    y = "HDI Prediksi"
  ) +

  theme_minimal()

Grafik perbandingan nilai HDI aktual dan prediksi digunakan untuk melihat seberapa dekat hasil prediksi model terhadap nilai HDI sebenarnya.

Garis diagonal putus-putus berwarna merah menunjukkan kondisi ketika nilai prediksi sama dengan nilai aktual. Titik-titik yang berada semakin dekat dengan garis tersebut menunjukkan bahwa hasil prediksi model semakin mendekati nilai sebenarnya.

Sebaliknya, titik yang semakin jauh dari garis diagonal menunjukkan adanya kesalahan prediksi yang lebih besar. Visualisasi ini melengkapi hasil evaluasi numerik melalui MAE, RMSE, dan R² sehingga kesesuaian hasil prediksi dapat diamati secara visual.

13 Kesimpulan

Berdasarkan hasil analisis menggunakan metode Support Vector Regression (SVR), dapat disimpulkan bahwa model SVR mampu digunakan untuk memprediksi nilai Human Development Index (HDI) berdasarkan enam indikator World Happiness, yaitu GDP per capita, Social support, Healthy life expectancy, Freedom to make life choices, Generosity, dan Perceptions of corruption.

Hasil pemodelan baseline menunjukkan bahwa SVR dengan kernel linear memberikan kinerja yang sedikit lebih baik dibandingkan kernel radial, dengan nilai MAE sebesar 0,0286, RMSE sebesar 0,0372, dan R² sebesar 0,9213. Selanjutnya, proses optimasi hyperparameter menggunakan 5-Fold Cross Validation menghasilkan kombinasi terbaik berupa kernel linear dengan nilai cost sebesar 0,1 dan epsilon sebesar 0,1, serta nilai rata-rata CV RMSE sebesar 0,0407.

Setelah dilakukan evaluasi pada data testing, model SVR terbaik hasil tuning menghasilkan nilai MAE sebesar 0,0270, RMSE sebesar 0,0347, dan R² sebesar 0,9315. Hasil tersebut menunjukkan bahwa model hasil tuning memiliki kinerja yang lebih baik dibandingkan kedua model baseline, ditunjukkan oleh nilai MAE dan RMSE yang lebih rendah serta R² yang lebih tinggi.

Dengan demikian, berdasarkan kombinasi hyperparameter yang diuji, SVR dengan kernel linear setelah proses tuning merupakan model terbaik untuk memprediksi HDI pada dataset yang digunakan. Hasil ini juga menunjukkan bahwa model dengan kernel yang lebih kompleks tidak selalu menghasilkan kinerja prediksi yang lebih baik dibandingkan kernel linear.