{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Chapter 3 - Modeling and prediction"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {
"collapsed": false
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Populating the interactive namespace from numpy and matplotlib\n"
]
}
],
"source": [
"%pylab inline"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### The Titanic dataset\n",
"\n",
"We use the Pandas library to import the Titanic survival dataset."
]
},
{
"cell_type": "code",
"execution_count": 27,
"metadata": {
"collapsed": false
},
"outputs": [
{
"data": {
"text/html": [
"
\n",
"
\n",
" \n",
" \n",
" | \n",
" PassengerId | \n",
" Survived | \n",
" Pclass | \n",
" Name | \n",
" Sex | \n",
" Age | \n",
" SibSp | \n",
" Parch | \n",
" Ticket | \n",
" Fare | \n",
" Cabin | \n",
" Embarked | \n",
"
\n",
" \n",
" \n",
" \n",
" 0 | \n",
" 1 | \n",
" 0 | \n",
" 3 | \n",
" Braund, Mr. Owen Harris | \n",
" male | \n",
" 22 | \n",
" 1 | \n",
" 0 | \n",
" A/5 21171 | \n",
" 7.2500 | \n",
" NaN | \n",
" S | \n",
"
\n",
" \n",
" 1 | \n",
" 2 | \n",
" 1 | \n",
" 1 | \n",
" Cumings, Mrs. John Bradley (Florence Briggs Th... | \n",
" female | \n",
" 38 | \n",
" 1 | \n",
" 0 | \n",
" PC 17599 | \n",
" 71.2833 | \n",
" C85 | \n",
" C | \n",
"
\n",
" \n",
" 2 | \n",
" 3 | \n",
" 1 | \n",
" 3 | \n",
" Heikkinen, Miss. Laina | \n",
" female | \n",
" 26 | \n",
" 0 | \n",
" 0 | \n",
" STON/O2. 3101282 | \n",
" 7.9250 | \n",
" NaN | \n",
" S | \n",
"
\n",
" \n",
" 3 | \n",
" 4 | \n",
" 1 | \n",
" 1 | \n",
" Futrelle, Mrs. Jacques Heath (Lily May Peel) | \n",
" female | \n",
" 35 | \n",
" 1 | \n",
" 0 | \n",
" 113803 | \n",
" 53.1000 | \n",
" C123 | \n",
" S | \n",
"
\n",
" \n",
" 4 | \n",
" 5 | \n",
" 0 | \n",
" 3 | \n",
" Allen, Mr. William Henry | \n",
" male | \n",
" 35 | \n",
" 0 | \n",
" 0 | \n",
" 373450 | \n",
" 8.0500 | \n",
" NaN | \n",
" S | \n",
"
\n",
" \n",
"
\n",
"
"
],
"text/plain": [
" PassengerId Survived Pclass \\\n",
"0 1 0 3 \n",
"1 2 1 1 \n",
"2 3 1 3 \n",
"3 4 1 1 \n",
"4 5 0 3 \n",
"\n",
" Name Sex Age SibSp \\\n",
"0 Braund, Mr. Owen Harris male 22 1 \n",
"1 Cumings, Mrs. John Bradley (Florence Briggs Th... female 38 1 \n",
"2 Heikkinen, Miss. Laina female 26 0 \n",
"3 Futrelle, Mrs. Jacques Heath (Lily May Peel) female 35 1 \n",
"4 Allen, Mr. William Henry male 35 0 \n",
"\n",
" Parch Ticket Fare Cabin Embarked \n",
"0 0 A/5 21171 7.2500 NaN S \n",
"1 0 PC 17599 71.2833 C85 C \n",
"2 0 STON/O2. 3101282 7.9250 NaN S \n",
"3 0 113803 53.1000 C123 S \n",
"4 0 373450 8.0500 NaN S "
]
},
"execution_count": 27,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"import pandas\n",
"data = pandas.read_csv(\"data/titanic.csv\")\n",
"data[:5]"
]
},
{
"cell_type": "code",
"execution_count": 30,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"# We make a 80/20% train/test split of the data\n",
"data_train = data[:int(0.8*len(data))]\n",
"data_test = data[int(0.8*len(data)):]"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Preparing the data"
]
},
{
"cell_type": "code",
"execution_count": 46,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"# The categorical-to-numerical function from chapter 2\n",
"# Changed to automatically add column names\n",
"def cat_to_num(data):\n",
" categories = unique(data)\n",
" features = {}\n",
" for cat in categories:\n",
" binary = (data == cat)\n",
" features[\"%s=%s\" % (data.name, cat)] = binary.astype(\"int\")\n",
" return pandas.DataFrame(features)"
]
},
{
"cell_type": "code",
"execution_count": 57,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"def prepare_data(data):\n",
" \"\"\"Takes a dataframe of raw data and returns ML model features\n",
" \"\"\"\n",
" \n",
" # Initially, we build a model only on the available numerical values\n",
" features = data.drop([\"PassengerId\", \"Survived\", \"Fare\", \"Name\", \"Sex\", \"Ticket\", \"Cabin\", \"Embarked\"], axis=1)\n",
" \n",
" # Setting missing age values to -1\n",
" features[\"Age\"] = data[\"Age\"].fillna(-1)\n",
" \n",
" # Adding the sqrt of the fare feature\n",
" features[\"sqrt_Fare\"] = sqrt(data[\"Fare\"])\n",
" \n",
" # Adding gender categorical value\n",
" features = features.join( cat_to_num(data['Sex']) )\n",
" \n",
" # Adding Embarked categorical value\n",
" features = features.join( cat_to_num(data['Embarked']) )\n",
" \n",
" return features"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Building a logistic regression classifier with Scikit-Learn"
]
},
{
"cell_type": "code",
"execution_count": 58,
"metadata": {
"collapsed": false
},
"outputs": [
{
"data": {
"text/html": [
"\n",
"
\n",
" \n",
" \n",
" | \n",
" Pclass | \n",
" Age | \n",
" SibSp | \n",
" Parch | \n",
" sqrt_Fare | \n",
" Sex=female | \n",
" Sex=male | \n",
" Embarked=C | \n",
" Embarked=Q | \n",
" Embarked=S | \n",
" Embarked=nan | \n",
"
\n",
" \n",
" \n",
" \n",
" 0 | \n",
" 3 | \n",
" 22 | \n",
" 1 | \n",
" 0 | \n",
" 2.692582 | \n",
" 0 | \n",
" 1 | \n",
" 0 | \n",
" 0 | \n",
" 1 | \n",
" 0 | \n",
"
\n",
" \n",
" 1 | \n",
" 1 | \n",
" 38 | \n",
" 1 | \n",
" 0 | \n",
" 8.442944 | \n",
" 1 | \n",
" 0 | \n",
" 1 | \n",
" 0 | \n",
" 0 | \n",
" 0 | \n",
"
\n",
" \n",
" 2 | \n",
" 3 | \n",
" 26 | \n",
" 0 | \n",
" 0 | \n",
" 2.815138 | \n",
" 1 | \n",
" 0 | \n",
" 0 | \n",
" 0 | \n",
" 1 | \n",
" 0 | \n",
"
\n",
" \n",
" 3 | \n",
" 1 | \n",
" 35 | \n",
" 1 | \n",
" 0 | \n",
" 7.286975 | \n",
" 1 | \n",
" 0 | \n",
" 0 | \n",
" 0 | \n",
" 1 | \n",
" 0 | \n",
"
\n",
" \n",
" 4 | \n",
" 3 | \n",
" 35 | \n",
" 0 | \n",
" 0 | \n",
" 2.837252 | \n",
" 0 | \n",
" 1 | \n",
" 0 | \n",
" 0 | \n",
" 1 | \n",
" 0 | \n",
"
\n",
" \n",
"
\n",
"
"
],
"text/plain": [
" Pclass Age SibSp Parch sqrt_Fare Sex=female Sex=male Embarked=C \\\n",
"0 3 22 1 0 2.692582 0 1 0 \n",
"1 1 38 1 0 8.442944 1 0 1 \n",
"2 3 26 0 0 2.815138 1 0 0 \n",
"3 1 35 1 0 7.286975 1 0 0 \n",
"4 3 35 0 0 2.837252 0 1 0 \n",
"\n",
" Embarked=Q Embarked=S Embarked=nan \n",
"0 0 1 0 \n",
"1 0 0 0 \n",
"2 0 1 0 \n",
"3 0 1 0 \n",
"4 0 1 0 "
]
},
"execution_count": 58,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"#cat_to_num(data['Sex'])\n",
"features = prepare_data(data_train)\n",
"features[:5]"
]
},
{
"cell_type": "code",
"execution_count": 59,
"metadata": {
"collapsed": false
},
"outputs": [
{
"data": {
"text/plain": [
"LogisticRegression(C=1.0, class_weight=None, dual=False, fit_intercept=True,\n",
" intercept_scaling=1, max_iter=100, multi_class='ovr',\n",
" penalty='l2', random_state=None, solver='liblinear', tol=0.0001,\n",
" verbose=0)"
]
},
"execution_count": 59,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"from sklearn.linear_model import LogisticRegression\n",
"model = LogisticRegression()\n",
"model.fit(features, data_train[\"Survived\"])"
]
},
{
"cell_type": "code",
"execution_count": 60,
"metadata": {
"collapsed": false
},
"outputs": [
{
"data": {
"text/plain": [
"array([0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0,\n",
" 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0,\n",
" 0, 1, 0, 0, 0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0, 1, 1,\n",
" 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 0, 1, 0, 1, 0, 0,\n",
" 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0,\n",
" 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1,\n",
" 0, 0, 1, 1, 1, 1, 1, 0, 1, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0,\n",
" 0, 1, 1, 0, 0, 0, 1, 1, 0, 1, 0, 0, 0, 0, 1, 1, 0, 0])"
]
},
"execution_count": 60,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# Make predictions\n",
"model.predict(prepare_data(data_test))"
]
},
{
"cell_type": "code",
"execution_count": 64,
"metadata": {
"collapsed": false
},
"outputs": [
{
"data": {
"text/plain": [
"0.86033519553072624"
]
},
"execution_count": 64,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# The accuracy of the model on the test data\n",
"# (this will be introduced in more details in chapter 4)\n",
"model.score(prepare_data(data_test), data_test[\"Survived\"])"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Non-linear model with Support Vector Machines"
]
},
{
"cell_type": "code",
"execution_count": 62,
"metadata": {
"collapsed": false
},
"outputs": [
{
"data": {
"text/plain": [
"SVC(C=1.0, cache_size=200, class_weight=None, coef0=0.0, degree=3, gamma=0.0,\n",
" kernel='rbf', max_iter=-1, probability=False, random_state=None,\n",
" shrinking=True, tol=0.001, verbose=False)"
]
},
"execution_count": 62,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"from sklearn.svm import SVC\n",
"model = SVC()\n",
"model.fit(features, data_train[\"Survived\"])"
]
},
{
"cell_type": "code",
"execution_count": 63,
"metadata": {
"collapsed": false
},
"outputs": [
{
"data": {
"text/plain": [
"0.86033519553072624"
]
},
"execution_count": 63,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"model.score(prepare_data(data_test), data_test[\"Survived\"])"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Classification with multiple classes: hand-written digits\n",
"\n",
"We use the popular non-linear multi-class K-nearest neighbor algorithm to predict hand-written digits from the MNIST dataset.\n"
]
},
{
"cell_type": "code",
"execution_count": 65,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"mnist = pandas.read_csv(\"data/mnist_small.csv\")\n",
"mnist_train = mnist[:int(0.8*len(mnist))]\n",
"mnist_test = mnist[int(0.8*len(mnist)):]"
]
},
{
"cell_type": "code",
"execution_count": 66,
"metadata": {
"collapsed": false
},
"outputs": [
{
"data": {
"text/plain": [
"KNeighborsClassifier(algorithm='auto', leaf_size=30, metric='minkowski',\n",
" metric_params=None, n_neighbors=10, p=2, weights='uniform')"
]
},
"execution_count": 66,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"from sklearn.neighbors import KNeighborsClassifier\n",
"knn = KNeighborsClassifier(n_neighbors=10)\n",
"knn.fit(mnist_train.drop(\"label\", axis=1), mnist_train['label'])"
]
},
{
"cell_type": "code",
"execution_count": 71,
"metadata": {
"collapsed": false
},
"outputs": [
{
"data": {
"text/html": [
"\n",
"
\n",
" \n",
" \n",
" | \n",
" 0 | \n",
" 1 | \n",
" 2 | \n",
" 3 | \n",
" 4 | \n",
" 5 | \n",
" 6 | \n",
" 7 | \n",
" 8 | \n",
" 9 | \n",
"
\n",
" \n",
" \n",
" \n",
" Digit 1 | \n",
" 0.0 | \n",
" 0 | \n",
" 0 | \n",
" 0.0 | \n",
" 0.0 | \n",
" 1 | \n",
" 0.0 | \n",
" 0.0 | \n",
" 0.0 | \n",
" 0.0 | \n",
"
\n",
" \n",
" Digit 2 | \n",
" 0.0 | \n",
" 0 | \n",
" 0 | \n",
" 1.0 | \n",
" 0.0 | \n",
" 0 | \n",
" 0.0 | \n",
" 0.0 | \n",
" 0.0 | \n",
" 0.0 | \n",
"
\n",
" \n",
" Digit 3 | \n",
" 0.3 | \n",
" 0 | \n",
" 0 | \n",
" 0.0 | \n",
" 0.0 | \n",
" 0 | \n",
" 0.6 | \n",
" 0.0 | \n",
" 0.1 | \n",
" 0.0 | \n",
"
\n",
" \n",
" Digit 4 | \n",
" 0.0 | \n",
" 0 | \n",
" 0 | \n",
" 0.1 | \n",
" 0.0 | \n",
" 0 | \n",
" 0.0 | \n",
" 0.5 | \n",
" 0.0 | \n",
" 0.4 | \n",
"
\n",
" \n",
" Digit 5 | \n",
" 0.0 | \n",
" 0 | \n",
" 0 | \n",
" 0.0 | \n",
" 0.7 | \n",
" 0 | \n",
" 0.0 | \n",
" 0.0 | \n",
" 0.0 | \n",
" 0.3 | \n",
"
\n",
" \n",
"
\n",
"
"
],
"text/plain": [
" 0 1 2 3 4 5 6 7 8 9\n",
"Digit 1 0.0 0 0 0.0 0.0 1 0.0 0.0 0.0 0.0\n",
"Digit 2 0.0 0 0 1.0 0.0 0 0.0 0.0 0.0 0.0\n",
"Digit 3 0.3 0 0 0.0 0.0 0 0.6 0.0 0.1 0.0\n",
"Digit 4 0.0 0 0 0.1 0.0 0 0.0 0.5 0.0 0.4\n",
"Digit 5 0.0 0 0 0.0 0.7 0 0.0 0.0 0.0 0.3"
]
},
"execution_count": 71,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"preds = knn.predict_proba(mnist_test.drop(\"label\", axis=1))\n",
"pandas.DataFrame(preds[:5], index=[\"Digit %d\"%(i+1) for i in range(5)])"
]
},
{
"cell_type": "code",
"execution_count": 73,
"metadata": {
"collapsed": false
},
"outputs": [
{
"data": {
"text/plain": [
"0.81999999999999995"
]
},
"execution_count": 73,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"knn.score(mnist_test.drop(\"label\", axis=1), mnist_test['label'])"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Predicting numerical values with a regression model\n",
"\n",
"We use the the Linear Regression algorithm to predict miles-per-gallon of various automobiles."
]
},
{
"cell_type": "code",
"execution_count": 79,
"metadata": {
"collapsed": false
},
"outputs": [
{
"data": {
"text/html": [
"\n",
"
\n",
" \n",
" \n",
" | \n",
" mpg | \n",
" cylinders | \n",
" displacement | \n",
" horsepower | \n",
" weight | \n",
" acceleration | \n",
" modelyear | \n",
" origin=1 | \n",
" origin=2 | \n",
" origin=3 | \n",
"
\n",
" \n",
" \n",
" \n",
" 0 | \n",
" 18 | \n",
" 8 | \n",
" 307 | \n",
" 130 | \n",
" 3504 | \n",
" 12.0 | \n",
" 70 | \n",
" 1 | \n",
" 0 | \n",
" 0 | \n",
"
\n",
" \n",
" 1 | \n",
" 15 | \n",
" 8 | \n",
" 350 | \n",
" 165 | \n",
" 3693 | \n",
" 11.5 | \n",
" 70 | \n",
" 1 | \n",
" 0 | \n",
" 0 | \n",
"
\n",
" \n",
" 2 | \n",
" 18 | \n",
" 8 | \n",
" 318 | \n",
" 150 | \n",
" 3436 | \n",
" 11.0 | \n",
" 70 | \n",
" 1 | \n",
" 0 | \n",
" 0 | \n",
"
\n",
" \n",
" 3 | \n",
" 16 | \n",
" 8 | \n",
" 304 | \n",
" 150 | \n",
" 3433 | \n",
" 12.0 | \n",
" 70 | \n",
" 1 | \n",
" 0 | \n",
" 0 | \n",
"
\n",
" \n",
" 4 | \n",
" 17 | \n",
" 8 | \n",
" 302 | \n",
" 140 | \n",
" 3449 | \n",
" 10.5 | \n",
" 70 | \n",
" 1 | \n",
" 0 | \n",
" 0 | \n",
"
\n",
" \n",
"
\n",
"
"
],
"text/plain": [
" mpg cylinders displacement horsepower weight acceleration modelyear \\\n",
"0 18 8 307 130 3504 12.0 70 \n",
"1 15 8 350 165 3693 11.5 70 \n",
"2 18 8 318 150 3436 11.0 70 \n",
"3 16 8 304 150 3433 12.0 70 \n",
"4 17 8 302 140 3449 10.5 70 \n",
"\n",
" origin=1 origin=2 origin=3 \n",
"0 1 0 0 \n",
"1 1 0 0 \n",
"2 1 0 0 \n",
"3 1 0 0 \n",
"4 1 0 0 "
]
},
"execution_count": 79,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"auto = pandas.read_csv(\"data/auto-mpg.csv\")\n",
"\n",
"# Convert origin to categorical variable\n",
"auto = auto.join(cat_to_num(auto['origin']))\n",
"auto = auto.drop('origin', axis=1)\n",
"\n",
"# Split in train/test set\n",
"auto_train = auto[:int(0.8*len(auto))]\n",
"auto_test = auto[int(0.8*len(auto)):]\n",
"\n",
"auto[:5]"
]
},
{
"cell_type": "code",
"execution_count": 80,
"metadata": {
"collapsed": false
},
"outputs": [
{
"data": {
"text/plain": [
"LinearRegression(copy_X=True, fit_intercept=True, n_jobs=1, normalize=False)"
]
},
"execution_count": 80,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"from sklearn.linear_model import LinearRegression\n",
"reg = LinearRegression()\n",
"reg.fit(auto_train.drop('mpg', axis=1), auto_train[\"mpg\"])"
]
},
{
"cell_type": "code",
"execution_count": 83,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"pred_mpg = reg.predict(auto_test.drop('mpg',axis=1))"
]
},
{
"cell_type": "code",
"execution_count": 89,
"metadata": {
"collapsed": false
},
"outputs": [
{
"data": {
"image/png": "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\nAAAAAElFTkSuQmCC\n",
"text/plain": [
""
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"plot(auto_test.mpg, pred_mpg, 'o')\n",
"x = linspace(10,40,5)\n",
"plot(x, x, '-');"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 2",
"language": "python",
"name": "python2"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 2
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython2",
"version": "2.7.10"
}
},
"nbformat": 4,
"nbformat_minor": 0
}