Spaces:
Sleeping
Sleeping
File size: 2,762 Bytes
3ecb175 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 | """Run M1, M2, M3, and RF under leave-one-trial-out yield prediction.
Adds the M3 structural features, runs LOTO for each of the four models,
and writes the per-fold metrics, per-plot predictions, and the cross-fold
summary.
Usage:
uv run python scripts/run_loto_models.py \\
--input outputs/df_model_yield_by_plot.csv \\
--out-dir outputs/loto/
"""
from __future__ import annotations
import argparse
from pathlib import Path
import pandas as pd
from potatopheno.evaluate import (
run_loto_linear,
run_loto_rf,
summarize_across_trials,
)
from potatopheno.models import (
PREDICTORS_M1,
PREDICTORS_M2,
PREDICTORS_M3,
PREDICTORS_RF,
RESPONSE,
RF_KWARGS,
add_model_features,
)
def _parse_args() -> argparse.Namespace:
p = argparse.ArgumentParser(description=__doc__.splitlines()[0])
p.add_argument(
"--input",
type=Path,
required=True,
help="Plot-level model dataset (output of build_plot_model_dataset.py).",
)
p.add_argument(
"--out-dir",
type=Path,
required=True,
help="Directory to write the metrics, predictions, and summary CSVs.",
)
return p.parse_args()
def main() -> None:
args = _parse_args()
args.out_dir.mkdir(parents=True, exist_ok=True)
df = pd.read_csv(args.input)
df = add_model_features(df)
runs = [
("M1", run_loto_linear, PREDICTORS_M1, {}),
("M2", run_loto_linear, PREDICTORS_M2, {}),
("M3", run_loto_linear, PREDICTORS_M3, {}),
("RF", run_loto_rf, PREDICTORS_RF, RF_KWARGS),
]
pred_parts: list[pd.DataFrame] = []
metric_parts: list[pd.DataFrame] = []
for name, runner, predictors, extra in runs:
df_pred, df_metrics = runner(df, predictors, RESPONSE, name, **extra)
pred_parts.append(df_pred)
metric_parts.append(df_metrics)
df_pred_all = pd.concat(pred_parts, ignore_index=True)
df_metrics_all = (
pd.concat(metric_parts, ignore_index=True)
.sort_values(["model", "test_trial"])
.reset_index(drop=True)
)
df_summary = summarize_across_trials(df_metrics_all).sort_values("mean_MAPE")
df_metrics_all.to_csv(args.out_dir / "loto_metrics_by_fold.csv", index=False)
df_pred_all.to_csv(args.out_dir / "loto_predictions_by_plot.csv", index=False)
df_summary.to_csv(args.out_dir / "loto_summary_by_model.csv", index=False)
print("\nLOTO metrics by fold:\n")
print(df_metrics_all.round(3).to_string(index=False))
print("\nLOTO summary across folds (mean of trial-level metrics):\n")
print(df_summary.round(3).to_string(index=False))
print(f"\n[DONE] wrote 3 CSVs → {args.out_dir}")
if __name__ == "__main__":
main()
|