Repository: scikit-learn/scikit-learn
File: examples/release_highlights/plot_release_highlights_1_8_0.py (Python)

Code before:
# - alternative: add link to Colab notebook?

# %%
# Free-threaded CPython 3.14 support
# ----------------------------------
#
# scikit-learn has support for free-threaded CPython, in particular
# free-threaded wheels are available for all of our supported platforms on Python
# 3.14.
#
# Free-threaded (also known as nogil) CPython is a version of CPython that aims at
# enabling efficient multi-threaded use cases by removing the Global Interpreter
# Lock (GIL).
#
# If you want to try out free-threaded Python, the recommendation is to use
# Python 3.14, that has fixed a number of issues compared to Python 3.13. Feel
# free to try free-threaded on your use case and report any issues!
#
# For more details about free-threaded CPython see `py-free-threading doc <https://py-free-threading.github.io>`_,
# in particular `how to install a free-threaded CPython <https://py-free-threading.github.io/installing_cpython/>`_
# and `Ecosystem compatibility tracking <https://py-free-threading.github.io/tracking/>`_.

# %%
# Temperature scaling in `CalibratedClassifierCV`
# -----------------------------------------------
# TODO

# %%
# Linear models improvements
# --------------------------
# There are two main developments going on for linear models: efficiency and API
# changes.
#
# Efficiency of squared error based models with L1 penalty
# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
# The first one is a massive improvement of efficiency, in particular a reduced fit
# time, for squared error based estimators with L1 penalty: `ElasticNet`, `Lasso`,
# `MultiTaskElasticNet`, `MultiTaskLasso` and their CV variants. The fit time
# improvement is mainly achieved by **gap safe screening rules**. They enable the
# coordinate descent solver to set feature coefficients early to 0 and not look at them
# again. The stronger the L1 penalty the earlier features can be excluded from further
# updates.

from time import time

from sklearn.datasets import make_regression
from sklearn.linear_model import ElasticNetCV

X, y = make_regression(n_features=5000)
model = ElasticNetCV()
tic = time()

Review comment (suggestion):
```suggestion
# Temperature scaling in `CalibratedClassifierCV`
# -----------------------------------------------
# Probability calibration with temperature scaling is available in
# :class:`calibration.CalibratedClassifierCV` by setting `method = "temperature"`.
# This method offers a natural way to obtain (better-)calibrated multi-class
# probabilities with just one free parameter, in contrast to using a
# "One-vs-Rest" scheme that adds more parameters for each single class.

from sklearn.calibration import CalibratedClassifierCV
from sklearn.datasets import make_classification
from sklearn.frozen import FrozenEstimator
from sklearn.model_selection import train_test_split
from sklearn.svm import LinearSVC

X, y = make_classification(
    n_samples=1000,
    n_features=10,
    n_informative=10,
    n_redundant=0,
    n_classes=5,
    n_clusters_per_class=1,
    class_sep=2.0,
    random_state=42,
)
X_train, X_calib, y_train, y_calib = train_test_split(X, y, random_state=42)
clf = LinearSVC(random_state=42)
clf.fit(X_train, y_train)
ts = CalibratedClassifierCV(FrozenEstimator(clf), method="temperature", ensemble=False)
ts.fit(X_calib, y_calib)
beta = ts.calibrated_classifiers_[0].calibrators[0].beta_
print(f"Optimal temperature = {1 / beta:.3}")
```

Code after:
# Please refer to the :ref:`array API support<array_api>` page for instructions
# to use scikit-learn with array API compatible libraries such as PyTorch or CuPy.
# Note: Array API support is experimental and must be explicitly enabled both
# in SciPy and scikit-learn.
#
# Here is an excerpt of using a feature engineering preprocessor on the CPU,
# followed by :class:`calibration.CalibratedClassifierCV`
# and :class:`linear_model.RidgeCV` together on a GPU with the help of PyTorch:
#
# .. code-block:: python
#
#     ridge_pipeline_gpu = make_pipeline(
#         # Ensure that all features (including categorical features) are preprocessed
#         # on the CPU and mapped to a numerical representation.
#         feature_preprocessor,
#         # Move the results to the GPU and perform computations there
#         FunctionTransformer(
#             lambda x: torch.tensor(x.to_numpy().astype(np.float32), device="cuda"))
#         ,
#         CalibratedClassifierCV(
#             RidgeClassifierCV(alphas=alphas), method="temperature"
#         ),
#     )
#     with sklearn.config_context(array_api_dispatch=True):
#         cv_results = cross_validate(ridge_pipeline_gpu, features, target)
#
#
# See the `full notebook on Google Colab
# <https://colab.research.google.com/drive/1ztH8gUPv31hSjEeR_8pw20qShTwViGRx?usp=sharing>`_
# for more details. On this particular example, using the Colab GPU vs using a
# single CPU core leads to a 10x speedup which is quite typical for such workloads.

# %%
# Free-threaded CPython 3.14 support
# ----------------------------------
#
# scikit-learn has support for free-threaded CPython, in particular
# free-threaded wheels are available for all of our supported platforms on Python
# 3.14.
#
# We would be very interested by user feedback. Here are a few things you can
# try:
#
# - install free-threaded CPython 3.14, run your favourite
#   scikit-learn script and check that nothing breaks unexpectedly.
#   Note that CPython 3.14 (rather than 3.13) is strongly advised because a
#   number of free-threaded bugs have been fixed since CPython 3.13.
# - if you use some estimators with a `n_jobs` parameter, try changing the
#   default backend to threading with `joblib.parallel_config` as in the
#   snippet below. This could potentially speed-up your code because the
#   default joblib backend is process-based and incurs more overhead than