{
  "cells": [
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "\n# SVM: Weighted samples\n\nPlot decision function of a weighted dataset, where the size of points\nis proportional to its weight.\n\nThe sample weighting rescales the C parameter, which means that the classifier\nputs more emphasis on getting these points right. The effect might often be\nsubtle.\nTo emphasize the effect here, we particularly increase the weight of the positive\nclass, making the deformation of the decision boundary more visible.\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "# Authors: The scikit-learn developers\n# SPDX-License-Identifier: BSD-3-Clause\n\nimport matplotlib.pyplot as plt\nimport numpy as np\n\nfrom sklearn.datasets import make_classification\nfrom sklearn.inspection import DecisionBoundaryDisplay\nfrom sklearn.svm import SVC\n\nX, y = make_classification(\n    n_samples=1_000,\n    n_features=2,\n    n_informative=2,\n    n_redundant=0,\n    n_clusters_per_class=1,\n    class_sep=1.1,\n    weights=[0.9, 0.1],\n    random_state=0,\n)\n# down-sample for plotting\nrng = np.random.RandomState(0)\nplot_indices = rng.choice(np.arange(X.shape[0]), size=100, replace=True)\nX_plot, y_plot = X[plot_indices], y[plot_indices]\n\n\ndef plot_decision_function(classifier, sample_weight, axis, title):\n    \"\"\"Plot the synthetic data and the classifier decision function. Points with\n    larger sample_weight are mapped to larger circles in the scatter plot.\"\"\"\n    axis.scatter(\n        X_plot[:, 0],\n        X_plot[:, 1],\n        c=y_plot,\n        s=100 * sample_weight[plot_indices],\n        alpha=0.9,\n        cmap=plt.cm.bone,\n        edgecolors=\"black\",\n    )\n    DecisionBoundaryDisplay.from_estimator(\n        classifier,\n        X_plot,\n        response_method=\"decision_function\",\n        alpha=0.75,\n        ax=axis,\n        cmap=plt.cm.bone,\n    )\n    axis.axis(\"off\")\n    axis.set_title(title)\n\n\n# we define constant weights as expected by the plotting function\nsample_weight_constant = np.ones(len(X))\n# assign random weights to all points\nsample_weight_modified = abs(rng.randn(len(X)))\n# assign bigger weights to the positive class\npositive_class_indices = np.asarray(y == 1).nonzero()[0]\nsample_weight_modified[positive_class_indices] *= 15\n\n# This model does not include sample weights.\nclf_no_weights = SVC(gamma=1)\nclf_no_weights.fit(X, y)\n\n# This other model includes sample weights.\nclf_weights = SVC(gamma=1)\nclf_weights.fit(X, y, sample_weight=sample_weight_modified)\n\nfig, axes = plt.subplots(1, 2, figsize=(14, 6))\nplot_decision_function(\n    clf_no_weights, sample_weight_constant, axes[0], \"Constant weights\"\n)\nplot_decision_function(clf_weights, sample_weight_modified, axes[1], \"Modified weights\")\n\nplt.show()"
      ]
    }
  ],
  "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
}