{"id":1381,"date":"2026-10-23T07:58:41","date_gmt":"2026-10-23T07:58:41","guid":{"rendered":"https:\/\/helpwithmygisassignment.com\/blog\/?p=1381"},"modified":"2026-10-23T07:58:41","modified_gmt":"2026-10-23T07:58:41","slug":"geospatial-cross-validation-machine-learning-gis","status":"publish","type":"post","link":"https:\/\/helpwithmygisassignment.com\/blog\/geospatial-cross-validation-machine-learning-gis\/","title":{"rendered":"Geospatial Cross-Validation in Machine Learning: Preventing Spatial Autocorrelation Leakage"},"content":{"rendered":"<div><\/div>\n<div>\n<div id=\"ez-toc-container\" class=\"ez-toc-v2_0_89 counter-hierarchy ez-toc-counter ez-toc-grey ez-toc-container-direction\">\n<div class=\"ez-toc-title-container\">\n<p class=\"ez-toc-title\" style=\"cursor:inherit\">Table of Contents<\/p>\n<span class=\"ez-toc-title-toggle\"><a href=\"#\" class=\"ez-toc-pull-right ez-toc-btn ez-toc-btn-xs ez-toc-btn-default ez-toc-toggle\" aria-label=\"Toggle Table of Content\"><span class=\"ez-toc-js-icon-con\"><span class=\"\"><span class=\"eztoc-hide\" style=\"display:none;\">Toggle<\/span><span class=\"ez-toc-icon-toggle-span\"><svg style=\"fill: #999;color:#999\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\" class=\"list-377408\" width=\"20px\" height=\"20px\" viewBox=\"0 0 24 24\" fill=\"none\"><path d=\"M6 6H4v2h2V6zm14 0H8v2h12V6zM4 11h2v2H4v-2zm16 0H8v2h12v-2zM4 16h2v2H4v-2zm16 0H8v2h12v-2z\" fill=\"currentColor\"><\/path><\/svg><svg style=\"fill: #999;color:#999\" class=\"arrow-unsorted-368013\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"10px\" height=\"10px\" viewBox=\"0 0 24 24\" version=\"1.2\" baseProfile=\"tiny\"><path d=\"M18.2 9.3l-6.2-6.3-6.2 6.3c-.2.2-.3.4-.3.7s.1.5.3.7c.2.2.4.3.7.3h11c.3 0 .5-.1.7-.3.2-.2.3-.5.3-.7s-.1-.5-.3-.7zM5.8 14.7l6.2 6.3 6.2-6.3c.2-.2.3-.5.3-.7s-.1-.5-.3-.7c-.2-.2-.4-.3-.7-.3h-11c-.3 0-.5.1-.7.3-.2.2-.3.5-.3.7s.1.5.3.7z\"\/><\/svg><\/span><\/span><\/span><\/a><\/span><\/div>\n<nav><ul class='ez-toc-list ez-toc-list-level-1 ' ><li class='ez-toc-page-1 ez-toc-heading-level-1'><a class=\"ez-toc-link ez-toc-heading-1\" href=\"https:\/\/helpwithmygisassignment.com\/blog\/geospatial-cross-validation-machine-learning-gis\/#Geospatial_Cross-Validation_in_Machine_Learning_Preventing_Spatial_Autocorrelation_Leakage\" >Geospatial Cross-Validation in Machine Learning: Preventing Spatial Autocorrelation Leakage<\/a><ul class='ez-toc-list-level-2' ><li class='ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-2\" href=\"https:\/\/helpwithmygisassignment.com\/blog\/geospatial-cross-validation-machine-learning-gis\/#1_Introduction\" >1. Introduction<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-3\" href=\"https:\/\/helpwithmygisassignment.com\/blog\/geospatial-cross-validation-machine-learning-gis\/#2_The_problem_spatial_data_leakage\" >2. The problem: spatial data leakage<\/a><ul class='ez-toc-list-level-3' ><li class='ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-4\" href=\"https:\/\/helpwithmygisassignment.com\/blog\/geospatial-cross-validation-machine-learning-gis\/#21_Spatial_autocorrelation_and_the_independence_assumption\" >2.1 Spatial autocorrelation and the independence assumption<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-5\" href=\"https:\/\/helpwithmygisassignment.com\/blog\/geospatial-cross-validation-machine-learning-gis\/#22_Why_random_K-fold_can_produce_optimistic_scores\" >2.2 Why random K-fold can produce optimistic scores<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-6\" href=\"https:\/\/helpwithmygisassignment.com\/blog\/geospatial-cross-validation-machine-learning-gis\/#23_Spatial_leakage_is_not_always_the_same_as_poor_model_design\" >2.3 Spatial leakage is not always the same as poor model design<\/a><\/li><\/ul><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-7\" href=\"https:\/\/helpwithmygisassignment.com\/blog\/geospatial-cross-validation-machine-learning-gis\/#3_Understanding_spatial_cross-validation_methods\" >3. Understanding spatial cross-validation methods<\/a><ul class='ez-toc-list-level-3' ><li class='ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-8\" href=\"https:\/\/helpwithmygisassignment.com\/blog\/geospatial-cross-validation-machine-learning-gis\/#31_Spatial_block_cross-validation\" >3.1 Spatial block cross-validation<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-9\" href=\"https:\/\/helpwithmygisassignment.com\/blog\/geospatial-cross-validation-machine-learning-gis\/#32_Spatial_clustering_and_leave-region-out_validation\" >3.2 Spatial clustering and leave-region-out validation<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-10\" href=\"https:\/\/helpwithmygisassignment.com\/blog\/geospatial-cross-validation-machine-learning-gis\/#33_Buffer-based_cross-validation\" >3.3 Buffer-based cross-validation<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-11\" href=\"https:\/\/helpwithmygisassignment.com\/blog\/geospatial-cross-validation-machine-learning-gis\/#34_Environmental_cross-validation\" >3.4 Environmental cross-validation<\/a><\/li><\/ul><\/li><\/ul><\/li><li class='ez-toc-page-1 ez-toc-heading-level-1'><a class=\"ez-toc-link ez-toc-heading-12\" href=\"https:\/\/helpwithmygisassignment.com\/blog\/geospatial-cross-validation-machine-learning-gis\/#4_Step-by-step_implementation_in_Python\" >4. Step-by-step implementation in Python<\/a><ul class='ez-toc-list-level-2' ><li class='ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-13\" href=\"https:\/\/helpwithmygisassignment.com\/blog\/geospatial-cross-validation-machine-learning-gis\/#Step_1_Install_the_required_packages\" >Step 1: Install the required packages<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-14\" href=\"https:\/\/helpwithmygisassignment.com\/blog\/geospatial-cross-validation-machine-learning-gis\/#Step_2_Load_the_spatial_dataset\" >Step 2: Load the spatial dataset<\/a><ul class='ez-toc-list-level-3' ><li class='ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-15\" href=\"https:\/\/helpwithmygisassignment.com\/blog\/geospatial-cross-validation-machine-learning-gis\/#Why_use_a_projected_CRS\" >Why use a projected CRS?<\/a><\/li><\/ul><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-16\" href=\"https:\/\/helpwithmygisassignment.com\/blog\/geospatial-cross-validation-machine-learning-gis\/#Step_3_Generate_spatial_block_folds\" >Step 3: Generate spatial block folds<\/a><ul class='ez-toc-list-level-3' ><li class='ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-17\" href=\"https:\/\/helpwithmygisassignment.com\/blog\/geospatial-cross-validation-machine-learning-gis\/#Inspect_the_spatial_configuration\" >Inspect the spatial configuration<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-18\" href=\"https:\/\/helpwithmygisassignment.com\/blog\/geospatial-cross-validation-machine-learning-gis\/#Alternative_Spatial_K-fold_through_coordinate_clustering\" >Alternative: Spatial K-fold through coordinate clustering<\/a><\/li><\/ul><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-19\" href=\"https:\/\/helpwithmygisassignment.com\/blog\/geospatial-cross-validation-machine-learning-gis\/#Step_4_Define_random_and_spatial_validation_splits\" >Step 4: Define random and spatial validation splits<\/a><ul class='ez-toc-list-level-3' ><li class='ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-20\" href=\"https:\/\/helpwithmygisassignment.com\/blog\/geospatial-cross-validation-machine-learning-gis\/#Random_five-fold_cross-validation\" >Random five-fold cross-validation<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-21\" href=\"https:\/\/helpwithmygisassignment.com\/blog\/geospatial-cross-validation-machine-learning-gis\/#Spatial_leave-one-region-out_validation\" >Spatial leave-one-region-out validation<\/a><\/li><\/ul><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-22\" href=\"https:\/\/helpwithmygisassignment.com\/blog\/geospatial-cross-validation-machine-learning-gis\/#Step_5_Train_a_Random_Forest_regression_model\" >Step 5: Train a Random Forest regression model<\/a><ul class='ez-toc-list-level-3' ><li class='ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-23\" href=\"https:\/\/helpwithmygisassignment.com\/blog\/geospatial-cross-validation-machine-learning-gis\/#Implement_a_cross-validation_evaluation_function\" >Implement a cross-validation evaluation function<\/a><\/li><\/ul><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-24\" href=\"https:\/\/helpwithmygisassignment.com\/blog\/geospatial-cross-validation-machine-learning-gis\/#Step_6_Run_the_two_validation_experiments\" >Step 6: Run the two validation experiments<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-25\" href=\"https:\/\/helpwithmygisassignment.com\/blog\/geospatial-cross-validation-machine-learning-gis\/#Step_7_Compare_accuracy_metrics\" >Step 7: Compare accuracy metrics<\/a><ul class='ez-toc-list-level-3' ><li class='ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-26\" href=\"https:\/\/helpwithmygisassignment.com\/blog\/geospatial-cross-validation-machine-learning-gis\/#Interpreting_the_metrics\" >Interpreting the metrics<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-27\" href=\"https:\/\/helpwithmygisassignment.com\/blog\/geospatial-cross-validation-machine-learning-gis\/#Pooled_scores_versus_mean_fold_scores\" >Pooled scores versus mean fold scores<\/a><\/li><\/ul><\/li><\/ul><\/li><li class='ez-toc-page-1 ez-toc-heading-level-1'><a class=\"ez-toc-link ez-toc-heading-28\" href=\"https:\/\/helpwithmygisassignment.com\/blog\/geospatial-cross-validation-machine-learning-gis\/#5_Implement_buffer-based_cross-validation\" >5. Implement buffer-based cross-validation<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-1'><a class=\"ez-toc-link ez-toc-heading-29\" href=\"https:\/\/helpwithmygisassignment.com\/blog\/geospatial-cross-validation-machine-learning-gis\/#6_Environmental_cross-validation_in_Python\" >6. Environmental cross-validation in Python<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-1'><a class=\"ez-toc-link ez-toc-heading-30\" href=\"https:\/\/helpwithmygisassignment.com\/blog\/geospatial-cross-validation-machine-learning-gis\/#7_Adapting_the_workflow_for_classification\" >7. Adapting the workflow for classification<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-1'><a class=\"ez-toc-link ez-toc-heading-31\" href=\"https:\/\/helpwithmygisassignment.com\/blog\/geospatial-cross-validation-machine-learning-gis\/#8_Using_PySAL_for_spatial_validation\" >8. Using PySAL for spatial validation<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-1'><a class=\"ez-toc-link ez-toc-heading-32\" href=\"https:\/\/helpwithmygisassignment.com\/blog\/geospatial-cross-validation-machine-learning-gis\/#9_Interpreting_the_Results_Scientifically\" >9. Interpreting the Results Scientifically<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-1'><a class=\"ez-toc-link ez-toc-heading-33\" href=\"https:\/\/helpwithmygisassignment.com\/blog\/geospatial-cross-validation-machine-learning-gis\/#10_Best_practices_for_academic_research_papers\" >10. Best practices for academic research papers<\/a><ul class='ez-toc-list-level-2' ><li class='ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-34\" href=\"https:\/\/helpwithmygisassignment.com\/blog\/geospatial-cross-validation-machine-learning-gis\/#101_Justify_block_dimensions\" >10.1 Justify block dimensions<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-35\" href=\"https:\/\/helpwithmygisassignment.com\/blog\/geospatial-cross-validation-machine-learning-gis\/#102_Keep_model_selection_inside_the_validation_design\" >10.2 Keep model selection inside the validation design<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-36\" href=\"https:\/\/helpwithmygisassignment.com\/blog\/geospatial-cross-validation-machine-learning-gis\/#103_Report_fold-level_uncertainty\" >10.3 Report fold-level uncertainty<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-37\" href=\"https:\/\/helpwithmygisassignment.com\/blog\/geospatial-cross-validation-machine-learning-gis\/#104_Document_the_full_reproducibility_setup\" >10.4 Document the full reproducibility setup<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-38\" href=\"https:\/\/helpwithmygisassignment.com\/blog\/geospatial-cross-validation-machine-learning-gis\/#105_A_practical_decision_guide\" >10.5 A practical decision guide<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-39\" href=\"https:\/\/helpwithmygisassignment.com\/blog\/geospatial-cross-validation-machine-learning-gis\/#Conclusion\" >Conclusion<\/a><\/li><\/ul><\/li><\/ul><\/nav><\/div>\n<h1><span class=\"ez-toc-section\" id=\"Geospatial_Cross-Validation_in_Machine_Learning_Preventing_Spatial_Autocorrelation_Leakage\"><\/span>Geospatial Cross-Validation in Machine Learning: Preventing Spatial Autocorrelation Leakage<span class=\"ez-toc-section-end\"><\/span><\/h1>\n<h2><span class=\"ez-toc-section\" id=\"1_Introduction\"><\/span>1. Introduction<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-large wp-image-1532\" src=\"https:\/\/helpwithmygisassignment.com\/blog\/wp-content\/uploads\/2026\/10\/Gemini_Generated_Image_56fsf056fsf056fs-1024x572.jpg\" alt=\"Geospatial Cross Validation Machine Learning GIS spatial block folds map interface\" width=\"1024\" height=\"572\" srcset=\"https:\/\/helpwithmygisassignment.com\/blog\/wp-content\/uploads\/2026\/10\/Gemini_Generated_Image_56fsf056fsf056fs-1024x572.jpg 1024w, https:\/\/helpwithmygisassignment.com\/blog\/wp-content\/uploads\/2026\/10\/Gemini_Generated_Image_56fsf056fsf056fs-300x167.jpg 300w, https:\/\/helpwithmygisassignment.com\/blog\/wp-content\/uploads\/2026\/10\/Gemini_Generated_Image_56fsf056fsf056fs-768x429.jpg 768w, https:\/\/helpwithmygisassignment.com\/blog\/wp-content\/uploads\/2026\/10\/Gemini_Generated_Image_56fsf056fsf056fs.jpg 1376w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/p>\n<p>Using <b data-path-to-node=\"2,0,1,0\" data-index-in-node=\"7\">Geospatial Cross Validation Machine Learning GIS<\/b> techniques is essential when modeling<a href=\"https:\/\/helpwithmygisassignment.com\/blog\/building-real-time-spatial-dashboards-in-qgis-with-geonode-and-postgis\/\"> spatial phenomena<\/a> like land surface temperature or soil properties. Machine learning models are increasingly used to predict spatial phenomena, including land surface temperature, soil properties, flood susceptibility, vegetation condition, species distributions, housing values, and urban expansion. These applications often combine satellite imagery, environmental covariates, terrain derivatives, socioeconomic variables, and geographically referenced observations.<\/p>\n<p>A common approach is to evaluate a model using random <span data-math-source=\"K\" data-math-display=\"false\">\\(K\\)<\/span>-fold cross-validation. The dataset is divided into <span data-math-source=\"K\" data-math-display=\"false\">\\(K\\)<\/span> subsets; the model is trained on <span data-math-source=\"K-1\" data-math-display=\"false\">\\(K-1\\)<\/span> subsets and evaluated on the remaining subset. The process repeats until every subset has served as the test set.<\/p>\n<p>For independently sampled data, this procedure can provide a useful estimate of predictive performance. Spatial data, however, frequently violate the independence assumption underlying this interpretation.<\/p>\n<p>Nearby observations often share similar environmental conditions, spatial context, measurement errors, and unobserved influences. When a training point is close to a test point, the model may benefit from geographic similarity that will not be available when predicting an entirely new region.<\/p>\n<p>For example, suppose a Random Forest predicts soil organic carbon from elevation, rainfall, vegetation indices, and soil observations. Random cross-validation may place one sample from a field in the training set and another sample from the same field in the test set. Those samples could share nearly identical predictors and similar soil properties. The resulting test score may reflect the model&#8217;s ability to interpolate within a familiar landscape rather than generalize to a new one.<\/p>\n<p>Spatial cross-validation addresses this problem by designing validation folds around the geographic or environmental structure of the prediction task. Depending on the method, test observations may be assigned to geographically separated blocks, isolated from training observations by a buffer, or grouped into distinct environmental conditions.<\/p>\n<p>The central methodological principle is:<\/p>\n<blockquote><p>Validation data must represent the kind of new observations or locations for which the model will actually be used.<\/p><\/blockquote>\n<p>A lower spatial cross-validation score is not necessarily evidence that the model is poor. It may be a more realistic estimate of performance when predicting beyond the spatial neighborhoods represented in the training data.<\/p>\n<h2><span class=\"ez-toc-section\" id=\"2_The_problem_spatial_data_leakage\"><\/span>2. The problem: spatial data leakage<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>Spatial data leakage occurs when information about test observations is indirectly available to the model during training. In geographic machine learning, this often arises because samples that belong to neighboring locations are distributed across different folds.<\/p>\n<h3><span class=\"ez-toc-section\" id=\"21_Spatial_autocorrelation_and_the_independence_assumption\"><\/span>2.1 Spatial autocorrelation and the independence assumption<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>Let <span data-math-source=\"Y(\\mathbf{s})\" data-math-display=\"false\">\\(Y(\\mathbf{s})\\)<\/span> be a target variable at spatial location <span data-math-source=\"\\mathbf{s}\" data-math-display=\"false\">\\(\\mathbf{s}\\)<\/span>, and let <span data-math-source=\"X(\\mathbf{s})\" data-math-display=\"false\">\\(X(\\mathbf{s})\\)<\/span> represent its predictor vector. A spatial prediction model can be written as<\/p>\n<div><span data-math-source=\"Y(\\mathbf{s})=f(X(\\mathbf{s}))+\\varepsilon(\\mathbf{s})\" data-math-display=\"true\">\\[ Y(\\mathbf{s})=f(X(\\mathbf{s}))+\\varepsilon(\\mathbf{s}) \\]<\/span><\/div>\n<p>where <span data-math-source=\"f\" data-math-display=\"false\">\\(f\\)<\/span> is the fitted prediction function and <span data-math-source=\"\\varepsilon(\\mathbf{s})\" data-math-display=\"false\">\\(\\varepsilon(\\mathbf{s})\\)<\/span> is the residual process.<\/p>\n<p>For geographically dependent observations, residual covariance may depend on the distance between locations:<\/p>\n<div><span data-math-source=\"\\operatorname{Cov} \\left[ \\varepsilon(\\mathbf{s}), \\varepsilon(\\mathbf{s}+\\mathbf{h}) \\right] =C(\\mathbf{h})\" data-math-display=\"true\">\\[ \\operatorname{Cov} \\left[ \\varepsilon(\\mathbf{s}), \\varepsilon(\\mathbf{s}+\\mathbf{h}) \\right] =C(\\mathbf{h}) \\]<\/span><\/div>\n<p>Here, <span data-math-source=\"\\mathbf{h}\" data-math-display=\"false\">\\(\\mathbf{h}\\)<\/span> is the spatial separation vector and <span data-math-source=\"C(\\mathbf{h})\" data-math-display=\"false\">\\(C(\\mathbf{h})\\)<\/span> describes how dependence changes with distance and direction.<\/p>\n<p>When nearby observations are correlated, a randomly selected test point may have a training observation very close to it. That proximity can make the prediction problem substantially easier than prediction in an unobserved region.<\/p>\n<p>Spatially structured data can therefore produce underestimated prediction errors when ordinary random cross-validation ignores spatial dependence. This problem is documented in the methodological literature on structured cross-validation.<\/p>\n<div>\n<div>\n<div><img decoding=\"async\" src=\"https:\/\/www.google.com\/s2\/favicons?domain=https:\/\/nsojournals.onlinelibrary.wiley.com&amp;sz=32\" \/><\/div>\n<\/div>\n<div>\n<div>Wiley Online Library<\/div>\n<div>+1<\/div>\n<\/div>\n<\/div>\n<p>&nbsp;<\/p>\n<h3><span class=\"ez-toc-section\" id=\"22_Why_random_K-fold_can_produce_optimistic_scores\"><\/span>2.2 Why random K-fold can produce optimistic scores<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>Consider two validation strategies.<\/p>\n<div>\n<p>Random K-fold<\/p>\n<p>Training and test samples are interspersed; nearby observations often remain in the training data.<\/p>\n<div><\/div>\n<p>Spatially blocked validation<\/p>\n<p>Whole geographic regions are held out, testing whether the model generalizes beyond the locations represented in training.<\/p>\n<\/div>\n<p>Random cross-validation does not necessarily leak target values directly. Instead, it can allow a model to exploit spatially redundant information shared between nearby observations.<\/p>\n<p>For example, two adjacent satellite pixels can have almost identical NDVI, elevation, surface reflectance, and land-cover characteristics. If the target is also spatially smooth, a model may predict one pixel accurately because comparable pixels are present in its training set.<\/p>\n<p>This issue is especially important when the intended application involves predicting in new districts, new watersheds, unsampled agricultural areas, or other geographic regions outside the training sample&#8217;s spatial neighborhoods.<\/p>\n<h3><span class=\"ez-toc-section\" id=\"23_Spatial_leakage_is_not_always_the_same_as_poor_model_design\"><\/span>2.3 Spatial leakage is not always the same as poor model design<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>A spatially structured validation score estimates performance under its particular split strategy. Spatially blocked validation is more suitable for testing geographic transfer, but random validation may still be appropriate for an interpolation task in a densely sampled region.<\/p>\n<p>Consequently, the objective is not to maximize the distance between training and test observations in every study. It is to design the validation procedure around the actual prediction task.<\/p>\n<p>For example:<\/p>\n<ul>\n<li>\n<div>\n<div>\n<p>Mapping gaps between existing soil samples may require local interpolation validation.<\/p>\n<\/div>\n<\/div>\n<\/li>\n<li>\n<div>\n<div>\n<p>Predicting soil properties in an entirely new agricultural district requires geographic transfer validation.<\/p>\n<\/div>\n<\/div>\n<\/li>\n<li>\n<div>\n<div>\n<p>Predicting land-cover classes under unfamiliar environmental conditions may require environmental separation.<\/p>\n<\/div>\n<\/div>\n<\/li>\n<li>\n<div>\n<div>\n<p>Forecasting future conditions requires a temporally appropriate split, potentially combined with spatial separation.<\/p>\n<\/div>\n<\/div>\n<\/li>\n<\/ul>\n<div><\/div>\n<h2><span class=\"ez-toc-section\" id=\"3_Understanding_spatial_cross-validation_methods\"><\/span>3. Understanding spatial cross-validation methods<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>Spatial cross-validation refers to a family of strategies rather than one specific splitting algorithm.<\/p>\n<h3><span class=\"ez-toc-section\" id=\"31_Spatial_block_cross-validation\"><\/span>3.1 Spatial block cross-validation<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-large wp-image-1533\" src=\"https:\/\/helpwithmygisassignment.com\/blog\/wp-content\/uploads\/2026\/10\/Gemini_Generated_Image_55kvg255kvg255kv-1024x559.jpg\" alt=\"Geospatial Cross Validation Machine Learning GIS block vs random cross validation comparison\" width=\"1024\" height=\"559\" srcset=\"https:\/\/helpwithmygisassignment.com\/blog\/wp-content\/uploads\/2026\/10\/Gemini_Generated_Image_55kvg255kvg255kv-1024x559.jpg 1024w, https:\/\/helpwithmygisassignment.com\/blog\/wp-content\/uploads\/2026\/10\/Gemini_Generated_Image_55kvg255kvg255kv-300x164.jpg 300w, https:\/\/helpwithmygisassignment.com\/blog\/wp-content\/uploads\/2026\/10\/Gemini_Generated_Image_55kvg255kvg255kv-768x419.jpg 768w, https:\/\/helpwithmygisassignment.com\/blog\/wp-content\/uploads\/2026\/10\/Gemini_Generated_Image_55kvg255kvg255kv.jpg 1408w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/p>\n<p>Spatial block cross-validation divides the study area into geographic blocks and assigns those blocks to validation folds.<\/p>\n<p>Instead of randomly assigning individual observations, the method assigns all observations in a block to the same geographic fold.<\/p>\n<p>Common block shapes include rectangles, squares, and hexagons. Blocks may be arranged as contiguous regions or assigned to folds using other spatial configurations. The R package <code>blockCV<\/code> provides established implementations of spatial blocks, environmental blocks, and buffered validation.<\/p>\n<p>Let <span data-math-source=\"B(\\mathbf{s})\" data-math-display=\"false\">\\(B(\\mathbf{s})\\)<\/span> represent the block containing a sample at location <span data-math-source=\"\\mathbf{s}\" data-math-display=\"false\">\\(\\mathbf{s}\\)<\/span>. The fold assignment is a function of block membership:<\/p>\n<div><span data-math-source=\"F(\\mathbf{s})=g(B(\\mathbf{s}))\" data-math-display=\"true\">\\[ F(\\mathbf{s})=g(B(\\mathbf{s})) \\]<\/span><\/div>\n<p>where <span data-math-source=\"g\" data-math-display=\"false\">\\(g\\)<\/span> assigns each block to a fold.<\/p>\n<p>A five-fold spatial cross-validation procedure could train on four spatial regions and evaluate on the fifth, repeating the procedure until all five regions have been held out.<\/p>\n<p>Choosing the block size is critical. Blocks that are too small may leave nearby training observations next to test observations, preserving spatial dependence across the split. Blocks that are too large may leave too few independent regions for reliable evaluation.<\/p>\n<p>Use domain knowledge, spatial autocorrelation analysis, residual variograms, and sensitivity testing to select a defensible scale.<\/p>\n<h3><span class=\"ez-toc-section\" id=\"32_Spatial_clustering_and_leave-region-out_validation\"><\/span>3.2 Spatial clustering and leave-region-out validation<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>Spatial clustering groups nearby observations into regions. Each region becomes a validation group.<\/p>\n<p>For example, K-means clustering applied to projected coordinates divides a set of points into spatial clusters. The clusters can then be used with<a href=\"https:\/\/scikit-learn.org\/stable\/\" target=\"_blank\" rel=\"noopener\"> scikit-learn<\/a>&#8216;s <code>LeaveOneGroupOut<\/code> splitter.<\/p>\n<p>This strategy is useful when the region is irregularly shaped or sample locations are unevenly distributed.<\/p>\n<p>The Python package <code>spatial-kfold<\/code> supports spatial clustering and spatial block resampling and integrates with scikit-learn&#8217;s group-based cross-validation methods.<\/p>\n<div>\n<div><\/div>\n<\/div>\n<p>However, clustering points into regions does not automatically enforce a minimum distance between train and test samples. Adjacent clusters may still border each other.<\/p>\n<h3><span class=\"ez-toc-section\" id=\"33_Buffer-based_cross-validation\"><\/span>3.3 Buffer-based cross-validation<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>Buffer-based cross-validation removes nearby training observations around held-out test locations.<\/p>\n<p>For a test set <span data-math-source=\"T_k\" data-math-display=\"false\">\\(T_k\\)<\/span>, the retained training set can be defined as<\/p>\n<div><span data-math-source=\"T_k^{\\text{train}} = \\left\\{ i\\notin T_k: \\min_{j\\in T_k}d(\\mathbf{s}_i,\\mathbf{s}_j) \\geq r \\right\\}\" data-math-display=\"true\">\\[ T_k^{\\text{train}} = \\left\\{ i\\notin T_k: \\min_{j\\in T_k}d(\\mathbf{s}_i,\\mathbf{s}_j) \\geq r \\right\\} \\]<\/span><\/div>\n<p>where:<\/p>\n<ul>\n<li>\n<div>\n<div>\n<p><span data-math-source=\"d(\\mathbf{s}_i,\\mathbf{s}_j)\" data-math-display=\"false\">\\(d(\\mathbf{s}_i,\\mathbf{s}_j)\\)<\/span> is geographic distance.<\/p>\n<\/div>\n<\/div>\n<\/li>\n<li>\n<div>\n<div>\n<p><span data-math-source=\"r\" data-math-display=\"false\">\\(r\\)<\/span> is a buffer radius.<\/p>\n<\/div>\n<\/div>\n<\/li>\n<li>\n<div>\n<div>\n<p><span data-math-source=\"T_k\" data-math-display=\"false\">\\(T_k\\)<\/span> is the held-out test fold.<\/p>\n<\/div>\n<\/div>\n<\/li>\n<\/ul>\n<p>A test region is evaluated using training samples beyond the chosen separation distance.<\/p>\n<p>Buffering is useful when a specific minimum distance is required and residual spatial autocorrelation extends across nearby geographic blocks.<\/p>\n<p>The disadvantage is that a large buffer may remove a substantial proportion of the training observations. The remaining training sample can become too small or geographically unrepresentative.<\/p>\n<div>\n<div><\/div>\n<\/div>\n<h3><span class=\"ez-toc-section\" id=\"34_Environmental_cross-validation\"><\/span>3.4 Environmental cross-validation<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>Environmental cross-validation groups samples by similarity in predictor space rather than geographic location alone.<\/p>\n<p>Suppose the model uses temperature, rainfall, elevation, NDVI, and soil texture. Samples can be clustered using these variables, and entire environmental clusters can be held out during validation.<\/p>\n<p>This approach tests whether the model can transfer into environmental conditions not represented by the remaining training groups.<\/p>\n<p>Spatial and environmental separation answer different questions:<\/p>\n<div>\n<table>\n<tbody>\n<tr>\n<th>Method<\/th>\n<th>Primary question<\/th>\n<\/tr>\n<tr>\n<td>Random K-fold<\/td>\n<td>How accurately can the model predict randomly held-out observations from a similar sample distribution?<\/td>\n<\/tr>\n<tr>\n<td>Spatial blocks<\/td>\n<td>How accurately can the model predict observations in held-out geographic regions?<\/td>\n<\/tr>\n<tr>\n<td>Spatial buffers<\/td>\n<td>How accurately can the model predict when nearby training observations are excluded?<\/td>\n<\/tr>\n<tr>\n<td>Environmental blocks<\/td>\n<td>How accurately can the model transfer to held-out environmental conditions?<\/td>\n<\/tr>\n<tr>\n<td>Spatial plus environmental separation<\/td>\n<td>How well does the model generalize across both geographic and environmental differences?<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<p>These designs can produce very different scores. None is universally optimal; each should be selected according to the scientific question.<\/p>\n<div><\/div>\n<h1><span class=\"ez-toc-section\" id=\"4_Step-by-step_implementation_in_Python\"><\/span>4. Step-by-step implementation in Python<span class=\"ez-toc-section-end\"><\/span><\/h1>\n<p>We will build a reproducible workflow using GeoPandas, <code>spatial-kfold<\/code>, scikit-learn, and SciPy.<\/p>\n<p>The example predicts soil organic carbon from spatial covariates. The same architecture can be adapted for regression tasks such as land surface temperature or vegetation biomass, and the classification adaptation is described later.<\/p>\n<h2><span class=\"ez-toc-section\" id=\"Step_1_Install_the_required_packages\"><\/span>Step 1: Install the required packages<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<div>\n<div>\n<pre dir=\"ltr\"><code>python -m pip install geopandas spatial-kfold scikit-learn scipy pandas numpy matplotlib<\/code><\/pre>\n<\/div>\n<\/div>\n<p>The <code>spatial-kfold<\/code> distribution is imported in Python as <code>spatialkfold<\/code>. It supports geographic clustering and rectangular or hexagonal spatial block generation.<\/p>\n<div>\n<div><\/div>\n<\/div>\n<p>For this tutorial, the input is a point vector file such as <code>training_samples.gpkg<\/code>. Each feature contains a measured target and its associated predictor values.<\/p>\n<p>Example attribute structure:<\/p>\n<div>\n<table>\n<tbody>\n<tr>\n<th>Field<\/th>\n<th>Description<\/th>\n<\/tr>\n<tr>\n<td><code>soil_carbon<\/code><\/td>\n<td>Target variable<\/td>\n<\/tr>\n<tr>\n<td><code>elevation<\/code><\/td>\n<td>Terrain elevation<\/td>\n<\/tr>\n<tr>\n<td><code>rainfall<\/code><\/td>\n<td>Precipitation covariate<\/td>\n<\/tr>\n<tr>\n<td><code>ndvi<\/code><\/td>\n<td>Vegetation index<\/td>\n<\/tr>\n<tr>\n<td><code>slope<\/code><\/td>\n<td>Terrain slope<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<p>The sample locations must be represented by point geometries, and each row should correspond to one independent observation record.<\/p>\n<h2><span class=\"ez-toc-section\" id=\"Step_2_Load_the_spatial_dataset\"><\/span>Step 2: Load the spatial dataset<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<div>\n<div>\n<pre dir=\"ltr\"><code>import numpy as npimport pandas as pdimport geopandas as gpdfrom sklearn.model_selection import KFold, LeaveOneGroupOutfrom sklearn.ensemble import RandomForestRegressorfrom sklearn.base import clonefrom sklearn.metrics import (    r2_score,    mean_squared_error,    mean_absolute_error,)# --------------------------------------------------------# 1. Read the spatial observations.# --------------------------------------------------------samples = gpd.read_file(\"data\/training_samples.gpkg\")TARGET = \"soil_carbon\"PREDICTORS = [    \"elevation\",    \"rainfall\",    \"ndvi\",    \"slope\",]required = PREDICTORS + [TARGET]# --------------------------------------------------------# 2. Validate the input schema and geometries.# --------------------------------------------------------missing_columns = set(required) - set(samples.columns)<\/code><\/pre>\n<\/div>\n<div><\/div>\n<\/div>\n<h3><span class=\"ez-toc-section\" id=\"Why_use_a_projected_CRS\"><\/span>Why use a projected CRS?<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>Spatial block widths and buffer radii are distance-based parameters. Longitude and latitude are angular coordinates, not linear distances in meters.<\/p>\n<p>A projected CRS allows the workflow to create blocks such as 5,000 m wide and calculate distances in compatible units.<\/p>\n<p>The <code>estimate_utm_crs()<\/code> method provides a useful starting point for regional data. For larger or multi-zone study areas, use a projection designed for the full analysis region instead.<\/p>\n<div>\n<div><\/div>\n<\/div>\n<p>Also note that this example explicitly removes missing predictor and target values. If imputation is required, fit the imputation procedure inside each training fold through a scikit-learn <code>Pipeline<\/code>. Do not estimate imputation statistics using the entire dataset before validation.<\/p>\n<div><\/div>\n<h2><span class=\"ez-toc-section\" id=\"Step_3_Generate_spatial_block_folds\"><\/span>Step 3: Generate spatial block folds<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>We will first use the <code>spatial-kfold<\/code> package to produce geographically structured blocks.<\/p>\n<p>The example below uses 5 km by 5 km rectangular grid cells and assigns them to contiguous spatial folds. These dimensions are illustrative and should be replaced with a scientifically justified block scale.<\/p>\n<div>\n<div>\n<pre dir=\"ltr\"><code>from spatialkfold.blocks import spatial_blocks# --------------------------------------------------------# Create rectangular spatial blocks.# --------------------------------------------------------block_polygons = spatial_blocks(    gdf=samples[[\"sample_id\", \"geometry\"]].copy(),    width=5000,    height=5000,    method=\"continuous\",    orientation=\"tb-lr\",    grid_type=\"rect\",    nfolds=5,    random_state=42,)# --------------------------------------------------------# Assign each point to the fold of its containing block.# --------------------------------------------------------point_blocks = gpd.sjoin(    samples[[\"sample_id\", \"geometry\"]],    block_polygons[[\"folds\", \"geometry\"]],    how=\"left\",    predicate=\"intersects\",)# Some points exactly on a block boundary may intersect# more than one polygon. Resolve those ties deterministically.point_blocks = (    point_blocks    .dropna(subset=[\"folds\"])    .sort_values([\"sample_id\", \"folds\"])    .drop_duplicates(subset=[\"sample_id\"]))<\/code><\/pre>\n<\/div>\n<div><\/div>\n<\/div>\n<p>The package&#8217;s <code>spatial_blocks()<\/code> method supports rectangular and hexagonal blocks and provides different arrangements for spatially resampled blocks.<\/p>\n<div>\n<div><\/div>\n<\/div>\n<p>The <code>intersects<\/code> predicate is used to handle sample locations exactly on a block boundary. When a point intersects multiple adjoining cells, the code assigns it deterministically to one fold.<\/p>\n<h3><span class=\"ez-toc-section\" id=\"Inspect_the_spatial_configuration\"><\/span>Inspect the spatial configuration<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>Always examine the distribution of folds before fitting the model.<\/p>\n<div>\n<div>\n<pre dir=\"ltr\"><code>import matplotlib.pyplot as pltfig, ax = plt.subplots(figsize=(10, 8))block_polygons.plot(    column=\"folds\",    categorical=True,    legend=True,    edgecolor=\"black\",    linewidth=0.5,    ax=ax,)samples.plot(    ax=ax,    color=\"black\",    markersize=3,    alpha=0.6,)ax.set_title(\"Spatial Cross-Validation Fold Assignment\")ax.set_axis_off()plt.tight_layout()plt.show()<\/code><\/pre>\n<\/div>\n<div><\/div>\n<\/div>\n<p>Check whether the held-out folds correspond to the kind of geographic transfer you intend to measure.<\/p>\n<p>A set of tiny blocks scattered randomly across the study area would not provide the same separation as five coherent geographic regions.<\/p>\n<p>Also verify that each fold contains sufficient test observations and that the remaining training dataset is large enough to fit the model.<\/p>\n<h3><span class=\"ez-toc-section\" id=\"Alternative_Spatial_K-fold_through_coordinate_clustering\"><\/span>Alternative: Spatial K-fold through coordinate clustering<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>If contiguous rectangular blocks do not fit the study geometry, use the package&#8217;s spatial clustering function instead.<\/p>\n<div>\n<div>\n<pre dir=\"ltr\"><code>from spatialkfold.clusters import spatial_kfold_clusterscluster_folds = spatial_kfold_clusters(    gdf=samples[[\"sample_id\", \"geometry\"]].copy(),    name=\"sample_id\",    nfolds=5,    algorithm=\"kmeans\",    n_init=\"auto\",    random_state=42,)cluster_lookup = cluster_folds.set_index(    \"sample_id\")[\"folds\"]samples[\"cluster_fold\"] = samples[\"sample_id\"].map(    cluster_lookup)assert samples[\"cluster_fold\"].notna().all()<\/code><\/pre>\n<\/div>\n<div><\/div>\n<\/div>\n<p>This groups observations into spatial clusters that can be used as validation groups. The package documents both K-means and Bisecting K-means options.<\/p>\n<div>\n<div><\/div>\n<\/div>\n<p>Spatial clusters and predefined blocks are not identical. Use blocks when you want the separation scale to be controlled explicitly through geographic dimensions. Use spatial clustering when data distribution or irregular study geometry makes regional grouping more convenient.<\/p>\n<div><\/div>\n<h2><span class=\"ez-toc-section\" id=\"Step_4_Define_random_and_spatial_validation_splits\"><\/span>Step 4: Define random and spatial validation splits<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>Now we create two competing validation designs using the same observations and the same predictive model.<\/p>\n<h3><span class=\"ez-toc-section\" id=\"Random_five-fold_cross-validation\"><\/span>Random five-fold cross-validation<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<div>\n<div>\n<pre dir=\"ltr\"><code>random_cv = KFold(    n_splits=5,    shuffle=True,    random_state=42,)random_splits = list(random_cv.split(X, y))<\/code><\/pre>\n<\/div>\n<div><\/div>\n<\/div>\n<p>Random K-fold does not consider geographic coordinates. Its test points may be surrounded by training points.<\/p>\n<h3><span class=\"ez-toc-section\" id=\"Spatial_leave-one-region-out_validation\"><\/span>Spatial leave-one-region-out validation<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<div>\n<div>\n<pre dir=\"ltr\"><code>spatial_groups = samples[\"spatial_fold\"].to_numpy()spatial_cv = LeaveOneGroupOut()spatial_splits = list(    spatial_cv.split(        X,        y,        groups=spatial_groups,    ))print(\"Random CV folds:\", len(random_splits))print(\"Spatial CV folds:\", len(spatial_splits))<\/code><\/pre>\n<\/div>\n<div><\/div>\n<\/div>\n<p><code>LeaveOneGroupOut<\/code> holds out one complete group at a time, placing all observations belonging to that group in the test fold and observations from the other groups in the training fold. This is the group-based validation strategy supported by scikit-learn.<\/p>\n<div>\n<div><\/div>\n<\/div>\n<p>Because the <code>spatial_fold<\/code> field contains geographic group assignments, the spatial split keeps each group intact.<\/p>\n<p>This is a critical difference from using ordinary <code>KFold<\/code> on the same records.<\/p>\n<div><\/div>\n<h2><span class=\"ez-toc-section\" id=\"Step_5_Train_a_Random_Forest_regression_model\"><\/span>Step 5: Train a Random Forest regression model<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>We now use the same estimator for both validation strategies.<\/p>\n<p>Random Forest is useful for this demonstration because it accommodates nonlinear relationships and interactions between environmental variables without requiring feature standardization.<\/p>\n<div>\n<div>\n<pre dir=\"ltr\"><code>model = RandomForestRegressor(    n_estimators=400,    max_features=1.0,    min_samples_leaf=2,    random_state=42,    n_jobs=-1,)<\/code><\/pre>\n<\/div>\n<div><\/div>\n<\/div>\n<p>The chosen values are example settings, not universally optimal hyperparameters. Do not tune the model on the same held-out folds that will be used to report final performance.<\/p>\n<h3><span class=\"ez-toc-section\" id=\"Implement_a_cross-validation_evaluation_function\"><\/span>Implement a cross-validation evaluation function<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>The following function trains a fresh estimator for every fold and records out-of-fold predictions.<\/p>\n<div>\n<div>\n<pre dir=\"ltr\"><code>def evaluate_splits(splits, estimator, X, y):    \"\"\"    Evaluate an estimator using predefined train\/test splits.    Returns    -------    fold_results : pandas.DataFrame        Fold-level evaluation metrics and sample counts.    oof_predictions : numpy.ndarray        Prediction for each observation from the fold where        that observation served as test data.    \"\"\"    oof_predictions = np.full(len(y), np.nan, dtype=float)    rows = []    for fold_number, (train_idx, test_idx) in enumerate(        splits, start=1    ):        if len(train_idx) == 0 or len(test_idx) == 0:            raise ValueError(                f\"Fold {fold_number} has an empty train\/test set.\"            )        # Create a fresh estimator for this fold.        fold_model = clone(estimator)        X_train = X[train_idx]        y_train = y[train_idx]        X_test = X[test_idx]        y_test = y[test_idx]        # Fit only on the training observations.        fold_model.fit(X_train, y_train)<\/code><\/pre>\n<\/div>\n<div><\/div>\n<\/div>\n<p>Each fold receives a cloned estimator to prevent fitted trees from carrying across validation iterations. Each observation&#8217;s stored prediction therefore comes from a model that was not trained on that observation.<\/p>\n<div><\/div>\n<h2><span class=\"ez-toc-section\" id=\"Step_6_Run_the_two_validation_experiments\"><\/span>Step 6: Run the two validation experiments<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<div>\n<div>\n<pre dir=\"ltr\"><code># --------------------------------------------------------# Random K-fold# --------------------------------------------------------random_results, random_oof = evaluate_splits(    random_splits,    model,    X,    y,)# --------------------------------------------------------# Spatial-block cross-validation# --------------------------------------------------------spatial_results, spatial_oof = evaluate_splits(    spatial_splits,    model,    X,    y,)print(\"Random K-fold results:\")print(random_results)print(\"\\nSpatial-block results:\")print(spatial_results)<\/code><\/pre>\n<\/div>\n<div><\/div>\n<\/div>\n<p>At this stage, you should compare the performance distributions across folds, rather than relying only on one overall score.<\/p>\n<p>If random cross-validation gives a much higher <span data-math-source=\"R^2\" data-math-display=\"false\">\\(R^2\\)<\/span> than spatial-block validation, the result may indicate that the model benefits from spatial similarity between training and test observations.<\/p>\n<p>However, do not interpret the difference as definitive proof of leakage without examining the fold configurations and prediction task. Spatial blocks may also create a more difficult extrapolation problem or a different distribution of test observations.<\/p>\n<div><\/div>\n<h2><span class=\"ez-toc-section\" id=\"Step_7_Compare_accuracy_metrics\"><\/span>Step 7: Compare accuracy metrics<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>The following code computes pooled out-of-fold metrics for both strategies.<\/p>\n<div>\n<div>\n<pre dir=\"ltr\"><code>def summarize_oof(y_true, predictions, fold_results):    \"\"\"    Calculate pooled out-of-fold metrics and average fold metrics.    \"\"\"    return {        \"OOF_R2\": r2_score(y_true, predictions),        \"OOF_RMSE\": np.sqrt(            mean_squared_error(y_true, predictions)        ),        \"OOF_MAE\": mean_absolute_error(            y_true, predictions        ),        \"Mean_Fold_R2\": fold_results[\"R2\"].mean(),        \"Mean_Fold_RMSE\": fold_results[\"RMSE\"].mean(),        \"Mean_Fold_MAE\": fold_results[\"MAE\"].mean(),    }comparison = pd.DataFrame({    \"Random_KFold\": summarize_oof(        y, random_oof, random_results    ),    \"Spatial_Block_CV\": summarize_oof(        y, spatial_oof, spatial_results    ),}).Tprint(comparison.round(4))<\/code><\/pre>\n<\/div>\n<div><\/div>\n<\/div>\n<p>The script calculates metrics from the observed target values and the corresponding out-of-fold predictions. It does not assume that the spatial model must perform worse; the comparison depends on the data.<\/p>\n<h3><span class=\"ez-toc-section\" id=\"Interpreting_the_metrics\"><\/span>Interpreting the metrics<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>Coefficient of determination (<span data-math-source=\"R^2\" data-math-display=\"false\">\\(R^2\\)<\/span>)<\/p>\n<div><span data-math-source=\"R^2 = 1- \\frac{ \\sum_{i=1}^{n}(y_i-\\hat y_i)^2 }{ \\sum_{i=1}^{n}(y_i-\\bar y)^2 }\" data-math-display=\"true\">\\[ R^2 = 1- \\frac{ \\sum_{i=1}^{n}(y_i-\\hat y_i)^2 }{ \\sum_{i=1}^{n}(y_i-\\bar y)^2 } \\]<\/span><\/div>\n<p>Higher values indicate better performance relative to predicting the test observations using their mean as a baseline. <span data-math-source=\"R^2\" data-math-display=\"false\">\\(R^2\\)<\/span> can be negative when predictions perform worse than that baseline.<\/p>\n<p>Root Mean Squared Error (RMSE)<\/p>\n<div><span data-math-source=\"RMSE = \\sqrt{ \\frac{1}{n} \\sum_{i=1}^{n}(y_i-\\hat y_i)^2 }\" data-math-display=\"true\">\\[ RMSE = \\sqrt{ \\frac{1}{n} \\sum_{i=1}^{n}(y_i-\\hat y_i)^2 } \\]<\/span><\/div>\n<p>RMSE penalizes large prediction errors more heavily than smaller errors.<\/p>\n<p>Mean Absolute Error (MAE)<\/p>\n<div><span data-math-source=\"MAE = \\frac{1}{n} \\sum_{i=1}^{n}|y_i-\\hat y_i|\" data-math-display=\"true\">\\[ MAE = \\frac{1}{n} \\sum_{i=1}^{n}|y_i-\\hat y_i| \\]<\/span><\/div>\n<p>MAE provides an average absolute error in the target variable&#8217;s units.<\/p>\n<p>For soil organic carbon, RMSE and MAE are expressed in the same units as the target measurement. Confirm whether the target is represented as a concentration, percentage, or mass-per-area quantity before reporting the results.<\/p>\n<h3><span class=\"ez-toc-section\" id=\"Pooled_scores_versus_mean_fold_scores\"><\/span>Pooled scores versus mean fold scores<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>The pooled out-of-fold metrics combine predictions from all held-out observations. The mean fold metrics average the results calculated within each validation fold.<\/p>\n<p>These can differ, especially when spatial folds contain unequal numbers of observations or have substantially different target distributions.<\/p>\n<p>For academic reporting, retain both the fold-level metrics and the pooled metrics. If one fold represents an unusually difficult region, the fold-specific result is scientifically informative rather than something to hide in the mean.<\/p>\n<div><\/div>\n<h1><span class=\"ez-toc-section\" id=\"5_Implement_buffer-based_cross-validation\"><\/span>5. Implement buffer-based cross-validation<span class=\"ez-toc-section-end\"><\/span><\/h1>\n<p>Spatial blocks may still place training and test observations close to each other across neighboring fold boundaries. Buffering adds an explicit minimum-distance rule.<\/p>\n<p>The following implementation starts with the existing spatial folds, then removes training samples that are closer than a chosen distance to any sample in the held-out test fold.<\/p>\n<div>\n<div>\n<pre dir=\"ltr\"><code>from scipy.spatial import cKDTreedef make_buffered_splits(    X,    y,    groups,    coordinates,    buffer_m,):    \"\"\"    Generate leave-one-spatial-group-out splits with a    minimum training-to-test sample distance.    Coordinates must use a projected CRS in meters.    \"\"\"    if buffer_m &lt; 0:        raise ValueError(\"buffer_m must be non-negative.\")    logo = LeaveOneGroupOut()    for train_idx, test_idx in logo.split(        X, y, groups=groups    ):        # Build a nearest-neighbor index from test locations.        test_tree = cKDTree(coordinates[test_idx])        # Distance from every candidate training point to        # its closest test observation.        nearest_distance, _ = test_tree.query(            coordinates[train_idx],            k=1,        )        # Keep only training samples outside the buffer.<\/code><\/pre>\n<\/div>\n<div><\/div>\n<\/div>\n<p>Choose the distance based on the spatial process and the intended transfer task. For example, if residual spatial autocorrelation decays substantially over several kilometers, a buffer measured in kilometers may be defensible. A very large arbitrary buffer, however, can unnecessarily discard useful training data.<\/p>\n<p>Run the buffered workflow:<\/p>\n<div>\n<div>\n<pre dir=\"ltr\"><code>BUFFER_M = 3000  # Example only: a 3 km separation distance.buffered_splits = list(    make_buffered_splits(        X=X,        y=y,        groups=spatial_groups,        coordinates=coords,        buffer_m=BUFFER_M,    ))buffered_results, buffered_oof = evaluate_splits(    buffered_splits,    model,    X,    y,)buffered_summary = summarize_oof(    y,    buffered_oof,    buffered_results,)print(pd.Series(buffered_summary).round(4))<\/code><\/pre>\n<\/div>\n<div><\/div>\n<\/div>\n<p>The code excludes training points within the specified radius of each test observation. It does not buffer the entire outline of a test polygon; it implements a point-based buffer around the test sample locations.<\/p>\n<p>For a highly clustered sample design or a study where distance is measured from the boundaries of sampled regions, use an appropriate geometry-based buffer instead.<\/p>\n<p>If the buffer causes the model to perform much worse, consider whether training observations were providing genuinely transferable local information, or whether they were too close to the test observations for the intended deployment setting.<\/p>\n<div><\/div>\n<h1><span class=\"ez-toc-section\" id=\"6_Environmental_cross-validation_in_Python\"><\/span>6. Environmental cross-validation in Python<span class=\"ez-toc-section-end\"><\/span><\/h1>\n<p>Geographic blocking tests transfer to new locations. Environmental blocking tests transfer to predictor combinations that are held out as distinct environmental groups.<\/p>\n<p>We can form environmental clusters using standardized predictor data and K-means. The resulting cluster labels become the groups for leave-one-group-out validation.<\/p>\n<div>\n<div>\n<pre dir=\"ltr\"><code>from sklearn.preprocessing import StandardScalerfrom sklearn.cluster import KMeans# --------------------------------------------------------# Create environmental groups using predictors only.# --------------------------------------------------------X_environment = StandardScaler().fit_transform(    samples[PREDICTORS].to_numpy(dtype=float))environment_model = KMeans(    n_clusters=5,    n_init=20,    random_state=42,)environment_groups = environment_model.fit_predict(    X_environment)# --------------------------------------------------------# Hold out one environmental cluster at a time.# --------------------------------------------------------environment_cv = LeaveOneGroupOut()environment_splits = list(    environment_cv.split(        X,        y,        groups=environment_groups,    ))environment_results, environment_oof = evaluate_splits(<\/code><\/pre>\n<\/div>\n<div><\/div>\n<\/div>\n<p>This code uses all predictor values to define the environmental group structure. That is deliberate: the groups represent the observed environmental domain, not model-fitted predictions.<\/p>\n<p>Nevertheless, the scaler and clustering model here are used solely to construct validation groups. In the predictive modeling pipeline, any preprocessing learned from data should be fitted within training folds. If the intended application requires extrapolation beyond the environmental range of training data, evaluate the environmental grouping design carefully and check that it creates the intended separation.<\/p>\n<p>Environmental clustering can produce groups that are geographically scattered but environmentally similar. Therefore, environmental cross-validation should not replace geographic blocking when the goal is to evaluate transfer into a new geographic region.<\/p>\n<p>The <code>blockCV<\/code> methodology explicitly distinguishes spatial blocks, spatial buffers, and environmental blocking as separate approaches.<\/p>\n<div>\n<div><\/div>\n<\/div>\n<div><\/div>\n<h1><span class=\"ez-toc-section\" id=\"7_Adapting_the_workflow_for_classification\"><\/span>7. Adapting the workflow for classification<span class=\"ez-toc-section-end\"><\/span><\/h1>\n<p>The same spatial fold assignments can be used for classification problems such as land-cover mapping, landslide susceptibility classes, or flood-risk categories.<\/p>\n<p>Replace the regression estimator with <code>RandomForestClassifier<\/code>, then assess classification-specific metrics.<\/p>\n<div>\n<div>\n<pre dir=\"ltr\"><code>from sklearn.ensemble import RandomForestClassifierfrom sklearn.metrics import (    accuracy_score,    balanced_accuracy_score,    f1_score,)classifier = RandomForestClassifier(    n_estimators=400,    min_samples_leaf=2,    class_weight=\"balanced\",    random_state=42,    n_jobs=-1,)def evaluate_classification_splits(    splits, estimator, X, y):    rows = []    oof = np.empty(len(y), dtype=object)    assigned = np.zeros(len(y), dtype=bool)    for fold_number, (train_idx, test_idx) in enumerate(        splits, start=1    ):        fold_model = clone(estimator)        fold_model.fit(X[train_idx], y[train_idx])        prediction = fold_model.predict(X[test_idx])        oof[test_idx] = prediction        assigned[test_idx] = True        rows.append({            \"fold\": fold_number,<\/code><\/pre>\n<\/div>\n<div><\/div>\n<\/div>\n<p>For classification, accuracy alone may be inadequate, particularly when classes are imbalanced. Balanced accuracy and macro-averaged F1 help reveal performance differences across classes.<\/p>\n<p>Before using the example, replace <code>land_cover<\/code> with a categorical target field that actually exists in your dataset. The predictor matrix and target must be constructed consistently for the classification task.<\/p>\n<p>Also inspect class representation in each spatial fold. If a test fold contains classes absent from the training data, that is a meaningful limitation of the study design and may make class-specific evaluation unstable.<\/p>\n<div><\/div>\n<h1><span class=\"ez-toc-section\" id=\"8_Using_PySAL_for_spatial_validation\"><\/span>8. Using PySAL for spatial validation<span class=\"ez-toc-section-end\"><\/span><\/h1>\n<p>If your workflow already uses the<a href=\"https:\/\/pysal.org\" target=\"_blank\" rel=\"noopener\"> PySAL<\/a> ecosystem, its newer <code>spml<\/code> validation tools provide additional approaches to geographic splitting.<\/p>\n<p>For example:<\/p>\n<ul>\n<li>\n<div>\n<div>\n<p><code>LeaveCellOut<\/code> uses discrete global grid cells to hold out entire geographic cells.<\/p>\n<\/div>\n<\/div>\n<\/li>\n<li>\n<div>\n<div>\n<p><code>LeaveClusterOut<\/code> uses spatial clusters to hold out complete regions.<\/p>\n<div>\n<div><\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/li>\n<\/ul>\n<p>These methods can be useful when you want grid-cell or cluster-based validation without manually constructing every fold.<\/p>\n<p>A package interface can evolve, so check the installed version&#8217;s API before integrating these classes into a production pipeline. The central methodological requirement remains the same: each held-out geographic group must be excluded from model fitting, and any preprocessing or hyperparameter optimization must respect the outer validation split.<\/p>\n<div><\/div>\n<h1><span class=\"ez-toc-section\" id=\"9_Interpreting_the_Results_Scientifically\"><\/span>9. Interpreting the Results Scientifically<span class=\"ez-toc-section-end\"><\/span><\/h1>\n<p>Consider a hypothetical pattern in which random K-fold produces higher <span data-math-source=\"R^2\" data-math-display=\"false\">\\(R^2\\)<\/span> and lower RMSE than spatial-block cross-validation.<\/p>\n<p>That pattern is consistent with spatial dependence making the random test samples easier to predict. It can also reflect the fact that the spatial folds contain environmentally unusual regions or a different range of target values.<\/p>\n<p>Do not fabricate a universal correction factor, such as assuming that spatial validation will reduce <span data-math-source=\"R^2\" data-math-display=\"false\">\\(R^2\\)<\/span> by a fixed percentage. The difference depends on sample density, spatial autocorrelation, predictor structure, model flexibility, fold geometry, and the intended prediction domain.<\/p>\n<p>A defensible interpretation should address four questions:<\/p>\n<ol>\n<li>\n<div>\n<div>\n<p>Were the spatial folds geographically separated? Inspect the fold map and nearest training-to-test distances.<\/p>\n<\/div>\n<\/div>\n<\/li>\n<li>\n<div>\n<div>\n<p>Were the test environments comparable to the training environments? Describe differences in predictor distributions and target values.<\/p>\n<\/div>\n<\/div>\n<\/li>\n<li>\n<div>\n<div>\n<p>Did model performance vary between regions? Report individual fold metrics as well as aggregated scores.<\/p>\n<\/div>\n<\/div>\n<\/li>\n<li>\n<div>\n<div>\n<p>Does the validation design match the deployment task? Explain whether the model is intended for local interpolation, regional transfer, or extrapolation into new environments.<\/p>\n<\/div>\n<\/div>\n<\/li>\n<\/ol>\n<p>A useful next diagnostic is to inspect residual spatial autocorrelation and evaluate whether the chosen block or buffer size is plausible given the observed spatial dependence.<\/p>\n<div><\/div>\n<h1><span class=\"ez-toc-section\" id=\"10_Best_practices_for_academic_research_papers\"><\/span>10. Best practices for academic research papers<span class=\"ez-toc-section-end\"><\/span><\/h1>\n<h2><span class=\"ez-toc-section\" id=\"101_Justify_block_dimensions\"><\/span>10.1 Justify block dimensions<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>A block width should be scientifically motivated, not selected solely because it produces balanced folds.<\/p>\n<p>Useful evidence includes residual variograms, spatial correlograms, predictor autocorrelation ranges, sampling design, and the distances between the locations where predictions will be needed.<\/p>\n<p>Test multiple reasonable block sizes when uncertainty about the spatial dependence range is substantial.<\/p>\n<h2><span class=\"ez-toc-section\" id=\"102_Keep_model_selection_inside_the_validation_design\"><\/span>10.2 Keep model selection inside the validation design<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>Do not select predictors, tune hyperparameters, or choose feature thresholds using all samples and then report the score from the same spatial folds as if no selection had occurred.<\/p>\n<p>The recommended approach is nested spatial cross-validation:<\/p>\n<ul>\n<li>\n<div>\n<div>\n<p>The outer spatial folds estimate generalization to held-out regions.<\/p>\n<\/div>\n<\/div>\n<\/li>\n<li>\n<div>\n<div>\n<p>The inner validation process selects hyperparameters and preprocessing choices using only the outer training observations.<\/p>\n<\/div>\n<\/div>\n<\/li>\n<li>\n<div>\n<div>\n<p>The final outer test fold remains untouched until prediction.<\/p>\n<\/div>\n<\/div>\n<\/li>\n<\/ul>\n<p>This is important because the same geographic structure that inflates random validation performance can also contaminate feature selection and model tuning.<\/p>\n<h2><span class=\"ez-toc-section\" id=\"103_Report_fold-level_uncertainty\"><\/span>10.3 Report fold-level uncertainty<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>Include the number of observations in each fold, the geographic extent of each held-out region, the chosen block or buffer size, and metrics for individual folds.<\/p>\n<p>A mean score alone may hide a model that works very well in some regions but fails in others. Where appropriate, report fold-level distributions or uncertainty summaries, while explaining that folds can be spatially dependent and should not automatically be treated as independent replicates.<\/p>\n<h2><span class=\"ez-toc-section\" id=\"104_Document_the_full_reproducibility_setup\"><\/span>10.4 Document the full reproducibility setup<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>A spatial machine learning study should report:<\/p>\n<ul>\n<li>\n<div>\n<div>\n<p>The study area and its CRS.<\/p>\n<\/div>\n<\/div>\n<\/li>\n<li>\n<div>\n<div>\n<p>The sampling design and spatial unit of analysis.<\/p>\n<\/div>\n<\/div>\n<\/li>\n<li>\n<div>\n<div>\n<p>The target variable and predictor sources.<\/p>\n<\/div>\n<\/div>\n<\/li>\n<li>\n<div>\n<div>\n<p>The validation algorithm and number of folds.<\/p>\n<\/div>\n<\/div>\n<\/li>\n<li>\n<div>\n<div>\n<p>The projected coordinate system and block dimensions.<\/p>\n<\/div>\n<\/div>\n<\/li>\n<li>\n<div>\n<div>\n<p>The buffer radius, if used.<\/p>\n<\/div>\n<\/div>\n<\/li>\n<li>\n<div>\n<div>\n<p>The method used to choose these spatial scales.<\/p>\n<\/div>\n<\/div>\n<\/li>\n<li>\n<div>\n<div>\n<p>The estimator, hyperparameters, and random seed.<\/p>\n<\/div>\n<\/div>\n<\/li>\n<li>\n<div>\n<div>\n<p>All preprocessing and feature-selection steps.<\/p>\n<\/div>\n<\/div>\n<\/li>\n<li>\n<div>\n<div>\n<p>The validation metrics and per-fold results.<\/p>\n<\/div>\n<\/div>\n<\/li>\n<li>\n<div>\n<div>\n<p>Software versions and data availability.<\/p>\n<\/div>\n<\/div>\n<\/li>\n<\/ul>\n<p>For current Python workflows, also report the versions of scikit-learn, GeoPandas, and the spatial resampling library. This is particularly valuable when spatial fold assignment is generated by third-party code.<\/p>\n<h2><span class=\"ez-toc-section\" id=\"105_A_practical_decision_guide\"><\/span>10.5 A practical decision guide<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<div>\n<table>\n<tbody>\n<tr>\n<th>Research objective<\/th>\n<th>Suggested validation design<\/th>\n<\/tr>\n<tr>\n<td>Interpolate between dense nearby observations<\/td>\n<td>Random CV as a benchmark, supplemented by spatial diagnostics<\/td>\n<\/tr>\n<tr>\n<td>Predict in new geographic districts<\/td>\n<td>Spatial block or leave-region-out validation<\/td>\n<\/tr>\n<tr>\n<td>Require a minimum distance between training and test samples<\/td>\n<td>Buffered spatial validation<\/td>\n<\/tr>\n<tr>\n<td>Predict in different climate, soil, or environmental conditions<\/td>\n<td>Environmental blocking<\/td>\n<\/tr>\n<tr>\n<td>Transfer to new places with unfamiliar environmental conditions<\/td>\n<td>Combined geographic and environmental separation<\/td>\n<\/tr>\n<tr>\n<td>Predict future spatial patterns<\/td>\n<td>Temporally separated validation, potentially combined with geographic blocking<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<p>These methods estimate different forms of generalization. The strongest methodology is not necessarily the one that produces the lowest score; it is the one whose validation design most faithfully reflects the intended prediction task.<\/p>\n<h2><span class=\"ez-toc-section\" id=\"Conclusion\"><\/span>Conclusion<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>Geospatial Cross Validation in Machine Learning GIS requires more careful experimental design than ordinary random K-fold validation because geographic observations are often spatially dependent.<\/p>\n<p>Random splitting can distribute neighboring observations across training and test sets, creating an evaluation that is optimistic for applications involving new geographic regions. Spatial blocks, leave-region-out clustering, buffering, and environmental separation offer different ways to evaluate model generalization under more realistic conditions.<\/p>\n<p>The practical Python workflow developed here uses <code>spatial-kfold<\/code> to construct geographic folds, scikit-learn to fit a Random Forest, and out-of-fold predictions to compare <span data-math-source=\"R^2\" data-math-display=\"false\">\\(R^2\\)<\/span>, RMSE, and MAE across validation strategies.<\/p>\n<p>The essential steps are:<\/p>\n<ol>\n<li>\n<div>\n<div>\n<p>Prepare spatial observations in a suitable projected CRS.<\/p>\n<\/div>\n<\/div>\n<\/li>\n<li>\n<div>\n<div>\n<p>Construct geographically meaningful folds.<\/p>\n<\/div>\n<\/div>\n<\/li>\n<li>\n<div>\n<div>\n<p>Train the same model under random and spatial validation.<\/p>\n<\/div>\n<\/div>\n<\/li>\n<li>\n<div>\n<div>\n<p>Compare fold-level and pooled out-of-fold performance.<\/p>\n<\/div>\n<\/div>\n<\/li>\n<li>\n<div>\n<div>\n<p>Test buffer and environmental designs where the research question requires them.<\/p>\n<\/div>\n<\/div>\n<\/li>\n<li>\n<div>\n<div>\n<p>Document the validation assumptions and justify the final choice.<\/p>\n<\/div>\n<\/div>\n<\/li>\n<\/ol>\n<p>Ultimately, a reliable spatial machine learning score is determined not only by the algorithm but also by where the held-out data come from. A thoughtfully designed validation strategy makes model performance more interpretable, exposes geographic weaknesses, and produces more defensible predictions for real-world GIS applications.<\/p>\n<\/div>\n","protected":false},"excerpt":{"rendered":"<p>Geospatial Cross-Validation in Machine Learning: Preventing Spatial Autocorrelation Leakage 1. Introduction Using Geospatial Cross Validation Machine Learning GIS techniques is essential when modeling spatial phenomena like land surface temperature or soil properties. Machine learning models are increasingly used to predict spatial phenomena, including land surface temperature, soil properties, flood susceptibility, vegetation condition, species distributions, housing &#8230; <a title=\"Geospatial Cross-Validation in Machine Learning: Preventing Spatial Autocorrelation Leakage\" class=\"read-more\" href=\"https:\/\/helpwithmygisassignment.com\/blog\/geospatial-cross-validation-machine-learning-gis\/\" aria-label=\"Read more about Geospatial Cross-Validation in Machine Learning: Preventing Spatial Autocorrelation Leakage\">Read more<\/a><\/p>\n","protected":false},"author":1,"featured_media":1533,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1,4],"tags":[],"class_list":["post-1381","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-uncategorized","category-gis-articles"],"_links":{"self":[{"href":"https:\/\/helpwithmygisassignment.com\/blog\/wp-json\/wp\/v2\/posts\/1381","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/helpwithmygisassignment.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/helpwithmygisassignment.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/helpwithmygisassignment.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/helpwithmygisassignment.com\/blog\/wp-json\/wp\/v2\/comments?post=1381"}],"version-history":[{"count":3,"href":"https:\/\/helpwithmygisassignment.com\/blog\/wp-json\/wp\/v2\/posts\/1381\/revisions"}],"predecessor-version":[{"id":1534,"href":"https:\/\/helpwithmygisassignment.com\/blog\/wp-json\/wp\/v2\/posts\/1381\/revisions\/1534"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/helpwithmygisassignment.com\/blog\/wp-json\/wp\/v2\/media\/1533"}],"wp:attachment":[{"href":"https:\/\/helpwithmygisassignment.com\/blog\/wp-json\/wp\/v2\/media?parent=1381"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/helpwithmygisassignment.com\/blog\/wp-json\/wp\/v2\/categories?post=1381"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/helpwithmygisassignment.com\/blog\/wp-json\/wp\/v2\/tags?post=1381"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}