{
  "cells": [
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "\n# Release Highlights for scikit-learn 1.2\n\n.. currentmodule:: sklearn\n\nWe are pleased to announce the release of scikit-learn 1.2! Many bug fixes\nand improvements were added, as well as some new key features. We detail\nbelow a few of the major features of this release. **For an exhaustive list of\nall the changes**, please refer to the `release notes <release_notes_1_2>`.\n\nTo install the latest version (with pip)::\n\n    pip install --upgrade scikit-learn\n\nor with conda::\n\n    conda install -c conda-forge scikit-learn\n"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "## Pandas output with `set_output` API\nscikit-learn's transformers now support pandas output with the `set_output` API.\nTo learn more about the `set_output` API see the example:\n`sphx_glr_auto_examples_miscellaneous_plot_set_output.py` and\n# this [video, pandas DataFrame output for scikit-learn transformers\n(some examples)](https://youtu.be/5bCg8VfX2x8)_.\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "import numpy as np\n\nfrom sklearn.compose import ColumnTransformer\nfrom sklearn.datasets import load_iris\nfrom sklearn.preprocessing import KBinsDiscretizer, StandardScaler\n\nX, y = load_iris(as_frame=True, return_X_y=True)\nsepal_cols = [\"sepal length (cm)\", \"sepal width (cm)\"]\npetal_cols = [\"petal length (cm)\", \"petal width (cm)\"]\n\npreprocessor = ColumnTransformer(\n    [\n        (\"scaler\", StandardScaler(), sepal_cols),\n        (\n            \"kbin\",\n            KBinsDiscretizer(encode=\"ordinal\", quantile_method=\"averaged_inverted_cdf\"),\n            petal_cols,\n        ),\n    ],\n    verbose_feature_names_out=False,\n).set_output(transform=\"pandas\")\n\nX_out = preprocessor.fit_transform(X)\nX_out.sample(n=5, random_state=0)"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "## Interaction constraints in Histogram-based Gradient Boosting Trees\n:class:`~ensemble.HistGradientBoostingRegressor` and\n:class:`~ensemble.HistGradientBoostingClassifier` now supports interaction constraints\nwith the `interaction_cst` parameter. For details, see the\n`User Guide <interaction_cst_hgbt>`. In the following example, features are not\nallowed to interact.\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "from sklearn.datasets import load_diabetes\nfrom sklearn.ensemble import HistGradientBoostingRegressor\n\nX, y = load_diabetes(return_X_y=True, as_frame=True)\n\nhist_no_interact = HistGradientBoostingRegressor(\n    interaction_cst=[[i] for i in range(X.shape[1])], random_state=0\n)\nhist_no_interact.fit(X, y)"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "## New and enhanced displays\n:class:`~metrics.PredictionErrorDisplay` provides a way to analyze regression\nmodels in a qualitative manner.\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "import matplotlib.pyplot as plt\n\nfrom sklearn.metrics import PredictionErrorDisplay\n\nfig, axs = plt.subplots(nrows=1, ncols=2, figsize=(12, 5))\n_ = PredictionErrorDisplay.from_estimator(\n    hist_no_interact, X, y, kind=\"actual_vs_predicted\", ax=axs[0]\n)\n_ = PredictionErrorDisplay.from_estimator(\n    hist_no_interact, X, y, kind=\"residual_vs_predicted\", ax=axs[1]\n)"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        ":class:`~model_selection.LearningCurveDisplay` is now available to plot\nresults from :func:`~model_selection.learning_curve`.\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "from sklearn.model_selection import LearningCurveDisplay\n\n_ = LearningCurveDisplay.from_estimator(\n    hist_no_interact, X, y, cv=5, n_jobs=2, train_sizes=np.linspace(0.1, 1, 5)\n)"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        ":class:`~inspection.PartialDependenceDisplay` exposes a new parameter\n`categorical_features` to display partial dependence for categorical features\nusing bar plots and heatmaps.\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "from sklearn.datasets import fetch_openml\n\nX, y = fetch_openml(\n    \"titanic\", version=1, as_frame=True, return_X_y=True, parser=\"pandas\"\n)\nX = X.select_dtypes([\"number\", \"category\"]).drop(columns=[\"body\"])"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "from sklearn.pipeline import make_pipeline\nfrom sklearn.preprocessing import OrdinalEncoder\n\ncategorical_features = [\"pclass\", \"sex\", \"embarked\"]\nmodel = make_pipeline(\n    ColumnTransformer(\n        transformers=[(\"cat\", OrdinalEncoder(), categorical_features)],\n        remainder=\"passthrough\",\n    ),\n    HistGradientBoostingRegressor(random_state=0),\n).fit(X, y)"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "from sklearn.inspection import PartialDependenceDisplay\n\nfig, ax = plt.subplots(figsize=(14, 4), constrained_layout=True)\n_ = PartialDependenceDisplay.from_estimator(\n    model,\n    X,\n    features=[\"age\", \"sex\", (\"pclass\", \"sex\")],\n    categorical_features=categorical_features,\n    ax=ax,\n)"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "## Faster parser in :func:`~datasets.fetch_openml`\n:func:`~datasets.fetch_openml` now supports a new `\"pandas\"` parser that is\nmore memory and CPU efficient. In v1.4, the default will change to\n`parser=\"auto\"` which will automatically use the `\"pandas\"` parser for dense\ndata and `\"liac-arff\"` for sparse data.\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "X, y = fetch_openml(\n    \"titanic\", version=1, as_frame=True, return_X_y=True, parser=\"pandas\"\n)\nX.head()"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "## Experimental Array API support in :class:`~discriminant_analysis.LinearDiscriminantAnalysis`\nExperimental support for the [Array API](https://data-apis.org/array-api/latest/)\nspecification was added to :class:`~discriminant_analysis.LinearDiscriminantAnalysis`.\nThe estimator can now run on any Array API compliant libraries such as\n[CuPy](https://docs.cupy.dev/en/stable/overview.html)_, a GPU-accelerated array\nlibrary. For details, see the `User Guide <array_api>`.\n\n"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "## Improved efficiency of many estimators\nIn version 1.1 the efficiency of many estimators relying on the computation of\npairwise distances (essentially estimators related to clustering, manifold\nlearning and neighbors search algorithms) was greatly improved for float64\ndense input. Efficiency improvement especially were a reduced memory footprint\nand a much better scalability on multi-core machines.\nIn version 1.2, the efficiency of these estimators was further improved for all\ncombinations of dense and sparse inputs on float32 and float64 datasets, except\nthe sparse-dense and dense-sparse combinations for the Euclidean and Squared\nEuclidean Distance metrics.\nA detailed list of the impacted estimators can be found in the\n`changelog <release_notes_1_2>`.\n\n"
      ]
    }
  ],
  "metadata": {
    "kernelspec": {
      "display_name": "Python 3",
      "language": "python",
      "name": "python3"
    },
    "language_info": {
      "codemirror_mode": {
        "name": "ipython",
        "version": 3
      },
      "file_extension": ".py",
      "mimetype": "text/x-python",
      "name": "python",
      "nbconvert_exporter": "python",
      "pygments_lexer": "ipython3",
      "version": "3.11.14"
    }
  },
  "nbformat": 4,
  "nbformat_minor": 0
}