mirror of
https://github.com/gsi-upm/sitc
synced 2024-11-25 15:52:29 +00:00
655 lines
58 KiB
Plaintext
655 lines
58 KiB
Plaintext
{
|
|
"cells": [
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"![](files/images/EscUpmPolit_p.gif \"UPM\")"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"# Course Notes for Learning Intelligent Systems"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"Department of Telematic Engineering Systems, Universidad Politécnica de Madrid, © 2016 Carlos A. Iglesias"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"## [Introduction to Machine Learning](2_0_0_Intro_ML.ipynb)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"# Table of Contents\n",
|
|
"* [Decision Tree Learning](#Decision-Tree-Learning)\n",
|
|
"* [Load data and preprocessing](#Load-data-and-preprocessing)\n",
|
|
"* [Train classifier](#Train-classifier)\n",
|
|
"* [Evaluating the algorithm](#Evaluating-the-algorithm)\n",
|
|
"\t* [Precision, recall and f-score](#Precision,-recall-and-f-score)\n",
|
|
"\t* [Confusion matrix](#Confusion-matrix)\n",
|
|
"\t* [K-Fold cross validation](#K-Fold-cross-validation)\n",
|
|
"* [References](#References)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"# Decision Tree Learning"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"The goal of this notebook is to learn how to create a classification object using a [decision tree learning algorithm](https://en.wikipedia.org/wiki/Decision_tree_learning). \n",
|
|
"\n",
|
|
"There are a number of well known machine learning algorithms for decision tree learning, such as ID3, C4.5, C5.0 and CART. The scikit-learn uses an optimised version of the [CART (Classification and Regression Trees) algorithm](https://en.wikipedia.org/wiki/Predictive_analytics#Classification_and_regression_trees).\n",
|
|
"\n",
|
|
"This notebook will follow the same steps that the previous notebook for learning using the [kNN Model](2_5_1_kNN_Model.ipynb), and details some peculiarities of the decision tree algorithms."
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"## Load data and preprocessing\n",
|
|
"\n",
|
|
"Here we repeat the same operations for loading data and preprocessing than in the previous notebooks."
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 1,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"# library for displaying plots\n",
|
|
"import matplotlib.pyplot as plt\n",
|
|
"# display plots in the notebook \n",
|
|
"%matplotlib inline\n",
|
|
"\n",
|
|
"## First, we repeat the load and preprocessing steps\n",
|
|
"\n",
|
|
"# Load data\n",
|
|
"from sklearn import datasets\n",
|
|
"iris = datasets.load_iris()\n",
|
|
"\n",
|
|
"# Training and test spliting\n",
|
|
"from sklearn.model_selection import train_test_split\n",
|
|
"\n",
|
|
"x_iris, y_iris = iris.data, iris.target\n",
|
|
"# Test set will be the 25% taken randomly\n",
|
|
"x_train, x_test, y_train, y_test = train_test_split(x_iris, y_iris, test_size=0.25, random_state=33)\n",
|
|
"\n",
|
|
"# Preprocess: normalize\n",
|
|
"from sklearn import preprocessing\n",
|
|
"scaler = preprocessing.StandardScaler().fit(x_train)\n",
|
|
"x_train = scaler.transform(x_train)\n",
|
|
"x_test = scaler.transform(x_test)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {
|
|
"collapsed": true
|
|
},
|
|
"source": [
|
|
"## Train classifier"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"The usual steps for creating a classifier are:\n",
|
|
"1. Create classifier object\n",
|
|
"2. Call *fit* to train the classifier\n",
|
|
"3. Call *predict* to obtain predictions\n",
|
|
"\n",
|
|
"*DecisionTreeClassifier* is capable of both binary (where the labels are [-1, 1]) classification and multiclass (where the labels are [0, ..., K-1]) classification."
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 2,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"data": {
|
|
"text/plain": [
|
|
"DecisionTreeClassifier(class_weight=None, criterion='gini', max_depth=3,\n",
|
|
" max_features=None, 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",
|
|
" presort=False, random_state=1, splitter='best')"
|
|
]
|
|
},
|
|
"execution_count": 2,
|
|
"metadata": {},
|
|
"output_type": "execute_result"
|
|
}
|
|
],
|
|
"source": [
|
|
"from sklearn.tree import DecisionTreeClassifier\n",
|
|
"import numpy as np\n",
|
|
"\n",
|
|
"from sklearn import tree\n",
|
|
"\n",
|
|
"max_depth=3\n",
|
|
"random_state=1\n",
|
|
"\n",
|
|
"# Create decision tree model\n",
|
|
"model = tree.DecisionTreeClassifier(max_depth=max_depth, random_state=random_state)\n",
|
|
"\n",
|
|
"# Train the model using the training sets\n",
|
|
"model.fit(x_train, y_train) "
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 3,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"Prediction [1 0 1 1 1 0 0 1 0 2 0 0 1 2 0 1 2 2 1 1 0 0 2 0 0 2 1 1 2 2 2 2 0 0 1 1 0\n",
|
|
" 1 2 1 2 0 2 0 1 0 2 1 0 2 2 0 0 2 0 0 0 2 2 0 1 0 1 0 1 1 1 1 1 0 1 0 1 2\n",
|
|
" 0 0 0 0 2 2 0 1 1 2 1 0 0 2 1 1 0 1 1 0 2 1 2 1 2 0 1 0 0 0 2 1 2 1 2 1 2\n",
|
|
" 0]\n",
|
|
"Expected [1 0 1 1 1 0 0 1 0 2 0 0 1 2 0 1 2 2 1 1 0 0 2 0 0 2 1 1 2 2 2 2 0 0 1 1 0\n",
|
|
" 1 2 1 2 0 2 0 1 0 2 1 0 2 2 0 0 2 0 0 0 2 2 0 1 0 1 0 1 1 1 1 1 0 1 0 1 2\n",
|
|
" 0 0 0 0 2 2 0 1 1 2 1 0 0 1 1 1 0 1 1 0 2 2 2 1 2 0 1 0 0 0 2 1 2 1 2 1 2\n",
|
|
" 0]\n"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"print(\"Prediction \", model.predict(x_train))\n",
|
|
"print(\"Expected \", y_train)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"Alternatively, the probability of each class can be predicted, which is the fraction of training samples of the same class in a leaf:"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 4,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"Predicted probabilities [[ 0. 0.97368421 0.02631579]\n",
|
|
" [ 1. 0. 0. ]\n",
|
|
" [ 0. 0.97368421 0.02631579]\n",
|
|
" [ 0. 0.97368421 0.02631579]\n",
|
|
" [ 0. 0.97368421 0.02631579]\n",
|
|
" [ 1. 0. 0. ]\n",
|
|
" [ 1. 0. 0. ]\n",
|
|
" [ 0. 0.97368421 0.02631579]\n",
|
|
" [ 1. 0. 0. ]\n",
|
|
" [ 0. 0. 1. ]]\n"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"# Print the \n",
|
|
"print(\"Predicted probabilities\", model.predict_proba(x_train[:10]))"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 5,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"Accuracy in training 0.982142857143\n"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"# Evaluate Accuracy in training\n",
|
|
"\n",
|
|
"from sklearn import metrics\n",
|
|
"y_train_pred = model.predict(x_train)\n",
|
|
"print(\"Accuracy in training\", metrics.accuracy_score(y_train, y_train_pred))"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 6,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"Accuracy in testing 0.921052631579\n"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"# Now we evaluate error in testing\n",
|
|
"y_test_pred = model.predict(x_test)\n",
|
|
"print(\"Accuracy in testing \", metrics.accuracy_score(y_test, y_test_pred))"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"Now we are going to visualize the DecisionTree classification. It will plot the decision boundaries for each class.\n",
|
|
"\n",
|
|
"The current version of pydot does not work well in Python 3.\n",
|
|
"For obtaining an image, you need to install `pip install pydotplus` and then `conda install graphviz`.\n",
|
|
"\n",
|
|
"You can skip this example. Since it can require installing additional packages, we include here the result.\n",
|
|
"![Decision Tree](files/images/cart.png)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 7,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"ename": "ModuleNotFoundError",
|
|
"evalue": "No module named 'pydotplus'",
|
|
"output_type": "error",
|
|
"traceback": [
|
|
"\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
|
|
"\u001b[0;31mModuleNotFoundError\u001b[0m Traceback (most recent call last)",
|
|
"\u001b[0;32m<ipython-input-7-1bf5ec7fb043>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m()\u001b[0m\n\u001b[1;32m 1\u001b[0m \u001b[0;32mfrom\u001b[0m \u001b[0mIPython\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mdisplay\u001b[0m \u001b[0;32mimport\u001b[0m \u001b[0mImage\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 2\u001b[0m \u001b[0;32mfrom\u001b[0m \u001b[0msklearn\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mexternals\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0msix\u001b[0m \u001b[0;32mimport\u001b[0m \u001b[0mStringIO\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 3\u001b[0;31m \u001b[0;32mimport\u001b[0m \u001b[0mpydotplus\u001b[0m \u001b[0;32mas\u001b[0m \u001b[0mpydot\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 4\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 5\u001b[0m \u001b[0mdot_data\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mStringIO\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
|
|
"\u001b[0;31mModuleNotFoundError\u001b[0m: No module named 'pydotplus'"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"from IPython.display import Image \n",
|
|
"from sklearn.externals.six import StringIO\n",
|
|
"import pydotplus as pydot\n",
|
|
"\n",
|
|
"dot_data = StringIO() \n",
|
|
"tree.export_graphviz(model, out_file=dot_data, \n",
|
|
" feature_names=iris.feature_names, \n",
|
|
" class_names=iris.target_names, \n",
|
|
" filled=True, rounded=True, \n",
|
|
" special_characters=True) \n",
|
|
"\n",
|
|
"\n",
|
|
"graph = pydot.graph_from_dot_data(dot_data.getvalue()) \n",
|
|
"graph.write_png('iris-tree.png')\n",
|
|
"Image(graph.create_png()) "
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"Here we show a graph of the decision tree boundaries. For each pair of iris features, the decision tree learns decision boundaries made of combinations of simple thresholding rules inferred from the training samples.\n",
|
|
"\n",
|
|
"We are going to import a function defined in the file [util_ds.py](files/util_ds.py) using the *magic command* **%run**."
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 8,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"data": {
|
|
"image/png": "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\n",
|
|
"text/plain": [
|
|
"<matplotlib.figure.Figure at 0x7f6e096d9eb8>"
|
|
]
|
|
},
|
|
"metadata": {},
|
|
"output_type": "display_data"
|
|
}
|
|
],
|
|
"source": [
|
|
"%run util_ds\n",
|
|
"\n",
|
|
"# display plots in the notebook \n",
|
|
"%matplotlib inline\n",
|
|
"plot_tree_iris()"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"Next we are going to export the pseudocode of the the learnt decision tree."
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 9,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"if ( petal width (cm) <= -0.415243178606 ) {\n",
|
|
" return setosa ( 42 examples )\n",
|
|
"}\n",
|
|
"else {\n",
|
|
" if ( petal width (cm) <= 0.861689627171 ) {\n",
|
|
" if ( petal length (cm) <= 0.818572163582 ) {\n",
|
|
" return versicolor ( 37 examples )\n",
|
|
" return virginica ( 1 examples )\n",
|
|
" }\n",
|
|
" else {\n",
|
|
" return versicolor ( 1 examples )\n",
|
|
" return virginica ( 2 examples )\n",
|
|
" }\n",
|
|
" }\n",
|
|
" else {\n",
|
|
" if ( petal length (cm) <= 0.707377433777 ) {\n",
|
|
" return versicolor ( 1 examples )\n",
|
|
" }\n",
|
|
" else {\n",
|
|
" return virginica ( 28 examples )\n",
|
|
" }\n",
|
|
" }\n",
|
|
"}\n"
|
|
]
|
|
},
|
|
{
|
|
"data": {
|
|
"text/plain": [
|
|
"<matplotlib.figure.Figure at 0x7f6e0709def0>"
|
|
]
|
|
},
|
|
"metadata": {},
|
|
"output_type": "display_data"
|
|
}
|
|
],
|
|
"source": [
|
|
"%run util_ds\n",
|
|
"get_code(model, iris.feature_names, iris.target_names)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"We can also obtain the feature importance of the fitted model as follows."
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 10,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"['sepal length (cm)', 'sepal width (cm)', 'petal length (cm)', 'petal width (cm)']\n",
|
|
"[ 0. 0. 0.05947455 0.94052545]\n"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"print(iris.feature_names)\n",
|
|
"print(model.feature_importances_)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"We see that the most important feature for this classifier is `petal width`."
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"## Evaluating the algorithm"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"### Precision, recall and f-score"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"For evaluating classification algorithms, we usually calculate three metrics: precision, recall and F1-score\n",
|
|
"\n",
|
|
"* **Precision**: This computes the proportion of instances predicted as positives that were correctly evaluated (it measures how right our classifier is when it says that an instance is positive).\n",
|
|
"* **Recall**: This counts the proportion of positive instances that were correctly evaluated (measuring how right our classifier is when faced with a positive instance).\n",
|
|
"* **F1-score**: This is the harmonic mean of precision and recall, and tries to combine both in a single number."
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 11,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
" precision recall f1-score support\n",
|
|
"\n",
|
|
" setosa 1.00 1.00 1.00 8\n",
|
|
" versicolor 0.79 1.00 0.88 11\n",
|
|
" virginica 1.00 0.84 0.91 19\n",
|
|
"\n",
|
|
"avg / total 0.94 0.92 0.92 38\n",
|
|
"\n"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"print(metrics.classification_report(y_test, y_test_pred,target_names=iris.target_names))"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"### Confusion matrix"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"Another useful metric is the confusion matrix"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 12,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"[[ 8 0 0]\n",
|
|
" [ 0 11 0]\n",
|
|
" [ 0 3 16]]\n"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"print(metrics.confusion_matrix(y_test, y_test_pred))"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"We see we classify well all the 'setosa' and 'versicolor' samples. "
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"### K-Fold cross validation"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"In order to avoid bias in the training and testing dataset partition, it is recommended to use **k-fold validation**.\n",
|
|
"\n",
|
|
"Sklearn comes with other strategies for [cross validation](http://scikit-learn.org/stable/modules/cross_validation.html#cross-validation), such as stratified K-fold, label k-fold, Leave-One-Out, Leave-P-Out, Leave-One-Label-Out, Leave-P-Label-Out or Shuffle & Split."
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 14,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"[ 1. 0.8 1. 0.93333333 0.93333333 1. 1.\n",
|
|
" 1. 0.86666667 0.93333333]\n"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"from sklearn.model_selection import cross_val_score, KFold\n",
|
|
"from sklearn.pipeline import Pipeline\n",
|
|
"from sklearn.preprocessing import StandardScaler\n",
|
|
"\n",
|
|
"# create a composite estimator made by a pipeline of preprocessing and the KNN model\n",
|
|
"model = Pipeline([\n",
|
|
" ('scaler', StandardScaler()),\n",
|
|
" ('DecisionTree', DecisionTreeClassifier())\n",
|
|
"])\n",
|
|
"\n",
|
|
"# create a k-fold cross validation iterator of k=10 folds\n",
|
|
"cv = KFold(10, shuffle=True, random_state=33)\n",
|
|
"\n",
|
|
"# by default the score used is the one returned by score method of the estimator (accuracy)\n",
|
|
"scores = cross_val_score(model, x_iris, y_iris, cv=cv)\n",
|
|
"print(scores)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {
|
|
"collapsed": true
|
|
},
|
|
"source": [
|
|
"We get an array of k scores. We can calculate the mean and the standard error to obtain a final figure"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 15,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"Mean score: 0.947 (+/- 0.022)\n"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"from scipy.stats import sem\n",
|
|
"def mean_score(scores):\n",
|
|
" return (\"Mean score: {0:.3f} (+/- {1:.3f})\").format(np.mean(scores), sem(scores))\n",
|
|
"print(mean_score(scores))"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"So, we get an average accuracy of 0.947."
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"## References"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"* [Plot the decision surface of a decision tree on the iris dataset](http://scikit-learn.org/stable/auto_examples/tree/plot_iris.html)\n",
|
|
"* [Learning scikit-learn: Machine Learning in Python](http://proquest.safaribooksonline.com/book/programming/python/9781783281930/1dot-machine-learning-a-gentle-introduction/ch01s02_html), Raúl Garreta; Guillermo Moncecchi, Packt Publishing, 2013.\n",
|
|
"* [Python Machine Learning](http://proquest.safaribooksonline.com/book/programming/python/9781783555130), Sebastian Raschka, Packt Publishing, 2015.\n",
|
|
"* [Parameter estimation using grid search with cross-validation](http://scikit-learn.org/stable/auto_examples/model_selection/grid_search_digits.html)\n",
|
|
"* [Decision trees in python with scikit-learn and pandas](http://chrisstrelioff.ws/sandbox/2015/06/08/decision_trees_in_python_with_scikit_learn_and_pandas.html)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"## Licence\n",
|
|
"The notebook is freely licensed under under the [Creative Commons Attribution Share-Alike license](https://creativecommons.org/licenses/by/2.0/). \n",
|
|
"\n",
|
|
"© 2016 Carlos A. Iglesias, Universidad Politécnica de Madrid."
|
|
]
|
|
}
|
|
],
|
|
"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.3"
|
|
}
|
|
},
|
|
"nbformat": 4,
|
|
"nbformat_minor": 1
|
|
}
|