{
"metadata": {
"celltoolbar": "Slideshow",
"name": "",
"signature": "sha256:e1f952a8600390364b6b97ee76ae75210e3615993b9f2ac1e6e271b023c664dd"
},
"nbformat": 3,
"nbformat_minor": 0,
"worksheets": [
{
"cells": [
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"# Me: Chris Hausler\n",
"# Today - Pandas and Scikit-Learn\n",
"\n",
"## And a lot of firsts\n",
" + first MPUG meeting... Hi \n",
" + first presentation using IPython Notebook"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"## Python Data Analysis Library (pandas)\n",
"\n",
"pandas is an open source, BSD-licensed library providing high-performance, easy-to-use data structures and data analysis tools for the Python programming language.
\n",
"Creates somthing similar to R DataFrames.. but better\n",
"\n",
"### I think it's great, but I'm still a bit clumsy with it .. also the doco is still a little hit and miss\n"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"#### Some imports"
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"import warnings\n",
"warnings.filterwarnings(\"ignore\", category=DeprecationWarning)\n",
"warnings.filterwarnings(\"ignore\", category=UserWarning)"
],
"language": "python",
"metadata": {
"slideshow": {
"slide_type": "-"
}
},
"outputs": [],
"prompt_number": 1
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"import numpy as np\n",
"import pandas as pd\n",
"import pylab as plt\n",
"import matplotlib \n",
"%matplotlib inline\n",
"pd.__version__"
],
"language": "python",
"metadata": {
"slideshow": {
"slide_type": "-"
}
},
"outputs": [
{
"metadata": {},
"output_type": "pyout",
"prompt_number": 2,
"text": [
"'0.13.1'"
]
}
],
"prompt_number": 2
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"### pandas has two main data structures: Series and DataFrame"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"## Series - Like a one dimensional array but better"
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"values = [5,3,4,8,2,9]\n",
"vals = pd.Series(values)\n",
"vals"
],
"language": "python",
"metadata": {},
"outputs": [
{
"metadata": {},
"output_type": "pyout",
"prompt_number": 3,
"text": [
"0 5\n",
"1 3\n",
"2 4\n",
"3 8\n",
"4 2\n",
"5 9\n",
"dtype: int64"
]
}
],
"prompt_number": 3
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Each value is now associated with an _index_. The index itself is an object of class Index and can be manipulated directly."
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"vals.index"
],
"language": "python",
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"outputs": [
{
"metadata": {},
"output_type": "pyout",
"prompt_number": 4,
"text": [
"Int64Index([0, 1, 2, 3, 4, 5], dtype='int64')"
]
}
],
"prompt_number": 4
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"vals.values"
],
"language": "python",
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"outputs": [
{
"metadata": {},
"output_type": "pyout",
"prompt_number": 5,
"text": [
"array([5, 3, 4, 8, 2, 9])"
]
}
],
"prompt_number": 5
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"vals * 2.5"
],
"language": "python",
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"outputs": [
{
"metadata": {},
"output_type": "pyout",
"prompt_number": 6,
"text": [
"0 12.5\n",
"1 7.5\n",
"2 10.0\n",
"3 20.0\n",
"4 5.0\n",
"5 22.5\n",
"dtype: float64"
]
}
],
"prompt_number": 6
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"We can give named indexes"
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"vals2 = pd.Series(values, index=['tom','sally','jeff','george','pablo','florence'])\n",
"vals2"
],
"language": "python",
"metadata": {
"slideshow": {
"slide_type": "-"
}
},
"outputs": [
{
"metadata": {},
"output_type": "pyout",
"prompt_number": 7,
"text": [
"tom 5\n",
"sally 3\n",
"jeff 4\n",
"george 8\n",
"pablo 2\n",
"florence 9\n",
"dtype: int64"
]
}
],
"prompt_number": 7
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"source": [
"\n",
"And use these to get the data we want"
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"vals2[['florence','tom']]"
],
"language": "python",
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"outputs": [
{
"metadata": {},
"output_type": "pyout",
"prompt_number": 8,
"text": [
"florence 9\n",
"tom 5\n",
"dtype: int64"
]
}
],
"prompt_number": 8
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"vals2[['florence','tom','kate']]"
],
"language": "python",
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"outputs": [
{
"metadata": {},
"output_type": "pyout",
"prompt_number": 9,
"text": [
"florence 9\n",
"tom 5\n",
"kate NaN\n",
"dtype: float64"
]
}
],
"prompt_number": 9
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"Dealing with missing values"
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"vals3 = vals2[['tom','sally','pablo','florence','ricky','katrin']]\n",
"vals3"
],
"language": "python",
"metadata": {
"slideshow": {
"slide_type": "-"
}
},
"outputs": [
{
"metadata": {},
"output_type": "pyout",
"prompt_number": 10,
"text": [
"tom 5\n",
"sally 3\n",
"pablo 2\n",
"florence 9\n",
"ricky NaN\n",
"katrin NaN\n",
"dtype: float64"
]
}
],
"prompt_number": 10
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"Get rid of them"
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"vals3.dropna()"
],
"language": "python",
"metadata": {
"slideshow": {
"slide_type": "-"
}
},
"outputs": [
{
"metadata": {},
"output_type": "pyout",
"prompt_number": 11,
"text": [
"tom 5\n",
"sally 3\n",
"pablo 2\n",
"florence 9\n",
"dtype: float64"
]
}
],
"prompt_number": 11
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"Fill them with a value"
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"\n",
"vals3.fillna(0)"
],
"language": "python",
"metadata": {
"slideshow": {
"slide_type": "-"
}
},
"outputs": [
{
"metadata": {},
"output_type": "pyout",
"prompt_number": 12,
"text": [
"tom 5\n",
"sally 3\n",
"pablo 2\n",
"florence 9\n",
"ricky 0\n",
"katrin 0\n",
"dtype: float64"
]
}
],
"prompt_number": 12
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"Fill them with a calculated value"
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"vals3.fillna(vals3.mean())"
],
"language": "python",
"metadata": {
"slideshow": {
"slide_type": "-"
}
},
"outputs": [
{
"metadata": {},
"output_type": "pyout",
"prompt_number": 13,
"text": [
"tom 5.00\n",
"sally 3.00\n",
"pablo 2.00\n",
"florence 9.00\n",
"ricky 4.75\n",
"katrin 4.75\n",
"dtype: float64"
]
}
],
"prompt_number": 13
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"Use a function like forward fill"
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"vals3.fillna(method='ffill')"
],
"language": "python",
"metadata": {
"slideshow": {
"slide_type": "-"
}
},
"outputs": [
{
"metadata": {},
"output_type": "pyout",
"prompt_number": 14,
"text": [
"tom 5\n",
"sally 3\n",
"pablo 2\n",
"florence 9\n",
"ricky 9\n",
"katrin 9\n",
"dtype: float64"
]
}
],
"prompt_number": 14
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"A handy way to get a picture of our data"
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"vals3.describe()"
],
"language": "python",
"metadata": {
"slideshow": {
"slide_type": "-"
}
},
"outputs": [
{
"metadata": {},
"output_type": "pyout",
"prompt_number": 15,
"text": [
"count 4.000000\n",
"mean 4.750000\n",
"std 3.095696\n",
"min 2.000000\n",
"25% 2.750000\n",
"50% 4.000000\n",
"75% 6.000000\n",
"max 9.000000\n",
"dtype: float64"
]
}
],
"prompt_number": 15
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"## DataFrame - Like a 2D array... with bells and whistles"
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"vals.index=pd.Index(['tom','sally','pablo','florence','ricky','katrin'])\n",
"vals3=vals3[['tom','sally','pablo','florence','billy','katrin']]"
],
"language": "python",
"metadata": {},
"outputs": [],
"prompt_number": 16
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"# create a dataframe\n",
"dat = pd.DataFrame({'orig':vals,'new':vals3})\n",
"dat"
],
"language": "python",
"metadata": {},
"outputs": [
{
"html": [
"
| \n", " | new | \n", "orig | \n", "
|---|---|---|
| billy | \n", "NaN | \n", "NaN | \n", "
| florence | \n", "9 | \n", "8 | \n", "
| katrin | \n", "NaN | \n", "9 | \n", "
| pablo | \n", "2 | \n", "4 | \n", "
| ricky | \n", "NaN | \n", "2 | \n", "
| sally | \n", "3 | \n", "3 | \n", "
| tom | \n", "5 | \n", "5 | \n", "
7 rows \u00d7 2 columns
\n", "| \n", " | new | \n", "orig | \n", "
|---|---|---|
| billy | \n", "True | \n", "True | \n", "
| florence | \n", "False | \n", "False | \n", "
| katrin | \n", "True | \n", "False | \n", "
| pablo | \n", "False | \n", "False | \n", "
| ricky | \n", "True | \n", "False | \n", "
| sally | \n", "False | \n", "False | \n", "
| tom | \n", "False | \n", "False | \n", "
7 rows \u00d7 2 columns
\n", "| \n", " | new | \n", "orig | \n", "
|---|---|---|
| florence | \n", "9 | \n", "8 | \n", "
| pablo | \n", "2 | \n", "4 | \n", "
| sally | \n", "3 | \n", "3 | \n", "
| tom | \n", "5 | \n", "5 | \n", "
4 rows \u00d7 2 columns
\n", "| \n", " | Date | \n", "hipster | \n", "modcloth | \n", "gumtree perth | \n", "
|---|---|---|---|---|
| 0 | \n", "2004-01-04 | \n", "-0.976 | \n", "-0.817 | \n", "-0.844 | \n", "
| 1 | \n", "2004-01-11 | \n", "-0.816 | \n", "-0.817 | \n", "-0.844 | \n", "
| 2 | \n", "2004-01-18 | \n", "-0.837 | \n", "-0.817 | \n", "-0.844 | \n", "
| 3 | \n", "2004-01-25 | \n", "-0.976 | \n", "-0.817 | \n", "-0.844 | \n", "
| 4 | \n", "2004-02-01 | \n", "-0.722 | \n", "-0.817 | \n", "-0.844 | \n", "
| 5 | \n", "2004-02-08 | \n", "-0.795 | \n", "-0.817 | \n", "-0.844 | \n", "
| 6 | \n", "2004-02-15 | \n", "-0.723 | \n", "-0.817 | \n", "-0.844 | \n", "
| 7 | \n", "2004-02-22 | \n", "-0.713 | \n", "-0.817 | \n", "-0.844 | \n", "
| 8 | \n", "2004-02-29 | \n", "-0.786 | \n", "-0.817 | \n", "-0.844 | \n", "
| 9 | \n", "2004-03-07 | \n", "-0.675 | \n", "-0.817 | \n", "-0.844 | \n", "
10 rows \u00d7 4 columns
\n", "| \n", " | hipster | \n", "modcloth | \n", "gumtree perth | \n", "
|---|---|---|---|
| 2004-01-04 | \n", "-0.976 | \n", "-0.817 | \n", "-0.844 | \n", "
| 2004-01-11 | \n", "-0.816 | \n", "-0.817 | \n", "-0.844 | \n", "
| 2004-01-18 | \n", "-0.837 | \n", "-0.817 | \n", "-0.844 | \n", "
| 2004-01-25 | \n", "-0.976 | \n", "-0.817 | \n", "-0.844 | \n", "
| 2004-02-01 | \n", "-0.722 | \n", "-0.817 | \n", "-0.844 | \n", "
| 2004-02-08 | \n", "-0.795 | \n", "-0.817 | \n", "-0.844 | \n", "
| 2004-02-15 | \n", "-0.723 | \n", "-0.817 | \n", "-0.844 | \n", "
| 2004-02-22 | \n", "-0.713 | \n", "-0.817 | \n", "-0.844 | \n", "
| 2004-02-29 | \n", "-0.786 | \n", "-0.817 | \n", "-0.844 | \n", "
| 2004-03-07 | \n", "-0.675 | \n", "-0.817 | \n", "-0.844 | \n", "
10 rows \u00d7 3 columns
\n", "| \n", " | yellow pages | \n", "windows installer | \n", "techno | \n", "
|---|---|---|---|
| 2004-01-04 | \n", "1.341 | \n", "0.668 | \n", "0.871 | \n", "
| 2004-01-11 | \n", "1.239 | \n", "1.000 | \n", "1.122 | \n", "
| 2004-01-18 | \n", "1.022 | \n", "0.768 | \n", "1.053 | \n", "
| 2004-01-25 | \n", "0.923 | \n", "0.943 | \n", "0.807 | \n", "
| 2004-02-01 | \n", "0.904 | \n", "0.799 | \n", "0.612 | \n", "
| 2004-02-08 | \n", "0.786 | \n", "0.613 | \n", "0.614 | \n", "
| 2004-02-15 | \n", "0.729 | \n", "0.956 | \n", "0.391 | \n", "
| 2004-02-22 | \n", "0.537 | \n", "0.667 | \n", "1.124 | \n", "
| 2004-02-29 | \n", "0.534 | \n", "1.415 | \n", "1.078 | \n", "
| 2004-03-07 | \n", "0.229 | \n", "0.220 | \n", "1.918 | \n", "
10 rows \u00d7 3 columns
\n", "numpy.ndarray"
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"hipster['gumtree perth'].values[:20]"
],
"language": "python",
"metadata": {
"slideshow": {
"slide_type": "-"
}
},
"outputs": [
{
"metadata": {},
"output_type": "pyout",
"prompt_number": 25,
"text": [
"array([-0.844, -0.844, -0.844, -0.844, -0.844, -0.844, -0.844, -0.844,\n",
" -0.844, -0.844, -0.844, -0.844, -0.844, -0.844, -0.844, -0.844,\n",
" -0.844, -0.844, -0.844, -0.844])"
]
}
],
"prompt_number": 25
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"View the data types, they don't need to be homogenous"
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"hipster.dtypes"
],
"language": "python",
"metadata": {},
"outputs": [
{
"metadata": {},
"output_type": "pyout",
"prompt_number": 26,
"text": [
"hipster float64\n",
"modcloth float64\n",
"gumtree perth float64\n",
"dtype: object"
]
}
],
"prompt_number": 26
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"Joins on indexes are easy!"
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"trend = hipster.join(not_hipster, how='inner')\n",
"trend.head()"
],
"language": "python",
"metadata": {},
"outputs": [
{
"html": [
"| \n", " | hipster | \n", "modcloth | \n", "gumtree perth | \n", "yellow pages | \n", "windows installer | \n", "techno | \n", "
|---|---|---|---|---|---|---|
| 2004-01-04 | \n", "-0.976 | \n", "-0.817 | \n", "-0.844 | \n", "1.341 | \n", "0.668 | \n", "0.871 | \n", "
| 2004-01-11 | \n", "-0.816 | \n", "-0.817 | \n", "-0.844 | \n", "1.239 | \n", "1.000 | \n", "1.122 | \n", "
| 2004-01-18 | \n", "-0.837 | \n", "-0.817 | \n", "-0.844 | \n", "1.022 | \n", "0.768 | \n", "1.053 | \n", "
| 2004-01-25 | \n", "-0.976 | \n", "-0.817 | \n", "-0.844 | \n", "0.923 | \n", "0.943 | \n", "0.807 | \n", "
| 2004-02-01 | \n", "-0.722 | \n", "-0.817 | \n", "-0.844 | \n", "0.904 | \n", "0.799 | \n", "0.612 | \n", "
5 rows \u00d7 6 columns
\n", "| \n", " | hipster | \n", "modcloth | \n", "gumtree perth | \n", "yellow pages | \n", "windows installer | \n", "techno | \n", "
|---|---|---|---|---|---|---|
| 2012-01-01 | \n", "1.411 | \n", "1.192 | \n", "1.774 | \n", "-1.077 | \n", "-1.134 | \n", "-1.285 | \n", "
| 2012-01-08 | \n", "1.513 | \n", "1.111 | \n", "1.579 | \n", "-0.995 | \n", "-1.183 | \n", "-1.189 | \n", "
| 2012-01-15 | \n", "1.523 | \n", "1.427 | \n", "1.613 | \n", "-1.027 | \n", "-1.161 | \n", "-1.337 | \n", "
| 2012-01-22 | \n", "1.600 | \n", "1.490 | \n", "1.514 | \n", "-1.140 | \n", "-1.177 | \n", "-1.345 | \n", "
| 2012-01-29 | \n", "1.459 | \n", "1.561 | \n", "1.511 | \n", "-1.046 | \n", "-1.224 | \n", "-1.233 | \n", "
5 rows \u00d7 6 columns
\n", "| \n", " | hipster | \n", "modcloth | \n", "gumtree perth | \n", "yellow pages | \n", "windows installer | \n", "techno | \n", "
|---|---|---|---|---|---|---|
| 2012-12-16 | \n", "1.645 | \n", "1.175 | \n", "1.407 | \n", "-1.433 | \n", "-1.515 | \n", "-1.687 | \n", "
| 2012-12-23 | \n", "1.591 | \n", "1.695 | \n", "1.625 | \n", "-1.698 | \n", "-1.655 | \n", "-1.504 | \n", "
| 2012-12-30 | \n", "1.596 | \n", "1.515 | \n", "1.868 | \n", "-1.515 | \n", "-1.598 | \n", "-1.674 | \n", "
3 rows \u00d7 6 columns
\n", "| \n", " | hipster | \n", "modcloth | \n", "gumtree perth | \n", "yellow pages | \n", "windows installer | \n", "techno | \n", "
|---|---|---|---|---|---|---|
| 2004-04-11 | \n", "-0.510 | \n", "-0.817 | \n", "-0.844 | \n", "0.521 | \n", "0.301 | \n", "-0.270 | \n", "
| 2006-01-29 | \n", "-0.838 | \n", "-0.817 | \n", "-0.844 | \n", "1.421 | \n", "1.309 | \n", "-0.081 | \n", "
| 2006-06-25 | \n", "-0.799 | \n", "-0.817 | \n", "-0.833 | \n", "1.142 | \n", "1.458 | \n", "-0.070 | \n", "
| 2010-01-24 | \n", "-0.454 | \n", "-0.183 | \n", "-0.107 | \n", "-0.017 | \n", "0.053 | \n", "-0.010 | \n", "
| 2010-01-31 | \n", "-0.381 | \n", "-0.276 | \n", "-0.142 | \n", "0.187 | \n", "0.116 | \n", "-0.044 | \n", "
5 rows \u00d7 6 columns
\n", "| \n", " | hipster | \n", "modcloth | \n", "gumtree perth | \n", "yellow pages | \n", "windows installer | \n", "techno | \n", "
|---|---|---|---|---|---|---|
| 2004-01-31 | \n", "-0.90125 | \n", "-0.817 | \n", "-0.844 | \n", "1.13125 | \n", "0.84475 | \n", "0.96325 | \n", "
| 2004-02-29 | \n", "-0.74780 | \n", "-0.817 | \n", "-0.844 | \n", "0.69800 | \n", "0.89000 | \n", "0.76380 | \n", "
| 2004-03-31 | \n", "-0.78950 | \n", "-0.817 | \n", "-0.844 | \n", "0.35650 | \n", "0.73125 | \n", "1.09175 | \n", "
| 2004-04-30 | \n", "-0.70400 | \n", "-0.817 | \n", "-0.844 | \n", "0.48125 | \n", "0.89125 | \n", "0.41950 | \n", "
| 2004-05-31 | \n", "-0.81820 | \n", "-0.817 | \n", "-0.844 | \n", "0.34780 | \n", "0.62040 | \n", "0.72860 | \n", "
5 rows \u00d7 6 columns
\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", "
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 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", "
| 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", "
| 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", "
| 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", "
| 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", "
5 rows \u00d7 12 columns
\n", "| \n", " | \n", " | Age | \n", "Survived | \n", "
|---|---|---|---|
| Pclass | \n", "Sex | \n", "\n", " | \n", " |
| 1 | \n", "female | \n", "34.611765 | \n", "0.968085 | \n", "
| male | \n", "41.281386 | \n", "0.368852 | \n", "|
| 2 | \n", "female | \n", "28.722973 | \n", "0.921053 | \n", "
| male | \n", "30.740707 | \n", "0.157407 | \n", "|
| 3 | \n", "female | \n", "21.750000 | \n", "0.500000 | \n", "
| male | \n", "26.507589 | \n", "0.135447 | \n", "
6 rows \u00d7 2 columns
\n", "| \n", " | Sex | \n", "isFemale | \n", "
|---|---|---|
| 0 | \n", "male | \n", "0 | \n", "
| 1 | \n", "female | \n", "1 | \n", "
| 2 | \n", "female | \n", "1 | \n", "
| 3 | \n", "female | \n", "1 | \n", "
| 4 | \n", "male | \n", "0 | \n", "
5 rows \u00d7 2 columns
\n", "
"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"Prediction with scikit-learn is easy - who will survive?"
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"from sklearn.linear_model import LogisticRegression\n",
"from sklearn.metrics import accuracy_score as acc"
],
"language": "python",
"metadata": {},
"outputs": [],
"prompt_number": 54
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"# create our classifier\n",
"clf = LogisticRegression()\n",
"# fit it to the data\n",
"clf.fit(X, y)\n",
"# and predict\n",
"preds = clf.predict(X)\n",
"res_acc = acc(y, preds)\n",
"print 'Accuracy Score: {:.2f}'.format(res_acc)\n",
"print 'Not too bad'"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "stream",
"stream": "stdout",
"text": [
"Accuracy Score: 0.80\n",
"Not too bad\n"
]
}
],
"prompt_number": 55
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"##Cross-validation is a fairer performance estimate\n",
"
"
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"from sklearn.cross_validation import KFold"
],
"language": "python",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"outputs": [],
"prompt_number": 56
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"cv = KFold(n=len(y), n_folds=5, shuffle=True)\n",
"preds = np.zeros_like(y)\n",
"for train, test in cv:\n",
" clf = LogisticRegression()\n",
" clf.fit(X.ix[train], y.ix[train])\n",
" preds[test] = clf.predict(X.ix[test])\n",
"res_acc = acc(y, preds)\n",
"print 'Accuracy Score: {:.2f}'.format(res_acc)\n"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "stream",
"stream": "stdout",
"text": [
"Accuracy Score: 0.79\n"
]
}
],
"prompt_number": 57
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"And cross-validation can be done more easily"
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"# scikits can actually take care of this for us\n",
"from sklearn.cross_validation import cross_val_score\n",
"\n",
"# here\n",
"clf = LogisticRegression()\n",
"scores = cross_val_score(clf, X, y, cv=5, scoring='accuracy')\n",
"# to here\n",
"\n",
"print scores\n",
"print(\"Accuracy: %0.2f (+/- %0.2f)\" % (scores.mean(), scores.std() * 2))"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "stream",
"stream": "stdout",
"text": [
"[ 0.81564246 0.76966292 0.75842697 0.83707865 0.78651685]\n",
"Accuracy: 0.79 (+/- 0.06)\n"
]
}
],
"prompt_number": 58
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"### dealing with categorical data"
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"df.Embarked.head()"
],
"language": "python",
"metadata": {},
"outputs": [
{
"metadata": {},
"output_type": "pyout",
"prompt_number": 59,
"text": [
"0 S\n",
"1 C\n",
"2 S\n",
"3 S\n",
"4 S\n",
"Name: Embarked, dtype: object"
]
}
],
"prompt_number": 59
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"set(df.Embarked.fillna('O'))"
],
"language": "python",
"metadata": {},
"outputs": [
{
"metadata": {},
"output_type": "pyout",
"prompt_number": 60,
"text": [
"{'C', 'O', 'Q', 'S'}"
]
}
],
"prompt_number": 60
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"Use the LabelEncoder"
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"from sklearn import preprocessing\n",
"df.Embarked = df.Embarked.fillna('O')\n",
"le = preprocessing.LabelEncoder()\n",
"le.fit(df.Embarked.values)\n",
"le.classes_\n"
],
"language": "python",
"metadata": {
"slideshow": {
"slide_type": "-"
}
},
"outputs": [
{
"metadata": {},
"output_type": "pyout",
"prompt_number": 61,
"text": [
"array(['C', 'O', 'Q', 'S'], dtype=object)"
]
}
],
"prompt_number": 61
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"X['Embarked'] = le.transform(df.Embarked.values)\n",
"X.Embarked.head()"
],
"language": "python",
"metadata": {},
"outputs": [
{
"metadata": {},
"output_type": "pyout",
"prompt_number": 62,
"text": [
"0 3\n",
"1 0\n",
"2 3\n",
"3 3\n",
"4 3\n",
"Name: Embarked, dtype: int64"
]
}
],
"prompt_number": 62
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"### tuning classifier parameters"
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"for C in [0.001, 0.01, 0.1, 1, 10, 100]:\n",
" clf = LogisticRegression(C=C, penalty='l1')\n",
" scores = cross_val_score(clf, X, y, cv=5, scoring='accuracy') \n",
" print(\"n_estimators: {:3.3f}\\tAccuracy: {:.2f} (+/- {:.2f})\"\n",
" .format(C, scores.mean(), scores.std() * 2))"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "stream",
"stream": "stdout",
"text": [
"n_estimators: 0.001\tAccuracy: 0.67 (+/- 0.03)\n",
"n_estimators: 0.010\tAccuracy: 0.67 (+/- 0.03)\n",
"n_estimators: 0.100\tAccuracy: 0.79 (+/- 0.05)\n",
"n_estimators: 1.000\tAccuracy: 0.80 (+/- 0.06)"
]
},
{
"output_type": "stream",
"stream": "stdout",
"text": [
"\n",
"n_estimators: 10.000\tAccuracy: 0.79 (+/- 0.04)\n",
"n_estimators: 100.000\tAccuracy: 0.79 (+/- 0.04)"
]
},
{
"output_type": "stream",
"stream": "stdout",
"text": [
"\n"
]
}
],
"prompt_number": 63
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"### Comparing classifiers is easy"
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"# normalise the data\n",
"from sklearn.preprocessing import StandardScaler\n",
"X = StandardScaler().fit_transform(X)"
],
"language": "python",
"metadata": {},
"outputs": [],
"prompt_number": 64
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"from sklearn.linear_model import LogisticRegression\n",
"from sklearn.neighbors import KNeighborsClassifier\n",
"from sklearn.svm import SVC\n",
"from sklearn.tree import DecisionTreeClassifier\n",
"from sklearn.ensemble import RandomForestClassifier, AdaBoostClassifier\n",
"from sklearn.naive_bayes import GaussianNB\n",
"from sklearn.lda import LDA\n",
"from sklearn.qda import QDA\n",
"\n",
"names = [\"Nearest Neighbors\", \"Linear SVM\", \"RBF SVM\", \"Decision Tree\",\n",
" \"Random Forest\", \"AdaBoost\", \"Naive Bayes\", \"LDA\",\n",
" \"QDA\", \"Logistic Regression\"]\n",
"classifiers = [\n",
" KNeighborsClassifier(3),\n",
" SVC(kernel=\"linear\", C=0.025),\n",
" SVC(gamma=2, C=1),\n",
" DecisionTreeClassifier(),\n",
" RandomForestClassifier(),\n",
" AdaBoostClassifier(),\n",
" GaussianNB(),\n",
" LDA(),\n",
" QDA(),\n",
" LogisticRegression(class_weight='auto')]\n",
"\n"
],
"language": "python",
"metadata": {},
"outputs": [],
"prompt_number": 65
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"# fit each classifier and find the mean performance\n",
"res = []\n",
"for name, clf in zip(names, classifiers):\n",
" scores = cross_val_score(clf, X, y, cv=5, scoring='accuracy')\n",
" res.append(scores.mean())"
],
"language": "python",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"outputs": [],
"prompt_number": 66
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"import prettyplotlib as ppl\n",
"res = np.array(res)\n",
"names = np.array(names)\n",
"idx = np.argsort(res)[::-1]\n",
"fig, ax = plt.subplots(1, figsize=(14, 6))\n",
"ppl.bar(ax, np.arange(len(res)), res[idx], annotate=True,\n",
" xticklabels=names[idx], grid='y')\n",
"plt.xticks(rotation=30)\n",
"_ = ax.set_ylim(res.min() * 0.95, res.max() * 1.05)"
],
"language": "python",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"outputs": [
{
"metadata": {},
"output_type": "display_data",
"png": "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\nKSnZ5mdLSkq48MILufDCCwt4dJIkSUoTe2jUaMuXL6dHjx5069aN8vJyhgwZwsKFC+vs07VrV/7x\nj38A8N5779GlSxfKysoa/GxNTU2LHoskSZLSzYBGjbZu3Tr233//2u3KykrWrVtXZ5+RI0fyyiuv\n0L9/f4YPH86YMWN26LP33Xdf7f7vvPNOMx+JJEmS0s6ARo1WUlLS4D533HEHhx9+OEuWLGHOnDlM\nmDChtsdmW8455xwWLlzInDlz6Nq1K9/+9rebqsiSJElqowxo1GiVlZWsWbOmdnvt2rVUVlbW2ef5\n559n0KBBALUpZitXrmS//fbb5mf32WcfSkpKKCkp4ayzzuLFF19sgaORJElSmhnQqNF69+7NqlWr\nWL16NRs3buSxxx5j4MCBdfbp2bMnzz77LABvvPEGK1eupHv37tv97N///vfazy9YsIBDDz205Q5K\nkiRJqeQsZ2q0srIyxo4dS3V1NVu2bGHEiBFUVVUxY8YMAEaNGsXo0aMZM2YMw4cPp6amhquvvpou\nXboA1PtZgFtuuYWXXnqJkpISunXrxoQJEwp2jJIkSUqHhgdDNLNx48bVjB8/vtDFkCRJktSKlWxj\nILcpZ5IkSZJSy4BGaiGLFy9m0KBBnHLKKdx5551bvb9+/Xqqq6s57bTTGDp0KLNmzWrws/Pnz2fI\nkCEcccQR/OEPf2iR45AkSWpNDGikFrB582YmTpzIXXfdxbx585g3bx4rVqyos8/9999Pr169mDNn\nDvfccw+TJk1i06ZN2/3soYceyve//3369etXiMOSJEkqOAMaqQUsX768dvrq8vJyhgwZwsKFC+vs\n07Vr19q1et577z26dOlCWVnZdj9bVVXFIYcc0uLHI0mS1FoY0EgtYN26dey///6125WVlaxbt67O\nPiNHjuSVV16hf//+DB8+nDFjxuzwZyVJkoqVAY3UArYxKUcdd9xxB4cffjhLlixhzpw5TJgwobbH\nRpIkSfUzoJFaQGVlJWvWrKndXrt2LZWVlXX2ef755xk0aBBAbYrZypUr2W+//Rr8rCRJUrEyoJFa\nQO/evVm1ahWrV69m48aNPPbYYwwcOLDOPj179uTZZ58F4I033mDlypV07959hz4LUFNT0yLHIkmS\n1JqUFboAUjEoKytj7NixVFdXs2XLFkaMGEFVVRUzZswAYNSoUYwePZoxY8YwfPhwampquPrqq+nS\npQtAvZ8FePzxx/nmN7/JW2+9xejRozniiCO46667CnackiRJLa3hxP5mNm7cuJrx48cXuhiSJEmS\nWrGSbQxKNuVMkiRJUmqZciapVVq8eDE33nhjbZrdJZdcUuf9qVOn8sgjjwCxcOmKFStYunQpFRUV\nTJ8+nZkzZ1JTU8NZZ53FBRdcAMR6QBMmTGDTpk2UlpYybtw4+vbt2+LHJkmSmo49NJJanc2bNzNx\n4kTuuusu5s2bx7x581ixYkWdfaqrq5k9ezazZ8/myiuv5Nhjj6WiooKXX36ZmTNnMnPmTObMmcOT\nTz7Jq6++CsDkyZO57LLLmD17NpdeeimTJ08uxOFJkqQmZEAjqdVZvnx57dTV5eXlDBkyhIULF25z\n/0cffZQhQ4YAsGLFCvr27UuHDh0oLS3lmGOO4Ve/+hUAXbt25d133wXg3XffdfprSZLaAAMaSa3O\nunXr2H///Wu3KysrWbduXb37vv/++yxZsoRTTz0VgEMPPZRly5axYcMG3n//fZ566inWrl0LwFVX\nXcWkSZM48cQTufnmm7nqqqua/2AkSVKzcgyNpFZnG5OY1GvRokUcffTRVFRUAFBVVcXFF1/MRRdd\nRKdOnTjiiCMoLS0F4LrrruP666/n5JNPZv78+YwZM4Zp06Y1yzEUQnOMO7riiitYuXIlAO+88w4V\nFRXMnj27ZQ9MkqTtMKCR1OpUVlayZs2a2u21a9duMz1s3rx5DB06tM5rI0aMYMSIEQB85zvfqe3t\nWb58OXfffTcAgwYN4vrrr2+G0hdGMu5o2rRpVFZWMmLECAYOHFi7ZhHEuKPq6mogAsHp06dvNe6o\nrKyML33pS3zmM5+hR48e3HbbbbWfnzRpEp07d27xY5MkaXtMOZPU6vTu3ZtVq1axevVqNm7cyGOP\nPcbAgQO32u/dd99l2bJlW7335ptvAvD666/z+OOPM2zYMAAOOuggnnvuOQCWLl3KwQcf3LwH0oKa\na9xRoqamhvnz528VPEqSVGj20EhqdcrKyhg7dizV1dW16VNVVVXMmDEDgFGjRgGwYMEC+vfvT8eO\nHet8/tJLL2XDhg2UlZUxbtw49thjDwAmTJjAhAkT2LhxIx07dmTixIkte2DNqL5xR8uXL69332Tc\n0bhx44AYd/Td736XDRs20KFDB5566in69OlT5zPLli1jn332oUePHs13EC2sOVL0AO69914eeOAB\nSktLGTBgAFdffXWLHpckFRsDGkmt0oABAxgwYECd15JAJnHGGWdwxhlnbPXZ+++/v97f2adPHx56\n6KGmK2Qr0tTjjtq1q9uB/+ijj9b2dLUFzZWit3TpUp544gnmzp1LeXk569evL9QhSlLRMOVMktqA\nphh3NGvWLO677z4qKio45JBDat/btGkTCxYsYPDgwc1T+AJorhS9n/70p1xyySWUl5cDsPfeezf/\nwUhSkTOgkaQ2oLnGHQE888wz9OzZs02t29NcU4OvWrWKZcuWMXLkSM4//3xefPHF5j8YSSpyppxJ\nUhvQXOOOgDY5GUBzTQ2+efNm3n77bR588EGWL1/O5Zdfvt2eH0nSrjOgkaQ2ojnGHQHcdNNNTVPA\nVqS5pgavrKzklFNOAaBv3760a9eOt956i7322qs5DkOShClnkqQi1FwpeieddBJLly4FYOXKlXzw\nwQcGM5LUzHa0h2YQ8F2gFLgLmJT3/r7AfcB+md95C3A30B24B/gQUAPcCfznrhZakqRd0Vwpemee\neSZjxoxh2LBhlJeXM2lS/uNSktTUdiSJuBT4M3AS8BrwG+Ac4KWcfcYDHYBrieDmz0Bl5uf9gN8B\newD/DZye+9lx48bVjB8/fteOQpIkSVKbVrKNAZA7knJ2LPAK8FfgA2AGcFrePmuAiszPFcCbwCZg\nLRHMAPyDCGQOaES5JUmSJGmbdiTl7EDgbznbq4FP5O3zY+AJ4HWgMzCynt9zMPAx4NeNLqUkSZIk\n1WNHApqaHdhnDNETcyJQBTwOHAW8m3l/D2AmcBnRUyNJklJm8eLF3HjjjbXjji655JI670+dOpVH\nHnkEiCmsV6xYwdKlS6moqGD69OnMnDmTmpoazjrrLC644AIAJk2axJNPPkl5eTk9evTgpptuonPn\nzi1+bJLSa0dSzl4jBvcnuhO9NLmOAx7K/LwCWAkcltkuBx4mJg2YvdMllSRJBbN582YmTpzIXXfd\nxbx585g3bx4rVqyos091dTWzZ89m9uzZXHnllRx77LFUVFTw8ssvM3PmTGbOnMmcOXN48sknefXV\nVwHo378/8+bNY+7cuRx88MFMmTKlEIcnKcV2JKBZBnyESBlrD5wNzM3b50/EpAEQkwEcBvwPMenA\nVOCPxCxpkiQphZYvX06PHj3o1q0b5eXlDBkyZLuLhj766KMMGTIEgBUrVtC3b186dOhAaWkpxxxz\n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\nSZIkSZLUTX8CTR9knafcSGIAAAAASUVORK5CYII=\n",
"text": [
"
"
]
}
],
"metadata": {}
}
]
}