Penelitian ini bertujuan untuk membandingkan kinerja dua metode klasifikasi multiclass, yaitu Linear Discriminant Analysis (LDA) dan Multinomial Logistic Regression (MLR), dalam mengklasifikasikan data makanan berdasarkan kandungan gizi.
Melakukan pembacaan file cvs yang didapatkan dari hasil scrapping di website FatSecret dimana kami melakukan pengambilan data pada beberapa tipe yaitu makanan energi, makanan low-fat, makanan pembentuk otot dan makanan ringan
library(nnet)
data <- read.csv("C:\\Users\\lenovo\\Documents\\Semester 4\\Multivariat\\UAS\\Dataset Gizi FIXX.csv")
str(data)
## 'data.frame': 327 obs. of 14 variables:
## $ Nama : chr "Kentang Goreng" "Mie" "Nasi Putih" "Roti Putih" ...
## $ karbohidrat : num 35.7 25 27.9 50.6 48 ...
## $ protein : num 3.48 4.51 2.66 7.64 5 ...
## $ kalori : int 274 137 129 266 474 157 301 307 197 260 ...
## $ lemak : num 14.06 2.06 0.28 3.29 31 ...
## $ energi : int 1146 573 540 1113 1983 657 1259 1283 824 1090 ...
## $ lemak.jenuh : num 3.28 0.42 0.08 0.72 8.11 0.18 5.49 0.84 1.38 8.96 ...
## $ kolestrol : num 0 29 0 0 61 0 24 0 8 57 ...
## $ serat : num 3.3 1.2 0.4 2.4 2 1.8 1.6 6.4 1 1.4 ...
## $ gula : num 0.58 0.4 0.05 4.31 23.37 ...
## $ sodium : num 300 236 365 681 429 232 693 372 128 350 ...
## $ kalium : int 527 38 35 100 196 45 206 330 180 323 ...
## $ kategori.makanan: chr "nabati" "nabati" "nabati" "nabati" ...
## $ label : chr "makanan energi" "makanan energi" "makanan energi" "makanan energi" ...
Setelah melakukan pembacaan data dilakukan proses penghapusan kolom non-numerik yang tidak relevan menggunakan MLR
data$Nama <- NULL
data$kategori.makanan <- NULL
Melakukan pengecekan data dengan melakukan ringkasan serta melakukan pengubahan kolom variabel label pada data menjadi tipe faktor.
str(data)
## 'data.frame': 327 obs. of 12 variables:
## $ karbohidrat: num 35.7 25 27.9 50.6 48 ...
## $ protein : num 3.48 4.51 2.66 7.64 5 ...
## $ kalori : int 274 137 129 266 474 157 301 307 197 260 ...
## $ lemak : num 14.06 2.06 0.28 3.29 31 ...
## $ energi : int 1146 573 540 1113 1983 657 1259 1283 824 1090 ...
## $ lemak.jenuh: num 3.28 0.42 0.08 0.72 8.11 0.18 5.49 0.84 1.38 8.96 ...
## $ kolestrol : num 0 29 0 0 61 0 24 0 8 57 ...
## $ serat : num 3.3 1.2 0.4 2.4 2 1.8 1.6 6.4 1 1.4 ...
## $ gula : num 0.58 0.4 0.05 4.31 23.37 ...
## $ sodium : num 300 236 365 681 429 232 693 372 128 350 ...
## $ kalium : int 527 38 35 100 196 45 206 330 180 323 ...
## $ label : chr "makanan energi" "makanan energi" "makanan energi" "makanan energi" ...
data$label <- as.factor(data$label)
Output yang dihasilkan terdapat 327 baris data observasi serta 11 kolom variabel yaitu karbohidrat, protein, kalori, lemak, energi, lemak jenuh, kolestrol, serat, gula, sodium, dan kalium dari output yang dihasilkan akan digunakan untuk menjadi dasar penting sebelum dilakukannya modeling.
Setelah melakukan peringkasan data dan menentukan variabe mana yang dijadikan target maka langkah selanjutnya adalah melakukan uji serentak serta melakukan fit model dan uji parsial pada data.
model_null <- multinom(label ~ 1, data = data, trace = FALSE)
model_full <- multinom(label ~ karbohidrat + protein + kalori + lemak + energi + lemak.jenuh + kolestrol + serat + gula + sodium + kalium,
data = data, trace = FALSE)
lrtest(model_null, model_full)
## Likelihood ratio test
##
## Model 1: label ~ 1
## Model 2: label ~ karbohidrat + protein + kalori + lemak + energi + lemak.jenuh +
## kolestrol + serat + gula + sodium + kalium
## #Df LogLik Df Chisq Pr(>Chisq)
## 1 3 -452.94
## 2 36 -190.61 33 524.66 < 2.2e-16 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
Dari hasil uji ini menunjukkan bahwa model multinomial logistik yang menggunakan sebelas variabel prediktor lebih baik dalam menjelaskan variabel abel dibandingkan dengan model yang hanya memuat interceot dengan nilai statistik Chi-Square yang didapatkan 524.66 dengan derajat bebas 33 serta p-value kurang dari 2.2e-16. dapat disimpulkan bahwa kandungan nutrisi yang digunakan sebagai prediksi memiliki pengaruh yang signifikan terhadap pengelompokan kategori makanan dalam data yang digunakan.
Selanjutnya kita melakukan pelatihan model regresi logistik multinomial serta melihat variabel prediktor berdasarkan kelas target.
model_mlr <- multinom(label ~ karbohidrat + protein + kalori + lemak + energi + kolestrol + serat + gula + sodium + kalium, data = data)
## # weights: 48 (33 variable)
## initial value 453.318256
## iter 10 value 338.055643
## iter 20 value 303.711602
## iter 30 value 205.863167
## iter 40 value 191.289397
## iter 50 value 190.997290
## iter 60 value 190.985586
## final value 190.985562
## converged
summary(model_mlr)
## Call:
## multinom(formula = label ~ karbohidrat + protein + kalori + lemak +
## energi + kolestrol + serat + gula + sodium + kalium, data = data)
##
## Coefficients:
## (Intercept) karbohidrat protein kalori
## makanan low-fat 1.516986 0.14127082 -0.07943267 -1.9432774
## makanan pembentuk otot -3.391066 0.08067081 0.43770903 -0.7686755
## makanan ringan -2.041255 -0.17042688 -0.34972079 2.0344782
## lemak energi kolestrol serat gula
## makanan low-fat 0.4339562 0.4521069 -0.01048595 -0.06440660 0.07615717
## makanan pembentuk otot 0.4790793 0.1704845 0.02259873 0.04806559 0.11039821
## makanan ringan -0.3213874 -0.4744159 0.01973076 0.05038109 0.05872350
## sodium kalium
## makanan low-fat -0.0016478940 0.0043856400
## makanan pembentuk otot 0.0040633605 0.0025570292
## makanan ringan -0.0005683729 0.0003732306
##
## Std. Errors:
## (Intercept) karbohidrat protein kalori lemak
## makanan low-fat 0.46885483 0.0807476 0.1629985 0.02868622 0.1981852
## makanan pembentuk otot 0.08261517 0.2297233 0.2623263 0.00755073 0.5103634
## makanan ringan 0.54029759 0.1244845 0.1414823 0.07253874 0.2718647
## energi kolestrol serat gula
## makanan low-fat 0.009440971 0.015737012 0.07894466 0.02904542
## makanan pembentuk otot 0.012602460 0.009896429 0.02916676 0.07875991
## makanan ringan 0.019216402 0.008740515 0.02678299 0.02691098
## sodium kalium
## makanan low-fat 0.002175226 0.0011719279
## makanan pembentuk otot 0.001891537 0.0024525132
## makanan ringan 0.001009324 0.0009889493
##
## Residual Deviance: 381.9711
## AIC: 447.9711
tidy(model_mlr, conf.int = TRUE) %>%
kable() %>%
kable_styling("basic", full_width = FALSE)
| y.level | term | estimate | std.error | statistic | p.value | conf.low | conf.high |
|---|---|---|---|---|---|---|---|
| makanan low-fat | (Intercept) | 1.5169864 | 0.4688548 | 3.2355142 | 0.0012142 | 0.5980479 | 2.4359250 |
| makanan low-fat | karbohidrat | 0.1412708 | 0.0807476 | 1.7495358 | 0.0801985 | -0.0169916 | 0.2995332 |
| makanan low-fat | protein | -0.0794327 | 0.1629985 | -0.4873214 | 0.6260306 | -0.3989039 | 0.2400386 |
| makanan low-fat | kalori | -1.9432774 | 0.0286862 | -67.7425317 | 0.0000000 | -1.9995013 | -1.8870534 |
| makanan low-fat | lemak | 0.4339562 | 0.1981852 | 2.1896499 | 0.0285496 | 0.0455204 | 0.8223921 |
| makanan low-fat | energi | 0.4521069 | 0.0094410 | 47.8877569 | 0.0000000 | 0.4336029 | 0.4706109 |
| makanan low-fat | kolestrol | -0.0104859 | 0.0157370 | -0.6663239 | 0.5052041 | -0.0413299 | 0.0203580 |
| makanan low-fat | serat | -0.0644066 | 0.0789447 | -0.8158449 | 0.4145889 | -0.2191353 | 0.0903221 |
| makanan low-fat | gula | 0.0761572 | 0.0290454 | 2.6220030 | 0.0087415 | 0.0192292 | 0.1330851 |
| makanan low-fat | sodium | -0.0016479 | 0.0021752 | -0.7575735 | 0.4487063 | -0.0059113 | 0.0026155 |
| makanan low-fat | kalium | 0.0043856 | 0.0011719 | 3.7422439 | 0.0001824 | 0.0020887 | 0.0066826 |
| makanan pembentuk otot | (Intercept) | -3.3910664 | 0.0826152 | -41.0465325 | 0.0000000 | -3.5529892 | -3.2291437 |
| makanan pembentuk otot | karbohidrat | 0.0806708 | 0.2297233 | 0.3511652 | 0.7254644 | -0.3695785 | 0.5309201 |
| makanan pembentuk otot | protein | 0.4377090 | 0.2623263 | 1.6685671 | 0.0952032 | -0.0764411 | 0.9518591 |
| makanan pembentuk otot | kalori | -0.7686755 | 0.0075507 | -101.8014784 | 0.0000000 | -0.7834746 | -0.7538763 |
| makanan pembentuk otot | lemak | 0.4790793 | 0.5103634 | 0.9387024 | 0.3478836 | -0.5212145 | 1.4793731 |
| makanan pembentuk otot | energi | 0.1704845 | 0.0126025 | 13.5278765 | 0.0000000 | 0.1457842 | 0.1951849 |
| makanan pembentuk otot | kolestrol | 0.0225987 | 0.0098964 | 2.2835234 | 0.0223996 | 0.0032021 | 0.0419954 |
| makanan pembentuk otot | serat | 0.0480656 | 0.0291668 | 1.6479577 | 0.0993613 | -0.0091002 | 0.1052314 |
| makanan pembentuk otot | gula | 0.1103982 | 0.0787599 | 1.4017056 | 0.1610032 | -0.0439684 | 0.2647648 |
| makanan pembentuk otot | sodium | 0.0040634 | 0.0018915 | 2.1481789 | 0.0316995 | 0.0003560 | 0.0077707 |
| makanan pembentuk otot | kalium | 0.0025570 | 0.0024525 | 1.0426159 | 0.2971262 | -0.0022498 | 0.0073639 |
| makanan ringan | (Intercept) | -2.0412552 | 0.5402976 | -3.7780201 | 0.0001581 | -3.1002190 | -0.9822914 |
| makanan ringan | karbohidrat | -0.1704269 | 0.1244845 | -1.3690607 | 0.1709803 | -0.4144121 | 0.0735583 |
| makanan ringan | protein | -0.3497208 | 0.1414823 | -2.4718348 | 0.0134422 | -0.6270209 | -0.0724206 |
| makanan ringan | kalori | 2.0344782 | 0.0725387 | 28.0467803 | 0.0000000 | 1.8923049 | 2.1766515 |
| makanan ringan | lemak | -0.3213874 | 0.2718647 | -1.1821593 | 0.2371425 | -0.8542326 | 0.2114577 |
| makanan ringan | energi | -0.4744159 | 0.0192164 | -24.6880724 | 0.0000000 | -0.5120794 | -0.4367525 |
| makanan ringan | kolestrol | 0.0197308 | 0.0087405 | 2.2573906 | 0.0239837 | 0.0025997 | 0.0368618 |
| makanan ringan | serat | 0.0503811 | 0.0267830 | 1.8810853 | 0.0599603 | -0.0021126 | 0.1028748 |
| makanan ringan | gula | 0.0587235 | 0.0269110 | 2.1821395 | 0.0290992 | 0.0059790 | 0.1114680 |
| makanan ringan | sodium | -0.0005684 | 0.0010093 | -0.5631224 | 0.5733515 | -0.0025466 | 0.0014099 |
| makanan ringan | kalium | 0.0003732 | 0.0009889 | 0.3774012 | 0.7058755 | -0.0015651 | 0.0023115 |
Hasil yang didapatkan dalam model ini adalah masing-masing variabel nutrisi saling memengaruhi serta nilai deviance serta AIC yang dihasilkan mengidektifikasikan adanya kecocokan model secara keseluruhan dan model dapat membantu memahami faktor nutrisi yang membedakan jenis makanan berdasarkan tujuannya.
Sebelum melakukan evaluasi model kita harus melakukan pengubahan log-odds ke odds ratio untuk memberi interpretasi seberapa besar peluang yang diperoleh.
exp(coef(model_mlr))
## (Intercept) karbohidrat protein kalori lemak
## makanan low-fat 4.55846725 1.1517365 0.9236402 0.1432337 1.5433513
## makanan pembentuk otot 0.03367275 1.0840140 1.5491541 0.4636267 1.6145872
## makanan ringan 0.12986560 0.8433047 0.7048849 7.6482604 0.7251422
## energi kolestrol serat gula sodium
## makanan low-fat 1.5716199 0.9895688 0.9376237 1.079132 0.9983535
## makanan pembentuk otot 1.1858793 1.0228560 1.0492395 1.116723 1.0040716
## makanan ringan 0.6222484 1.0199267 1.0516718 1.060482 0.9994318
## kalium
## makanan low-fat 1.004395
## makanan pembentuk otot 1.002560
## makanan ringan 1.000373
tidy(model_mlr, conf.int = TRUE, exponentiate = TRUE) %>%
kable() %>%
kable_styling("basic", full_width = FALSE)
| y.level | term | estimate | std.error | statistic | p.value | conf.low | conf.high |
|---|---|---|---|---|---|---|---|
| makanan low-fat | (Intercept) | 4.5584673 | 0.4688548 | 3.2355142 | 0.0012142 | 1.8185652 | 11.4263834 |
| makanan low-fat | karbohidrat | 1.1517365 | 0.0807476 | 1.7495358 | 0.0801985 | 0.9831520 | 1.3492289 |
| makanan low-fat | protein | 0.9236402 | 0.1629985 | -0.4873214 | 0.6260306 | 0.6710552 | 1.2712982 |
| makanan low-fat | kalori | 0.1432337 | 0.0286862 | -67.7425317 | 0.0000000 | 0.1354028 | 0.1515176 |
| makanan low-fat | lemak | 1.5433513 | 0.1981852 | 2.1896499 | 0.0285496 | 1.0465723 | 2.2759377 |
| makanan low-fat | energi | 1.5716199 | 0.0094410 | 47.8877569 | 0.0000000 | 1.5428062 | 1.6009719 |
| makanan low-fat | kolestrol | 0.9895688 | 0.0157370 | -0.6663239 | 0.5052041 | 0.9595125 | 1.0205667 |
| makanan low-fat | serat | 0.9376237 | 0.0789447 | -0.8158449 | 0.4145889 | 0.8032130 | 1.0945268 |
| makanan low-fat | gula | 1.0791322 | 0.0290454 | 2.6220030 | 0.0087415 | 1.0194153 | 1.1423473 |
| makanan low-fat | sodium | 0.9983535 | 0.0021752 | -0.7575735 | 0.4487063 | 0.9941062 | 1.0026189 |
| makanan low-fat | kalium | 1.0043953 | 0.0011719 | 3.7422439 | 0.0001824 | 1.0020909 | 1.0067050 |
| makanan pembentuk otot | (Intercept) | 0.0336727 | 0.0826152 | -41.0465325 | 0.0000000 | 0.0286389 | 0.0395914 |
| makanan pembentuk otot | karbohidrat | 1.0840140 | 0.2297233 | 0.3511652 | 0.7254644 | 0.6910255 | 1.7004963 |
| makanan pembentuk otot | protein | 1.5491541 | 0.2623263 | 1.6685671 | 0.0952032 | 0.9264075 | 2.5905213 |
| makanan pembentuk otot | kalori | 0.4636267 | 0.0075507 | -101.8014784 | 0.0000000 | 0.4568160 | 0.4705391 |
| makanan pembentuk otot | lemak | 1.6145872 | 0.5103634 | 0.9387024 | 0.3478836 | 0.5937989 | 4.3901926 |
| makanan pembentuk otot | energi | 1.1858793 | 0.0126025 | 13.5278765 | 0.0000000 | 1.1569464 | 1.2155357 |
| makanan pembentuk otot | kolestrol | 1.0228560 | 0.0098964 | 2.2835234 | 0.0223996 | 1.0032072 | 1.0428897 |
| makanan pembentuk otot | serat | 1.0492395 | 0.0291668 | 1.6479577 | 0.0993613 | 0.9909411 | 1.1109676 |
| makanan pembentuk otot | gula | 1.1167227 | 0.0787599 | 1.4017056 | 0.1610032 | 0.9569842 | 1.3031244 |
| makanan pembentuk otot | sodium | 1.0040716 | 0.0018915 | 2.1481789 | 0.0316995 | 1.0003561 | 1.0078010 |
| makanan pembentuk otot | kalium | 1.0025603 | 0.0024525 | 1.0426159 | 0.2971262 | 0.9977527 | 1.0073910 |
| makanan ringan | (Intercept) | 0.1298656 | 0.5402976 | -3.7780201 | 0.0001581 | 0.0450393 | 0.3744521 |
| makanan ringan | karbohidrat | 0.8433047 | 0.1244845 | -1.3690607 | 0.1709803 | 0.6607286 | 1.0763313 |
| makanan ringan | protein | 0.7048849 | 0.1414823 | -2.4718348 | 0.0134422 | 0.5341808 | 0.9301396 |
| makanan ringan | kalori | 7.6482604 | 0.0725387 | 28.0467803 | 0.0000000 | 6.6346432 | 8.8167344 |
| makanan ringan | lemak | 0.7251422 | 0.2718647 | -1.1821593 | 0.2371425 | 0.4256097 | 1.2354777 |
| makanan ringan | energi | 0.6222484 | 0.0192164 | -24.6880724 | 0.0000000 | 0.5992482 | 0.6461314 |
| makanan ringan | kolestrol | 1.0199267 | 0.0087405 | 2.2573906 | 0.0239837 | 1.0026030 | 1.0375497 |
| makanan ringan | serat | 1.0516718 | 0.0267830 | 1.8810853 | 0.0599603 | 0.9978896 | 1.1083526 |
| makanan ringan | gula | 1.0604820 | 0.0269110 | 2.1821395 | 0.0290992 | 1.0059969 | 1.1179180 |
| makanan ringan | sodium | 0.9994318 | 0.0010093 | -0.5631224 | 0.5733515 | 0.9974566 | 1.0014109 |
| makanan ringan | kalium | 1.0003733 | 0.0009889 | 0.3774012 | 0.7058755 | 0.9984361 | 1.0023142 |
Output yang dihasilkan menunjukkan bahwa variabel-variabel memiliki pengaruh yang relatif kecil terhadap klasifikasi makanan.
Evaluasi model dilakukan guna melihat hasil prediksi dari model yang sudah dilatih.
library(caret)
## Loading required package: lattice
##
## Attaching package: 'caret'
## The following object is masked from 'package:purrr':
##
## lift
library(ggplot2)
library(reshape2)
##
## Attaching package: 'reshape2'
## The following object is masked from 'package:tidyr':
##
## smiths
predicted <- predict(model_mlr, newdata = data)
actual <- as.factor(data$label)
cm <- confusionMatrix(data = as.factor(predicted), reference = actual)
print(cm)
## Confusion Matrix and Statistics
##
## Reference
## Prediction makanan energi makanan low-fat makanan pembentuk otot
## makanan energi 55 7 5
## makanan low-fat 14 71 0
## makanan pembentuk otot 3 1 69
## makanan ringan 12 5 1
## Reference
## Prediction makanan ringan
## makanan energi 15
## makanan low-fat 8
## makanan pembentuk otot 3
## makanan ringan 58
##
## Overall Statistics
##
## Accuracy : 0.7737
## 95% CI : (0.7244, 0.8179)
## No Information Rate : 0.2569
## P-Value [Acc > NIR] : <2e-16
##
## Kappa : 0.6981
##
## Mcnemar's Test P-Value : 0.4392
##
## Statistics by Class:
##
## Class: makanan energi Class: makanan low-fat
## Sensitivity 0.6548 0.8452
## Specificity 0.8889 0.9095
## Pos Pred Value 0.6707 0.7634
## Neg Pred Value 0.8816 0.9444
## Prevalence 0.2569 0.2569
## Detection Rate 0.1682 0.2171
## Detection Prevalence 0.2508 0.2844
## Balanced Accuracy 0.7718 0.8774
## Class: makanan pembentuk otot Class: makanan ringan
## Sensitivity 0.9200 0.6905
## Specificity 0.9722 0.9259
## Pos Pred Value 0.9079 0.7632
## Neg Pred Value 0.9761 0.8964
## Prevalence 0.2294 0.2569
## Detection Rate 0.2110 0.1774
## Detection Prevalence 0.2324 0.2324
## Balanced Accuracy 0.9461 0.8082
cm_table <- as.table(cm$table)
cm_df <- as.data.frame(cm_table)
colnames(cm_df) <- c("Actual", "Predicted", "Freq")
Hasil evaluasi model confusion matrix menunjukkan bahwa model multinomial logistic regression memiliki akurasi 77.37% dan nilai kappa 0.6981 dimana hasil yang diperoleh menunjukkan performa klasifikasi yang cukup baik.
ggplot(cm_df, aes(x = Actual, y = Predicted, fill = Freq)) +
geom_tile(color = "white") +
geom_text(aes(label = Freq), size = 5) +
scale_fill_gradient(low = "white", high = "blue") +
labs(title = "Confusion Matrix", x = "Actual Label", y = "Predicted Label") +
theme_minimal() +
theme(axis.text.x = element_text(angle = 45, hjust = 1))
Hasil visualisasi confusion matrix menunjukkan bahwa model paling akurat
dalam mengklasifikasi makanan low-fat dan makanan pembentuk otot. Namun,
terjadi banyak kesalahan antara makanan energi dan makanan ringan, yang
sering tertukar. Hal ini menunjukkan bahwa kedua kategori tersebut
memiliki karakteristik yang mirip dan sulit dibedakan oleh model.
Melakukan pembacaan file cvs yang didapatkan dari hasil scrapping di website FatSecret dimana kami melakukan pengambilan data pada beberapa tipe yaitu makanan energi, makanan low-fat, makanan pembentuk otot dan makanan ringan
data <- read.csv("C:\\Users\\lenovo\\Documents\\Semester 4\\Multivariat\\UAS\\Dataset Gizi FIXX.csv")
data[, 2:12] <- lapply(data[, 2:12], function(x) as.numeric(as.character(x)))
data$label <- as.factor(data$label)
data$Nama <- NULL
data$kategori.makanan <- NULL
str(data)
## 'data.frame': 327 obs. of 12 variables:
## $ karbohidrat: num 35.7 25 27.9 50.6 48 ...
## $ protein : num 3.48 4.51 2.66 7.64 5 ...
## $ kalori : num 274 137 129 266 474 157 301 307 197 260 ...
## $ lemak : num 14.06 2.06 0.28 3.29 31 ...
## $ energi : num 1146 573 540 1113 1983 ...
## $ lemak.jenuh: num 3.28 0.42 0.08 0.72 8.11 0.18 5.49 0.84 1.38 8.96 ...
## $ kolestrol : num 0 29 0 0 61 0 24 0 8 57 ...
## $ serat : num 3.3 1.2 0.4 2.4 2 1.8 1.6 6.4 1 1.4 ...
## $ gula : num 0.58 0.4 0.05 4.31 23.37 ...
## $ sodium : num 300 236 365 681 429 232 693 372 128 350 ...
## $ kalium : num 527 38 35 100 196 45 206 330 180 323 ...
## $ label : Factor w/ 4 levels "makanan energi",..: 1 1 1 1 1 1 1 1 1 3 ...
Melakukan pengecekan data untuk memastikan tidak ada data yang kosong (NA)
cat("Jumlah NA:\n")
## Jumlah NA:
print(colSums(is.na(data)))
## karbohidrat protein kalori lemak energi lemak.jenuh
## 0 0 0 0 0 0
## kolestrol serat gula sodium kalium label
## 0 0 0 0 0 0
Melakukan analisis untuk melihat perbandingan distribusi berbagai variabel antar kelas makanan dan hasil visualisasi yang didapatkan pada setiap kelasnya memiliki ciri khas distribusi nutrisi yang berbeda-beda.
library(ggplot2)
vars <- c("karbohidrat", "protein", "kalori", "lemak", "energi",
"lemak.jenuh", "kolestrol", "serat", "gula", "sodium", "kalium")
data_long <- data %>%
dplyr::select(all_of(vars), label) %>%
pivot_longer(cols = all_of(vars), names_to = "Nutrisi", values_to = "Nilai")
ggplot(data_long, aes(x = Nilai, fill = label)) +
geom_histogram(alpha = 0.6, bins = 30, position = "identity") +
facet_wrap(~ Nutrisi, scales = "free") +
theme_minimal() +
labs(title = "Distribusi Nutrisi per Kelas Makanan",
x = "Nilai Nutrisi",
y = "Frekuensi",
fill = "Kelas Makanan")
Lakukan standarisasi data untuk melihat korelasi antar variabel tanpa
memasukkan label data.
library(lattice)
library(caret)
preProcValues <- preProcess(dplyr::select(data, -label), method = c("center", "scale"))
data_scaled <- predict(preProcValues, newdata = dplyr::select(data, -label))
data_scaled$label <- data$label
cor_matrix <- cor(data_scaled[, -which(names(data_scaled) == "label")])
library(corrplot)
## corrplot 0.95 loaded
corrplot(cor_matrix, method = "color")
Lakukan kalsifikasi model LDA berdasarkan data yang sudah
diproses.diperoleh beberapa output yang oertama ada prior probabilities
of grups dengan masih rata-rata 25% yang menunjukkan bahwa dataset cukup
seimbang, selanjutnya ada grup means per kelas, selanjutnya ada
coefficients of linear discriminants LD1, LD2, LD3 pada setiap kelas dan
yang terakhir niali proportion of trace dimana LD1 73.3%, LD2 21.0% dan
LD3 5.7% dimana LD1 sangan dominan
library(dplyr)
library(MASS)
##
## Attaching package: 'MASS'
## The following object is masked from 'package:dplyr':
##
## select
lda_model <- lda(label ~ ., data = data_scaled)
print(lda_model)
## Call:
## lda(label ~ ., data = data_scaled)
##
## Prior probabilities of groups:
## makanan energi makanan low-fat makanan pembentuk otot
## 0.2568807 0.2568807 0.2293578
## makanan ringan
## 0.2568807
##
## Group means:
## karbohidrat protein kalori lemak
## makanan energi 0.3238541 -0.1848959 -0.02338361 -0.3241319
## makanan low-fat -0.1239382 -0.8324875 -0.78418742 -0.6843374
## makanan pembentuk otot -0.9823925 1.4476429 0.07105225 0.5328204
## makanan ringan 0.6772203 -0.2751549 0.74413152 0.5327367
## energi lemak.jenuh kolestrol serat
## makanan energi -0.02339547 -0.3216662 -0.2763402 -0.07293848
## makanan low-fat -0.78401655 -0.5417830 -0.4069607 -0.13340596
## makanan pembentuk otot 0.07104870 0.3904986 0.8115496 -0.01785298
## makanan ringan 0.74397569 0.5147897 -0.0412969 0.22228459
## gula sodium kalium
## makanan energi -0.3133346 0.2716713 -0.24877236
## makanan low-fat 0.4284466 -0.7215896 0.11232712
## makanan pembentuk otot -0.5512094 0.3638302 0.20942382
## makanan ringan 0.3770392 0.1250699 -0.05054032
##
## Coefficients of linear discriminants:
## LD1 LD2 LD3
## karbohidrat 0.68730962 -3.3853604 -1.47406022
## protein 2.08661897 -1.5504750 -0.69144738
## kalori -1.65984463 148.0625580 63.13723121
## lemak 1.31232322 -3.9089333 -0.02117724
## energi -0.35378244 -141.3656395 -61.75234352
## lemak.jenuh -0.04810644 0.3105622 -0.09423941
## kolestrol 0.33467839 0.1278817 0.14993641
## serat 0.03851340 0.2371136 0.16559464
## gula 0.21719246 -0.3686203 0.87610085
## sodium 0.20335145 -0.0213199 -0.23708520
## kalium -0.01390272 -0.4559236 0.11500442
##
## Proportion of trace:
## LD1 LD2 LD3
## 0.7332 0.2103 0.0565
Melakukan analisis dengan asumsi homogenitas matriks kovarian antar kelas makanan yang tidak terpenuhi didapatkan hasil Box’s M-test dengan nilai p < 2.2e-16, yang sangat signifikan. Artinya, variansi-kovarians antar kelas makanan berbeda secara signifikan. Namun, hasil MANOVA dengan uji Wilks Lambda juga sangat signifikan (p < 2.2e-16), menunjukkan bahwa secara keseluruhan terdapat perbedaan yang signifikan dalam kombinasi fitur nutrisi antar kelas makanan.
library(biotools)
## Warning: package 'biotools' was built under R version 4.4.3
## ---
## biotools version 4.3
boxM(data_scaled[, -which(names(data_scaled) == "label")], data_scaled$label)
##
## Box's M-test for Homogeneity of Covariance Matrices
##
## data: data_scaled[, -which(names(data_scaled) == "label")]
## Chi-Sq (approx.) = 2223.2, df = 198, p-value < 2.2e-16
manova_model <- manova(as.matrix(data_scaled[, -which(names(data_scaled) == "label")]) ~ data_scaled$label)
summary(manova_model, test = "Wilks")
## Df Wilks approx F num Df den Df Pr(>F)
## data_scaled$label 3 0.11076 31.052 33 922.86 < 2.2e-16 ***
## Residuals 323
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
Hasil visualisasi LDA menunjukkan bahwa makanan pembentuk otot (hijau) paling jelas terpisah dari kelas lain, menandakan fitur gizinya sangat berbeda. Sementara itu, kelas makanan energi, low-fat, dan ringan cenderung tumpang tindih, sehingga lebih sulit dibedakan. Ini menunjukkan bahwa model LDA efektif membedakan kelas tertentu tetapi bisa mengalami kesalahan pada kelas yang fitur gizinya mirip.
lda_pred <- predict(lda_model)
lda_df <- as.data.frame(lda_pred$x)
lda_df$label <- data_scaled$label
ggplot(lda_df, aes(x = LD1, y = LD2, color = label)) +
geom_point(alpha = 0.8, size = 2.5) +
theme_minimal() +
labs(title = "Visualisasi LDA: Klasifikasi Makanan Berdasarkan Gizi",
x = "LD1", y = "LD2") +
scale_color_brewer(palette = "Set1")
pred <- predict(lda_model)$class
table(pred, data_scaled$label)
##
## pred makanan energi makanan low-fat makanan pembentuk otot
## makanan energi 57 7 7
## makanan low-fat 17 72 0
## makanan pembentuk otot 2 1 68
## makanan ringan 8 4 0
##
## pred makanan ringan
## makanan energi 18
## makanan low-fat 13
## makanan pembentuk otot 3
## makanan ringan 50
ggplot(lda_df, aes(x = LD1, y = LD2, color = label)) +
geom_point(alpha = 0.8, size = 2.5) +
theme_minimal() +
labs(title = "Visualisasi LDA: Klasifikasi Makanan Berdasarkan Gizi",
x = "LD1", y = "LD2") +
scale_color_brewer(palette = "Set1")
pred <- predict(lda_model)$class
table(pred, data_scaled$label)
##
## pred makanan energi makanan low-fat makanan pembentuk otot
## makanan energi 57 7 7
## makanan low-fat 17 72 0
## makanan pembentuk otot 2 1 68
## makanan ringan 8 4 0
##
## pred makanan ringan
## makanan energi 18
## makanan low-fat 13
## makanan pembentuk otot 3
## makanan ringan 50
Melakukan rata-rata oada kandungan gizi pada setiap kategori makanan dengan menampilkan visualisasi dalam bentuk heatmap Pada plot, sumbu-x menunjukkan jenis kandungan gizi, sumbu-y menunjukkan kategori makanan, dan warna kotak (dari biru ke merah) merepresentasikan nilai rata-rata nutrisi—merah untuk nilai tinggi, biru untuk nilai rendah, dan putih untuk nilai mendekati rata-rata keseluruhan.
library(tidyr)
library(reshape2)
means <- aggregate(. ~ label, data = data_scaled, mean)
means_long <- melt(means, id.vars = "label")
ggplot(means_long, aes(x = variable, y = label, fill = value)) +
geom_tile(color = "white") +
scale_fill_gradient2(low = "blue", mid = "white", high = "red", midpoint = 0) +
theme_minimal() +
labs(title = "Heatmap Rata-rata Kandungan Gizi per Kategori Makanan",
x = "Kandungan Gizi", y = "Kategori Makanan")
Visualisai untuk melihat perbandingan rata-rata kandungan gizi beberapa
kategori makanan pada berbagai variabel nutrisi. Setiap warna mewakili
satu kategori makanan, dan pola garis menunjukkan keunggulan relatif
tiap nutrisi.
library(tidyr)
library(fmsb)
## Warning: package 'fmsb' was built under R version 4.4.3
## Registered S3 methods overwritten by 'fmsb':
## method from
## print.roc pROC
## plot.roc pROC
means_scaled <- rbind(
max = apply(means[,-1], 2, max),
min = apply(means[,-1], 2, min),
means[,-1]
)
rownames(means_scaled) <- c("max", "min", as.character(means$label))
radarchart(means_scaled,
axistype = 1,
pcol = c("red", "orange", "blue", "green", "purple"),
plwd = 2,
plty = 1,
title = "Profil Gizi Kategori Makanan (Radar Chart)",
cglcol = "grey", cglty = 1, axislabcol = "grey",
vlcex = 0.8)
legend("topright", legend = as.character(means$label), col = c("red", "orange", "blue", "green", "purple"),
lty = 1, lwd = 2, cex = 0.8)
Setelah dilakukan modeling pada data hasil yang didapatkan berdasarkan
confusion matrix pada model LDA dapat mengklasifikasikan data ke dalam
kategori makanan secara benar dengan tingkat akurasi sebesar 75,54%.
Kategori ‘makanan low-fat’ menunjukkan tingkat klasifikasi tertinggi,
sementara kesalahan klasifikasi banyak terjadi antara kategori ‘makanan
ringan’.
conf_mat <- table(Predicted = lda_pred$class, Actual = data_scaled$label)
print(conf_mat)
## Actual
## Predicted makanan energi makanan low-fat makanan pembentuk otot
## makanan energi 57 7 7
## makanan low-fat 17 72 0
## makanan pembentuk otot 2 1 68
## makanan ringan 8 4 0
## Actual
## Predicted makanan ringan
## makanan energi 18
## makanan low-fat 13
## makanan pembentuk otot 3
## makanan ringan 50
cat("Akurasi Training:", mean(lda_pred$class == data_scaled$label), "\n")
## Akurasi Training: 0.7553517
conf_mat <- table(Predicted = lda_pred$class, Actual = data_scaled$label)
conf_df <- as.data.frame(conf_mat)
colnames(conf_df) <- c("Predicted", "Actual", "Freq")
ggplot(conf_df, aes(x = Actual, y = Predicted, fill = Freq)) +
geom_tile(color = "white") +
geom_text(aes(label = Freq), color = "black", size = 4) +
scale_fill_gradient(low = "white", high = "steelblue") +
theme_minimal() +
labs(title = "Confusion Matrix LDA (Heatmap)",
x = "Kelas Aktual", y = "Kelas Prediksi")
Berdasarkan hasil analisis yang telah dilakukan, kedua model mempunyai akurasi yang tidak terlalu berbeda jauh. Model Linear Discriminant Analysis (LDA) berhasil mengklasifikasikan jenis makanan berdasarkan kandungan gizinya dengan nilai akurasi sebesar 75,54% sedangkan model Multinomial Logistic Regression (MLR) menghasilkan akurasi yang lebih tinggi yaitu 77,37%.
Hasil uji serentak pada kedua model menunjukkan bahwa kombinasi variabel kandungan gizi secara signifikan mampu membedakan kategori makanan. Dari hasil uji parsial pada model MLR, diketahui bahwa variabel kalori merupakan faktor yang paling membedakan antara kategori, diikuti oleh protein dan karbohidrat. Kalori sangat berperan dalam membedakan makanan ringan dari kategori lainnya, sementara protein berpengaruh besar terhadap makanan pembentuk otot, dan karbohidrat berperan besar dalam kategori makanan low-fat. Selain itu, nilai Kappa pada model MLR lebih tinggi dibandingkan LDA, menunjukkan bahwa MLR memiliki tingkat kesesuaian prediksi yang sedikit lebih kuat.
Oleh karena itu, dari hasil perbandingan kedua metode yang dilakukan dapat disimpulkan bahwa MLR dianggap sebagai metode yang lebih efektif dan efisien dalam melakukan klasifikasi kategori makanan berdasarkan kandungan gizi.