{
  "cells": [
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "%matplotlib inline"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "\n# One class classification\n\nData descriptors generalise knowledge about a target class of data to the whole attribute space.\nThis can be used to predict whether new data instances belong to the target class or not,\nor to identify which new instances should be subjected to further inspection.\nThis type of binary classification is known as *one-class classification*,\n*semi-supervised outlier detection*, *semi-supervised anomaly detection*, or *novelty detection*.\nIn principle, there is no good or bad way to generalise the target class, this can only be evaluated empirically.\nIn practice, we want a good balance between variance and bias.\n\nThe following graphs illustrate the behaviour of the data descriptors in fuzzy-rough-learn,\nwith their default hyperparameter values as established in [1]_.\nNote that the predicted scores have been converted to quantiles\nto obtain clear contour lines that illustrate how the predicted scores taper off.\n\n## References\n.. [1] `Lenz OU, Peralta D, Cornelis C (2021).\n   Average Localised Proximity: A new data descriptor with good default one-class classification performance.\n   Pattern Recognition, vol 118, no 107991.\n   doi: 10.1016/j.patcog.2021.107991\n   <https://www.sciencedirect.com/science/article/abs/pii/S0031320321001783>`_\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "print(__doc__)\n\nimport numpy as np\nimport matplotlib.pyplot as plt\n\nfrom frlearn.data_descriptors import ALP, CD, IF, MD, NND, LNND, LOF, SVM\n\n\n# Sample attribute space, to use as test data\nxx, yy = np.meshgrid(np.linspace(-6, 6, 300), np.linspace(-6, 6, 300))\n\n# Generate training data\nrng = np.random.default_rng(0)\nX = rng.standard_normal((100, 2))\nX_train = np.r_[1 * X + 2, 0.75*X, 0.5 * X - 2]\n\n# Initialise data descriptors to include\ndata_descriptors = [\n    ('ALP', ALP()),\n    ('CD', CD()),\n    ('IF', IF()),\n    ('LNND', LNND()),\n    ('LOF', LOF()),\n    ('MD', MD()),\n    ('NND', NND()),\n    ('SVM', SVM()),\n]\n\n# Calculate number of rows\ncols = 3\nrows = (len(data_descriptors) + (cols - 1)) // cols\n\n# Create plot layout with square subplots\nfig, axs = plt.subplots(rows, cols, figsize=(3*cols, 3*rows), subplot_kw=dict(box_aspect=1), )\n\n# Iterate over data descriptors\nfor i, (name, clf) in enumerate(data_descriptors):\n    ax = axs[i // cols][i % cols]\n\n    # Create model and query for scores\n    model = clf(X_train)\n    Z = model(np.c_[xx.ravel(), yy.ravel()])\n\n    # Transform scores into their respective centile\n    centiles = np.quantile(Z, np.linspace(0, 1, 101))\n    Z = np.searchsorted(centiles, Z)/100\n    Z = Z.reshape(xx.shape)\n\n    # Plot contours\n    ax.contourf(xx, yy, Z, levels=np.linspace(0, 1, 12), cmap=plt.cm.PuBu)\n\n    # Plot training data\n    c = ax.scatter(X_train[:, 0], X_train[:, 1], c='white', s=10, edgecolors='k')\n\n    # Set axis limits and delete ticks and legends\n    plt.xlim((-6, 6))\n    plt.ylim((-6, 6))\n    c.axes.get_xaxis().set_visible(False)\n    c.axes.get_yaxis().set_visible(False)\n\n    ax.set_title(name)\n\n# Delete spare subfigures\nfor i in range((-len(data_descriptors)) % cols):\n    fig.delaxes(axs[-1, -(i + 1)])\n\nfig.tight_layout()\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.7.9"
    }
  },
  "nbformat": 4,
  "nbformat_minor": 0
}