{
  "cells": [
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "\n# Release Highlights for scikit-learn 1.0\n\n.. currentmodule:: sklearn\n\nWe are very pleased to announce the release of scikit-learn 1.0! The library\nhas been stable for quite some time, releasing version 1.0 is recognizing that\nand signalling it to our users. This release does not include any breaking\nchanges apart from the usual two-release deprecation cycle. For the future, we\ndo our best to keep this pattern.\n\nThis release includes some new key features as well as many improvements and\nbug fixes. We detail below a few of the major features of this release. **For\nan exhaustive list of all the changes**, please refer to the `release\nnotes <release_notes_1_0>`.\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": [
        "## Keyword and positional arguments\nThe scikit-learn API exposes many functions and methods which have many input\nparameters. For example, before this release, one could instantiate a\n:class:`~ensemble.HistGradientBoostingRegressor` as::\n\n        HistGradientBoostingRegressor(\"squared_error\", 0.1, 100, 31, None,\n            20, 0.0, 255, None, None, False, \"auto\", \"loss\", 0.1, 10, 1e-7,\n            0, None)\n\nUnderstanding the above code requires the reader to go to the API\ndocumentation and to check each and every parameter for its position and\nits meaning. To improve the readability of code written based on scikit-learn,\nnow users have to provide most parameters with their names, as keyword\narguments, instead of positional arguments. For example, the above code would\nbe::\n\n    HistGradientBoostingRegressor(\n        loss=\"squared_error\",\n        learning_rate=0.1,\n        max_iter=100,\n        max_leaf_nodes=31,\n        max_depth=None,\n        min_samples_leaf=20,\n        l2_regularization=0.0,\n        max_bins=255,\n        categorical_features=None,\n        monotonic_cst=None,\n        warm_start=False,\n        early_stopping=\"auto\",\n        scoring=\"loss\",\n        validation_fraction=0.1,\n        n_iter_no_change=10,\n        tol=1e-7,\n        verbose=0,\n        random_state=None,\n    )\n\nwhich is much more readable. Positional arguments have been deprecated since\nversion 0.23 and will now raise a ``TypeError``. A limited number of\npositional arguments are still allowed in some cases, for example in\n:class:`~decomposition.PCA`, where ``PCA(10)`` is still allowed, but ``PCA(10,\nFalse)`` is not allowed.\n\n"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "## Spline Transformers\nOne way to add nonlinear terms to a dataset's feature set is to generate\nspline basis functions for continuous/numerical features with the new\n:class:`~preprocessing.SplineTransformer`. Splines are piecewise polynomials,\nparametrized by their polynomial degree and the positions of the knots. The\n:class:`~preprocessing.SplineTransformer` implements a B-spline basis.\n\n.. figure:: ../linear_model/images/sphx_glr_plot_polynomial_interpolation_001.png\n  :target: ../linear_model/plot_polynomial_interpolation.html\n  :align: center\n\nThe following code shows splines in action, for more information, please\nrefer to the `User Guide <spline_transformer>`.\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "import numpy as np\n\nfrom sklearn.preprocessing import SplineTransformer\n\nX = np.arange(5).reshape(5, 1)\nspline = SplineTransformer(degree=2, n_knots=3)\nspline.fit_transform(X)"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "## Quantile Regressor\nQuantile regression estimates the median or other quantiles of $y$\nconditional on $X$, while ordinary least squares (OLS) estimates the\nconditional mean.\n\nAs a linear model, the new :class:`~linear_model.QuantileRegressor` gives\nlinear predictions $\\hat{y}(w, X) = Xw$ for the $q$-th quantile,\n$q \\in (0, 1)$. The weights or coefficients $w$ are then found by\nthe following minimization problem:\n\n\\begin{align}\\min_{w} {\\frac{1}{n_{\\text{samples}}}\n    \\sum_i PB_q(y_i - X_i w) + \\alpha ||w||_1}.\\end{align}\n\nThis consists of the pinball loss (also known as linear loss),\nsee also :class:`~sklearn.metrics.mean_pinball_loss`,\n\n\\begin{align}PB_q(t) = q \\max(t, 0) + (1 - q) \\max(-t, 0) =\n    \\begin{cases}\n        q t, & t > 0, \\\\\n        0,    & t = 0, \\\\\n        (1-q) t, & t < 0\n    \\end{cases}\\end{align}\n\nand the L1 penalty controlled by parameter ``alpha``, similar to\n:class:`linear_model.Lasso`.\n\nPlease check the following example to see how it works, and the `User\nGuide <quantile_regression>` for more details.\n\n.. figure:: ../linear_model/images/sphx_glr_plot_quantile_regression_002.png\n   :target: ../linear_model/plot_quantile_regression.html\n   :align: center\n   :scale: 50%\n\n"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "## Feature Names Support\nWhen an estimator is passed a [pandas' dataframe](https://pandas.pydata.org/docs/user_guide/dsintro.html#dataframe) during\n:term:`fit`, the estimator will set a `feature_names_in_` attribute\ncontaining the feature names. This is a part of\n[SLEP007](https://scikit-learn-enhancement-proposals.readthedocs.io/en/latest/slep007/proposal.html)_.\nNote that feature names support is only enabled\nwhen the column names in the dataframe are all strings. `feature_names_in_`\nis used to check that the column names of the dataframe passed in\nnon-:term:`fit`, such as :term:`predict`, are consistent with features in\n:term:`fit`:\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "import pandas as pd\n\nfrom sklearn.preprocessing import StandardScaler\n\nX = pd.DataFrame([[1, 2, 3], [4, 5, 6]], columns=[\"a\", \"b\", \"c\"])\nscalar = StandardScaler().fit(X)\nscalar.feature_names_in_"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "The support of :term:`get_feature_names_out` is available for transformers\nthat already had `get_feature_names` and transformers with a one-to-one\ncorrespondence between input and output such as\n:class:`~preprocessing.StandardScaler`. :term:`get_feature_names_out` support\nwill be added to all other transformers in future releases. Additionally,\n:meth:`compose.ColumnTransformer.get_feature_names_out` is available to\ncombine feature names of its transformers:\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "import pandas as pd\n\nfrom sklearn.compose import ColumnTransformer\nfrom sklearn.preprocessing import OneHotEncoder\n\nX = pd.DataFrame({\"pet\": [\"dog\", \"cat\", \"fish\"], \"age\": [3, 7, 1]})\npreprocessor = ColumnTransformer(\n    [\n        (\"numerical\", StandardScaler(), [\"age\"]),\n        (\"categorical\", OneHotEncoder(), [\"pet\"]),\n    ],\n    verbose_feature_names_out=False,\n).fit(X)\n\npreprocessor.get_feature_names_out()"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "When this ``preprocessor`` is used with a pipeline, the feature names used\nby the classifier are obtained by slicing and calling\n:term:`get_feature_names_out`:\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "from sklearn.linear_model import LogisticRegression\nfrom sklearn.pipeline import make_pipeline\n\ny = [1, 0, 1]\npipe = make_pipeline(preprocessor, LogisticRegression())\npipe.fit(X, y)\npipe[:-1].get_feature_names_out()"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "## A more flexible plotting API\n:class:`metrics.ConfusionMatrixDisplay`,\n:class:`metrics.PrecisionRecallDisplay`, :class:`metrics.DetCurveDisplay`,\nand :class:`inspection.PartialDependenceDisplay` now expose two class\nmethods: `from_estimator` and `from_predictions` which allow users to create\na plot given the predictions or an estimator. This means the corresponding\n`plot_*` functions are deprecated. Please check `example one\n<sphx_glr_auto_examples_model_selection_plot_confusion_matrix.py>` and\n`example two\n<sphx_glr_auto_examples_classification_plot_digits_classification.py>` for\nhow to use the new plotting functionalities.\n\n"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "## Online One-Class SVM\nThe new class :class:`~linear_model.SGDOneClassSVM` implements an online\nlinear version of the One-Class SVM using a stochastic gradient descent.\nCombined with kernel approximation techniques,\n:class:`~linear_model.SGDOneClassSVM` can be used to approximate the solution\nof a kernelized One-Class SVM, implemented in :class:`~svm.OneClassSVM`, with\na fit time complexity linear in the number of samples. Note that the\ncomplexity of a kernelized One-Class SVM is at best quadratic in the number\nof samples. :class:`~linear_model.SGDOneClassSVM` is thus well suited for\ndatasets with a large number of training samples (> 10,000) for which the SGD\nvariant can be several orders of magnitude faster. Please check this\n`example\n<sphx_glr_auto_examples_miscellaneous_plot_anomaly_comparison.py>` to see how\nit's used, and the `User Guide <sgd_online_one_class_svm>` for more\ndetails.\n\n.. figure:: ../miscellaneous/images/sphx_glr_plot_anomaly_comparison_001.png\n   :target: ../miscellaneous/plot_anomaly_comparison.html\n   :align: center\n\n"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "## Histogram-based Gradient Boosting Models are now stable\n:class:`~sklearn.ensemble.HistGradientBoostingRegressor` and\n:class:`~ensemble.HistGradientBoostingClassifier` are no longer experimental\nand can simply be imported and used as::\n\n    from sklearn.ensemble import HistGradientBoostingClassifier\n\n"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "## New documentation improvements\nThis release includes many documentation improvements. Out of over 2100\nmerged pull requests, about 800 of them are improvements to our\ndocumentation.\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
}