Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Comments

API: move geometry back to fit, implement score and backbone for metadata routing#55

Merged
martinfleis merged 6 commits intomainfrom
pipe
Jan 6, 2026
Merged

API: move geometry back to fit, implement score and backbone for metadata routing#55
martinfleis merged 6 commits intomainfrom
pipe

Conversation

@martinfleis
Copy link
Member

This went a bit out of hand. I was experimenting with the stuff in #45, which turned out needed implementation of score among other things.

With all this, I can make the sklearn grid search run successfully like this. Not sure if this is intended by sklearn of if there's a way to simplify this for a user (e.g. to avoid those set calls). @theralavineela any ideas? I am also not sure to which degree made this your PR obsolete. Sorry, a rabbit hole sucked me in.

import geopandas as gpd
import sklearn
from geodatasets import get_path
from sklearn.model_selection import GridSearchCV

from gwlearn.linear_model import GWLinearRegression

sklearn.set_config(enable_metadata_routing=True)

gdf = gpd.read_file(get_path("geoda.guerry"))

gwlr = GWLinearRegression(fixed=False, keep_models=True)
gwlr.set_fit_request(geometry=True)
gwlr.set_predict_proba_request(geometry=True)
gwlr.set_predict_request(geometry=True)
gwlr.set_score_request(geometry=True)

gs = GridSearchCV(gwlr, {'bandwidth': [15, 25]}, cv=2)
gs.fit(
    gdf[['Crm_prp', 'Litercy', 'Donatns', 'Lottery']],
    gdf["Suicids"],
    geometry=gdf.representative_point()
)

gs.cv_results_

{'mean_fit_time': array([0.082605  , 0.07042313]),
 'std_fit_time': array([0.01016295, 0.0070281 ]),
 'mean_score_time': array([0.01314092, 0.02728152]),
 'std_score_time': array([3.19480896e-05, 1.44383907e-02]),
 'param_bandwidth': masked_array(data=[15, 25],
              mask=[False, False],
        fill_value=999999),
 'params': [{'bandwidth': 15}, {'bandwidth': 25}],
 'split0_test_score': array([0.25171764, 0.25787701]),
 'split1_test_score': array([-0.6960835 , -0.19733769]),
 'mean_test_score': array([-0.22218293,  0.03026966]),
 'std_test_score': array([0.47390057, 0.22760735]),
 'rank_test_score': array([2, 1], dtype=int32)}

@martinfleis martinfleis changed the title Pipe API: move geometry back to fit, implement score and backbone for metadata routing Jan 6, 2026
@martinfleis martinfleis linked an issue Jan 6, 2026 that may be closed by this pull request
@martinfleis martinfleis requested a review from Copilot January 6, 2026 22:56
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR refactors the API to move the geometry parameter from model initialization to the fit() method, implements score() methods for both classifiers and regressors, and adds metadata routing helpers to support scikit-learn's metadata routing framework. This change aligns with scikit-learn conventions where data-related parameters are passed to fit() rather than __init__().

Key changes:

  • Moved geometry parameter from __init__() to fit() across all model classes
  • Implemented score() methods for BaseClassifier (accuracy) and BaseRegressor (R²)
  • Added metadata routing helper methods (set_fit_request, set_predict_request, set_predict_proba_request, set_score_request)

Reviewed changes

Copilot reviewed 12 out of 16 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
gwlearn/base.py Core changes - moved geometry to fit(), added score() methods and metadata routing helpers
gwlearn/linear_model.py Updated GWLinearRegression and GWLogisticRegression fit() signatures to accept geometry parameter
gwlearn/ensemble.py Updated ensemble models (GWRandomForestClassifier, GWGradientBoostingClassifier, GWRandomForestRegressor) fit() signatures
gwlearn/search.py Updated BandwidthSearch to accept geometry in fit() instead of init()
gwlearn/tests/test_base.py Updated tests to pass geometry to fit(); added new tests for score() methods
gwlearn/tests/test_linear_model.py Updated tests to pass geometry to fit() instead of init()
gwlearn/tests/test_ensemble.py Updated tests to pass geometry to fit() instead of init()
gwlearn/tests/test_search.py Updated BandwidthSearch tests to pass geometry to fit()
docs/source/network_graph.ipynb Updated examples to use new API
docs/source/linear.ipynb Updated examples to use new API
docs/source/introduction.ipynb Updated examples to use new API
README.md Updated example code to demonstrate new API

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@martinfleis martinfleis merged commit 459caf0 into main Jan 6, 2026
12 checks passed
@martinfleis martinfleis deleted the pipe branch January 6, 2026 23:15
@codecov
Copy link

codecov bot commented Jan 6, 2026

Codecov Report

❌ Patch coverage is 78.72340% with 10 lines in your changes missing coverage. Please review.
✅ Project coverage is 85.71%. Comparing base (d41eccb) to head (20d093c).
⚠️ Report is 1 commits behind head on main.

Files with missing lines Patch % Lines
gwlearn/base.py 71.42% 10 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main      #55      +/-   ##
==========================================
- Coverage   86.45%   85.71%   -0.75%     
==========================================
  Files           6        6              
  Lines         768      798      +30     
==========================================
+ Hits          664      684      +20     
- Misses        104      114      +10     

☔ View full report in Codecov by Sentry.
📢 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.

@theralavineela
Copy link

Please don't apologize, I'm totally fine with it. If your changes have moved us in a better direction, I’m happy to start fresh with some new ideas on simplifying this for a user. Should I go ahead and close this PR for now to keep things clean, or would you like to keep it open while we decide on the next steps, I’m still learning how sklearn intends this to be used, so I'm happy to follow your lead

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.

Implement score

2 participants