Skip to content

Decision tree panic - #470

Open
slievens wants to merge 6 commits into
smartcorelib:mainfrom
slievens:decision_tree_panic
Open

slievens wants to merge 6 commits into
smartcorelib:mainfrom
slievens:decision_tree_panic

Conversation

@slievens

Copy link
Copy Markdown
Contributor

Fixes #469

Checklist

  • [x ] My branch is up-to-date with main branch.
  • [ x] Everything works and tested on latest stable Rust.
  • [ x] Coverage and Linting have been applied

Current behaviour

Many "predict" and related methods panic when fit hasn't been called.

New expected behaviour

"predict" no longer panics in said case, but returns a Result.

Change logs

Changed

learner methods
DecisionTreeClassifier predict
RandomForestClassifier predict
RandomForestRegressor predict, predict_oob
ExtraTreesRegressor predict, predict_oob
KNNClassifier predict, predict_oob
KNNRegressor predict
SVC predict
SVR predict
LinearRegression predict, predict_matrix
RidgeRegression predict
Lasso predict
ElasticNet predict
LogisticRegression predict
GaussianNB predict
BernoulliNB predict
CategoricalNB predict
MultinomialNB predict

Make sure predict (and cousins) do not panic when called on a learner that hasn't been fit yet.
The following learners all follow the same pattern and were easy to fix.

- src/ensemble/extra_trees_regressor.rs
- src/ensemble/random_forest_regressor.rs
- src/naive_bayes/bernoulli.rs
- src/naive_bayes/categorical.rs
- src/naive_bayes/gaussian.rs
- src/naive_bayes/multinomial.rs
- src/tree/decision_tree_regressor.rs
Following classes got a guard against calling predict without fit.
Test cases were added.

- src/neighbors/knn_classifier.rs
- src/neighbors/knn_regressor.rs
- src/svm/svc.rs
- src/svm/svr.rs
Changes to the following classes with tests.

- src/linear/elastic_net.rs
- src/linear/lasso.rs
- src/linear/linear_regression.rs
- src/linear/logistic_regression.rs
- src/linear/ridge_regression.rs
Added for
- src/ensemble/random_forest_classifier.rs
- src/tree/decision_tree_classifier.rs

Tests were added.
@slievens
slievens requested a review from Mec-iS as a code owner September 28, 2026 18:49
@codecov

codecov Bot commented Sep 28, 2026 •

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 55.74468% with 104 lines in your changes missing coverage. Please review.
✅ Project coverage is 63.63%. Comparing base (9eaae9e) to head (6e81d2e).
⚠️ Report is 191 commits behind head on main.

Files with missing lines Patch % Lines
src/ensemble/random_forest_classifier.rs 40.00% 18 Missing ⚠️
src/svm/svc.rs 41.93% 18 Missing ⚠️
src/linear/lasso.rs 42.85% 8 Missing ⚠️
src/linear/logistic_regression.rs 68.18% 7 Missing ⚠️
src/neighbors/knn_classifier.rs 68.18% 7 Missing ⚠️
src/ensemble/extra_trees_regressor.rs 25.00% 6 Missing ⚠️
src/xgboost/xgb_regressor.rs 62.50% 6 Missing ⚠️
src/ensemble/random_forest_regressor.rs 37.50% 5 Missing ⚠️
src/svm/svr.rs 63.63% 4 Missing ⚠️
src/linear/elastic_net.rs 72.72% 3 Missing ⚠️
... and 9 more
Additional details and impacted files
@@             Coverage Diff             @@
##             main     #470       +/-   ##
===========================================
+ Coverage   43.97%   63.63%   +19.65%     
===========================================
  Files          85       96       +11     
  Lines        7281     8514     +1233     
===========================================
+ Hits         3202     5418     +2216     
+ Misses       4079     3096      -983     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

predict changed and test added
@Mec-iS

Mec-iS commented Sep 28, 2026 •

Copy link
Copy Markdown
Collaborator

@slievens Great contribution — the fix is well-scoped and the consistent error message makes it easy to match on downstream. A few issues to address and suggestions below.


Issues to Address

1. Inconsistent guard strategies

Two patterns are used interchangeably with no apparent reason:

  • match on Option — extra_trees_regressor, random_forest_regressor, decision_tree_regressor, all Naive Bayes, svc.rs
  • Early-return is_none() check — knn_classifier, knn_regressor, svr.rs, all src/linear/*.rs, random_forest_classifier.rs (predict_oob)

The match style is more idiomatic and avoids leaving a latent .unwrap() immediately after the guard. For example in lasso.rs, after the early-return guard, self.coefficients is still unwrapped via self.coefficients(). Recommend standardizing on match throughout.

2. Missing test: predict_oob for RandomForestClassifier

The predict_oob method in random_forest_classifier.rs received a guard but no corresponding test, unlike RandomForestRegressor and ExtraTreesRegressor which both have predict_oob_without_fit_should_not_panic tests.

3. Missing test: predict_proba for DecisionTreeClassifier

predict_proba in decision_tree_classifier.rs received a guard (at line 916), but there is no test for it — only predict is covered.

4. Wrong variable name in DecisionTreeClassifier test

let knn: DecisionTreeClassifier<...> = DecisionTreeClassifier::new();

knn should be tree or dtc — looks like copy-paste from knn_classifier.rs.

5. Missing blank line before test in linear_regression.rs

    }
    #[test]  // ← missing blank line
    fn predict_matrix_without_fit_should_not_panic() {

All other test cases in the file have a blank line before #[test].


Suggestions (Non-blocking)

  • decision_function in SVR: svr.rs guards predict via self.instances.is_none(), but decision_function (called internally by predict) may still panic if invoked directly. Worth checking whether it also needs a guard.
  • Reusable helper: With 17+ identical guard blocks now scattered across the codebase, a small require_fitted() helper method (or a Fitted trait) could centralize this logic and make future learners easier to implement correctly. Could be a good follow-up issue.
  • Dedicated error variant: Failed::predict(msg) maps to PredictFailed. A NotFitted variant in FailedError would let callers distinguish "model not fitted" from "prediction failed on valid input" — larger API change, but worth tracking as a future improvement.

- Removed all is_none and replaced by match.
- Added missing tests
- Fixed typo
- Fixed lint issue
@slievens

Copy link
Copy Markdown
Contributor Author

Issues 1 to 5 addressed in commit 6e81d2e.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

predict method on DecisionTreeRegressor panics when tree is not fit

2 participants