(Acest articol a fost publicat pentru prima dată pe geocompxși a contribuit cu drag la R-Bloggers). (Puteți raporta problema despre conținutul de pe această pagină aici)
Doriți să vă împărtășiți conținutul pe R-Bloggers? Faceți clic aici dacă aveți un blog sau aici dacă nu.
Aceasta este a doua parte a unei serii de postări pe blog despre învățarea spațială a mașinilor cu R.
Puteți găsi lista altor postări pe blog în această serie în prima parte.
Introducere
Acest document arată aplicația semn de omisiune pentru modelarea spațială la exemplul prezicerii temperaturii aerului în Spania. Prin urmare, folosim măsurători ale temperaturii aerului disponibile numai în anumite locații din Spania pentru a crea o hartă continuă spațial a temperaturii aerului. Prin urmare, modelele de învățare a mașinilor sunt instruite pentru a învăța relația dintre predictorii continuu spațial și temperatura aerului.
Atunci când folosim metode de învățare automată cu date spațiale, trebuie să avem grijă, de exemplu, autocorelația spațială, precum și extrapolarea atunci când prezicem regiuni care sunt departe de datele de instruire. Pentru a face față acestor probleme, au fost dezvoltate mai multe metode. În acest document, vom arăta cum să combinăm fluxul de lucru de învățare automată a semn de omisiune Cu pachete concepute pentru a face față învățării automate cu date spațiale. Prin urmare, folosim blockCV::cv_spatial()
şi CAST::knndm()
pentru validare încrucișată spațială și CAST::aoa()
pentru a masca zonele de extrapolare. Folosim SF şi Terra pentru procesarea datelor vectoriale și, respectiv, raster.
Pachetul Caret
semn de omisiune Pachetul conține funcții pentru a antrena modele de învățare a mașinilor, precum și pentru, de exemplu, selecția modelului. Funcția sa principală este caret::train()
care oferă o interfață uniformă la peste 200 de algoritmi de învățare a mașinilor. (Metodele specificate de utilizator) pot fi definite prin intermediul caret::trainControl()
. Un tutorial online extins este disponibil la https://topepo.github.io/caret/. Furthermore, a paper (https://doi.org/10.18637/jss.v028.i05), as well as a book (http://appliedpredictivemodeling.com/), describing the use of semn de omisiune sunt disponibile.
Instalați și încărcați pachetele R necesare
# install.packages("caret") # install.packages("CAST") # install.packages("blockCV") # install.packages("sf") # install.packages("terra")
library(caret) library(CAST) library(blockCV) library(sf) library(terra)
Date de studiu de caz
Încărcați datele necesare în acest exemplu de modelare:
- Predictor Stack: setul de date raster al predictorilor de mediu utilizați pentru a prezice temperatura aerului
- Puncte de tren: setul de date vectorial al măsurătorilor la sol ale temperaturii aerului
- Spania: regiune pentru care se fac predicții
predictor_stack <- terra::rast( "https://github.com/LOEK-RS/FOSSGIS2025-examples/raw/refs/heads/main/data/predictors.tif" ) predictor_names <- names(predictor_stack) spain <- sf::st_read( "https://github.com/LOEK-RS/FOSSGIS2025-examples/raw/refs/heads/main/data/spain.gpkg" )
Reading layer `spain' from data source `https://github.com/LOEK-RS/FOSSGIS2025-examples/raw/refs/heads/main/data/spain.gpkg' using driver `GPKG' Simple feature collection with 1 feature and 0 fields Geometry type: MULTIPOLYGON Dimension: XY Bounding box: xmin: -13454.15 ymin: 3988025 xmax: 1020771 ymax: 4859816 Projected CRS: ED50 / UTM zone 30N
train_points <- sf::st_read( "https://github.com/LOEK-RS/FOSSGIS2025-examples/raw/refs/heads/main/data/temp_train.gpkg" )
Reading layer `temp_train' from data source `https://github.com/LOEK-RS/FOSSGIS2025-examples/raw/refs/heads/main/data/temp_train.gpkg' using driver `GPKG' Simple feature collection with 195 features and 1 field Geometry type: POINT Dimension: XY Bounding box: xmin: 36026.79 ymin: 3988818 xmax: 978160.6 ymax: 4858999 Projected CRS: ED50 / UTM zone 30N
train_data <- terra::extract( predictor_stack, train_points, bind = TRUE, ID = FALSE ) |> sf::st_as_sf() plot(sf::st_geometry(spain)) plot(sf::st_geometry(train_points), col = "blue4", add = TRUE)
Flux de lucru standard de modelare
În primul rând, este afișat un flux de lucru simplu de modelare fără selecția caracteristicilor și reglarea hiperparameterului:
- împărțiți datele în date de instruire și testare
- Model de antrenament folosind doar datele de instruire
- Prezice pe datele de testare pentru a obține valori de eroare
- prezice pe stiva de predictor pentru a obține predicția continuă continuă a temperaturii aerului
Coloana de geometrie trebuie să fie abandonată înainte de a utiliza caret::train()
.
# 1. train-test split set.seed(321) trainIndex <- caret::createDataPartition( train_data$temp, p = .8, list = FALSE, times = 1 ) temperature_train <- train_data(trainIndex, ) temperature_test <- train_data(-trainIndex, ) # 2. model training model <- caret::train( temp ~ ., data = sf::st_drop_geometry(temperature_train), method = "ranger", tuneGrid = expand.grid( "mtry" = 4, "splitrule" = "variance", "min.node.size" = 5 ), num.trees = 100 ) # 3. predict on test data test_df <- temperature_test(, "temp", drop = FALSE) test_df$prediction <- predict(model, temperature_test) test_metrics <- caret::postResample( pred = test_df$prediction, obs = test_df$temp ) |> round(3) |> t() |> as.data.frame() print(test_metrics)
RMSE Rsquared MAE 1 0.913 0.901 0.741
# 4. predict to raster stack prediction_spatial <- terra::predict(predictor_stack, model, na.rm = TRUE)
Validare încrucișată spațială pentru selecția modelului
Metodele de validare încrucișată (CV) sunt adesea folosite pentru a obține valori optime de hiperparameter. Prin urmare, datele de instruire sunt împărțite în pliuri și un model este instruit pe
-1 pliuri. Fold -ul care nu este utilizat pentru antrenamentul modelului este apoi utilizat pentru a obține statistica testului. Acest lucru se repetă pe toate pliurile, iar metrica testului este medie pe parcursul
pliuri.
În învățarea spațială a mașinilor, este adesea nevoie de un CV spațial pentru a preveni datele foarte similare să fie în pliurile de instruire și testare în același timp, ceea ce este adesea cazul dacă datele de instruire sunt grupate și duce la estimări de eroare CV excesiv de optimiste. Pachetele R care implementează CV -ul spațial includ, de exemplu, blockcv şi Distribuire. Aici, vom explora integrarea celor doi cu semn de omisiune.
Reglarea hiperparameterului folosind validarea încrucișată a blocului spațial
blockcv Pachetul implementează diferite metode de blocare pentru CV -ul spațial. Obiectul rezultat al funcției principale blockCV::cv_spatial()
conține o listă cuibărită a pliurile și rândurile de date de instruire care aparțin fiecărui pliu, precum și o listă a datelor de testare lăsate în fiecare dintre
repetare. Aceste liste pot fi obținute folosind
lapply()
și apoi să fie utilizat ca intrare la caret::trainControl()
funcția de îngrijire care definește strategia CV folosită în caret::train()
. Grila valorilor hiperparametrului testate în timpul CV este definită folosind tune_grid
argument în caret::train()
. Aici, testăm mtry
Valori de la 2 la 12 și min.node.size
Valori între 5 și 15. Combinația dintre mtry
şi min.node.size
Acest lucru minimizează RMSE este apoi utilizat automat pentru a re-antrena un model final cu setul de date de instruire complet.
set.seed(333) spatial_blocks <- blockCV::cv_spatial( temperature_train, k = 5, progress = FALSE )
train test 1 126 33 2 126 33 3 128 31 4 128 31 5 128 31
train_ids <- lapply(spatial_blocks$folds_list, function(x) x((1))) test_ids <- lapply(spatial_blocks$folds_list, function(x) x((2))) tr_control_block <- caret::trainControl( method = "cv", index = train_ids, indexOut = test_ids, savePredictions = TRUE ) hyperparameter_grid <- expand.grid( "mtry" = c(2, 4, 6, 10, 12), "min.node.size" = c(5, 10, 15), "splitrule" = "variance" ) model_spatial <- caret::train( temp ~ ., data = sf::st_drop_geometry(temperature_train), method = "ranger", trControl = tr_control_block, tuneGrid = hyperparameter_grid, num.trees = 100 ) model_spatial$finalModel
Ranger result Call: ranger::ranger(dependent.variable.name = ".outcome", data = x, mtry = min(param$mtry, ncol(x)), min.node.size = param$min.node.size, splitrule = as.character(param$splitrule), write.forest = TRUE, probability = classProbs, ...) Type: Regression Number of trees: 100 Sample size: 159 Number of independent variables: 22 Mtry: 10 Target node size: 5 Variable importance mode: none Splitrule: variance OOB prediction error (MSE): 0.8557959 R squared (OOB): 0.8952759
Reglarea hiperparameterului folosind CV orientat către țintă
O altă metodă CV spațială este KNNDM, care este implementată în Distribuire Pachet și vizează emularea situației de predicție întâlnită de model în timpul CV. În acest caz, situația de predicție este de a prezice de la stațiile de măsurare a temperaturii la întreaga zonă a Spaniei. Deoarece stațiile de măsurare a temperaturii sunt distribuite mai degrabă aleatoriu pe zona Spaniei, nu este necesară blocaj spațial și KNNDM atribuie la întâmplare puncte de antrenament la pliurile CV. Ieșirea KNNDM conține o listă de indici de rânduri de puncte de date de instruire care sunt utilizate în fiecare CV-Iiteration (indx_train
), precum și indicii care sunt lăsați în fiecare iterație (indx_test
) Aceste liste pot fi utilizate cu ușurință ca intrare la caret::trainControl()
funcția semn de omisiune care definește CV -ul folosit în caret::train()
.
knndm_folds <- CAST::knndm( tpoints = temperature_train, modeldomain = spain, space = "geographical", clustering = "kmeans", k = 5 ) tr_control_knndm <- caret::trainControl( method = "cv", index = knndm_folds$indx_train, indexOut = knndm_folds$indx_test, savePredictions = TRUE ) hyperparameter_grid <- expand.grid( "mtry" = c(2, 4, 6, 10, 12), "min.node.size" = c(5, 10, 15), "splitrule" = "variance" ) model_knndm <- caret::train( temp ~ ., data = sf::st_drop_geometry(temperature_train), method = "ranger", trControl = tr_control_knndm, tuneGrid = hyperparameter_grid, num.trees = 100 ) model_knndm$finalModel
Ranger result Call: ranger::ranger(dependent.variable.name = ".outcome", data = x, mtry = min(param$mtry, ncol(x)), min.node.size = param$min.node.size, splitrule = as.character(param$splitrule), write.forest = TRUE, probability = classProbs, ...) Type: Regression Number of trees: 100 Sample size: 159 Number of independent variables: 22 Mtry: 12 Target node size: 10 Variable importance mode: none Splitrule: variance OOB prediction error (MSE): 0.8728343 R squared (OOB): 0.8931909
Selectarea caracteristicilor folosind CV orientat către țintă
Pentru a reduce numărul de predictori de mediu și, astfel, îmbunătățirea generalizării modelului, selecția caracteristicilor se aplică în mod obișnuit în fluxurile de lucru de învățare automată. Distribuire implementează selecția înainte de caracteristică înainte, care poate fi utilizată cu CV spațial. Aici, folosim rezultatele reglării hiperparameterului de mai sus și CV -ul KNNDM pentru a selecta cele mai relevante caracteristici. Complotând rezultatele FFS()
arată că variabilele DEM
, Y
, EDF5
şi primaryroads
au fost selectate.
selected_hyperparams <- model_knndm$bestTune model_ffs <- CAST::ffs( predictors = sf::st_drop_geometry(temperature_train)(, predictor_names), response = sf::st_drop_geometry(temperature_train)$temp, method = "ranger", num.trees = 100, trControl = tr_control_knndm, tuneGrid = selected_hyperparams, verbose = FALSE ) plot(model_ffs, plotType = "selected")
# obtain prediction prediction_ffs <- terra::predict(predictor_stack, model_ffs, na.rm = TRUE)
AOA
În cele din urmă, zona care este prea diferită de datele de instruire pentru ca modelele să facă predicții fiabile (zona de aplicabilitate, AOA) este delimitată folosind funcția CAST::aoa()
. Funcția CAST::aoa()
ia ca intrări stiva de predictor, precum și antrenatul semn de omisiune model. Obiectul rezultat conține valorile de disimilaritate, pragul folosit pentru a delimita AOA (fiecare valoare de disimilaritate peste acest prag este considerată în afara AOA), precum și raster -ul final AOA. Deoarece datele noastre de instruire sunt distribuite aleatoriu în zona de studiu, cea mai mare parte a zonei se încadrează în AOA.
AOA_without_tuning <- CAST::aoa( newdata = predictor_stack, model = model, verbose = FALSE ) AOA_with_tuning <- CAST::aoa( newdata = predictor_stack, model = model_ffs, verbose = FALSE )
Comparați predicțiile obținute de modelul ne-reglat față de modelul reglat
par(mfrow = c(2, 2)) plot(prediction_spatial, main = "prediction without tuning") plot(AOA_without_tuning$AOA, main = "AOA without tuning") plot(prediction_ffs, main = "prediction with model selection") plot(AOA_with_tuning$AOA, main = "AOA with model selection")
Concluzie
semn de omisiune nu are funcții care să se ocupe în mod explicit de datele spațiale. Cu toate acestea, datorită designului său destul de flexibil, semn de omisiune este compatibil cu mai multe pachete concepute pentru învățarea spațială a mașinilor. caret::trainControl()
ia o listă de indici de CV ca intrare, ceea ce face destul de flexibil să funcționeze cu ieșirea de ex. CAST::knndm()
şi blockCV::cv_spatial()
. În plus, semn de omisiune este ușor de utilizat datorită paradigmei sale de programare funcțională. Documentația este extinsă și este destul de ușor să găsești algoritmi de modelare și hiperparametre. În cele din urmă, trebuie menționat că semn de omisiune nu este dezvoltat activ, deoarece principalul său dezvoltator s -a mutat la Tidymodels.
Această postare pe blog a fost scrisă inițial ca supliment la afișul „Un inventar al pachetelor de învățare automată spațială în R” prezentat la Conferința Fossgis 2025 din Muenster, Germania. Afișul este disponibil la https://doi.org/10.5281/zenodo.15088973.
Reutilizați
Citare
Citarea Bibtex:
@online{linnenbrink2025, author = {Linnenbrink, Jan}, title = {Spatial Machine Learning with Caret}, date = {2025-05-14}, url = {https://geocompx.org/post/2025/sml-bp2/}, langid = {en} }
Pentru atribuire, vă rugăm să citați această lucrare ca:
Linnenbrink, ianuarie 2025. „Învățarea spațială a mașinilor cu Caret.” 14 mai 2025. Https://geocompx.org/post/2025/sml-bp2/.