{
  "cells": [
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "%matplotlib inline"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "\n# Imputing missing values before building an estimator\n\n\nThis example shows that imputing the missing values can give better\nresults than discarding the samples containing any missing value.\nImputing does not always improve the predictions, so please check via\ncross-validation.  Sometimes dropping rows or using marker values is\nmore effective.\n\nMissing values can be replaced by the mean, the median or the most frequent\nvalue using the basic :func:`sklearn.impute.SimpleImputer`.\nThe median is a more robust estimator for data with high magnitude variables\nwhich could dominate results (otherwise known as a 'long tail').\n\nIn addition of using an imputing method, we can also keep an indication of the\nmissing information using :func:`sklearn.impute.MissingIndicator` which might\ncarry some information.\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "import numpy as np\nimport matplotlib.pyplot as plt\n\nfrom sklearn.datasets import load_diabetes\nfrom sklearn.datasets import load_boston\nfrom sklearn.ensemble import RandomForestRegressor\nfrom sklearn.pipeline import make_pipeline, make_union\nfrom sklearn.impute import SimpleImputer, MissingIndicator\nfrom sklearn.model_selection import cross_val_score\n\nrng = np.random.RandomState(0)\n\n\ndef get_results(dataset):\n    X_full, y_full = dataset.data, dataset.target\n    n_samples = X_full.shape[0]\n    n_features = X_full.shape[1]\n\n    # Estimate the score on the entire dataset, with no missing values\n    estimator = RandomForestRegressor(random_state=0, n_estimators=100)\n    full_scores = cross_val_score(estimator, X_full, y_full,\n                                  scoring='neg_mean_squared_error', cv=5)\n\n    # Add missing values in 75% of the lines\n    missing_rate = 0.75\n    n_missing_samples = int(np.floor(n_samples * missing_rate))\n    missing_samples = np.hstack((np.zeros(n_samples - n_missing_samples,\n                                          dtype=np.bool),\n                                 np.ones(n_missing_samples,\n                                         dtype=np.bool)))\n    rng.shuffle(missing_samples)\n    missing_features = rng.randint(0, n_features, n_missing_samples)\n\n    # Estimate the score after replacing missing values by 0\n    X_missing = X_full.copy()\n    X_missing[np.where(missing_samples)[0], missing_features] = 0\n    y_missing = y_full.copy()\n    estimator = RandomForestRegressor(random_state=0, n_estimators=100)\n    zero_impute_scores = cross_val_score(estimator, X_missing, y_missing,\n                                         scoring='neg_mean_squared_error',\n                                         cv=5)\n\n    # Estimate the score after imputation (mean strategy) of the missing values\n    X_missing = X_full.copy()\n    X_missing[np.where(missing_samples)[0], missing_features] = 0\n    y_missing = y_full.copy()\n    estimator = make_pipeline(\n        make_union(SimpleImputer(missing_values=0, strategy=\"mean\"),\n                   MissingIndicator(missing_values=0)),\n        RandomForestRegressor(random_state=0, n_estimators=100))\n    mean_impute_scores = cross_val_score(estimator, X_missing, y_missing,\n                                         scoring='neg_mean_squared_error',\n                                         cv=5)\n\n\n    return ((full_scores.mean(), full_scores.std()),\n            (zero_impute_scores.mean(), zero_impute_scores.std()),\n            (mean_impute_scores.mean(), mean_impute_scores.std()))\n\n\nresults_diabetes = np.array(get_results(load_diabetes()))\nmses_diabetes = results_diabetes[:, 0] * -1\nstds_diabetes = results_diabetes[:, 1]\n\nresults_boston = np.array(get_results(load_boston()))\nmses_boston = results_boston[:, 0] * -1\nstds_boston = results_boston[:, 1]\n\nn_bars = len(mses_diabetes)\nxval = np.arange(n_bars)\n\nx_labels = ['Full data',\n            'Zero imputation',\n            'Mean Imputation']\ncolors = ['r', 'g', 'b', 'orange']\n\n# plot diabetes results\nplt.figure(figsize=(12, 6))\nax1 = plt.subplot(121)\nfor j in xval:\n    ax1.barh(j, mses_diabetes[j], xerr=stds_diabetes[j],\n             color=colors[j], alpha=0.6, align='center')\n\nax1.set_title('Imputation Techniques with Diabetes Data')\nax1.set_xlim(left=np.min(mses_diabetes) * 0.9,\n             right=np.max(mses_diabetes) * 1.1)\nax1.set_yticks(xval)\nax1.set_xlabel('MSE')\nax1.invert_yaxis()\nax1.set_yticklabels(x_labels)\n\n# plot boston results\nax2 = plt.subplot(122)\nfor j in xval:\n    ax2.barh(j, mses_boston[j], xerr=stds_boston[j],\n             color=colors[j], alpha=0.6, align='center')\n\nax2.set_title('Imputation Techniques with Boston Data')\nax2.set_yticks(xval)\nax2.set_xlabel('MSE')\nax2.invert_yaxis()\nax2.set_yticklabels([''] * n_bars)\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.6.7"
    }
  },
  "nbformat": 4,
  "nbformat_minor": 0
}