<jupyter_start><jupyter_text>modeling notebookHere, we estimate country-wide tree height scores, using LVIS-derived height scores as the response variable and landsat- and palsar-derived remote sensing data as covariates.Steps:* Extract co-aligned pixel values for the following datasets    * LVIS lidar    * Landsat fractional cover    * PALSAR backscatter    * CCB tree cover* Perform hyperparameter tuning from a small subset of data* Train a model on the full dataset using the best-fit hyperparameters* Apply that model to the full country's covariates<jupyter_code># set to allow re-loading modules while in-dev
%load_ext autoreload
%autoreload 2
# import packages
import os
import ccb
import random
import pickle
import numpy as np
from sklearn import metrics
from sklearn import ensemble
from sklearn import multiclass
from sklearn import calibration
from sklearn import preprocessing
from sklearn import model_selection

# set the seed
random.seed(1985)

# set and create directories
data_dir = 'data'
model_dir = 'models'
if not os.path.exists(model_dir):
    os.mkdir(model_dir)
    
# set data paths
covariate_path = os.path.join(data_dir, 'covariate-stack.tif')
response_path = os.path.join(data_dir, 'tree-height-lvis-masked.tif')<jupyter_output><empty_output><jupyter_text>Reading input dataWe'll read data from two paths: the response data (LVIS lidar) and the covariate data (Landsat/PALSAR/tree cover). Each of these datasets were created and masked to the same good-data locations per the `data-processing` notebook.<jupyter_code># read the response data into memory and subset to the good-data values
print("Reading response variable data into memory")
r = ccb.read.raster(response_path)
r.read_all()
gd = r.data != r.no_data
gd_count = gd.sum()
response = r.data[gd]

# clear the ref
r.data = None
r = None

print("{n} good-data values found".format(n = gd_count))
# read the covariate data into memory, band-by-band, and do the same subset
c = ccb.read.raster(covariate_path)
covariates = np.zeros((gd_count, c.nb))
for band_number in range(c.nb):
    print("Reading covariate band: {n}".format(n = band_number + 1))
    c.read_band(band_number + 1)
    covariates[:, band_number] = c.data[gd]
    c.data = None
    
c = None<jupyter_output>Reading covariate band: 1
Reading covariate band: 2
Reading covariate band: 3
Reading covariate band: 4
Reading covariate band: 5
Reading covariate band: 6<jupyter_text>Model tuningWe'll create a small subset of data that we'll use to run a grid search for model hyperparameter selection<jupyter_code>xlarge, xsmall, ylarge, ysmall = model_selection.train_test_split(
    covariates, 
    response, 
    test_size=0.08
)
# run model tuning for gradient boosting regression
scoring = 'neg_mean_squared_error'

# create the tuning object
gbm = ccb.ml.tuner(
    xsmall, 
    ysmall, 
    scoring = scoring,
    n_splits = 3,
    cv = model_selection.KFold(3),
    n_jobs = 2,
    verbose = 2
)

gbm.GradientBoostRegressor()
# save the best model
gbm_tuned_path = os.path.join(model_dir, 'gbm-tuned.pck')
with open(gbm_tuned_path, 'wb') as f:
    pickle.dump(gbm.best_estimator, f)

# report performance on tuning data
ypred = gbm.best_estimator.predict(xsmall)
r2 = metrics.r2_score(ysmall, ypred)
rmse = metrics.mean_squared_error(ysmall, ypred)
print('r**2 on tuning data : {:0.3f}'.format(r2))    
print('rmse on tuning data : {:0.3f}'.format(rmse))<jupyter_output>r**2 on tuning data : 0.586
rmse on tuning data : 56.363
{'fraction_non_alphanumeric': 0.08895265423242468, 'fraction_numerical': 0.0109038737446198, 'mean_word_length': 4.76198347107438, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 11, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '3', 'dir': 'jupyter-structured-clean-dedup', 'id': '246323', 'license': 'MIT', 'n_tokens_mistral': 1225, 'n_tokens_neox': 1130, 'n_words': 379, 'path': '02-modeling.ipynb', 'repo_name': 'earth-chris/costa-rica-carbon', 'size': '3485'}