{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "# Загружаем необходимые библиотеки и классы (treeinterpreter можно \n",
    "# установить с помощью команды pip install treeinterpreter)\n",
    "from treeinterpreter import treeinterpreter as ti\n",
    "from sklearn.ensemble import RandomForestRegressor\n",
    "from sklearn.ensemble import RandomForestClassifier\n",
    "import numpy as np\n",
    "import pandas as pd"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "RandomForestRegressor(bootstrap=True, criterion='mse', max_depth=None,\n",
       "           max_features='auto', max_leaf_nodes=None,\n",
       "           min_impurity_split=1e-07, min_samples_leaf=1,\n",
       "           min_samples_split=2, min_weight_fraction_leaf=0.0,\n",
       "           n_estimators=10, n_jobs=1, oob_score=False, random_state=42,\n",
       "           verbose=0, warm_start=False)"
      ]
     },
     "execution_count": 2,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# Загружаем данные для задачи регрессии\n",
    "from sklearn.datasets import load_boston\n",
    "boston = load_boston()\n",
    "# Подгоняем ансамбль деревьев регрессии\n",
    "rf = RandomForestRegressor(random_state=42)\n",
    "rf.fit(boston.data, boston.target)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "# Отдельно запишем наблюдение, для которого будет смотреть прогноз\n",
    "observation=boston.data[300:301]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Прогноз для наблюдения: [ 26.36]\n"
     ]
    }
   ],
   "source": [
    "# Печатаем прогноз для наблюдения\n",
    "print(\"Прогноз для наблюдения:\", rf.predict(observation))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Прогноз [ 26.36]\n",
      "Смещение (среднее зависимой переменной в обучающем наборе) [ 22.63029644]\n",
      "Вклады признаков:\n",
      "CRIM -0.336032227032\n",
      "ZN -0.0375897435897\n",
      "INDUS 0.215891154189\n",
      "CHAS 0.0\n",
      "NOX 0.251317322288\n",
      "RM 2.91335204277\n",
      "AGE -0.641340080972\n",
      "DIS -1.57627007116\n",
      "RAD -0.042\n",
      "TAX -0.301164860662\n",
      "PTRATIO 0.00182041924623\n",
      "B -0.0351495726496\n",
      "LSTAT 3.31686917489\n"
     ]
    }
   ],
   "source": [
    "# Выполним декомпозицию прогноза для наблюдения\n",
    "prediction, bias, contributions = ti.predict(rf, observation)\n",
    "# Печатаем результаты декомпозиции прогноза\n",
    "print(\"Прогноз\", prediction)\n",
    "print(\"Смещение (среднее зависимой переменной в обучающем наборе)\", bias)\n",
    "print(\"Вклады признаков:\")\n",
    "for c, feature in zip(contributions[0], boston.feature_names):\n",
    "    print(feature, c)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Смещение (среднее зависимой переменной в обучающем наборе) [ 22.63029644]\n",
      "Вклады признаков:\n",
      "LSTAT 3.32\n",
      "RM 2.91\n",
      "DIS -1.58\n",
      "AGE -0.64\n",
      "CRIM -0.34\n",
      "TAX -0.3\n",
      "NOX 0.25\n",
      "INDUS 0.22\n",
      "RAD -0.04\n",
      "ZN -0.04\n",
      "B -0.04\n",
      "PTRATIO 0.0\n",
      "CHAS 0.0\n"
     ]
    }
   ],
   "source": [
    "# Печатаем результаты декомпозиции прогноза, отсортировав \n",
    "# вклады признаков по убыванию абсолютного значения и \n",
    "# выполнив округление до второго знака\n",
    "print(\"Смещение (среднее зависимой переменной в обучающем наборе)\", bias)\n",
    "print(\"Вклады признаков:\")\n",
    "for c, feature in sorted(zip(contributions[0], \n",
    "                             boston.feature_names), \n",
    "                             key=lambda x: -abs(x[0])):\n",
    "    print(feature, round(c, 2))    "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[ 26.36]\n",
      "[ 26.36]\n"
     ]
    }
   ],
   "source": [
    "# Сложим смещение и вклады признаков, чтобы проверить,\n",
    "# совпадает ли полученный результат с прогнозом\n",
    "print(prediction)\n",
    "print(bias + np.sum(contributions, axis=1))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "RandomForestClassifier(bootstrap=True, class_weight=None, criterion='gini',\n",
       "            max_depth=None, max_features='auto', max_leaf_nodes=None,\n",
       "            min_impurity_split=1e-07, min_samples_leaf=1,\n",
       "            min_samples_split=2, min_weight_fraction_leaf=0.0,\n",
       "            n_estimators=200, n_jobs=1, oob_score=False, random_state=42,\n",
       "            verbose=0, warm_start=False)"
      ]
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# Загружаем данные для задачи классификации в пандасовский DataFrame\n",
    "data = pd.read_csv(\"C:/Trees/BankloanPy.csv\", encoding='cp1251', sep=';')\n",
    "# Формируем массив признаков и массив меток\n",
    "y = data.loc[:, 'default']\n",
    "X = data.loc[:, 'age':'othdebt']\n",
    "# Записываем названия признаков, чтобы потом сопоставить их значениям вкладов\n",
    "features_names=X.columns\n",
    "# Разбиваем на обучение и тест\n",
    "from sklearn.model_selection import train_test_split\n",
    "X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42)\n",
    "# Подгоняем ансамбль деревьев классификации\n",
    "forest=RandomForestClassifier(n_estimators=200, random_state=42)\n",
    "forest.fit(X_train, y_train)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Прогноз [[ 0.95  0.05]]\n",
      "Смещение (среднее зависимой переменной в обучающем наборе) [[ 0.64397143  0.35602857]]\n",
      "Вклады признаков:\n",
      "age [ 0.04751199 -0.04751199]\n",
      "employ [ 0.07158361 -0.07158361]\n",
      "address [ 0.0427569 -0.0427569]\n",
      "income [ 0.04874334 -0.04874334]\n",
      "debtinc [ 0.07574518 -0.07574518]\n",
      "creddebt [ 0.00998228 -0.00998228]\n",
      "othdebt [ 0.00970526 -0.00970526]\n"
     ]
    }
   ],
   "source": [
    "# Печатаем результаты декомпозиции прогноза для конкретного наблюдения\n",
    "prediction_test, bias_test, contributions_test = ti.predict(forest, X_test[100:101])\n",
    "print(\"Прогноз\", prediction_test)\n",
    "print(\"Смещение (среднее зависимой переменной в обучающем наборе)\", bias_test)\n",
    "print(\"Вклады признаков:\")\n",
    "for c, feature in zip(contributions_test[0], features_names):\n",
    "    print(feature, c)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": []
  }
 ],
 "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.1"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
