Skip to content

Commit b913703

Browse files
committed
Separate classifier and regressor predicting and testing (prev. evaluate) CLI tools, add explicit outputs, add classification threshold param
1 parent 4ba04aa commit b913703

File tree

1 file changed

+109
-59
lines changed

1 file changed

+109
-59
lines changed

eis_toolkit/cli.py

+109-59
Original file line numberDiff line numberDiff line change
@@ -2313,38 +2313,77 @@ def gradient_boosting_regressor_train_cli(
23132313
typer.echo("Gradient boosting regressor training completed")
23142314

23152315

2316-
# EVALUATE ML MODEL
2316+
# TEST CLASSIFIER ML MODEL
23172317
@app.command()
2318-
def evaluate_trained_model_cli(
2318+
def classifier_test_cli(
23192319
input_rasters: INPUT_FILES_ARGUMENT,
23202320
target_labels: INPUT_FILE_OPTION,
23212321
model_file: INPUT_FILE_OPTION,
2322-
output_raster: OUTPUT_FILE_OPTION,
2323-
validation_metrics: Annotated[List[str], typer.Option()],
2322+
output_raster_probability: OUTPUT_FILE_OPTION,
2323+
output_raster_classified: OUTPUT_FILE_OPTION,
2324+
classification_threshold: float = 0.5,
2325+
validation_metrics: Annotated[List[ClassifierMetrics], typer.Option(case_sensitive=False)] = [
2326+
ClassifierMetrics.accuracy
2327+
],
23242328
):
2325-
"""Predict and evaluate a trained machine learning model by predicting and scoring."""
2326-
from sklearn.base import is_classifier
2327-
2329+
"""Test trained machine learning classifier model by predicting and scoring."""
23282330
from eis_toolkit.evaluation.scoring import score_predictions
23292331
from eis_toolkit.prediction.machine_learning_general import load_model, prepare_data_for_ml, reshape_predictions
2330-
from eis_toolkit.prediction.machine_learning_predict import predict_classifier, predict_regressor
2332+
from eis_toolkit.prediction.machine_learning_predict import predict_classifier
23312333

23322334
X, y, reference_profile, nodata_mask = prepare_data_for_ml(input_rasters, target_labels)
23332335
typer.echo("Progress: 30%")
23342336

23352337
model = load_model(model_file)
2336-
if is_classifier(model):
2337-
predictions, probabilities = predict_classifier(X, model, True)
2338-
probabilities = probabilities[:, 1]
2339-
probabilities = probabilities.astype(np.float32)
2340-
probabilities_reshaped = reshape_predictions(
2341-
probabilities, reference_profile["height"], reference_profile["width"], nodata_mask
2342-
)
2343-
else:
2344-
predictions = predict_regressor(X, model)
2338+
predictions, probabilities = predict_classifier(X, model, classification_threshold, True)
2339+
probabilities_reshaped = reshape_predictions(
2340+
probabilities, reference_profile["height"], reference_profile["width"], nodata_mask
2341+
)
2342+
predictions_reshaped = reshape_predictions(
2343+
predictions, reference_profile["height"], reference_profile["width"], nodata_mask
2344+
)
23452345

23462346
metrics_dict = score_predictions(y, predictions, validation_metrics)
2347+
json_str = json.dumps(metrics_dict)
2348+
typer.echo("Progress: 80%")
2349+
2350+
out_profile = reference_profile.copy()
2351+
out_profile.update({"count": 1, "dtype": np.float32})
2352+
2353+
with rasterio.open(output_raster_probability, "w", **out_profile) as dst:
2354+
dst.write(probabilities_reshaped, 1)
2355+
with rasterio.open(output_raster_classified, "w", **out_profile) as dst:
2356+
dst.write(predictions_reshaped, 1)
2357+
2358+
typer.echo("Progress: 100%")
2359+
typer.echo(f"Results: {json_str}")
2360+
2361+
typer.echo(
2362+
f"Testing classifier model completed, writing rasters to \
2363+
{output_raster_probability} and {output_raster_classified}."
2364+
)
2365+
2366+
2367+
# TEST REGRESSOR ML MODEL
2368+
@app.command()
2369+
def regressor_test_cli(
2370+
input_rasters: INPUT_FILES_ARGUMENT,
2371+
target_labels: INPUT_FILE_OPTION,
2372+
model_file: INPUT_FILE_OPTION,
2373+
output_raster: OUTPUT_FILE_OPTION,
2374+
validation_metrics: Annotated[List[RegressorMetrics], typer.Option(case_sensitive=False)] = [RegressorMetrics.mse],
2375+
):
2376+
"""Test trained machine learning regressor model by predicting and scoring."""
2377+
from eis_toolkit.evaluation.scoring import score_predictions
2378+
from eis_toolkit.prediction.machine_learning_general import load_model, prepare_data_for_ml, reshape_predictions
2379+
from eis_toolkit.prediction.machine_learning_predict import predict_regressor
2380+
2381+
X, y, reference_profile, nodata_mask = prepare_data_for_ml(input_rasters, target_labels)
2382+
typer.echo("Progress: 30%")
23472383

2384+
model = load_model(model_file)
2385+
predictions = predict_regressor(X, model)
2386+
metrics_dict = score_predictions(y, predictions, validation_metrics)
23482387
predictions_reshaped = reshape_predictions(
23492388
predictions, reference_profile["height"], reference_profile["width"], nodata_mask
23502389
)
@@ -2356,54 +2395,76 @@ def evaluate_trained_model_cli(
23562395
out_profile = reference_profile.copy()
23572396
out_profile.update({"count": 1, "dtype": np.float32})
23582397

2359-
if is_classifier(model):
2360-
directory = os.path.split(output_raster)[0]
2361-
name = os.path.splitext(os.path.basename(output_raster))[0]
2362-
labels_output = os.path.join(directory, name + "_labels" + ".tif")
2363-
probabilities_output = os.path.join(directory, name + "_probabilities" + ".tif")
2364-
for output_path, output_data in zip(
2365-
[labels_output, probabilities_output], [predictions_reshaped, probabilities_reshaped]
2366-
):
2367-
with rasterio.open(output_path, "w", **out_profile) as dst:
2368-
dst.write(output_data, 1)
2369-
else:
2370-
with rasterio.open(output_raster, "w", **out_profile) as dst:
2371-
dst.write(predictions_reshaped, 1)
2398+
with rasterio.open(output_raster, "w", **out_profile) as dst:
2399+
dst.write(predictions_reshaped, 1)
23722400

23732401
typer.echo("Progress: 100%")
23742402
typer.echo(f"Results: {json_str}")
23752403

2376-
typer.echo("Evaluating trained model completed")
2404+
typer.echo(f"Testing regressor model completed, writing raster to {output_raster}.")
23772405

23782406

23792407
# PREDICT WITH TRAINED ML MODEL
23802408
@app.command()
2381-
def predict_with_trained_model_cli(
2409+
def classifier_predict_cli(
23822410
input_rasters: INPUT_FILES_ARGUMENT,
23832411
model_file: INPUT_FILE_OPTION,
2384-
output_raster: OUTPUT_FILE_OPTION,
2412+
output_raster_probability: OUTPUT_FILE_OPTION,
2413+
output_raster_classified: OUTPUT_FILE_OPTION,
2414+
classification_threshold: float = 0.5,
23852415
):
2386-
"""Predict with a trained machine learning model."""
2387-
from sklearn.base import is_classifier
2388-
2416+
"""Predict with a trained machine learning classifier model."""
23892417
from eis_toolkit.prediction.machine_learning_general import load_model, prepare_data_for_ml, reshape_predictions
2390-
from eis_toolkit.prediction.machine_learning_predict import predict_classifier, predict_regressor
2418+
from eis_toolkit.prediction.machine_learning_predict import predict_classifier
23912419

23922420
X, _, reference_profile, nodata_mask = prepare_data_for_ml(input_rasters)
23932421

23942422
typer.echo("Progress: 30%")
23952423

23962424
model = load_model(model_file)
2397-
if is_classifier(model):
2398-
predictions, probabilities = predict_classifier(X, model, True)
2399-
probabilities = probabilities[:, 1]
2400-
probabilities = probabilities.astype(np.float32)
2401-
probabilities_reshaped = reshape_predictions(
2402-
probabilities, reference_profile["height"], reference_profile["width"], nodata_mask
2425+
predictions, probabilities = predict_classifier(X, model, classification_threshold, True)
2426+
probabilities_reshaped = reshape_predictions(
2427+
probabilities, reference_profile["height"], reference_profile["width"], nodata_mask
2428+
)
2429+
predictions_reshaped = reshape_predictions(
2430+
predictions, reference_profile["height"], reference_profile["width"], nodata_mask
2431+
)
2432+
typer.echo("Progress: 80%")
2433+
2434+
out_profile = reference_profile.copy()
2435+
out_profile.update({"count": 1, "dtype": np.float32})
2436+
2437+
with rasterio.open(output_raster_probability, "w", **out_profile) as dst:
2438+
dst.write(probabilities_reshaped, 1)
2439+
with rasterio.open(output_raster_classified, "w", **out_profile) as dst:
2440+
dst.write(predictions_reshaped, 1)
2441+
2442+
typer.echo("Progress: 100%")
2443+
typer.echo(
2444+
(
2445+
"Predicting with classifier model completed, writing rasters to "
2446+
f"{output_raster_probability} and {output_raster_classified}."
24032447
)
2404-
else:
2405-
predictions = predict_regressor(X, model)
2448+
)
2449+
24062450

2451+
# PREDICT WITH TRAINED ML MODEL
2452+
@app.command()
2453+
def regressor_predict_cli(
2454+
input_rasters: INPUT_FILES_ARGUMENT,
2455+
model_file: INPUT_FILE_OPTION,
2456+
output_raster: OUTPUT_FILE_OPTION,
2457+
):
2458+
"""Predict with a trained machine learning regressor model."""
2459+
from eis_toolkit.prediction.machine_learning_general import load_model, prepare_data_for_ml, reshape_predictions
2460+
from eis_toolkit.prediction.machine_learning_predict import predict_regressor
2461+
2462+
X, _, reference_profile, nodata_mask = prepare_data_for_ml(input_rasters)
2463+
2464+
typer.echo("Progress: 30%")
2465+
2466+
model = load_model(model_file)
2467+
predictions = predict_regressor(X, model)
24072468
predictions_reshaped = reshape_predictions(
24082469
predictions, reference_profile["height"], reference_profile["width"], nodata_mask
24092470
)
@@ -2413,22 +2474,11 @@ def predict_with_trained_model_cli(
24132474
out_profile = reference_profile.copy()
24142475
out_profile.update({"count": 1, "dtype": np.float32})
24152476

2416-
if is_classifier(model):
2417-
directory = os.path.split(output_raster)[0]
2418-
name = os.path.splitext(os.path.basename(output_raster))[0]
2419-
labels_output = os.path.join(directory, name + "_labels" + ".tif")
2420-
probabilities_output = os.path.join(directory, name + "_probabilities" + ".tif")
2421-
for output_path, output_data in zip(
2422-
[labels_output, probabilities_output], [predictions_reshaped, probabilities_reshaped]
2423-
):
2424-
with rasterio.open(output_path, "w", **out_profile) as dst:
2425-
dst.write(output_data, 1)
2426-
else:
2427-
with rasterio.open(output_raster, "w", **out_profile) as dst:
2428-
dst.write(predictions_reshaped, 1)
2477+
with rasterio.open(output_raster, "w", **out_profile) as dst:
2478+
dst.write(predictions_reshaped, 1)
24292479

24302480
typer.echo("Progress: 100%")
2431-
typer.echo("Predicting completed")
2481+
typer.echo(f"Predicting with regressor model completed, writing raster to {output_raster}.")
24322482

24332483

24342484
# FUZZY OVERLAYS

0 commit comments

Comments
 (0)