What's new in skore — August 2026 ================================= Local project storage format ---------------------------- Local projects used to be saved on disk in SQLite databases via the `diskcache` package. They are now backed by human-readable files instead, e.g. estimators in `.pickle` files and metrics in CSV files, so they can be browsed and copied independently of skore. See :pr:`2905` by :user:`jeromedockes`. .. code-block:: python p = skore.Project("demo") p.put("my-report", EstimatorReport(estimator, X, y)) # ./skore/ # └── projects/demo/reports/latest__my-report/ # ├── estimator.pickle # ├── metrics/summarize.csv # └── ... Project synchronisation ----------------------- It is now possible to synchronise the contents of Projects, including between a local Project and a Skore Hub project. Note that this is a one-time operation; it does not keep Projects in sync with eachother. More information about project synchronization is available at :ref:`synchronizing-projects` in the user guide. See :pr:`3201` by :user:`Aljutor`. .. code-block:: python # Work locally local = skore.Project("demo", mode="local") local.put(...) ... # Sync with the Hub hub = skore.Project("demo", mode="hub", workspace="team") local.sync(hub) # one-way (local to Hub) local.sync(hub, bidirectional=True) # both directions local.sync(hub, dry_run=True) # preview the transfer plan Baseline-related checks ----------------------- There have been several improvements to the checks which compare the estimator to a baseline, including: - SKD009 ("model worse than baseline") now always includes the baseline's performance, and is reported as a tip rather than an issue. It is now reported as an issue only if the model is significantly worse than the baseline, whereas previously it was when the model is not significantly better. One consequence of this change is that using the baseline itself as a model no longer triggers SKD009. - SKD010 ("model slower than baseline") now also looks at predict time, not just fit time; a model that is slow to predict will trigger SKD010. - The SKD010 timing gate floor was raised from 0.05s to 1s, to avoid false positives from timing noise on small or fast fits. See :pr:`3197` by :user:`GaetandeCast`. .. code-block:: python report = skore.evaluate(estimator, X, y, splitter=3) report.checks.summarize().frame(section="tip") # code section explanation # 8 SKD009 tip Your model is on par with or better than a # HistGradientBoosting baseline. Baseline # performance on the test set, for reference: # Accuracy=0.94, ROC AUC=0.958, ... Checks API examples ------------------- New examples have been added to illustrate common modeling pitfalls and how the automated checks catch them; they are available at :ref:`sphx_glr_auto_examples_pitfalls_and_solutions`. See :pr:`3134`, :pr:`3149`, :pr:`3150`, :pr:`3165`, :pr:`3163`, :pr:`3170` and :pr:`3171` by :user:`moujanrastgoo`. Import speed ------------ ``import skore`` is now much faster, thanks to switching to a "lazy imports" strategy in the project. The technique is inherited from the `Scientific Python Ecosystem standard `_. See :pr:`3236` by :user:`thomass-dev`. CoefficientsDisplay feature scales ---------------------------------- The :class:`~skore.CoefficientsDisplay` methods now have a new ``scale_features`` parameter, which multiplies coefficients by the training feature standard deviations so their magnitudes are comparable across features. See :pr:`3179` by :user:`glemaitre`. .. code-block:: python report.inspection.coefficients().frame() # coefficients in the natural units of each feature (not comparable) # # feature coefficient # 0 Intercept -0.934471 # 1 Feature #0 2.290953 # 2 Feature #1 -0.644018 # 3 Feature #2 -1.476243 # ... report.inspection.coefficients().frame(scale_features=True) # coefficients in the same unit for every feature: change in # log-odds per standard deviation of the feature # # feature coefficient # 0 Intercept -0.934471 # 1 Feature #0 2.912176 # 2 Feature #1 -0.984450 # 3 Feature #2 -1.890040 # ... EstimatorReport creation constraint ----------------------------------- skore previously allowed creating an EstimatorReport with *both* training data *and* a pre-fitted estimator, which was risky: this made it possible to provide an `X_train` which is not the data that was used to fit the estimator. This would cause subtle bugs. Thus, it is now forbidden to create an EstimatorReport with both training data and a pre-fitted estimator. See :pr:`3186` by :user:`glemaitre`. .. code-block:: python skore.EstimatorReport( SVC().fit(X_train, y_train), X_train=X_train, X_test=X_test, y_train=y_train, y_test=y_test, ) # ValueError: Training data must not be provided when the estimator is # already fitted. Please omit X_train/y_train/train_data, or pass an # unfitted estimator. ----- Thanks to the following contributors for their work this month (in no particular order): - :user:`thomass-dev` - :user:`glemaitre` - :user:`moujanrastgoo` - :user:`Aljutor` - :user:`GaetandeCast` - :user:`yashvisharma1204` - :user:`auguste-probabl` - :user:`jeromedockes` - :user:`ArturoAmorQ`