from pyPhenology import models, utils import numpy as np import pytest from copy import deepcopy obs, predictors = utils.load_test_data(name='vaccinium', phenophase='budburst') ########################################### # Setup various models ########################################### ######## # This is an ensemble of bootstrap models alternating_bootstrap = models.BootstrapModel(core_model=models.Alternating, num_bootstraps=10) thermaltime_bootstrap = models.BootstrapModel(core_model=models.ThermalTime, parameters={'t1':1,'T':0}, num_bootstraps=10) uniforc_bootstrap = models.BootstrapModel(core_model=models.Uniforc, parameters={'t1':1,}, num_bootstraps=10) ensemble_bootstrap_model = models.Ensemble(core_models=[alternating_bootstrap, thermaltime_bootstrap, uniforc_bootstrap]) ensemble_bootstrap_model.fit(obs, predictors, optimizer_params='testing') ########## # A simple ensemble model tt1 = models.ThermalTime(parameters={'T':0}) tt2 = models.ThermalTime(parameters={'T':5}) uniforc = models.Uniforc(parameters={'t1':1})
from pyPhenology import utils observations, temp = utils.load_test_data(name='vaccinium') import pandas as pd import time models_to_use = ['ThermalTime', 'Alternating', 'Uniforc', 'MSB', 'Unichill'] methods_to_use = ['DE', 'BF'] sensible_defaults = ['testing', 'practical', 'intensive'] timings = [] for m in models_to_use: for optimizer_method in methods_to_use: for s_default in sensible_defaults: model = utils.load_model(m)() start_time = time.time() model.fit(observations, temp, method=optimizer_method, optimizer_params=s_default) fitting_time = round(time.time() - start_time, 2) num_parameters = len(model.get_params()) timings.append({ 'model': m, 'num_parameters': num_parameters, 'method': optimizer_method, 'sensible_default': s_default, 'time': fitting_time
from pyPhenology import utils import pytest import numpy as np obs, predictors = utils.load_test_data() core_model_names = [ 'Uniforc', 'Unichill', 'ThermalTime', 'Alternating', 'MSB', 'Linear', 'Sequential', 'M1', 'Naive', 'FallCooling' ] # Setup a list of (model_name, fitted_model object) fitted_models = [ utils.load_model(model_name)() for model_name in core_model_names ] [ model.fit(obs, predictors, optimizer_params='testing') for model in fitted_models ] model_test_cases = list(zip(core_model_names, fitted_models)) ######################################################### @pytest.mark.parametrize('model_name, fitted_model', model_test_cases) def test_predict_output_length(model_name, fitted_model): """Predict output length should equal input length""" assert len(fitted_model.predict()) == len(obs)
def test_unknown_dataset_name(dataset): with pytest.raises(ValueError): obs, predictors = utils.load_test_data(name = dataset)
from pyPhenology import utils, models from warnings import warn import sys import pytest # Make sure some known parameters are estimated correctly # The number roughly match the estimates from the original model # codebase in github.com/sdtaylor/phenology_dataset_study. # They don't match exactly because that original stuff uses DE # while I'm using BF here for testing sake. ############################## # Use a specific species dataset that should never change leaves_obs, vaccinium_temp = utils.load_test_data(name='vaccinium', phenophase=371) flowers_obs, vaccinium_temp = utils.load_test_data(name='vaccinium', phenophase=501) aspen_leaves, aspen_temp = utils.load_test_data(name='aspen', phenophase=371) # thorough but still relatively quick thorough_DE_optimization = { 'method': 'DE', 'debug': True, 'optimizer_params': { 'seed': 1, 'popsize': 20, 'maxiter': 100, 'mutation': 1.5, 'recombination': 0.25 }
def test_invalid_dataset_phenophase(phenophase): with pytest.raises(TypeError): obs, predictors = utils.load_test_data(name='aspen', phenophase=phenophase)
def test_dataset_names(dataset): obs, predictors = utils.load_test_data(dataset) assert len(obs) > 0
def test_unknown_dataset_phenophase(phenophase): with pytest.raises(ValueError): obs, predictors = utils.load_test_data(name='aspen', phenophase=phenophase)
def test_dataset_phenophase(phenophase): obs, predictors = utils.load_test_data(name='aspen', phenophase=phenophase) assert len(obs) > 0
def test_invalid_dataset_name(dataset): 'dataset name needs to be a string' with pytest.raises(TypeError): obs, predictors = utils.load_test_data(name = dataset)
from pyPhenology import utils, models from pyPhenology.models import validation import pytest import sys obs, temp = utils.load_test_data() model_test_cases = [] # Bootstrap requires some special arguments model_test_cases.append({ 'model_name': 'BootstrapModel', 'model_func': models.BootstrapModel, 'fit_params': { 'optimizer_params': 'testing' }, 'initial_params': { 'num_bootstraps': 10, 'core_model': models.ThermalTime } }) # The rest can all be tested the same way model_names = [ 'Uniforc', 'Unichill', 'ThermalTime', 'Alternating', 'MSB', 'Linear', 'Sequential' ] for name in model_names: model_test_cases.append({ 'model_name': name, 'model_func': utils.load_model(name),
parameters={ 't1': 1, 'T': 5 }) models_to_fit = { 'TT Temp 0': bootstrapped_tt_model_1, 'TT Temp 5': bootstrapped_tt_model_2 } results = pd.DataFrame() for dataset in datasets_to_use: for phenophase in phenophases_to_use: observations, predictors = utils.load_test_data(name=dataset, phenophase=phenophase) # Setup 20% train test split using pandas methods observations_test = observations.sample(frac=0.2, random_state=1) observations_train = observations[~observations.index. isin(observations_test.index)] observed_doy = observations_test.doy.values for model_name, model in models_to_fit.items(): model.fit(observations_train, predictors, optimizer_params='practical') # Using aggregation='none' in BoostrapModel predict # returns results for all bootstrapped models in an