2121 get_default_metrics ,
2222 prepare_targets_preds ,
2323)
24- from cybench .models .naive_models import AverageYieldModel
24+ from cybench .models .naive_models import AverageYieldModel , MaxPredictorModel
2525from cybench .models .trend_models import TrendModel
2626from cybench .models .sklearn_models import SklearnRidge , SklearnRandomForest
2727from cybench .models .xgboost_model import XGBoostModel
4343
4444_BASELINE_MODEL_CONSTRUCTORS = {
4545 "AverageYieldModel" : AverageYieldModel ,
46+ "MaxPredictorModel" : MaxPredictorModel ,
4647 "LinearTrend" : TrendModel ,
4748 "SklearnRidge" : SklearnRidge ,
4849 "RidgeRes" : RidgeRes ,
6061
6162BASELINE_MODELS = list (_BASELINE_MODEL_CONSTRUCTORS .keys ())
6263
64+ BASELINE_MODELS = ["AverageYieldModel" , "MaxPredictorModel" ]
65+
6366_BASELINE_MODEL_INIT_KWARGS = defaultdict (dict )
6467
6568NN_MODELS_EPOCHS = 50
9093 "epochs" : NN_MODELS_EPOCHS ,
9194 "device" : "cuda" if torch .cuda .is_available () else "cpu" ,
9295}
96+ _BASELINE_MODEL_INIT_KWARGS ["MaxPredictorModel" ] = {
97+ "feature_column" : "twso" ,
98+ }
99+
100+ _BASELINE_MODEL_FIT_KWARGS ["MaxPredictorModel" ] = {
101+ "feature_column" : "twso" ,
102+ }
103+
104+
105+ def discover_datasets_from_disk (path_data_dir : str ):
106+ """
107+ Discover datasets by checking for:
108+ PATH_DATA_DIR/<crop>/<region>/twso_<crop>_<region>.csv
109+ Returns list of dataset_name strings like "maize_FR".
110+ """
111+ found = []
112+
113+ # iterate crops as folders under PATH_DATA_DIR
114+ if not os .path .isdir (path_data_dir ):
115+ raise FileNotFoundError (
116+ f"PATH_DATA_DIR does not exist or is not a directory: { path_data_dir } "
117+ )
118+
119+ for crop in sorted (os .listdir (path_data_dir )):
120+ crop_dir = os .path .join (path_data_dir , crop )
121+ if not os .path .isdir (crop_dir ):
122+ continue
123+
124+ # iterate regions as folders under crop
125+ for region in sorted (os .listdir (crop_dir )):
126+ region_dir = os .path .join (crop_dir , region )
127+ if not os .path .isdir (region_dir ):
128+ continue
129+
130+ twso_file = os .path .join (region_dir , f"twso_{ crop } _{ region } .csv" )
131+ if os .path .exists (twso_file ):
132+ found .append (f"{ crop } _{ region } " )
133+
134+ return found
93135
94136
95137def run_benchmark (
@@ -164,6 +206,7 @@ def run_benchmark(
164206 else :
165207 sel_years = all_years
166208
209+ all_results = []
167210 for test_year in sel_years :
168211 train_years = [y for y in all_years if y != test_year ]
169212 test_years = [test_year ]
@@ -194,13 +237,14 @@ def run_benchmark(
194237 df = pd .DataFrame .from_dict (model_output )
195238 df [KEY_COUNTRY ] = df [KEY_LOC ].str [:2 ]
196239 df .set_index ([KEY_COUNTRY , KEY_LOC , KEY_YEAR ], inplace = True )
197- df . to_csv ( os . path . join ( path_results , f" { dataset_name } _year_ { test_year } .csv" ) )
240+ all_results . append ( df )
198241
199- df_metrics = compute_metrics ( run_name , list ( model_constructors . keys ()) )
242+ df_all = pd . concat ( all_results ). sort_index ( )
200243
201- return {
202- "df_metrics" : df_metrics ,
203- }
244+ results_file = os .path .join (path_results , f"{ dataset_name } .csv" )
245+ print (f"write results to { results_file } " )
246+ df_all .to_csv (results_file )
247+ return
204248
205249
206250def load_results (
@@ -228,6 +272,8 @@ def load_results(
228272
229273 df_all = pd .DataFrame ()
230274 for file in files :
275+ if not file .lower ().endswith (".csv" ):
276+ continue
231277 path = os .path .join (path_results , file )
232278 df = pd .read_csv (path )
233279 df_all = pd .concat ([df_all , df ], axis = 0 )
@@ -339,7 +385,12 @@ def run_benchmark_on_all_data():
339385if __name__ == "__main__" :
340386 parser = argparse .ArgumentParser (prog = "run_benchmark.py" , description = "Run cybench" )
341387 parser .add_argument ("-r" , "--run-name" )
342- parser .add_argument ("-d" , "--dataset-name" )
388+ parser .add_argument (
389+ "-d" ,
390+ "--dataset-name" ,
391+ default = None ,
392+ help = "Dataset name (e.g. maize_FR). If omitted or 'all'/'none', run all datasets." ,
393+ )
343394 parser .add_argument ("-m" , "--mode" )
344395 parser .add_argument (
345396 "-y" ,
@@ -350,48 +401,45 @@ def run_benchmark_on_all_data():
350401 help = "Test year(s)" ,
351402 )
352403 args = parser .parse_args ()
353- dataset_name = args .dataset_name
354- assert dataset_name is not None
355-
356- if args .run_name is not None :
357- run_name = args .run_name
358- else :
359- run_name = dataset_name
360404
361- if args .years is None or [y .lower () for y in args .years ] in (["none" ], ["all" ]):
362- args .years = None
405+ if args .dataset_name is None or str (args .dataset_name ).lower () in ("none" , "all" ):
406+ dataset_names = discover_datasets_from_disk (PATH_DATA_DIR )
407+ if not dataset_names :
408+ raise FileNotFoundError (
409+ f"No datasets found. Expected files like "
410+ f"{ PATH_DATA_DIR } /<crop>/<region>/twso_<crop>_<region>.csv"
411+ )
363412 else :
364- args .years = [int (y ) for y in args .years ]
365- sel_years = args .years
366-
367- if (args .mode is not None ) and args .mode == "test" :
368- # skipping some models
369- baseline_models = [
370- "AverageYieldModel" ,
371- "LinearTrend" ,
372- "SklearnRidge" ,
373- "RidgeRes" ,
374- "LSTM" ,
375- "LSTMRes" ,
376- ]
377- # override epochs for nn-models
378- nn_models_epochs = 5
379- results = run_benchmark (
380- run_name = run_name ,
381- dataset_name = dataset_name ,
382- baseline_models = baseline_models ,
383- nn_models_epochs = nn_models_epochs ,
384- )
385- else :
386- results = run_benchmark (
387- run_name = run_name , dataset_name = dataset_name , sel_years = sel_years
388- )
389-
390- index_cols = results ["df_metrics" ].index .names
391- df_metrics = results ["df_metrics" ].reset_index ()
392-
393- metric_cols = [c for c in df_metrics .columns if c not in index_cols ]
394-
395- # Group and average all available metrics
396- agg_df = df_metrics .groupby ("model" )[metric_cols ].mean ().round (3 )
397- print (agg_df )
413+ dataset_names = [args .dataset_name ]
414+
415+ for dataset_name in dataset_names :
416+ run_name = args .run_name if args .run_name is not None else dataset_name
417+
418+ if args .years is None or [y .lower () for y in args .years ] in (["none" ], ["all" ]):
419+ args .years = None
420+ else :
421+ args .years = [int (y ) for y in args .years ]
422+ sel_years = args .years
423+
424+ if (args .mode is not None ) and args .mode == "test" :
425+ # skipping some models
426+ baseline_models = [
427+ "AverageYieldModel" ,
428+ "LinearTrend" ,
429+ "SklearnRidge" ,
430+ "RidgeRes" ,
431+ "LSTM" ,
432+ "LSTMRes" ,
433+ ]
434+ # override epochs for nn-models
435+ nn_models_epochs = 5
436+ results = run_benchmark (
437+ run_name = run_name ,
438+ dataset_name = dataset_name ,
439+ baseline_models = baseline_models ,
440+ nn_models_epochs = nn_models_epochs ,
441+ )
442+ else :
443+ run_benchmark (
444+ run_name = run_name , dataset_name = dataset_name , sel_years = sel_years
445+ )
0 commit comments