Pada penelitian ini, dilakukan analisis data Letter Recognition Dataset dengan menggunakan teknik Linear Discriminant Analysis (LDA) Multinomial. Tujuan dari analisis ini adalah untuk mengklasifikasikan 26 huruf abjad (A-Z) berdasarkan 16 fitur geometris, serta mengidentifikasi fitur-fitur yang paling berpengaruh dalam proses diskriminasi antar huruf. Dataset ini mencakup 20.000 sampel huruf hasil pemindaian dengan 16 variabel numerik seperti xbox, ybox, width, height, onpix, dan berbagai fitur edge yang merepresentasikan karakteristik geometris setiap huruf.
# Library yang digunakan
library(MASS)
## Warning: package 'MASS' was built under R version 4.5.3
library(ggplot2)
## Warning: package 'ggplot2' was built under R version 4.5.3
library(caret)
## Warning: package 'caret' was built under R version 4.5.3
## Loading required package: lattice
library(knitr)
# Membaca dataset
dataset <- read.csv("letter-recognition.csv", header = TRUE)
head(dataset)
## letter xbox ybox width height onpix xbar ybar x2bar y2bar xybar x2ybar xy2bar
## 1 T 2 8 3 5 1 8 13 0 6 6 10 8
## 2 I 5 12 3 7 2 10 5 5 4 13 3 9
## 3 D 4 11 6 8 6 10 6 2 6 10 3 7
## 4 N 7 11 6 6 3 5 9 4 6 4 4 10
## 5 G 2 1 3 1 1 8 6 6 6 6 5 9
## 6 S 4 11 5 8 3 8 8 6 9 5 6 6
## xedge xedgey yedge yedgex
## 1 0 8 0 8
## 2 2 8 4 10
## 3 3 7 3 9
## 4 6 10 2 8
## 5 1 7 5 10
## 6 0 8 9 7
Dataset memiliki 17 kolom, di mana kolom pertama adalah label huruf (A-Z) dan 16 kolom lainnya merupakan fitur numerik hasil ekstraksi dari citra huruf.
# Memberi nama pada kolom pertama
names(dataset)[1] <- "Letter"
# Mengubah kolom Letter menjadi faktor (kategorik)
dataset$Letter <- as.factor(dataset$Letter)
# Memisahkan data numerik (fitur) dan target
data_numeric <- dataset[, -1] # 16 fitur numerik
target <- dataset$Letter # target (huruf)
# Standarisasi data numerik
data_scaled <- scale(data_numeric)
# Cek hasil standarisasi
summary(data_scaled[, 1:3])
## xbox ybox width
## Min. :-2.10303 Min. :-2.12903 Min. :-2.54240
## 1st Qu.:-0.53499 1st Qu.:-0.61597 1st Qu.:-0.55687
## Median :-0.01231 Median :-0.01074 Median :-0.06048
## Mean : 0.00000 Mean : 0.00000 Mean : 0.00000
## 3rd Qu.: 0.51037 3rd Qu.: 0.59448 3rd Qu.: 0.43590
## Max. : 5.73719 Max. : 2.41016 Max. : 4.90335
Proses standarisasi dilakukan untuk memastikan bahwa setiap variabel memiliki skala yang seragam, dengan rata-rata 0 dan standar deviasi 1. Hal ini penting karena LDA sensitif terhadap skala variabel.
# Set seed untuk reproduksibilitas
set.seed(123)
# Membagi data (70% training, 30% testing)
trainIndex <- createDataPartition(dataset$Letter, p = 0.7, list = FALSE)
trainData <- dataset[trainIndex, ]
testData <- dataset[-trainIndex, ]
# Cek ukuran data
cat("Training set:", nrow(trainData), "sampel (70%)\n")
## Training set: 14015 sampel (70%)
cat("Testing set :", nrow(testData), "sampel (30%)\n")
## Testing set : 5985 sampel (30%)
# Cek proporsi kelas di training
prop.table(table(trainData$Letter))
##
## A B C D E F G
## 0.03945772 0.03831609 0.03681770 0.04024260 0.03838744 0.03874420 0.03867285
## H I J K L M N
## 0.03667499 0.03774527 0.03731716 0.03696040 0.03803068 0.03960043 0.03917232
## O P Q R S T U
## 0.03767392 0.04017125 0.03917232 0.03788798 0.03738851 0.03981448 0.04067071
## V W X Y Z
## 0.03817339 0.03760257 0.03931502 0.03931502 0.03667499
Data dibagi menjadi 70% untuk training (14.000 sampel) dan 30% untuk testing (6.000 sampel). Pembagian dilakukan secara stratified sehingga proporsi setiap huruf tetap terjaga.
LDA adalah teknik klasifikasi yang mencari kombinasi linear dari fitur-fitur yang paling mampu memisahkan antar kelompok (dalam hal ini, antar huruf). LDA bekerja dengan memaksimalkan rasio antara between-class variance dan within-class variance.
# Memisahkan prediktor dan target untuk training
X_train <- trainData[, -1] # 16 fitur numerik
y_train <- trainData$Letter # target (huruf)
# Membangun model LDA
lda_model <- lda(x = X_train, grouping = y_train)
# Menampilkan hasil model
print(lda_model)
## Call:
## lda(X_train, grouping = y_train)
##
## Prior probabilities of groups:
## A B C D E F G
## 0.03945772 0.03831609 0.03681770 0.04024260 0.03838744 0.03874420 0.03867285
## H I J K L M N
## 0.03667499 0.03774527 0.03731716 0.03696040 0.03803068 0.03960043 0.03917232
## O P Q R S T U
## 0.03767392 0.04017125 0.03917232 0.03788798 0.03738851 0.03981448 0.04067071
## V W X Y Z
## 0.03817339 0.03760257 0.03931502 0.03931502 0.03667499
##
## Group means:
## xbox ybox width height onpix xbar ybar x2bar
## A 3.330922 6.916817 5.086799 5.130199 2.922242 8.811935 3.623870 2.716094
## B 4.022346 7.026071 5.117318 5.242086 4.644320 7.620112 7.111732 5.437616
## C 4.013566 7.083333 4.656977 5.315891 2.713178 5.468992 7.649225 5.972868
## D 4.060284 7.400709 5.193262 5.363475 4.058511 7.531915 6.815603 5.920213
## E 3.758364 7.029740 4.758364 5.228625 3.635688 5.933086 7.364312 4.219331
## F 3.808471 7.009208 4.852670 5.149171 3.151013 4.950276 10.423573 3.460405
## G 4.064576 7.005535 4.970480 5.313653 3.538745 6.854244 6.605166 6.005535
## H 4.301556 6.830739 5.795720 5.161479 4.299611 7.332685 7.297665 6.546693
## I 2.349716 7.058601 2.703214 5.285444 1.880907 7.451796 7.088847 1.920605
## J 3.038241 6.950287 4.066922 5.743786 2.395793 9.648184 5.684512 3.908222
## K 4.586873 7.432432 6.036680 5.478764 4.057915 5.567568 7.065637 3.814672
## L 3.487805 7.260788 4.444653 5.378987 2.735460 4.878049 3.641651 3.416510
## M 4.962162 6.960360 6.736937 5.264865 5.291892 7.618018 6.436036 5.884685
## N 4.493625 7.260474 5.823315 5.371585 3.637523 7.056466 7.914390 6.579235
## O 4.138258 7.119318 4.888258 5.339015 3.488636 7.344697 7.007576 7.149621
## P 4.296625 7.253996 5.341030 5.541741 3.777975 6.300178 9.889876 5.250444
## Q 3.990893 6.276867 4.877960 6.340619 4.153005 8.169399 6.734062 6.107468
## R 4.109228 7.135593 5.252354 5.267420 4.182674 7.231638 8.079096 5.329567
## S 4.066794 7.341603 5.030534 5.374046 3.454198 7.750000 6.971374 4.538168
## T 3.976703 7.046595 4.811828 5.161290 2.881720 6.446237 11.403226 2.543011
## U 4.552632 6.921053 5.322807 5.105263 3.270175 6.047368 6.936842 7.217544
## V 4.200000 7.235514 5.271028 5.323364 2.757009 6.071028 10.089720 3.491589
## W 5.195446 7.222011 6.487666 5.360531 4.863378 6.077799 9.165085 3.497154
## X 3.990926 7.043557 5.611615 5.205082 3.156080 7.279492 7.172414 2.696915
## Y 4.174229 6.631579 5.246824 5.686025 3.054446 6.379310 9.528131 2.560799
## Z 3.745136 6.789883 4.879377 5.591440 3.254864 7.550584 7.093385 3.431907
## y2bar xybar x2ybar xy2bar xedge xedgey yedge yedgex
## A 1.983725 7.793852 2.316456 8.471971 2.7685353 6.285714 2.802893 7.508137
## B 5.597765 7.918063 5.525140 6.640596 3.1247672 7.914339 6.683426 9.059590
## C 7.201550 8.777132 7.480620 11.947674 1.9360465 8.862403 4.067829 8.575581
## D 6.523050 8.170213 5.113475 5.778369 3.4273050 7.826241 3.994681 7.601064
## E 7.680297 8.566914 6.241636 10.388476 2.0836431 8.245353 5.957249 8.418216
## F 4.885820 11.224678 7.795580 5.744015 1.7495396 9.090239 3.353591 6.718232
## G 5.354244 7.418819 6.188192 9.594096 2.8081181 8.345018 5.132841 9.225092
## H 4.321012 8.083658 5.939689 7.813230 3.8657588 8.073930 3.128405 7.834630
## I 6.009452 9.527410 5.809074 7.635161 0.5803403 8.056711 2.247637 7.918715
## J 5.066922 12.108987 4.648184 8.906310 1.1644359 6.913958 2.003824 7.399618
## K 5.314672 8.249035 6.262548 9.849421 4.0521236 7.679537 4.071429 8.791506
## L 6.609756 5.148218 2.649156 8.268293 1.1519700 7.412758 2.609756 7.712946
## M 3.363964 7.484685 6.772973 8.160360 8.2108108 6.158559 2.158559 7.533333
## N 3.715847 7.453552 5.861566 7.300546 5.4171220 8.438980 1.482696 7.010929
## O 4.820076 7.888258 5.897727 7.992424 3.3598485 8.107955 3.628788 7.903409
## P 3.531083 10.490231 5.879218 4.181172 2.2166963 9.793961 3.882771 7.730018
## Q 3.843352 6.779599 6.285974 9.251366 3.1402550 8.322404 5.304189 8.943534
## R 4.664783 7.770245 4.267420 7.606403 3.6233522 6.928437 5.109228 9.444444
## S 6.290076 8.225191 5.673664 7.578244 1.8530534 8.215649 6.996183 7.784351
## T 6.496416 8.747312 9.331541 6.761649 1.6093190 9.659498 2.265233 6.344086
## U 5.935088 7.636842 9.650877 8.533333 3.7701754 8.815789 1.771930 6.794737
## V 3.000000 7.809346 10.990654 7.648598 3.2485981 10.198131 1.566355 7.809346
## W 2.199241 7.603416 8.487666 7.796964 7.6337761 10.377609 1.550285 7.121442
## X 6.769510 7.956443 6.123412 7.894737 2.9074410 8.137931 4.840290 7.673321
## Y 4.785844 7.956443 10.564428 7.143376 2.1179673 10.591652 2.724138 6.337568
## Z 9.260700 9.227626 5.819066 7.951362 1.2315175 8.035019 7.153696 7.614786
##
## Coefficients of linear discriminants:
## LD1 LD2 LD3 LD4 LD5
## xbox 0.061278372 0.178181093 0.02739196 0.19329375 0.18162235
## ybox -0.034544045 0.008325415 0.02994827 -0.01127483 -0.10828595
## width 0.137486193 -0.223066447 -0.07092528 -0.07126699 -0.51274705
## height -0.118293061 0.040262295 -0.32013321 0.06323899 0.24293017
## onpix -0.007314345 0.092387815 0.20779160 -0.15492789 0.16814358
## xbar -0.042077720 0.163123664 -0.06870553 -0.05335791 0.43269340
## ybar 0.176644701 0.247972757 0.22468703 -0.26131056 0.07686387
## x2bar 0.069286643 -0.055675288 0.31794996 -0.21759951 0.11722477
## y2bar -0.028290350 0.038274968 0.42077751 0.10983128 0.24063297
## xybar -0.084861738 0.032425829 0.09386169 -0.23372628 0.22183690
## x2ybar 0.113602281 0.337917456 0.05795893 0.23415540 0.10908156
## xy2bar -0.041093015 -0.244297726 0.09859793 0.43870037 0.17178168
## xedge 0.668654872 -0.273032897 0.24345622 0.01235467 0.07941221
## xedgey -0.054842216 0.369438279 -0.09647995 0.28874176 -0.27284213
## yedge -0.431293214 0.056577123 0.15938259 -0.04600572 -0.23858466
## yedgex -0.006600119 -0.010378142 0.30170625 -0.01847027 -0.32725491
## LD6 LD7 LD8 LD9 LD10
## xbox 0.10504979 0.03517637 -0.15018986 -0.49940004 -0.237935704
## ybox 0.10459347 0.06633616 0.03340342 0.01570869 -0.001082091
## width -0.36169844 -0.35621955 -0.20383796 0.76848937 0.096512982
## height -0.11635747 -0.01889730 0.15070074 0.01358920 -0.002355991
## onpix 0.25885031 0.34421080 -0.14511704 -0.60813447 0.060047130
## xbar -0.15874798 -0.29775141 -0.06786426 -0.04695432 -0.365259259
## ybar -0.18191870 0.24238780 0.29016609 0.02320491 -0.448869832
## x2bar -0.03061579 0.07695799 -0.35497678 0.06519902 -0.025767921
## y2bar 0.42859296 0.04288022 0.11789040 0.05552014 -0.098793535
## xybar -0.16967379 0.19603055 0.01503213 0.13189131 0.334363358
## x2ybar 0.03258872 -0.40146376 -0.02080452 -0.22700688 0.323334312
## xy2bar -0.36283556 0.26473551 0.01514697 0.10902369 -0.173924856
## xedge 0.08052471 -0.02745907 0.37924368 0.23012944 0.043689844
## xedgey -0.07786693 0.26994370 -0.41486671 0.30613695 -0.117106471
## yedge -0.26172723 -0.31467356 0.06728941 0.20939945 0.109354775
## yedgex -0.06970222 0.09101907 0.15657278 -0.43431064 0.137971725
## LD11 LD12 LD13 LD14 LD15
## xbox -0.046464468 -0.4369407429 0.180934024 -0.055250837 -1.055106343
## ybox 0.136311531 0.5106904605 0.259054150 0.008398225 0.109352817
## width 0.542277953 0.1801292094 -0.456190951 0.336785282 0.450381706
## height -0.375012387 -0.4126314480 -0.580471452 -0.354917147 0.091655331
## onpix 0.009728699 -0.3973985655 0.522748350 0.433710258 0.087288946
## xbar -0.035841608 0.0863683140 0.044997758 0.167560990 -0.051287098
## ybar 0.229443821 -0.0438829163 0.006430953 -0.071128217 0.025546105
## x2bar 0.078128038 0.0571158847 -0.017760057 -0.053721764 0.080114923
## y2bar -0.120225197 0.0013576867 -0.114310033 0.103047882 0.005077098
## xybar -0.137572012 -0.0005357877 -0.029954090 0.033685964 -0.026906089
## x2ybar 0.093789658 0.0537835021 -0.001010650 -0.003729903 0.025630810
## xy2bar 0.085424524 -0.0492046605 0.136375699 0.016077018 0.022994001
## xedge -0.423032664 0.1619093254 -0.117816015 -0.227223408 0.045344803
## xedgey -0.549078548 0.1311895167 0.022684428 0.204498774 0.071930364
## yedge -0.052211626 0.0667189155 0.064492490 -0.216351535 0.022094686
## yedgex -0.111863251 0.1643547832 -0.325474136 0.241598466 -0.054480376
## LD16
## xbox 0.191852865
## ybox -0.246326861
## width -0.064661184
## height -0.131623256
## onpix -0.078967253
## xbar 0.001918281
## ybar -0.007685332
## x2bar -0.015060810
## y2bar 0.013263038
## xybar 0.013884973
## x2ybar -0.021310751
## xy2bar -0.020915462
## xedge 0.022643237
## xedgey 0.014397854
## yedge -0.008088153
## yedgex 0.051478676
##
## Proportion of trace:
## LD1 LD2 LD3 LD4 LD5 LD6 LD7 LD8 LD9 LD10 LD11
## 0.3126 0.2133 0.1198 0.1107 0.0626 0.0501 0.0399 0.0340 0.0178 0.0148 0.0132
## LD12 LD13 LD14 LD15 LD16
## 0.0050 0.0030 0.0025 0.0005 0.0001
| Komponen | Deskripsi |
|---|---|
| Prior probabilities | Probabilitas awal setiap kelas sebelum melihat data. Dihitung dari proporsi masing-masing kelas dalam data training. |
| Group means | Rata-rata setiap fitur untuk masing-masing kelas. Menunjukkan karakteristik tipikal setiap huruf. |
| Coefficients (scaling) | Bobot setiap fitur pada setiap fungsi diskriminan. Nilai absolut yang besar menunjukkan fitur penting. |
| Proportion of trace | Persentase varians antar kelas yang dijelaskan oleh setiap fungsi diskriminan. |
| SV (Singular Values) | Akar kuadrat dari eigenvalue. Menunjukkan kekuatan diskriminasi setiap fungsi. |
# Menghitung proporsi variansi tiap fungsi diskriminan
prop_trace <- lda_model$svd^2 / sum(lda_model$svd^2) * 100
names(prop_trace) <- paste0("LD", 1:length(prop_trace))
# Barplot proporsi variansi
barplot(prop_trace[1:10],
main = "Proporsi Variansi yang Dijelaskan oleh Fungsi Diskriminan",
xlab = "Fungsi Diskriminan",
ylab = "Proporsi Variansi (%)",
col = "lightblue",
border = "blue",
ylim = c(0, 35))
# Menambahkan garis pada kumulatif 80%
cumsum_prop <- cumsum(prop_trace)
abline(h = 80, col = "red", lty = 2, lwd = 2)
text(8, 82, "Kumulatif 80%", col = "red", cex = 0.8)
Hasil barplot menunjukkan bahwa dua fungsi diskriminan pertama (LD1 dan LD2) mampu menjelaskan sekitar 52,6% dari total variasi antar huruf, sementara tiga LD pertama menjelaskan 64,6%. Lima fungsi diskriminan pertama (LD1-LD5) telah menjelaskan 81,9% varians, sehingga melebihi threshold 80% yang umum digunakan.
# Melakukan prediksi pada data testing
X_test <- testData[, -1]
pred_test <- predict(lda_model, newdata = X_test)
# Confusion Matrix
conf_matrix <- table(Predicted = pred_test$class, Actual = testData$Letter)
# Menampilkan confusion matrix (5 huruf pertama)
kable(conf_matrix[1:5, 1:5], caption = "Confusion Matrix (5 Huruf Pertama)")
| A | B | C | D | E | |
|---|---|---|---|---|---|
| A | 203 | 0 | 0 | 1 | 0 |
| B | 0 | 161 | 2 | 14 | 16 |
| C | 0 | 0 | 162 | 0 | 25 |
| D | 0 | 8 | 0 | 189 | 1 |
| E | 0 | 0 | 9 | 0 | 98 |
# Menghitung akurasi keseluruhan
accuracy <- sum(diag(conf_matrix)) / sum(conf_matrix)
cat("\n**Akurasi Keseluruhan:**", round(accuracy * 100, 2), "%\n")
##
## **Akurasi Keseluruhan:** 69.82 %
Akurasi keseluruhan model LDA pada data testing mencapai 69,82%. Angka ini sangat signifikan dibandingkan dengan peluang acak sebesar 3,85% (1/26), sehingga dapat disimpulkan bahwa LDA efektif dalam mengklasifikasikan huruf.
# Menghitung akurasi per huruf
acc_per_class <- diag(conf_matrix) / rowSums(conf_matrix)
acc_df <- data.frame(
Huruf = names(acc_per_class),
Akurasi = round(acc_per_class * 100, 1)
)
# 5 huruf dengan akurasi tertinggi
kable(head(acc_df[order(-acc_df$Akurasi), ], 5),
caption = "5 Huruf dengan Akurasi Tertinggi")
| Huruf | Akurasi | |
|---|---|---|
| L | L | 94.6 |
| T | T | 91.8 |
| A | A | 86.4 |
| U | U | 86.4 |
| M | M | 84.4 |
# 5 huruf dengan akurasi terendah
kable(head(acc_df[order(acc_df$Akurasi), ], 5),
caption = "5 Huruf dengan Akurasi Terendah")
| Huruf | Akurasi | |
|---|---|---|
| H | H | 40.0 |
| S | S | 43.8 |
| G | G | 48.3 |
| B | B | 52.8 |
| X | X | 58.2 |
Dari hasil akurasi per kelas, terlihat bahwa:
Huruf dengan akurasi tertinggi (L, T, A, U, M) memiliki bentuk geometris yang sangat khas sehingga mudah dibedakan.
Huruf dengan akurasi terendah (H, S, G, B, X) cenderung memiliki kemiripan bentuk.
# Menghitung kontribusi fitur pada LD1
importance_LD1 <- abs(lda_model$scaling[, 1])
importance_sorted <- sort(importance_LD1, decreasing = TRUE)
# Menampilkan 5 fitur terpenting
imp_df <- data.frame(
Fitur = names(importance_sorted[1:5]),
Bobot = round(importance_sorted[1:5], 4)
)
kable(imp_df, caption = "5 Fitur Terpenting pada Fungsi Diskriminan Pertama (LD1)")
| Fitur | Bobot | |
|---|---|---|
| xedge | xedge | 0.6687 |
| yedge | yedge | 0.4313 |
| ybar | ybar | 0.1766 |
| width | width | 0.1375 |
| height | height | 0.1183 |
# Visualisasi kontribusi fitur
barplot(importance_sorted[1:8],
main = "Kontribusi Fitur pada LD1",
xlab = "Fitur",
ylab = "Nilai Absolut Bobot",
col = "skyblue",
las = 2,
cex.names = 0.8)
Fitur xedge (horizontal edge) memiliki kontribusi terbesar dalam membedakan antar huruf, diikuti oleh yedge (vertical edge) dan x2ybar. Hal ini masuk akal karena perbedaan paling mencolok antar huruf terletak pada jumlah dan posisi tepi horizontal dan vertikal (misalnya huruf ‘H’ memiliki banyak tepi vertikal, sedangkan ‘E’ memiliki banyak tepi horizontal).
# Menghitung skor diskriminan untuk data training
lda_scores <- predict(lda_model, X_train)$x
# Membuat plot proyeksi
plot(lda_scores[, 1], lda_scores[, 2],
col = as.numeric(y_train),
pch = 16,
cex = 0.5,
xlab = paste("LD1 (", round(prop_trace[1], 1), "%)", sep = ""),
ylab = paste("LD2 (", round(prop_trace[2], 1), "%)", sep = ""),
main = "Proyeksi Data ke 2 Fungsi Diskriminan Pertama")
# Menambahkan legend
legend("topright",
legend = levels(y_train),
col = 1:26,
pch = 16,
cex = 0.35,
ncol = 5,
title = "Huruf",
bty = "n")
# Boxplot untuk fitur xedge per huruf
boxplot(trainData$xedge ~ trainData$Letter,
main = "Distribusi Fitur xedge (Horizontal Edge) per Huruf",
xlab = "Huruf",
ylab = "Nilai xedge",
las = 2,
cex.axis = 0.6,
col = "skyblue",
border = "darkblue")
abline(h = mean(trainData$xedge), col = "red", lty = 2, lwd = 2)
Boxplot di atas menunjukkan distribusi nilai xedge (horizontal edge) untuk setiap huruf. Terlihat bahwa huruf seperti ‘M’ dan ‘W’ memiliki nilai xedge yang sangat tinggi (karena banyak tepi horizontal), sementara huruf seperti ‘I’ dan ‘L’ memiliki nilai yang rendah. Perbedaan inilah yang dimanfaatkan LDA untuk membedakan antar huruf.
Berdasarkan analisis komponen output model LDA, dapat disimpulkan bahwa model berhasil mengidentifikasi perbedaan profil geometris antar 26 huruf. Prior probabilities yang relatif seimbang mengindikasikan data training representatif untuk setiap huruf. Group means menunjukkan bahwa setiap huruf memiliki karakteristik fitur yang unik, seperti huruf ‘I’ yang ramping dan huruf ‘W’ yang lebar. Coefficients scaling mengungkapkan bahwa fitur tepi horizontal (xedge) dan tepi vertikal (yedge) merupakan kontributor terbesar dalam membedakan antar huruf. Sementara itu, proportion of trace menunjukkan bahwa lima fungsi diskriminan pertama mampu menjelaskan lebih dari 80% variasi antar huruf, sehingga cukup untuk mereduksi dimensi data tanpa kehilangan banyak informasi.