Tugas Regresi Spasial
Data yang Digunakan
Pada bagian ini digunakan data harga rumah di Boston, Amerika Serikat, dari paket spData. Data boston.c berisi informasi karakteristik perumahan di wilayah Boston, salah satunya nilai median harga rumah yang ditempati pemilik (CMEDV). Data juga mencakup koordinat geografis berupa garis bujur (LON) dan garis lintang (LAT) untuk menunjukkan lokasi setiap pengamatan. Koordinat tersebut digunakan sebagai informasi spasial dalam proses interpolasi.
# Memuat pustaka yang diperlukan
library(spData)
library(sf)
library(terra)
library(tmap)
library(viridis)
library(dismo)
library(dplyr)
# Memuat data properti Boston
data("boston.c", package = "spData")
d <- boston.c
# Mengubah data menjadi objek sf berdasarkan koordinat geografis
d <- st_as_sf(d, coords = c("LON", "LAT"), crs = 4326,
remove = FALSE)
# Mengubah sistem koordinat ke UTM
d <- st_transform(d, crs = 32619)
# Menambahkan kolom nilai median harga rumah ke dalam dataset
d$vble <- d$CMEDV
# Membuat batas wilayah berdasarkan sebaran titik pengamatan
map <- st_convex_hull(st_union(d)) %>% st_sf()
# Menampilkan peta harga properti
tmap_mode("plot")
tm_shape(map) + tm_polygons(alpha = 0.3) + tm_shape(d) +
tm_dots("vble", palette = "viridis")Pada data Boston, objek map merupakan batas wilayah yang dibentuk berdasarkan sebaran titik pengamatan perumahan di Boston menggunakan metode convex hull. Batas ini nantinya digunakan untuk membatasi area perhitungan interpolasi.
Untuk memprediksi nilai median harga rumah di Boston, dibuat grid yang mencakup seluruh area pengamatan. Titik pusat dari setiap grid digunakan sebagai lokasi prediksi.
Langkah-langkah: 1. Membuat grid dengan dimensi cukup kecil (misalnya 100 × 100) untuk mencakup area pengamatan di Boston. 2. Mengambil titik pusat dari setiap sel grid sebagai koordinat lokasi prediksi. 3. Mengubah titik pusat grid menjadi objek sf yang akan digunakan dalam proses interpolasi. 4. Membatasi titik-titik grid agar hanya berada di dalam batas wilayah pengamatan (map).
# Membuat grid raster 100x100 sel untuk mencakup wilayah pengamatan Boston
grid <- rast(vect(map), nrows = 100, ncols = 100)
# Mengambil koordinat titik pusat dari setiap sel dalam grid
xy <- xyFromCell(grid, 1:ncell(grid))
# Membuat objek sf untuk lokasi prediksi
coop <- st_as_sf(as.data.frame(xy), coords = c("x", "y"),
crs = st_crs(map))
# Menyaring lokasi prediksi yang berada dalam batas wilayah pengamatan Boston
coop <- st_filter(coop, map)
# Menampilkan peta lokasi prediksi
qtm(coop)Metode Deterministik
Closest Observation
Metode ini menggunakan diagram Voronoi untuk membagi ruang menjadi poligon yang masing-masing berisi satu titik pembangkit. Setiap titik dalam poligon lebih dekat ke titik pembangkitnya daripada ke titik lain. Prediksi harga properti dilakukan berdasarkan nilai titik terdekat.
Langkah-langkah:
- Membuat diagram Voronoi berdasarkan data titik properti.
- Menggunakan
st_intersection()untuk menentukan prediksi harga pada titik-titik yang terletak dalam setiap poligon Voronoi.
# Membuat diagram Voronoi dari lokasi properti Boston
v <- voronoi(x = vect(d), bnd = vect(map))
plot(v)
# Menampilkan titik properti di atas diagram Voronoi
points(vect(d), cex = 0.5)# Mengubah objek Voronoi menjadi objek sf
v <- st_as_sf(v)
# Menampilkan peta hasil pembagian wilayah Voronoi
tm_shape(v) +
tm_fill(col = "vble", palette = "viridis", alpha = 0.6)Setiap poligon dalam diagram Voronoi mewakili wilayah prediksi yang dipengaruhi oleh titik terdekat.
resp <- st_intersection(v, coop)
resp$pred <- resp$vble
pred <- rasterize(vect(resp), grid, field = "pred", fun = "mean")
c1 <- tm_shape(pred) +
tm_raster(alpha = 0.6, palette = "viridis")
c1Inverse Distance Weighting (IDW)
Metode IDW menggunakan bobot berdasarkan jarak antara lokasi yang belum teramati dan lokasi yang sudah teramati. Semakin dekat jaraknya, semakin besar bobot yang diberikan pada nilai lokasi teramati.
Langkah-langkah:
- Menerapkan IDW dengan fungsi
gstat(). - Menggunakan
predict()untuk mendapatkan prediksi harga pada lokasi yang tidak teramati.
library(gstat)
res <- gstat(formula = vble ~ 1, locations = d, nmax = nrow(d),
set = list(idp = 1))
resp <- predict(res, coop)## [inverse distance weighted interpolation]
resp$x <- st_coordinates(resp)[, 1]
resp$y <- st_coordinates(resp)[, 2]
resp$pred <- resp$var1.pred
pred <- rasterize(vect(resp), grid, field = "pred", fun = "mean")
c2 <- tm_shape(pred) +
tm_raster(alpha = 0.6, palette = "viridis")
c2Nearest Neighbors
Metode Nearest Neighbors menghitung rata-rata harga dari \(k\) titik terdekat. Setiap tetangga dianggap memiliki bobot yang sama.
Langkah-langkah:
- Menggunakan
gstat()dengan parameternmaxyang menentukan jumlah tetangga danidp = 0(bobot sama). - Menggunakan
predict()untuk memprediksi harga di lokasi yang tidak teramati.
res <- gstat(formula = vble ~ 1, locations = d, nmax = 5,
set = list(idp = 0))
resp <- predict(res, coop)## [inverse distance weighted interpolation]
resp$x <- st_coordinates(resp)[, 1]
resp$y <- st_coordinates(resp)[, 2]
resp$pred <- resp$var1.pred
pred <- rasterize(vect(resp), grid, field = "pred", fun = "mean")
c3 <- tm_shape(pred) +
tm_raster(alpha = 0.6, palette = "viridis")
c3Pendekatan Ensembel
Pendekatan ensembel menggabungkan hasil prediksi dari berbagai metode interpolasi (Closest Observation, IDW, dan Nearest Neighbors) dengan memberikan bobot pada setiap metode. Bobot dapat ditentukan berdasarkan kinerja masing-masing metode.
Langkah-langkah:
- Menghitung prediksi harga dengan masing-masing metode.
- Menggabungkan prediksi setiap metode menggunakan bobot tertentu.
# Closest observation (Voronoi)
v <- voronoi(x = vect(d), bnd = vect(map))
v <- st_as_sf(v)
p1 <- st_intersection(v, coop)$vble
# IDW
gs <- gstat(formula = vble ~ 1, locations = d, nmax = nrow(d),
set = list(idp = 1))
p2 <- predict(gs, coop)$var1.pred## [inverse distance weighted interpolation]
# Nearest neighbors
nn <- gstat(formula = vble ~ 1, locations = d, nmax = 5,
set = list(idp = 0))
p3 <- predict(nn, coop)$var1.pred## [inverse distance weighted interpolation]
# Ensemble (bobot sama)
weights <- c(1/3, 1/3, 1/3)
p4 <- p1 * weights[1] + p2 * weights[2] + p3 * weights[3]
# Membuat objek sf dari hasil prediksi ensemble
resp <- data.frame(x = st_coordinates(coop)[, 1],
y = st_coordinates(coop)[, 2],
pred = p4)
resp <- st_as_sf(resp, coords = c("x", "y"), crs = st_crs(map))
# Mengubah hasil prediksi menjadi raster
pred <- rasterize(vect(resp), grid, field = "pred", fun = "mean")
# Menampilkan peta hasil interpolasi Ensemble
c4 <- tm_shape(pred) +
tm_raster(alpha = 0.6, palette = "viridis")
c4Evaluasi Model
Untuk menilai kinerja setiap metode dilakukan K-fold cross-validation dan dihitung RMSE (Root Mean Square Error). Cross-validation digunakan untuk memastikan model tidak hanya cocok dengan data latih tetapi juga dapat memprediksi data baru dengan baik.
Langkah-langkah:
- Membagi data menjadi \(K\) bagian
dengan
dismo::kfold(). - Menghitung RMSE untuk setiap metode dengan membandingkan nilai prediksi dan nilai sebenarnya.
set.seed(123)
# Fungsi untuk menghitung RMSE
RMSE <- function(observed, predicted) {
sqrt(mean((observed - predicted)^2))
}
# Pembagian data untuk K-fold
kf <- kfold(nrow(d), k = 5)
# Vektor untuk menyimpan RMSE tiap metode
rmse1 <- rep(NA, 5) # Closest observation
rmse2 <- rep(NA, 5) # IDW
rmse3 <- rep(NA, 5) # Nearest neighbors
rmse4 <- rep(NA, 5) # Ensemble
for (k in 1:5) {
# Pisahkan data menjadi data uji dan data latih
test <- d[kf == k, ]
train <- d[kf != k, ]
# Closest observation
v <- voronoi(x = vect(train), bnd = vect(map))
v <- st_as_sf(v)
p1 <- st_intersection(v, test)$vble
rmse1[k] <- RMSE(test$vble, p1)
# IDW
gs <- gstat(formula = vble ~ 1, locations = train,
nmax = nrow(train), set = list(idp = 1))
p2 <- predict(gs, test)$var1.pred
rmse2[k] <- RMSE(test$vble, p2)
# Nearest neighbors
nn <- gstat(formula = vble ~ 1, locations = train,
nmax = 5, set = list(idp = 0))
p3 <- predict(nn, test)$var1.pred
rmse3[k] <- RMSE(test$vble, p3)
# Ensemble (bobot sama)
weights <- c(1/3, 1/3, 1/3)
p4 <- p1 * weights[1] + p2 * weights[2] + p3 * weights[3]
rmse4[k] <- RMSE(test$vble, p4)
}## [inverse distance weighted interpolation]
## [inverse distance weighted interpolation]
## [inverse distance weighted interpolation]
## [inverse distance weighted interpolation]
## [inverse distance weighted interpolation]
## [inverse distance weighted interpolation]
## [inverse distance weighted interpolation]
## [inverse distance weighted interpolation]
## [inverse distance weighted interpolation]
## [inverse distance weighted interpolation]
# RMSE pada masing-masing dari 5 fold
data.frame(closest.obs = rmse1, IDW = rmse2,
nearest.neigh = rmse3, ensemble = rmse4)## closest.obs IDW nearest.neigh ensemble
## 1 7.202166 9.644621 6.974510 7.011158
## 2 5.402557 8.968279 5.823436 5.925908
## 3 5.210359 7.547950 5.282393 5.224659
## 4 6.936230 7.340753 5.369727 5.598074
## 5 5.575956 6.813363 4.477856 4.570800
# Rata-rata RMSE dari 5 fold
data.frame(closest.obs = mean(rmse1), IDW = mean(rmse2),
nearest.neigh = mean(rmse3), ensemble = mean(rmse4))## closest.obs IDW nearest.neigh ensemble
## 1 6.065454 8.062993 5.585584 5.66612
Metode Stokastik
Kriging
Kriging adalah metode interpolasi geostatistik yang memperhitungkan autokorelasi spasial untuk membuat prediksi. Ordinary Kriging (OK) adalah salah satu varian Kriging yang paling umum, di mana nilai yang diprediksi adalah variabel \(z\) yang tidak diketahui dan dianggap sebagai variabel acak.
Variogram. Dalam Ordinary Kriging, penting untuk membangun variogram. Variogram adalah grafik yang menggambarkan bagaimana variabilitas antar titik pengamatan berubah seiring jarak antar titik tersebut. Kriging menggunakan informasi variogram ini untuk menghitung kovarians antar titik.
Model semivariogram. Setelah variogram dihitung, model semivariogram (seperti spherical, exponential, atau Gaussian) di-fit ke data untuk menangkap hubungan spasial di antara titik-titik pengamatan.
Ordinary Kriging mengasumsikan bahwa nilai rata-rata populasi tidak diketahui, tetapi konstan di seluruh wilayah.
# Memuat paket yang dibutuhkan
library(sp)
library(gstat)
library(sf)
library(mapview)
# Menggunakan data Boston dan grid prediksi yang sudah disiapkan
boston <- d
boston.grid <- coop
# Peta interaktif lokasi pengamatan harga rumah di Boston
mapview(boston, zcol = "vble",
map.types = "CartoDB.Voyager")Keterangan komponen semivariogram:
- Nugget: nilai semivarian ketika jarak antarobservasi mendekati nol, yang merepresentasikan variasi mikrospasial dan kesalahan pengukuran.
- Sill: nilai maksimum (plateau) semivarian yang merepresentasikan total varians spasial.
- Range: jarak ketika semivarian mencapai sill, yang menunjukkan batas jangkauan ketergantungan spasial.
Secara umum:
- Semivarian rendah pada jarak dekat: lokasi berdekatan memiliki nilai yang mirip.
- Semivarian meningkat seiring jarak: ada struktur ketergantungan spasial.
- Semivarian mencapai sill: variasi spasial relatif stabil setelah jarak tertentu.
## short long
## 1 Nug Nug (nugget)
## 2 Exp Exp (exponential)
## 3 Sph Sph (spherical)
## 4 Gau Gau (gaussian)
## 5 Exc Exclass (Exponential class/stable)
## 6 Mat Mat (Matern)
## 7 Ste Mat (Matern, M. Stein's parameterization)
## 8 Cir Cir (circular)
## 9 Lin Lin (linear)
## 10 Bes Bes (bessel)
## 11 Pen Pen (pentaspherical)
## 12 Per Per (periodic)
## 13 Wav Wav (wave)
## 14 Hol Hol (hole)
## 15 Log Log (logarithmic)
## 16 Pow Pow (power)
## 17 Spl Spl (spline)
## 18 Leg Leg (Legendre)
## 19 Err Err (Measurement error)
## 20 Int Int (Intercept)
# Model variogram awal: psill, model, range, dan nugget
vinitial <- vgm(psill = 0.5, model = "Sph", range = 10000, nugget = 0.1)
# Visualisasi variogram empiris dengan model awal
plot(v, vinitial, cex = 1.5)# Fitting model "Sph" ke variogram empiris
fv <- fit.variogram(object = v,
model = vgm(psill = 0.5, model = "Sph",
range = 10000, nugget = 0.1))
# Menampilkan hasil fitting variogram
fv## model psill range
## 1 Nug 0.1913782 0.000
## 2 Sph 0.5754841 7432.212
library(automap)
# Autofit variogram untuk data CMEDV Boston
afvg <- autofitVariogram(vble ~ 1, d)
# Menampilkan hasil fitting variogram otomatis
plot(afvg)library(ggplot2)
library(viridis)
# Objek gstat dengan model variogram hasil fitting (fv)
k <- gstat(formula = vble ~ 1, data = d, model = fv)
# Prediksi pada grid
kpred <- predict(k, coop)## [using ordinary kriging]
# Visualisasi prediksi CMEDV
ggplot() +
geom_sf(data = kpred, aes(color = var1.pred)) +
geom_sf(data = d) +
scale_color_viridis(name = "CMEDV") +
theme_bw()# Visualisasi varians prediksi
ggplot() +
geom_sf(data = kpred, aes(color = var1.var)) +
geom_sf(data = d) +
scale_color_viridis(name = "Variance") +
theme_bw()# Memanggil paket
library(sf)
library(gstat)
library(dismo)
# Menyiapkan data Boston
data("boston.c", package = "spData")
dm <- st_as_sf(
boston.c,
coords = c("LON", "LAT"),
crs = 4326,
remove = FALSE
)
dm <- st_transform(dm, crs = 32619)
dm$vble <- dm$CMEDV
set.seed(123)
# Fungsi menghitung RMSE
RMSE <- function(observed, predicted) {
sqrt(mean((observed - predicted)^2))
}
# Fungsi prediksi empat metode dasar
pred_base <- function(train, test) {
# 1. Closest Observation
p1 <- train$vble[st_nearest_feature(test, train)]
# 2. IDW
p2 <- predict(
gstat(formula = vble ~ 1, locations = train,
nmax = nrow(train), set = list(idp = 2)),
test
)$var1.pred
# 3. Nearest Neighbors
p3 <- predict(
gstat(formula = vble ~ 1, locations = train,
nmax = 5, set = list(idp = 0)),
test
)$var1.pred
# 4. Ordinary Kriging
vg <- variogram(vble ~ 1, train)
vgf <- fit.variogram(
vg,
vgm(psill = 0.5, model = "Sph",
range = 10000, nugget = 0.1)
)
p4 <- predict(
gstat(formula = vble ~ 1, locations = train,
model = vgf),
test
)$var1.pred
cbind(
closest = p1,
IDW = p2,
NN = p3,
kriging = p4
)
}
# Pembagian data menjadi 5 fold
K <- 5
kf <- kfold(nrow(dm), k = K)
# Menyiapkan tempat penyimpanan RMSE
hasil <- data.frame(
fold = 1:K,
closest.obs = NA,
IDW = NA,
NN = NA,
kriging = NA,
ens.equal = NA,
ens.invRMSE = NA
)
# Proses Cross Validation
for (k in 1:K) {
train <- dm[kf != k, ]
test <- dm[kf == k, ]
# Prediksi empat metode dasar
P <- pred_base(train, test)
# RMSE setiap metode
hasil[k, c("closest.obs", "IDW", "NN", "kriging")] <-
apply(P, 2, function(p) RMSE(test$vble, p))
# Ensemble bobot sama
hasil$ens.equal[k] <-
RMSE(test$vble, rowMeans(P))
# Ensemble bobot invers RMSE dari CV internal
inner <- kfold(nrow(train), k = 5)
Pin <- matrix(NA_real_, nrow(train), 4)
for (j in 1:5) {
idx_valid <- which(inner == j)
idx_train <- which(inner != j)
Pin[idx_valid, ] <- pred_base(
train[idx_train, ],
train[idx_valid, ]
)
}
# Menghitung bobot berdasarkan RMSE data latih
rmse_inner <- apply(
Pin, 2,
function(p) RMSE(train$vble, p)
)
w <- 1 / rmse_inner
w <- w / sum(w)
# Ensemble bobot invers RMSE
hasil$ens.invRMSE[k] <-
RMSE(test$vble, as.vector(P %*% w))
}## [inverse distance weighted interpolation]
## [inverse distance weighted interpolation]
## [using ordinary kriging]
## [inverse distance weighted interpolation]
## [inverse distance weighted interpolation]
## [using ordinary kriging]
## [inverse distance weighted interpolation]
## [inverse distance weighted interpolation]
## [using ordinary kriging]
## [inverse distance weighted interpolation]
## [inverse distance weighted interpolation]
## [using ordinary kriging]
## [inverse distance weighted interpolation]
## [inverse distance weighted interpolation]
## [using ordinary kriging]
## [inverse distance weighted interpolation]
## [inverse distance weighted interpolation]
## [using ordinary kriging]
## [inverse distance weighted interpolation]
## [inverse distance weighted interpolation]
## [using ordinary kriging]
## [inverse distance weighted interpolation]
## [inverse distance weighted interpolation]
## [using ordinary kriging]
## [inverse distance weighted interpolation]
## [inverse distance weighted interpolation]
## [using ordinary kriging]
## [inverse distance weighted interpolation]
## [inverse distance weighted interpolation]
## [using ordinary kriging]
## [inverse distance weighted interpolation]
## [inverse distance weighted interpolation]
## [using ordinary kriging]
## [inverse distance weighted interpolation]
## [inverse distance weighted interpolation]
## [using ordinary kriging]
## [inverse distance weighted interpolation]
## [inverse distance weighted interpolation]
## [using ordinary kriging]
## [inverse distance weighted interpolation]
## [inverse distance weighted interpolation]
## [using ordinary kriging]
## [inverse distance weighted interpolation]
## [inverse distance weighted interpolation]
## [using ordinary kriging]
## [inverse distance weighted interpolation]
## [inverse distance weighted interpolation]
## [using ordinary kriging]
## [inverse distance weighted interpolation]
## [inverse distance weighted interpolation]
## [using ordinary kriging]
## [inverse distance weighted interpolation]
## [inverse distance weighted interpolation]
## [using ordinary kriging]
## [inverse distance weighted interpolation]
## [inverse distance weighted interpolation]
## [using ordinary kriging]
## [inverse distance weighted interpolation]
## [inverse distance weighted interpolation]
## [using ordinary kriging]
## [inverse distance weighted interpolation]
## [inverse distance weighted interpolation]
## [using ordinary kriging]
## [inverse distance weighted interpolation]
## [inverse distance weighted interpolation]
## [using ordinary kriging]
## [inverse distance weighted interpolation]
## [inverse distance weighted interpolation]
## [using ordinary kriging]
## [inverse distance weighted interpolation]
## [inverse distance weighted interpolation]
## [using ordinary kriging]
## [inverse distance weighted interpolation]
## [inverse distance weighted interpolation]
## [using ordinary kriging]
## [inverse distance weighted interpolation]
## [inverse distance weighted interpolation]
## [using ordinary kriging]
## [inverse distance weighted interpolation]
## [inverse distance weighted interpolation]
## [using ordinary kriging]
## [inverse distance weighted interpolation]
## [inverse distance weighted interpolation]
## [using ordinary kriging]
## [inverse distance weighted interpolation]
## [inverse distance weighted interpolation]
## [using ordinary kriging]
## [inverse distance weighted interpolation]
## [inverse distance weighted interpolation]
## [using ordinary kriging]
## fold closest.obs IDW NN kriging ens.equal ens.invRMSE
## 1 1 7.202166 8.203659 6.974510 6.808036 6.674559 6.656807
## 2 2 5.402557 7.395315 5.823436 5.849891 5.551216 5.555257
## 3 3 5.210359 6.070428 5.282393 5.152435 5.007511 5.007111
## 4 4 6.936230 6.133962 5.369727 5.138275 5.349102 5.331965
## 5 5 5.575956 5.331444 4.477856 4.822692 4.486842 4.477640
## closest.obs IDW NN kriging ens.equal ens.invRMSE
## 6.065454 6.626962 5.585584 5.554266 5.413846 5.405756
Perbandingan RMSE
# Membuat tabel perbandingan RMSE
df_rmse <- data.frame(
metode = names(rmse_rata),
RMSE = as.numeric(rmse_rata)
)
# Mengurutkan dari RMSE terkecil
df_rmse <- df_rmse[order(df_rmse$RMSE), ]
df_rmse## metode RMSE
## 6 ens.invRMSE 5.405756
## 5 ens.equal 5.413846
## 4 kriging 5.554266
## 3 NN 5.585584
## 1 closest.obs 6.065454
## 2 IDW 6.626962
# Visualisasi perbandingan RMSE
ggplot(df_rmse, aes(x = reorder(metode, RMSE), y = RMSE)) +
geom_col(fill = "steelblue") +
geom_text(aes(label = round(RMSE, 3)), vjust = -0.3) +
labs(
x = "Metode Interpolasi",
y = "Rata-rata RMSE (5-Fold CV)",
title = "Perbandingan RMSE Metode Interpolasi Boston"
) +
theme_bw()Kesimpulan
Berdasarkan hasil evaluasi menggunakan metode 5-Fold Cross Validation, diperoleh bahwa Ensemble dengan bobot invers RMSE merupakan metode interpolasi dengan kinerja terbaik pada dataset Boston, dengan nilai rata-rata RMSE sebesar 5,406. Selanjutnya, Ensemble dengan bobot sama menghasilkan rata-rata RMSE sebesar 5,414, diikuti Ordinary Kriging sebesar 5,554, Nearest Neighbors sebesar 5,586, Closest Observation sebesar 6,065, dan IDW sebesar 6,627.
Hasil tersebut menunjukkan bahwa metode Ensemble dengan bobot invers RMSE mampu memberikan hasil estimasi yang lebih akurat dibandingkan metode interpolasi lainnya berdasarkan nilai RMSE terkecil. Metode ini menggabungkan prediksi dari Closest Observation, IDW, Nearest Neighbors, dan Ordinary Kriging dengan memberikan bobot lebih besar kepada metode yang memiliki kesalahan prediksi lebih kecil pada proses validasi internal data latih. Ensemble dengan bobot sama juga menunjukkan kinerja yang hampir serupa, dengan selisih RMSE yang sangat kecil, yaitu sekitar 0,008. Sementara itu, Ordinary Kriging tetap memberikan hasil yang cukup baik karena memiliki RMSE lebih rendah dibandingkan Closest Observation, IDW, dan Nearest Neighbors. Adapun IDW menghasilkan nilai RMSE terbesar sehingga memiliki tingkat kesalahan prediksi paling tinggi di antara metode yang dibandingkan.
Dengan demikian, Ensemble dengan bobot invers RMSE menjadi metode interpolasi terbaik untuk dataset Boston berdasarkan hasil 5-Fold Cross Validation, karena menghasilkan rata-rata kesalahan prediksi paling kecil dibandingkan lima metode lainnya.