Skip to content

Commit

Permalink
seminar04
Browse files Browse the repository at this point in the history
  • Loading branch information
Ilya Irkhin committed Nov 12, 2018
1 parent 5afe0f3 commit 4c243ca
Show file tree
Hide file tree
Showing 9 changed files with 17,553 additions and 0 deletions.
4 changes: 4 additions & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,7 @@ matplotlib==2.2.2
pandas==0.22.0
scikit-learn==0.19.2
requests==2.19.1
graphviz==0.10.1
pydotplus==2.0.2
xgboost==0.81
catboost==0.11.0
635 changes: 635 additions & 0 deletions seminar04/01_TreeVisualization.ipynb

Large diffs are not rendered by default.

247 changes: 247 additions & 0 deletions seminar04/02_Bagging.ipynb
Original file line number Diff line number Diff line change
@@ -0,0 +1,247 @@
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Бэггинг"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Пусть есть случайные одинаково распределённые величины $\\xi_1, \\xi_2, \\dots, \\xi_n$, скоррелированные с коэффициентом корреляции $\\rho$ и дисперсией $\\sigma^2$. Какова будет дисперсия величины $\\frac1n \\sum_{i=1}^n \\xi_i$?\n",
"\n",
"$$\\mathbf{D} \\frac1n \\sum_{i=1}^n \\xi_i = \\frac1{n^2}\\mathbf{cov} (\\sum_{i=1}^n \\xi_i, \\sum_{i=1}^n \\xi_i) = \\frac1{n^2} \\sum_{i=1, j=1}^n \\mathbf{cov}(\\xi_i, \\xi_j) = \\frac1{n^2} \\sum_{i=1}^n \\mathbf{cov}(\\xi_i, \\xi_i) + \\frac1{n^2} \\sum_{i=1, j=1, i\\neq j}^n \\mathbf{cov}(\\xi_i, \\xi_j) = \\frac1{n^2} \\sum_{i=1}^n \\sigma^2+ \\frac1{n^2} \\sum_{i=1, j=1, i\\neq j}^n \\rho \\sigma^2 =$$\n",
"$$ = \\frac1{n^2} n \\sigma^2 + \\frac1{n^2} n(n-1) \\rho \\sigma^2 = \\frac{\\sigma^2( 1 + \\rho(n-1))}{n}$$\n",
"\n",
"Таким образом, чем менее величины скоррелированы между собой, тем меньше будет дисперсия после их усреднения. Грубо говоря в этом и состоит идея бэггинга: давайте сделаем много максимально независимых моделей, а потом их усредим, и тогда предсказания станет более устойчивым!"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Бэггинг над решающими деревьями\n",
"\n",
"Посмотрим, какие модели можно получить из деревьев с помощью их рандомизации"
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [],
"source": [
"import pandas as pd\n",
"import numpy as np\n",
"from sklearn.model_selection import cross_val_score, train_test_split\n",
"from sklearn.ensemble import BaggingClassifier\n",
"from sklearn.tree import DecisionTreeClassifier\n",
"from sklearn.ensemble import RandomForestClassifier\n",
"from sklearn.linear_model import LogisticRegression"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {
"scrolled": true
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"['last_evaluation', 'number_project', 'average_montly_hours', 'time_spend_company', 'Work_accident', 'promotion_last_5years']\n"
]
}
],
"source": [
"data = pd.read_csv('HR.csv')\n",
"\n",
"target = 'left'\n",
"features = [c for c in data if c != target]\n",
"print(features)\n",
"\n",
"X, y = data[features], data[target]"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {},
"outputs": [],
"source": [
"rnd_d3 = DecisionTreeClassifier(max_features=int(len(features) ** 0.5)) # Решающее дерево с рандомизацией в сплитах\n",
"d3 = DecisionTreeClassifier() # Обычное решающее дерево"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Качество классификации решающим деревом с настройками по-умолчанию:"
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Decision tree: 0.6523099419883976\n"
]
}
],
"source": [
"print(\"Decision tree:\", cross_val_score(d3, X, y).mean())"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Бэггинг над решающими деревьями:"
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"D3 bagging: 0.7174495299059812\n"
]
}
],
"source": [
"print(\"D3 bagging:\", cross_val_score(BaggingClassifier(d3, random_state=42), X, y).mean())"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Усредненная модель оказалась намного лучше. Оказывается, у решающих деревьев есть существенный недостаток - нестабильность получаемого дерева при небольших изменениях в выборке. Но бэггинг обращает этот недостаток в достоинство, ведь усредненная модель работает лучше, когда базовые модели слабо скоррелированы."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Изучив параметры DecisionTreeClassifier, можно найти хороший способ сделать деревья еще более различными - при построении каждого узла отбирать случайные max_features признаков и искать информативное разбиение только по одному из них."
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Randomized D3 Bagging: 0.7194494632259785\n"
]
}
],
"source": [
"print(\"Randomized D3 Bagging:\", cross_val_score(BaggingClassifier(rnd_d3, random_state=42), X, y).mean())"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"В среднем, качество получается еще лучше. Для выбора числа признаков использовалась часто применяемая на практике эвристика - брать корень из общего числа признаков. Если бы мы решали задачу регрессии - брали бы треть от общего числа."
]
},
{
"cell_type": "code",
"execution_count": 7,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Random Forest: 0.7232495965859839\n"
]
}
],
"source": [
"print(\"Random Forest:\", cross_val_score(RandomForestClassifier(random_state=42), X, y).mean())"
]
},
{
"cell_type": "code",
"execution_count": 8,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Logistic Regression: 0.6287053143962126\n"
]
}
],
"source": [
"print(\"Logistic Regression:\", cross_val_score(LogisticRegression(), X, y).mean())"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Опциональное задание\n",
"Повторные запуски cross_val_score будут показывать различное качество модели.\n",
"\n",
"Это зависит от параметра рандомизации модели \"random_state\" в DecisionTreeClassifier, BaggingClassifie или RandomForest.\n",
"\n",
"Чтобы понять, действительно ли одна модель лучше другой, можно посмотреть на её качество в среднем, то есть усредняя запуски с разным random_state. Предлагаю сравнить качество и понять, действительно ли BaggingClassifier(d3) лучше BaggingClassifier(rnd_d3)?\n",
"\n",
"Также предлагаю ответить на вопрос, чем здесь отличается BaggingClassifier(rnd_d3) от RandomForestClassifier()?"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": []
}
],
"metadata": {
"anaconda-cloud": {},
"kernelspec": {
"display_name": "dmia",
"language": "python",
"name": "dmia"
},
"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.6"
}
},
"nbformat": 4,
"nbformat_minor": 1
}
Loading

0 comments on commit 4c243ca

Please sign in to comment.