Life_Expectancy_Data <- read_excel("C:/Users/USER/Downloads/Life Expectancy Data.xlsx")
str(Life_Expectancy_Data)
## tibble [2,938 × 22] (S3: tbl_df/tbl/data.frame)
## $ Country : chr [1:2938] "Afghanistan" "Afghanistan" "Afghanistan" "Afghanistan" ...
## $ Year : num [1:2938] 2015 2014 2013 2012 2011 ...
## $ Status : chr [1:2938] "Developing" "Developing" "Developing" "Developing" ...
## $ Life expectancy : num [1:2938] 65 59.9 59.9 59.5 59.2 58.8 58.6 58.1 57.5 57.3 ...
## $ Adult Mortality : num [1:2938] 263 271 268 272 275 279 281 287 295 295 ...
## $ infant deaths : num [1:2938] 62 64 66 69 71 74 77 80 82 84 ...
## $ Alcohol : num [1:2938] 0.01 0.01 0.01 0.01 0.01 0.01 0.01 0.03 0.02 0.03 ...
## $ percentage expenditure : num [1:2938] 71.3 73.5 73.2 78.2 7.1 ...
## $ Hepatitis B : num [1:2938] 65 62 64 67 68 66 63 64 63 64 ...
## $ Measles : num [1:2938] 1154 492 430 2787 3013 ...
## $ BMI : num [1:2938] 19.1 18.6 18.1 17.6 17.2 16.7 16.2 15.7 15.2 14.7 ...
## $ under-five deaths : num [1:2938] 83 86 89 93 97 102 106 110 113 116 ...
## $ Polio : num [1:2938] 6 58 62 67 68 66 63 64 63 58 ...
## $ Total expenditure : num [1:2938] 8.16 8.18 8.13 8.52 7.87 9.2 9.42 8.33 6.73 7.43 ...
## $ Diphtheria : num [1:2938] 65 62 64 67 68 66 63 64 63 58 ...
## $ HIV/AIDS : num [1:2938] 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 ...
## $ GDP : num [1:2938] 584.3 612.7 631.7 670 63.5 ...
## $ Population : num [1:2938] 33736494 327582 31731688 3696958 2978599 ...
## $ thinness 1-19 years : num [1:2938] 17.2 17.5 17.7 17.9 18.2 18.4 18.6 18.8 19 19.2 ...
## $ thinness 5-9 years : num [1:2938] 17.3 17.5 17.7 18 18.2 18.4 18.7 18.9 19.1 19.3 ...
## $ Income composition of resources: num [1:2938] 0.479 0.476 0.47 0.463 0.454 0.448 0.434 0.433 0.415 0.405 ...
## $ Schooling : num [1:2938] 10.1 10 9.9 9.8 9.5 9.2 8.9 8.7 8.4 8.1 ...
View(Life_Expectancy_Data)
Dataset Life Expectancy dari WHO yang tersedia di Kaggle merupakan kumpulan data yang memuat informasi kesehatan, ekonomi, dan demografi dari berbagai negara pada tahun 2000–2015. Sumber utama dataset ini adalah World Health Organization (WHO) dan United Nations. Dataset ini terdiri dari 22 variabel yang mencakup indikator harapan hidup, angka kematian dewasa, kematian bayi, imunisasi, prevalensi penyakit, kondisi gizi, pendidikan, pengeluaran kesehatan, hingga GDP setiap negara. Setiap baris data merepresentasikan suatu negara pada tahun tertentu sehingga dataset ini dapat digunakan untuk mempelajari perkembangan kesehatan global dari waktu ke waktu.
describe(Life_Expectancy_Data)
## vars n mean sd median
## Country* 1 2938 96.10 56.24 94.00
## Year 2 2938 2007.52 4.61 2008.00
## Status* 3 2938 1.83 0.38 2.00
## Life expectancy 4 2928 69.22 9.52 72.10
## Adult Mortality 5 2928 164.80 124.29 144.00
## infant deaths 6 2938 30.30 117.93 3.00
## Alcohol 7 2744 4.60 4.05 3.76
## percentage expenditure 8 2938 738.25 1987.91 64.91
## Hepatitis B 9 2385 80.94 25.07 92.00
## Measles 10 2938 2419.59 11467.27 17.00
## BMI 11 2904 38.32 20.04 43.50
## under-five deaths 12 2938 42.04 160.45 4.00
## Polio 13 2919 82.55 23.43 93.00
## Total expenditure 14 2712 5.94 2.50 5.76
## Diphtheria 15 2919 82.32 23.72 93.00
## HIV/AIDS 16 2938 1.74 5.08 0.10
## GDP 17 2490 7483.16 14270.17 1766.95
## Population 18 2286 12753375.12 61012096.51 1386542.00
## thinness 1-19 years 19 2904 4.84 4.42 3.30
## thinness 5-9 years 20 2904 4.87 4.51 3.30
## Income composition of resources 21 2771 0.63 0.21 0.68
## Schooling 22 2775 11.99 3.36 12.30
## trimmed mad min max
## Country* 95.90 72.65 1.00 1.930000e+02
## Year 2007.52 5.93 2000.00 2.015000e+03
## Status* 1.91 0.00 1.00 2.000000e+00
## Life expectancy 69.91 8.60 36.30 8.900000e+01
## Adult Mortality 150.51 112.68 1.00 7.230000e+02
## infant deaths 10.20 4.45 0.00 1.800000e+03
## Alcohol 4.23 4.81 0.01 1.787000e+01
## percentage expenditure 230.74 96.24 0.00 1.947991e+04
## Hepatitis B 86.89 8.90 1.00 9.900000e+01
## Measles 286.08 25.20 0.00 2.121830e+05
## BMI 39.05 24.17 1.00 8.730000e+01
## under-five deaths 14.15 5.93 0.00 2.500000e+03
## Polio 88.05 8.90 3.00 9.900000e+01
## Total expenditure 5.85 2.36 0.37 1.760000e+01
## Diphtheria 87.99 8.90 2.00 9.900000e+01
## HIV/AIDS 0.54 0.00 0.10 5.060000e+01
## GDP 3751.73 2360.98 1.68 1.191727e+05
## Population 3953693.58 2012347.06 34.00 1.293859e+09
## thinness 1-19 years 4.14 3.41 0.10 2.770000e+01
## thinness 5-9 years 4.15 3.41 0.10 2.860000e+01
## Income composition of resources 0.65 0.19 0.00 9.500000e-01
## Schooling 12.17 3.11 0.00 2.070000e+01
## range skew kurtosis se
## Country* 1.920000e+02 0.03 -1.22 1.04
## Year 1.500000e+01 -0.01 -1.21 0.09
## Status* 1.000000e+00 -1.72 0.95 0.01
## Life expectancy 5.270000e+01 -0.64 -0.24 0.18
## Adult Mortality 7.220000e+02 1.17 1.74 2.30
## infant deaths 1.800000e+03 9.78 115.76 2.18
## Alcohol 1.786000e+01 0.59 -0.81 0.08
## percentage expenditure 1.947991e+04 4.65 26.51 36.68
## Hepatitis B 9.800000e+01 -1.93 2.76 0.51
## Measles 2.121830e+05 9.43 114.58 211.56
## BMI 8.630000e+01 -0.22 -1.29 0.37
## under-five deaths 2.500000e+03 9.49 109.49 2.96
## Polio 9.600000e+01 -2.10 3.76 0.43
## Total expenditure 1.723000e+01 0.62 1.15 0.05
## Diphtheria 9.700000e+01 -2.07 3.55 0.44
## HIV/AIDS 5.050000e+01 5.39 34.80 0.09
## GDP 1.191711e+05 3.20 12.29 285.98
## Population 1.293859e+09 15.90 297.09 1276079.80
## thinness 1-19 years 2.760000e+01 1.71 3.96 0.08
## thinness 5-9 years 2.850000e+01 1.78 4.34 0.08
## Income composition of resources 9.500000e-01 -1.14 1.38 0.00
## Schooling 2.070000e+01 -0.60 0.88 0.06
Statistika deskriptif menunjukkan bahwa variabel-variabel dalam dataset memiliki rentang nilai yang sangat beragam, terutama pada indikator kesehatan seperti kematian bayi, kematian balita, measles, GDP, dan populasi yang memiliki sebaran sangat lebar. Variabel harapan hidup memiliki rata-rata 69 tahun dengan variasi cukup tinggi, menandakan perbedaan kondisi kesehatan antar negara. Variabel imunisasi (Polio, DPT, Hepatitis B) rata-rata tinggi tetapi memiliki nilai minimum rendah, sehingga dapat menjadi pembeda kuat antara negara dengan kesehatan baik dan buruk. Demikian pula indikator sosial ekonomi seperti GDP, schooling, dan income composition menunjukkan ketimpangan besar. Variasi tinggi ini membuat variabel-variabel tersebut sangat potensial sebagai prediktor dalam model klasifikasi, karena mampu membantu membedakan kategori negara berdasarkan tingkat harapan hidup atau kelompok kesehatan lainnya.
colSums(is.na(Life_Expectancy_Data))
## Country Year
## 0 0
## Status Life expectancy
## 0 10
## Adult Mortality infant deaths
## 10 0
## Alcohol percentage expenditure
## 194 0
## Hepatitis B Measles
## 553 0
## BMI under-five deaths
## 34 0
## Polio Total expenditure
## 19 226
## Diphtheria HIV/AIDS
## 19 0
## GDP Population
## 448 652
## thinness 1-19 years thinness 5-9 years
## 34 34
## Income composition of resources Schooling
## 167 163
sum(is.na(Life_Expectancy_Data))
## [1] 2563
names(Life_Expectancy_Data)[colSums(is.na(Life_Expectancy_Data)) > 0]
## [1] "Life expectancy" "Adult Mortality"
## [3] "Alcohol" "Hepatitis B"
## [5] "BMI" "Polio"
## [7] "Total expenditure" "Diphtheria"
## [9] "GDP" "Population"
## [11] "thinness 1-19 years" "thinness 5-9 years"
## [13] "Income composition of resources" "Schooling"
Hasil pengecekan missing value menunjukkan beberapa variabel memiliki jumlah hilang cukup besar, terutama Hepatitis B (553), GDP (448), Population (652), Total expenditure (226), dan beberapa variabel gizi. Oleh karena itu, tahap pembersihan data perlu dilakukan, baik dengan imputasi atau menghapus variabel yang terlalu banyak missing.
Life_Expectancy_Clean <- na.omit(Life_Expectancy_Data)
sum(is.na(Life_Expectancy_Clean))
## [1] 0
Karena jumlah missing cukup signifikan, saya melakukan pembersihan data dengan na.omit(), dan hasil akhir menunjukkan 0 missing value. Artinya, dataset Life_Expectancy_Clean sudah siap digunakan untuk klasifikasi tanpa nilai kosong.
Jumlah data setelah pembersihan adalah 2563 observasi, dan variabel predictor yang tersisa meliputi 14 variabel seperti Life expectancy, Adult Mortality, Alcohol, Polio, GDP, Schooling, dll.
data_num <- Life_Expectancy_Clean %>% select_if(is.numeric)
detect_outlier <- function(x) {
Q1 <- quantile(x, 0.25, na.rm = TRUE)
Q3 <- quantile(x, 0.75, na.rm = TRUE)
IQR <- Q3 - Q1
lower <- Q1 - 1.5 * IQR
upper <- Q3 + 1.5 * IQR
return(which(x < lower | x > upper))
}
outlier_before <- sapply(data_num, function(x) length(detect_outlier(x)))
cat("Jumlah outlier sebelum pembersihan:\n")
## Jumlah outlier sebelum pembersihan:
print(outlier_before)
## Year Life expectancy
## 0 39
## Adult Mortality infant deaths
## 54 199
## Alcohol percentage expenditure
## 2 187
## Hepatitis B Measles
## 165 297
## BMI under-five deaths
## 0 222
## Polio Total expenditure
## 142 7
## Diphtheria HIV/AIDS
## 134 299
## GDP Population
## 208 233
## thinness 1-19 years thinness 5-9 years
## 77 78
## Income composition of resources Schooling
## 48 16
data_long_before <- data_num %>%
pivot_longer(cols = everything(), names_to = "Variabel", values_to = "Nilai")
ggplot(data_long_before, aes(x = "", y = Nilai)) +
geom_boxplot(fill = "skyblue", color = "darkblue", outlier.color = "red", outlier.size = 1) +
facet_wrap(~ Variabel, scales = "free", ncol = 4) +
theme_minimal(base_size = 11) +
theme(
strip.text = element_text(face = "bold"),
axis.text.x = element_blank(),
axis.ticks.x = element_blank()
) +
labs(title = "Boxplot Sebelum Pembersihan Outlier", x = NULL, y = "Nilai")
“Boxplot menunjukkan bahwa hampir semua variabel, seperti Adult
Mortality dengan nilai ekstrem di atas 600, infant deaths
dan under-five deaths yang mencapai lebih dari 1500,
Measles yang memiliki outlier hingga ratusan ribu, serta
GDP dan Population dengan nilai sangat besar, memiliki
outlier dalam jumlah banyak dan distribusi menceng ke kanan, sedangkan
variabel seperti Life expectancy (50–80), BMI (20–60),
dan Schooling (8–15) relatif lebih stabil dengan sedikit
outlier, sehingga keseluruhan data menunjukkan ketimpangan nilai yang
tinggi antar negara dan memerlukan pembersihan outlier sebelum analisis
lanjutan.”
replace_outlier <- function(x) {
Q1 <- quantile(x, 0.25, na.rm = TRUE)
Q3 <- quantile(x, 0.75, na.rm = TRUE)
IQR <- Q3 - Q1
lower <- Q1 - 1.5 * IQR
upper <- Q3 + 1.5 * IQR
x[x < lower | x > upper] <- median(x, na.rm = TRUE)
return(x)
}
data_num_clean <- as.data.frame(lapply(data_num, replace_outlier))
outlier_after <- sapply(data_num_clean, function(x) length(detect_outlier(x)))
cat("\nJumlah outlier setelah pembersihan:\n")
##
## Jumlah outlier setelah pembersihan:
print(outlier_after)
## Year Life.expectancy
## 0 20
## Adult.Mortality infant.deaths
## 21 258
## Alcohol percentage.expenditure
## 0 131
## Hepatitis.B Measles
## 113 297
## BMI under.five.deaths
## 0 246
## Polio Total.expenditure
## 59 0
## Diphtheria HIV.AIDS
## 85 386
## GDP Population
## 81 205
## thinness..1.19.years thinness.5.9.years
## 19 19
## Income.composition.of.resources Schooling
## 0 8
data_long_after <- data_num_clean %>%
pivot_longer(cols = everything(), names_to = "Variabel", values_to = "Nilai")
ggplot(data_long_after, aes(x = "", y = Nilai)) +
geom_boxplot(fill = "lightgreen", color = "darkgreen", outlier.color = "red", outlier.size = 1) +
facet_wrap(~ Variabel, scales = "free", ncol = 4) +
theme_minimal(base_size = 11) +
theme(
strip.text = element_text(face = "bold"),
axis.text.x = element_blank(),
axis.ticks.x = element_blank()
) +
labs(title = "Boxplot Setelah Pembersihan Outlier", x = NULL, y = "Nilai")
Setelah pembersihan outlier, persebaran nilai pada hampir semua variabel
menjadi jauh lebih rapat dan stabil, misalnya Adult Mortality kini
berada pada kisaran sekitar 0–300, infant deaths dan under-five deaths
turun menjadi sekitar 0–50, Measles berada pada rentang 0–750, GDP
menyempit pada kisaran 0–10.000, Population berada di bawah 1.5×10⁷,
serta variabel lain seperti Life expectancy (50–85), BMI (20–60),
Schooling (8–15), dan imunisasi (70–100) menunjukkan distribusi lebih
konsisten sehingga dataset menjadi lebih bersih, tidak terlalu menceng,
dan lebih siap digunakan untuk analisis lanjutan
clean_outlier_iterative <- function(x, max_iter = 5) {
for (i in 1:max_iter) {
Q1 <- quantile(x, 0.25, na.rm = TRUE)
Q3 <- quantile(x, 0.75, na.rm = TRUE)
IQR <- Q3 - Q1
lower <- Q1 - 1.5 * IQR
upper <- Q3 + 1.5 * IQR
outliers <- which(x < lower | x > upper)
if (length(outliers) == 0) break
x[outliers] <- median(x, na.rm = TRUE)
}
return(x)
}
data_num_clean <- as.data.frame(lapply(data_num, clean_outlier_iterative))
outlier_after <- sapply(data_num_clean, function(x) length(detect_outlier(x)))
cat("Jumlah outlier setelah ditangani:\n")
## Jumlah outlier setelah ditangani:
print(outlier_after)
## Year Life.expectancy
## 0 0
## Adult.Mortality infant.deaths
## 0 0
## Alcohol percentage.expenditure
## 0 0
## Hepatitis.B Measles
## 0 0
## BMI under.five.deaths
## 0 0
## Polio Total.expenditure
## 68 0
## Diphtheria HIV.AIDS
## 92 0
## GDP Population
## 0 0
## thinness..1.19.years thinness.5.9.years
## 0 0
## Income.composition.of.resources Schooling
## 0 0
data_long_after <- data_num_clean %>%
pivot_longer(cols = everything(), names_to = "Variabel", values_to = "Nilai")
ggplot(data_long_after, aes(x = "", y = Nilai)) +
geom_boxplot(fill = "lightgreen", color = "darkgreen", outlier.color = "red", outlier.size = 1) +
facet_wrap(~ Variabel, scales = "free", ncol = 4) +
theme_minimal(base_size = 11) +
theme(
strip.text = element_text(face = "bold"),
axis.text.x = element_blank(),
axis.ticks.x = element_blank()
) +
labs(title = "Boxplot Setelah Pembersihan Outlier", y = "Nilai")
Boxplot setelah penanganan outlier tahap 2 menunjukkan bahwa seluruh
variabel kini memiliki persebaran yang jauh lebih rapat dan stabil,
seperti Adult Mortality yang berada pada kisaran 0–350, Alcohol sekitar
0–15, BMI sekitar 20–60, GDP menyempit pada rentang 0–3000, infant
deaths hanya 0–6, Measles pada kisaran 0–30, Population di bawah 3×10⁶,
Life expectancy sekitar 55–85, serta variabel lain seperti Schooling,
Total expenditure, HIV/AIDS, dan imunisasi yang tampil lebih homogen,
sehingga dataset menjadi bersih dari nilai ekstrem dan siap digunakan
untuk analisis lanjutan
cat_cols <- sapply(Life_Expectancy_Clean, is.character)
cat_cols <- names(Life_Expectancy_Clean)[cat_cols]
cat("Kolom kategorikal yang ditemukan:\n")
## Kolom kategorikal yang ditemukan:
print(cat_cols)
## [1] "Country" "Status"
for (col in cat_cols) {
unique_vals <- unique(Life_Expectancy_Clean[[col]])
if (length(unique_vals) == 2) {
Life_Expectancy_Clean[[col]] <- as.numeric(as.factor(Life_Expectancy_Clean[[col]])) - 1
} else {
cat(paste("Kolom", col, "memiliki lebih dari 2 kategori, perlu one-hot encoding.\n"))
}
}
## Kolom Country memiliki lebih dari 2 kategori, perlu one-hot encoding.
str(Life_Expectancy_Clean)
## tibble [1,649 × 22] (S3: tbl_df/tbl/data.frame)
## $ Country : chr [1:1649] "Afghanistan" "Afghanistan" "Afghanistan" "Afghanistan" ...
## $ Year : num [1:1649] 2015 2014 2013 2012 2011 ...
## $ Status : num [1:1649] 1 1 1 1 1 1 1 1 1 1 ...
## $ Life expectancy : num [1:1649] 65 59.9 59.9 59.5 59.2 58.8 58.6 58.1 57.5 57.3 ...
## $ Adult Mortality : num [1:1649] 263 271 268 272 275 279 281 287 295 295 ...
## $ infant deaths : num [1:1649] 62 64 66 69 71 74 77 80 82 84 ...
## $ Alcohol : num [1:1649] 0.01 0.01 0.01 0.01 0.01 0.01 0.01 0.03 0.02 0.03 ...
## $ percentage expenditure : num [1:1649] 71.3 73.5 73.2 78.2 7.1 ...
## $ Hepatitis B : num [1:1649] 65 62 64 67 68 66 63 64 63 64 ...
## $ Measles : num [1:1649] 1154 492 430 2787 3013 ...
## $ BMI : num [1:1649] 19.1 18.6 18.1 17.6 17.2 16.7 16.2 15.7 15.2 14.7 ...
## $ under-five deaths : num [1:1649] 83 86 89 93 97 102 106 110 113 116 ...
## $ Polio : num [1:1649] 6 58 62 67 68 66 63 64 63 58 ...
## $ Total expenditure : num [1:1649] 8.16 8.18 8.13 8.52 7.87 9.2 9.42 8.33 6.73 7.43 ...
## $ Diphtheria : num [1:1649] 65 62 64 67 68 66 63 64 63 58 ...
## $ HIV/AIDS : num [1:1649] 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 ...
## $ GDP : num [1:1649] 584.3 612.7 631.7 670 63.5 ...
## $ Population : num [1:1649] 33736494 327582 31731688 3696958 2978599 ...
## $ thinness 1-19 years : num [1:1649] 17.2 17.5 17.7 17.9 18.2 18.4 18.6 18.8 19 19.2 ...
## $ thinness 5-9 years : num [1:1649] 17.3 17.5 17.7 18 18.2 18.4 18.7 18.9 19.1 19.3 ...
## $ Income composition of resources: num [1:1649] 0.479 0.476 0.47 0.463 0.454 0.448 0.434 0.433 0.415 0.405 ...
## $ Schooling : num [1:1649] 10.1 10 9.9 9.8 9.5 9.2 8.9 8.7 8.4 8.1 ...
## - attr(*, "na.action")= 'omit' Named int [1:1289] 33 45 46 47 48 49 58 59 60 61 ...
## ..- attr(*, "names")= chr [1:1289] "33" "45" "46" "47" ...
View(Life_Expectancy_Clean)
numeric_cols <- sapply(Life_Expectancy_Clean, is.numeric)
numeric_cols["Year"] <- FALSE
numeric_cols["Status"] <- FALSE
Life_Expectancy_Normalized <- as.data.frame(
lapply(Life_Expectancy_Clean[, numeric_cols], function(x) {
(x - min(x, na.rm = TRUE)) / (max(x, na.rm = TRUE) - min(x, na.rm = TRUE))
})
)
Life_Expectancy_Normalized <- cbind(
Life_Expectancy_Clean[, !numeric_cols],
Life_Expectancy_Normalized
)
str(Life_Expectancy_Normalized)
## 'data.frame': 1649 obs. of 22 variables:
## $ Country : chr "Afghanistan" "Afghanistan" "Afghanistan" "Afghanistan" ...
## $ Year : num 2015 2014 2013 2012 2011 ...
## $ Status : num 1 1 1 1 1 1 1 1 1 1 ...
## $ Life.expectancy : num 0.467 0.353 0.353 0.344 0.338 ...
## $ Adult.Mortality : num 0.363 0.374 0.37 0.375 0.38 ...
## $ infant.deaths : num 0.0387 0.04 0.0413 0.0431 0.0444 ...
## $ Alcohol : num 0 0 0 0 0 ...
## $ percentage.expenditure : num 0.003759 0.003878 0.003861 0.004123 0.000374 ...
## $ Hepatitis.B : num 0.649 0.619 0.639 0.67 0.68 ...
## $ Measles : num 0.00878 0.00374 0.00327 0.0212 0.02292 ...
## $ BMI : num 0.228 0.221 0.214 0.208 0.202 ...
## $ under.five.deaths : num 0.0395 0.041 0.0424 0.0443 0.0462 ...
## $ Polio : num 0.0312 0.5729 0.6146 0.6667 0.6771 ...
## $ Total.expenditure : num 0.544 0.545 0.541 0.57 0.522 ...
## $ Diphtheria : num 0.649 0.619 0.639 0.67 0.68 ...
## $ HIV.AIDS : num 0 0 0 0 0 0 0 0 0 0 ...
## $ GDP : num 0.004889 0.005127 0.005287 0.005608 0.000519 ...
## $ Population : num 0.026074 0.000253 0.024525 0.002857 0.002302 ...
## $ thinness..1.19.years : num 0.631 0.642 0.649 0.657 0.668 ...
## $ thinness.5.9.years : num 0.612 0.619 0.626 0.637 0.644 ...
## $ Income.composition.of.resources: num 0.512 0.509 0.502 0.495 0.485 ...
## $ Schooling : num 0.358 0.352 0.345 0.339 0.321 ...
View(Life_Expectancy_Normalized)
data_final <- Life_Expectancy_Normalized
names(data_final)
## [1] "Country" "Year"
## [3] "Status" "Life.expectancy"
## [5] "Adult.Mortality" "infant.deaths"
## [7] "Alcohol" "percentage.expenditure"
## [9] "Hepatitis.B" "Measles"
## [11] "BMI" "under.five.deaths"
## [13] "Polio" "Total.expenditure"
## [15] "Diphtheria" "HIV.AIDS"
## [17] "GDP" "Population"
## [19] "thinness..1.19.years" "thinness.5.9.years"
## [21] "Income.composition.of.resources" "Schooling"
data_final <- Life_Expectancy_Normalized # data sudah normalisasi
target <- "Life.expectancy"
predictors <- setdiff(names(data_final), c("Country", "Year", target))
set.seed(123)
train_index <- sample(1:nrow(data_final), 0.8 * nrow(data_final))
data_train <- data_final[train_index, ]
data_test <- data_final[-train_index, ]
x_train <- data_train[, predictors, drop=FALSE]
y_train <- data_train[[target]]
x_test <- data_test[, predictors, drop=FALSE]
y_test <- data_test[[target]]
cat("Jumlah data training:", nrow(data_train), "\n")
## Jumlah data training: 1319
cat("Jumlah data testing:", nrow(data_test), "\n")
## Jumlah data testing: 330
# Response variable
response <- "Life.expectancy"
# Data utama yang dipakai VIF, PCA, Ridge, LASSO
df <- data_train # atau gunakan data_final kalau mau full data
# Pastikan predictors benar
predictors <- setdiff(names(df), c("Country", "Year", response))
formula_vif <- as.formula(
paste("Life.expectancy ~", paste(predictors, collapse = " + "))
)
# Fit model regresi linear
model_vif <- lm(formula_vif, data = data_train)
# Hitung VIF
vif_values <- vif(model_vif)
cat("=== HASIL VIF ===\n")
## === HASIL VIF ===
print(vif_values)
## Status Adult.Mortality
## 1.806313 1.808198
## infant.deaths Alcohol
## 245.900128 2.256621
## percentage.expenditure Hepatitis.B
## 14.287615 1.667816
## Measles BMI
## 1.539020 1.821104
## under.five.deaths Polio
## 234.891128 1.727204
## Total.expenditure Diphtheria
## 1.119102 2.142147
## HIV.AIDS GDP
## 1.473217 14.884693
## Population thinness..1.19.years
## 2.057050 6.890268
## thinness.5.9.years Income.composition.of.resources
## 6.932188 2.872390
## Schooling
## 3.399901
# Interpretasi otomatis
cat("\n=== INTERPRETASI OTOMATIS ===\n")
##
## === INTERPRETASI OTOMATIS ===
for (i in 1:length(vif_values)) {
if (vif_values[i] < 5) {
cat(names(vif_values)[i], ": Tidak ada indikasi multikolinearitas (VIF < 5)\n")
} else if (vif_values[i] >= 5 & vif_values[i] < 10) {
cat(names(vif_values)[i], ": Ada indikasi multikolinearitas sedang (5 ≤ VIF < 10)\n")
} else {
cat(names(vif_values)[i], ": Multikolinearitas tinggi (VIF ≥ 10)\n")
}
}
## Status : Tidak ada indikasi multikolinearitas (VIF < 5)
## Adult.Mortality : Tidak ada indikasi multikolinearitas (VIF < 5)
## infant.deaths : Multikolinearitas tinggi (VIF ≥ 10)
## Alcohol : Tidak ada indikasi multikolinearitas (VIF < 5)
## percentage.expenditure : Multikolinearitas tinggi (VIF ≥ 10)
## Hepatitis.B : Tidak ada indikasi multikolinearitas (VIF < 5)
## Measles : Tidak ada indikasi multikolinearitas (VIF < 5)
## BMI : Tidak ada indikasi multikolinearitas (VIF < 5)
## under.five.deaths : Multikolinearitas tinggi (VIF ≥ 10)
## Polio : Tidak ada indikasi multikolinearitas (VIF < 5)
## Total.expenditure : Tidak ada indikasi multikolinearitas (VIF < 5)
## Diphtheria : Tidak ada indikasi multikolinearitas (VIF < 5)
## HIV.AIDS : Tidak ada indikasi multikolinearitas (VIF < 5)
## GDP : Multikolinearitas tinggi (VIF ≥ 10)
## Population : Tidak ada indikasi multikolinearitas (VIF < 5)
## thinness..1.19.years : Ada indikasi multikolinearitas sedang (5 ≤ VIF < 10)
## thinness.5.9.years : Ada indikasi multikolinearitas sedang (5 ≤ VIF < 10)
## Income.composition.of.resources : Tidak ada indikasi multikolinearitas (VIF < 5)
## Schooling : Tidak ada indikasi multikolinearitas (VIF < 5)
model_full <- lm(as.formula(paste(response, "~", paste(predictors, collapse = " + "))),
data = df)
model_full <- lm(as.formula(paste(response, "~", paste(predictors, collapse = " + "))),
data = df)
vif_full <- vif(model_full)
vif_full
## Status Adult.Mortality
## 1.806313 1.808198
## infant.deaths Alcohol
## 245.900128 2.256621
## percentage.expenditure Hepatitis.B
## 14.287615 1.667816
## Measles BMI
## 1.539020 1.821104
## under.five.deaths Polio
## 234.891128 1.727204
## Total.expenditure Diphtheria
## 1.119102 2.142147
## HIV.AIDS GDP
## 1.473217 14.884693
## Population thinness..1.19.years
## 2.057050 6.890268
## thinness.5.9.years Income.composition.of.resources
## 6.932188 2.872390
## Schooling
## 3.399901
Hasil perhitungan VIF menunjukkan bahwa variabel infant.deaths (245.9), under.five.deaths (234.89), percentage.expenditure (14.28), GDP (14.88), serta thinness usia 1–19 tahun (6.89) dan 5–9 tahun (6.93) memiliki nilai VIF sangat tinggi, yang menandakan adanya multikolinearitas kuat terutama antara variabel mortalitas anak dan pengeluaran kesehatan, sehingga variabel-variabel ini perlu dipertimbangkan untuk dieliminasi atau direduksi pada model
high_vif <- names(vif_full[vif_full > 5])
high_vif
## [1] "infant.deaths" "percentage.expenditure" "under.five.deaths"
## [4] "GDP" "thinness..1.19.years" "thinness.5.9.years"
df_reduced <- df %>% select(-all_of(high_vif))
model_reduced <- lm(
as.formula(paste(response, "~ .")),
data = df_reduced
)
Setelah proses pembersihan multikolinearitas, variabel dengan nilai VIF sangat tinggi yaitu infant.deaths, percentage.expenditure, under.five.deaths, GDP, thinness 1–19 years, dan thinness 5–9 years telah dibuang karena berkontribusi besar terhadap multikolinearitas, sehingga model kini hanya mempertahankan variabel-variabel yang lebih stabil dan tidak saling berkorelasi kuat.
alias_info <- alias(model_reduced)$Complete
aliased_vars <- names(alias_info[alias_info == TRUE])
aliased_vars
## NULL
Hasil pengecekan aliased coefficients menunjukkan nilai NULL, yang berarti tidak ada koefisien yang tereliminasi karena linear dependency sehingga semua variabel yang tersisa bersifat independen dan dapat diestimasi dengan baik dalam model.
if(length(aliased_vars) > 0){
cat("Menghapus variabel aliased:\n")
print(aliased_vars)
df_reduced <- df_reduced %>% select(-all_of(aliased_vars))
model_reduced <- lm(
as.formula(paste(response, "~ .")),
data = df_reduced
)
}
# Ambil hanya prediktor numerik
X <- df_reduced %>% select(where(is.numeric))
# Buat matriks korelasi
cor_mat <- cor(X, use = "pairwise.complete.obs")
# Invers matriks korelasi
inv_cor <- solve(cor_mat)
# Ambil diagonal → itulah VIF
vif_cor <- diag(inv_cor)
vif_df <- data.frame(
variable = names(vif_cor),
VIF = vif_cor
)
vif_df
## variable VIF
## Year Year 1.157394
## Status Status 1.737264
## Life.expectancy Life.expectancy 5.721034
## Adult.Mortality Adult.Mortality 2.191515
## Alcohol Alcohol 2.229992
## Hepatitis.B Hepatitis.B 1.678801
## Measles Measles 1.196830
## BMI BMI 1.626715
## Polio Polio 1.735447
## Total.expenditure Total.expenditure 1.123413
## Diphtheria Diphtheria 2.130705
## HIV.AIDS HIV.AIDS 2.014932
## Population Population 1.169145
## Income.composition.of.resources Income.composition.of.resources 3.164593
## Schooling Schooling 3.878807
Hasil correlation-based VIF menunjukkan bahwa seluruh variabel memiliki nilai VIF rendah hingga moderat—mulai dari sekitar 1.12 pada Total.expenditure hingga 3.88 pada Schooling—dengan nilai tertinggi dimiliki oleh Schooling (3.88) dan Income.composition.of.resources (3.16), namun keseluruhannya masih berada jauh di bawah ambang batas kritis (VIF > 10), sehingga dapat disimpulkan bahwa model sudah bebas dari multikolinearitas signifikan
# 1. Ambil prediktor numerik saja
X_pca <- df %>%
select(all_of(predictors)) %>%
select(where(is.numeric)) %>%
as.data.frame()
# 2. Hapus variabel dengan varians nol (jika ada)
zero_var <- names(X_pca)[apply(X_pca, 2, var, na.rm = TRUE) == 0]
if(length(zero_var) > 0){
cat("Menghapus variabel varians nol:\n")
print(zero_var)
X_pca <- X_pca %>% select(-all_of(zero_var))
}
# 3. Tangani NA atau Infinite → isi dengan median kolom
X_pca_clean <- X_pca %>%
mutate_all(~ ifelse(!is.finite(.) | is.na(.), median(., na.rm = TRUE), .))
# 4. Jalankan PCA (TANPA ERROR)
pca_model <- prcomp(X_pca_clean, scale. = TRUE)
# 5. Ringkasan PCA
summary(pca_model)
## Importance of components:
## PC1 PC2 PC3 PC4 PC5 PC6 PC7
## Standard deviation 2.4210 1.7156 1.34467 1.23861 1.0871 0.93744 0.90330
## Proportion of Variance 0.3085 0.1549 0.09516 0.08075 0.0622 0.04625 0.04294
## Cumulative Proportion 0.3085 0.4634 0.55856 0.63931 0.7015 0.74775 0.79070
## PC8 PC9 PC10 PC11 PC12 PC13 PC14
## Standard deviation 0.83607 0.76642 0.72831 0.66200 0.6406 0.58930 0.56925
## Proportion of Variance 0.03679 0.03092 0.02792 0.02307 0.0216 0.01828 0.01706
## Cumulative Proportion 0.82749 0.85840 0.88632 0.90939 0.9310 0.94926 0.96632
## PC15 PC16 PC17 PC18 PC19
## Standard deviation 0.56190 0.45679 0.28006 0.18732 0.04566
## Proportion of Variance 0.01662 0.01098 0.00413 0.00185 0.00011
## Cumulative Proportion 0.98293 0.99392 0.99804 0.99989 1.00000
# 6. Ambil 2 PC pertama dan buat model regresi PCA
pc_df <- as.data.frame(pca_model$x[, 1:2])
pc_df$y <- df[[response]]
model_pca <- lm(y ~ PC1 + PC2, data = pc_df)
# 7. Hasil Model PCA
summary(model_pca)
##
## Call:
## lm(formula = y ~ PC1 + PC2, data = pc_df)
##
## Residuals:
## Min 1Q Median 3Q Max
## -0.41424 -0.07238 0.01545 0.08548 0.33167
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 0.561073 0.003316 169.23 <2e-16 ***
## PC1 -0.058974 0.001370 -43.05 <2e-16 ***
## PC2 -0.034832 0.001933 -18.02 <2e-16 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 0.1204 on 1316 degrees of freedom
## Multiple R-squared: 0.6233, Adjusted R-squared: 0.6227
## F-statistic: 1089 on 2 and 1316 DF, p-value: < 2.2e-16
Hasil PCA menunjukkan bahwa komponen utama pertama (PC1) menjelaskan 30.85% variasi dan PC2 menjelaskan 15.49% sehingga dua komponen ini sudah menangkap 46.34% total variasi data, dan ketika digunakan dalam regresi, model y ~ PC1 + PC2 memberikan hasil signifikan dengan kedua PC berpengaruh negatif (p < 2e-16), residual error kecil (0.1204), serta R² sebesar 0.623 yang menandakan bahwa dua komponen utama tersebut mampu menjelaskan sekitar 62% variasi respon secara efektif.
cat("AIC Model Full :", AIC(model_full), "\n")
## AIC Model Full : -2919.126
if (exists("model_reduced")) {
cat("AIC Model Reduced :", AIC(model_reduced), "\n")
}
## AIC Model Reduced : -4854.897
cat("AIC Model PCA :", AIC(model_pca), "\n")
## AIC Model PCA : -1836.037
Hasil perbandingan AIC menunjukkan bahwa model Reduced memiliki nilai AIC paling rendah (-4854.897) dibandingkan model Full (-2919.126) dan model PCA (-1836.037), sehingga model Reduced adalah model yang paling optimal dan efisien karena memberikan keseimbangan terbaik antara kompleksitas dan goodness-of-fit
library(glmnet)
## Warning: package 'glmnet' was built under R version 4.4.3
## Loading required package: Matrix
## Warning: package 'Matrix' was built under R version 4.4.3
##
## Attaching package: 'Matrix'
## The following objects are masked from 'package:tidyr':
##
## expand, pack, unpack
## Loaded glmnet 4.1-10
# Bersihkan data: hanya variabel yang terlibat dan non-NA
df_clean <- df %>%
select(all_of(c(response, predictors))) %>%
drop_na()
# Bangun X_mat dan y_vec dari data yang sama
X_mat <- model.matrix(as.formula(paste(response, "~ .")), df_clean)[,-1]
y_vec <- df_clean[[response]]
# Ridge & LASSO Cross-Validated Lambda
set.seed(123)
cv_ridge <- cv.glmnet(X_mat, y_vec, alpha = 0)
cv_lasso <- cv.glmnet(X_mat, y_vec, alpha = 1)
ridge_model <- glmnet(X_mat, y_vec, alpha = 0, lambda = cv_ridge$lambda.min)
lasso_model <- glmnet(X_mat, y_vec, alpha = 1, lambda = cv_lasso$lambda.min)
cat("Koef Ridge:\n"); print(coef(ridge_model))
## Koef Ridge:
## 20 x 1 sparse Matrix of class "dgCMatrix"
## s0
## (Intercept) 0.320057324
## Status -0.021952347
## Adult.Mortality -0.294033101
## infant.deaths 0.048510894
## Alcohol -0.040204914
## percentage.expenditure 0.102325446
## Hepatitis.B -0.007071805
## Measles 0.029128416
## BMI 0.064717666
## under.five.deaths -0.164137697
## Polio 0.034579366
## Total.expenditure 0.013476514
## Diphtheria 0.028328329
## HIV.AIDS -0.448987392
## GDP 0.072480111
## Population 0.076334973
## thinness..1.19.years -0.025959122
## thinness.5.9.years -0.012269314
## Income.composition.of.resources 0.197501700
## Schooling 0.293445522
cat("\nKoef LASSO:\n"); print(coef(lasso_model))
##
## Koef LASSO:
## 20 x 1 sparse Matrix of class "dgCMatrix"
## s0
## (Intercept) 0.325165657
## Status -0.020388837
## Adult.Mortality -0.289116719
## infant.deaths 2.622135430
## Alcohol -0.037802537
## percentage.expenditure 0.146728689
## Hepatitis.B -0.009064405
## Measles -0.006706986
## BMI 0.057986827
## under.five.deaths -2.635561702
## Polio 0.029876316
## Total.expenditure 0.016152878
## Diphtheria 0.018093458
## HIV.AIDS -0.470648052
## GDP 0.024375137
## Population 0.012342258
## thinness..1.19.years -0.021380257
## thinness.5.9.years -0.014322764
## Income.composition.of.resources 0.193680414
## Schooling 0.320272388
Model Ridge menunjukkan semua koefisien mengecil dan tetap stabil (misalnya Adult.Mortality = –0.294, HIV.AIDS = –0.449, Schooling = 0.293), sedangkan LASSO menonjolkan prediktor paling kuat dengan nilai koefisien ekstrem seperti infant.deaths = 2.622, under.five.deaths = –2.636, dan HIV.AIDS = –0.471 sebagai variabel yang paling memengaruhi variabel target.
library(caret)
set.seed(123)
folds <- createFolds(y_vec, k = 5)
mse_ridge <- mse_lasso <- c()
for(i in seq_along(folds)){
test_idx <- folds[[i]]
train_idx <- setdiff(seq_along(y_vec), test_idx)
X_train <- X_mat[train_idx, ]
X_test <- X_mat[test_idx, ]
y_train <- y_vec[train_idx]
y_test <- y_vec[test_idx]
# Ridge
mod_ridge <- glmnet(X_train, y_train, alpha = 0, lambda = cv_ridge$lambda.min)
pred_ridge <- predict(mod_ridge, X_test)
mse_ridge[i] <- mean((y_test - pred_ridge)^2)
# LASSO
mod_lasso <- glmnet(X_train, y_train, alpha = 1, lambda = cv_lasso$lambda.min)
pred_lasso <- predict(mod_lasso, X_test)
mse_lasso[i] <- mean((y_test - pred_lasso)^2)
}
cat("CV MSE Ridge :", mean(mse_ridge), "\n")
## CV MSE Ridge : 0.006801859
cat("CV MSE LASSO :", mean(mse_lasso), "\n")
## CV MSE LASSO : 0.006455907
Hasil K-Fold Cross Validation menunjukkan bahwa model LASSO memiliki performa sedikit lebih baik (CV MSE = 0.006456) dibandingkan Ridge (CV MSE = 0.006802), sehingga LASSO lebih optimal dalam memprediksi variabel target pada data ini.
cat("AIC Full :", AIC(model_full), "\n")
## AIC Full : -2919.126
if (exists("model_reduced")) {
cat("AIC Reduced :", AIC(model_reduced), "\n")
}
## AIC Reduced : -4854.897
cat("AIC PCA :", AIC(model_pca), "\n")
## AIC PCA : -1836.037
cat("MSE Ridge :", mean(mse_ridge), "\n")
## MSE Ridge : 0.006801859
cat("MSE LASSO :", mean(mse_lasso), "\n")
## MSE LASSO : 0.006455907
Dari perbandingan model, reduced model memiliki AIC paling rendah sehingga lebih efisien dan fit dibanding full dan PCA model, sedangkan LASSO memiliki MSE lebih rendah daripada Ridge, menunjukkan prediksi LASSO sedikit lebih akurat.
cat("\n=== KESIMPULAN AKHIR ===\n")
##
## === KESIMPULAN AKHIR ===
if (exists("model_reduced") && AIC(model_reduced) < AIC(model_full)) {
cat("- Model Reduced lebih baik dari Model Full (AIC lebih kecil).\n")
}
## - Model Reduced lebih baik dari Model Full (AIC lebih kecil).
if (AIC(model_pca) < AIC(model_full)) {
cat("- Model PCA memberikan hasil lebih baik & bebas multikolinearitas.\n")
}
if (mean(mse_ridge) < mean(mse_lasso)) {
cat("- Ridge memiliki MSE lebih kecil → koefisien lebih stabil.\n")
} else {
cat("- LASSO memiliki MSE lebih kecil → seleksi variabel efektif.\n")
}
## - LASSO memiliki MSE lebih kecil → seleksi variabel efektif.
cat("- Model terbaik dipilih berdasarkan AIC dan MSE terkecil.\n")
## - Model terbaik dipilih berdasarkan AIC dan MSE terkecil.