Skip to content

Commit df64bd5

Browse files
committed
Pushing the docs to dev/ for branch: main, commit 88283eeed565666fa7d11c3529c315bc1cab8efd
1 parent 366a32c commit df64bd5

File tree

1,546 files changed

+7246
-6266
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

1,546 files changed

+7246
-6266
lines changed
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.

dev/_downloads/07960f9087d379e9d0da6350d6ee3f41/plot_classification_probability.ipynb

+88-2
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,50 @@
44
"cell_type": "markdown",
55
"metadata": {},
66
"source": [
7-
"\n# Plot classification probability\n\nPlot the classification probability for different classifiers. We use a 3 class\ndataset, and we classify it with a Support Vector classifier, L1 and L2\npenalized logistic regression (multinomial multiclass), a One-Vs-Rest version with\nlogistic regression, and Gaussian process classification.\n\nLinear SVC is not a probabilistic classifier by default but it has a built-in\ncalibration option enabled in this example (`probability=True`).\n\nThe logistic regression with One-Vs-Rest is not a multiclass classifier out of\nthe box. As a result it has more trouble in separating class 2 and 3 than the\nother estimators.\n"
7+
"\n# Plot classification probability\n\nThis example illustrates the use of\n:class:`sklearn.inspection.DecisionBoundaryDisplay` to plot the predicted class\nprobabilities of various classifiers in a 2D feature space, mostly for didactic\npurposes.\n\nThe first three columns shows the predicted probability for varying values of\nthe two features. Round markers represent the test data that was predicted to\nbelong to that class.\n\nIn the last column, all three classes are represented on each plot; the class\nwith the highest predicted probability at each point is plotted. The round\nmarkers show the test data and are colored by their true label.\n"
8+
]
9+
},
10+
{
11+
"cell_type": "markdown",
12+
"metadata": {},
13+
"source": [
14+
"Authors: The scikit-learn developers\nSPDX-License-Identifier: BSD-3-Clause\n\n"
15+
]
16+
},
17+
{
18+
"cell_type": "code",
19+
"execution_count": null,
20+
"metadata": {
21+
"collapsed": false
22+
},
23+
"outputs": [],
24+
"source": [
25+
"import matplotlib as mpl\nimport matplotlib.pyplot as plt\nimport numpy as np\nimport pandas as pd\nfrom matplotlib import cm\n\nfrom sklearn import datasets\nfrom sklearn.ensemble import HistGradientBoostingClassifier\nfrom sklearn.gaussian_process import GaussianProcessClassifier\nfrom sklearn.gaussian_process.kernels import RBF\nfrom sklearn.inspection import DecisionBoundaryDisplay\nfrom sklearn.kernel_approximation import Nystroem\nfrom sklearn.linear_model import LogisticRegression\nfrom sklearn.metrics import accuracy_score, log_loss, roc_auc_score\nfrom sklearn.model_selection import train_test_split\nfrom sklearn.pipeline import make_pipeline\nfrom sklearn.preprocessing import (\n KBinsDiscretizer,\n PolynomialFeatures,\n SplineTransformer,\n)"
26+
]
27+
},
28+
{
29+
"cell_type": "markdown",
30+
"metadata": {},
31+
"source": [
32+
"## Data: 2D projection of the iris dataset\n\n"
33+
]
34+
},
35+
{
36+
"cell_type": "code",
37+
"execution_count": null,
38+
"metadata": {
39+
"collapsed": false
40+
},
41+
"outputs": [],
42+
"source": [
43+
"iris = datasets.load_iris()\nX = iris.data[:, 0:2] # we only take the first two features for visualization\ny = iris.target\n\nX_train, X_test, y_train, y_test = train_test_split(\n X, y, test_size=0.5, random_state=42\n)"
44+
]
45+
},
46+
{
47+
"cell_type": "markdown",
48+
"metadata": {},
49+
"source": [
50+
"## Probabilistic classifiers\n\nWe will plot the decision boundaries of several classifiers that have a\n`predict_proba` method. This will allow us to visualize the uncertainty of\nthe classifier in regions where it is not certain of its prediction.\n\n"
851
]
952
},
1053
{
@@ -15,7 +58,50 @@
1558
},
1659
"outputs": [],
1760
"source": [
18-
"# Authors: The scikit-learn developers\n# SPDX-License-Identifier: BSD-3-Clause\n\nimport matplotlib.pyplot as plt\nimport numpy as np\nfrom matplotlib import cm\n\nfrom sklearn import datasets\nfrom sklearn.gaussian_process import GaussianProcessClassifier\nfrom sklearn.gaussian_process.kernels import RBF\nfrom sklearn.inspection import DecisionBoundaryDisplay\nfrom sklearn.linear_model import LogisticRegression\nfrom sklearn.metrics import accuracy_score\nfrom sklearn.multiclass import OneVsRestClassifier\nfrom sklearn.svm import SVC\n\niris = datasets.load_iris()\nX = iris.data[:, 0:2] # we only take the first two features for visualization\ny = iris.target\n\nn_features = X.shape[1]\n\nC = 10\nkernel = 1.0 * RBF([1.0, 1.0]) # for GPC\n\n# Create different classifiers.\nclassifiers = {\n \"L1 logistic\": LogisticRegression(C=C, penalty=\"l1\", solver=\"saga\", max_iter=10000),\n \"L2 logistic (Multinomial)\": LogisticRegression(\n C=C, penalty=\"l2\", solver=\"saga\", max_iter=10000\n ),\n \"L2 logistic (OvR)\": OneVsRestClassifier(\n LogisticRegression(C=C, penalty=\"l2\", solver=\"saga\", max_iter=10000)\n ),\n \"Linear SVC\": SVC(kernel=\"linear\", C=C, probability=True, random_state=0),\n \"GPC\": GaussianProcessClassifier(kernel),\n}\n\nn_classifiers = len(classifiers)\n\nfig, axes = plt.subplots(\n nrows=n_classifiers,\n ncols=len(iris.target_names),\n figsize=(3 * 2, n_classifiers * 2),\n)\nfor classifier_idx, (name, classifier) in enumerate(classifiers.items()):\n y_pred = classifier.fit(X, y).predict(X)\n accuracy = accuracy_score(y, y_pred)\n print(f\"Accuracy (train) for {name}: {accuracy:0.1%}\")\n for label in np.unique(y):\n # plot the probability estimate provided by the classifier\n disp = DecisionBoundaryDisplay.from_estimator(\n classifier,\n X,\n response_method=\"predict_proba\",\n class_of_interest=label,\n ax=axes[classifier_idx, label],\n vmin=0,\n vmax=1,\n )\n axes[classifier_idx, label].set_title(f\"Class {label}\")\n # plot data predicted to belong to given class\n mask_y_pred = y_pred == label\n axes[classifier_idx, label].scatter(\n X[mask_y_pred, 0], X[mask_y_pred, 1], marker=\"o\", c=\"w\", edgecolor=\"k\"\n )\n axes[classifier_idx, label].set(xticks=(), yticks=())\n axes[classifier_idx, 0].set_ylabel(name)\n\nax = plt.axes([0.15, 0.04, 0.7, 0.02])\nplt.title(\"Probability\")\n_ = plt.colorbar(\n cm.ScalarMappable(norm=None, cmap=\"viridis\"), cax=ax, orientation=\"horizontal\"\n)\n\nplt.show()"
61+
"classifiers = {\n \"Logistic regression\\n(C=0.01)\": LogisticRegression(C=0.1),\n \"Logistic regression\\n(C=1)\": LogisticRegression(C=100),\n \"Gaussian Process\": GaussianProcessClassifier(kernel=1.0 * RBF([1.0, 1.0])),\n \"Logistic regression\\n(RBF features)\": make_pipeline(\n Nystroem(kernel=\"rbf\", gamma=5e-1, n_components=50, random_state=1),\n LogisticRegression(C=10),\n ),\n \"Gradient Boosting\": HistGradientBoostingClassifier(),\n \"Logistic regression\\n(binned features)\": make_pipeline(\n KBinsDiscretizer(n_bins=5, quantile_method=\"averaged_inverted_cdf\"),\n PolynomialFeatures(interaction_only=True),\n LogisticRegression(C=10),\n ),\n \"Logistic regression\\n(spline features)\": make_pipeline(\n SplineTransformer(n_knots=5),\n PolynomialFeatures(interaction_only=True),\n LogisticRegression(C=10),\n ),\n}"
62+
]
63+
},
64+
{
65+
"cell_type": "markdown",
66+
"metadata": {},
67+
"source": [
68+
"## Plotting the decision boundaries\n\nFor each classifier, we plot the per-class probabilities on the first three\ncolumns and the probabilities of the most likely class on the last column.\n\n"
69+
]
70+
},
71+
{
72+
"cell_type": "code",
73+
"execution_count": null,
74+
"metadata": {
75+
"collapsed": false
76+
},
77+
"outputs": [],
78+
"source": [
79+
"n_classifiers = len(classifiers)\nscatter_kwargs = {\n \"s\": 25,\n \"marker\": \"o\",\n \"linewidths\": 0.8,\n \"edgecolor\": \"k\",\n \"alpha\": 0.7,\n}\ny_unique = np.unique(y)\n\n# Ensure legend not cut off\nmpl.rcParams[\"savefig.bbox\"] = \"tight\"\nfig, axes = plt.subplots(\n nrows=n_classifiers,\n ncols=len(iris.target_names) + 1,\n figsize=(4 * 2.2, n_classifiers * 2.2),\n)\nevaluation_results = []\nlevels = 100\nfor classifier_idx, (name, classifier) in enumerate(classifiers.items()):\n y_pred = classifier.fit(X_train, y_train).predict(X_test)\n y_pred_proba = classifier.predict_proba(X_test)\n accuracy_test = accuracy_score(y_test, y_pred)\n roc_auc_test = roc_auc_score(y_test, y_pred_proba, multi_class=\"ovr\")\n log_loss_test = log_loss(y_test, y_pred_proba)\n evaluation_results.append(\n {\n \"name\": name.replace(\"\\n\", \" \"),\n \"accuracy\": accuracy_test,\n \"roc_auc\": roc_auc_test,\n \"log_loss\": log_loss_test,\n }\n )\n for label in y_unique:\n # plot the probability estimate provided by the classifier\n disp = DecisionBoundaryDisplay.from_estimator(\n classifier,\n X_train,\n response_method=\"predict_proba\",\n class_of_interest=label,\n ax=axes[classifier_idx, label],\n vmin=0,\n vmax=1,\n cmap=\"Blues\",\n levels=levels,\n )\n axes[classifier_idx, label].set_title(f\"Class {label}\")\n # plot data predicted to belong to given class\n mask_y_pred = y_pred == label\n axes[classifier_idx, label].scatter(\n X_test[mask_y_pred, 0], X_test[mask_y_pred, 1], c=\"w\", **scatter_kwargs\n )\n\n axes[classifier_idx, label].set(xticks=(), yticks=())\n # add column that shows all classes by plotting class with max 'predict_proba'\n max_class_disp = DecisionBoundaryDisplay.from_estimator(\n classifier,\n X_train,\n response_method=\"predict_proba\",\n class_of_interest=None,\n ax=axes[classifier_idx, len(y_unique)],\n vmin=0,\n vmax=1,\n levels=levels,\n )\n for label in y_unique:\n mask_label = y_test == label\n axes[classifier_idx, 3].scatter(\n X_test[mask_label, 0],\n X_test[mask_label, 1],\n c=max_class_disp.multiclass_colors_[[label], :],\n **scatter_kwargs,\n )\n\n axes[classifier_idx, 3].set(xticks=(), yticks=())\n axes[classifier_idx, 3].set_title(\"Max class\")\n axes[classifier_idx, 0].set_ylabel(name)\n\n# colorbar for single class plots\nax_single = fig.add_axes([0.15, 0.01, 0.5, 0.02])\nplt.title(\"Probability\")\n_ = plt.colorbar(\n cm.ScalarMappable(norm=None, cmap=disp.surface_.cmap),\n cax=ax_single,\n orientation=\"horizontal\",\n)\n\n# colorbars for max probability class column\nmax_class_cmaps = [s.cmap for s in max_class_disp.surface_]\n\nfor label in y_unique:\n ax_max = fig.add_axes([0.73, (0.06 - (label * 0.04)), 0.16, 0.015])\n plt.title(f\"Probability class {label}\", fontsize=10)\n _ = plt.colorbar(\n cm.ScalarMappable(norm=None, cmap=max_class_cmaps[label]),\n cax=ax_max,\n orientation=\"horizontal\",\n )\n if label in (0, 1):\n ax_max.set(xticks=(), yticks=())"
80+
]
81+
},
82+
{
83+
"cell_type": "markdown",
84+
"metadata": {},
85+
"source": [
86+
"## Quantitative evaluation\n\n"
87+
]
88+
},
89+
{
90+
"cell_type": "code",
91+
"execution_count": null,
92+
"metadata": {
93+
"collapsed": false
94+
},
95+
"outputs": [],
96+
"source": [
97+
"pd.DataFrame(evaluation_results).round(2)"
98+
]
99+
},
100+
{
101+
"cell_type": "markdown",
102+
"metadata": {},
103+
"source": [
104+
"## Analysis\n\nThe two logistic regression models fitted on the original features display\nlinear decision boundaries as expected. For this particular problem, this\ndoes not seem to be detrimental as both models are competitive with the\nnon-linear models when quantitatively evaluated on the test set. We can\nobserve that the amount of regularization influences the model confidence:\nlighter colors for the strongly regularized model with a lower value of `C`.\nRegularization also impacts the orientation of decision boundary leading to\nslightly different ROC AUC.\n\nThe log-loss on the other hand evaluates both sharpness and calibration and\nas a result strongly favors the weakly regularized logistic-regression model,\nprobably because the strongly regularized model is under-confident. This\ncould be confirmed by looking at the calibration curve using\n:class:`sklearn.calibration.CalibrationDisplay`.\n\nThe logistic regression model with RBF features has a \"blobby\" decision\nboundary that is non-linear in the original feature space and is quite\nsimilar to the decision boundary of the Gaussian process classifier which is\nconfigured to use an RBF kernel.\n\nThe logistic regression model fitted on binned features with interactions has\na decision boundary that is non-linear in the original feature space and is\nquite similar to the decision boundary of the gradient boosting classifier:\nboth models favor axis-aligned decisions when extrapolating to unseen region\nof the feature space.\n\nThe logistic regression model fitted on spline features with interactions\nhas a similar axis-aligned extrapolation behavior but a smoother decision\nboundary in the dense region of the feature space than the two previous\nmodels.\n\nTo conclude, it is interesting to observe that feature engineering for\nlogistic regression models can be used to mimic some of the inductive bias of\nvarious non-linear models. However, for this particular dataset, using the\nraw features is enough to train a competitive model. This would not\nnecessarily the case for other datasets.\n\n"
19105
]
20106
}
21107
],
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.

0 commit comments

Comments
 (0)