Skip to content

Instantly share code, notes, and snippets.

@jpotts18
Last active January 15, 2020 05:58
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save jpotts18/dac94dc9514172ce020c to your computer and use it in GitHub Desktop.
Save jpotts18/dac94dc9514172ce020c to your computer and use it in GitHub Desktop.
Linear Regression on Boston Housing Data
Display the source blob
Display the rendered blob
Raw
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Boston Housing Data\n",
"\n",
"In this exercise we will use linear regression to predict housing prices in Boston. The purpose of this exercise is to demonstrate basic use of sci-kit learn and understand some of the concepts behind machine learning. We will be taking the following steps from the [Cross Industry Standard Processing for Data Mining](https://en.wikipedia.org/wiki/Cross_Industry_Standard_Process_for_Data_Mining):\n",
"\n",
"1. Business Understanding\n",
"1. Data Understanding\n",
"1. Data Preparation\n",
"1. Modeling\n",
"1. Evaluation\n",
"1. Deployment\n",
"\n",
"![](https://upload.wikimedia.org/wikipedia/commons/thumb/b/b9/CRISP-DM_Process_Diagram.png/599px-CRISP-DM_Process_Diagram.png)\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 1. Business Understanding\n",
"\n",
"This initial phase focuses on understanding the project objectives and requirements from a business perspective, and then converting this knowledge into a data mining problem definition, and a preliminary plan designed to achieve the objectives. \n",
"\n",
"Creating a model is only valuable if someone needs it. Most things that can be predicted are valuable to someone. For example, lets say you were able to build a predictive model to predict earthquakes. This would be very valuable to insurance companies, city disaster planning, utility companies, etc.\n",
"\n",
"In this situation let's pretend we are a real estate agency in Boston MA and we are interested in purchasing some houses. We would like to know which houses are under value to help us narrow down the list and put in an accurate bid on a house.\n",
"\n",
"**Objective:** \n",
"\n",
"1. Identify what makes a property valuable?\n",
"1. What is a fair price for a house? "
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 2. Data Understanding\n",
"\n",
"The data understanding phase starts with an initial data collection and proceeds with activities in order to get familiar with the data, to identify data quality problems, to discover first insights into the data, or to detect interesting subsets to form hypotheses for hidden information.\n",
"\n",
"Now that we know what we are looking for we need to gather as much data as possible. As a company we would probably go and see if we can get access to MLS data.\n",
"\n",
"What are some other data sources that could give us information on housing prices if we needed to get this data?\n",
"\n",
"* [Realtor.com - Boston MA](http://www.realtor.com/realestateandhomes-search/Boston_MA)\n",
"* [Zillow API](http://www.zillow.com/howto/api/APIOverview.htm)\n",
"* [ProgrammableWeb API - Real Estate](http://www.programmableweb.com/category/real-estate)\n",
"\n",
"In this example, this data has been compiled already. Lets dive into the code!"
]
},
{
"cell_type": "code",
"execution_count": 98,
"metadata": {
"collapsed": false
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"\n"
]
}
],
"source": [
"import pandas as pd\n",
"import matplotlib.pyplot as plt\n",
"import numpy as np\n",
"import scipy.stats as stats\n",
"import sklearn\n",
"from sklearn.datasets import load_boston\n",
"%matplotlib inline"
]
},
{
"cell_type": "code",
"execution_count": 99,
"metadata": {
"collapsed": false
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"['data', 'feature_names', 'DESCR', 'target']\n"
]
}
],
"source": [
"boston = load_boston() # load the dataset\n",
"# This creates a dictionary that has data inside of it. Lets look at the keys of this dictionary\n",
"print boston.keys()"
]
},
{
"cell_type": "code",
"execution_count": 100,
"metadata": {
"collapsed": false
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"[[ 6.32000000e-03 1.80000000e+01 2.31000000e+00 ..., 1.53000000e+01\n",
" 3.96900000e+02 4.98000000e+00]\n",
" [ 2.73100000e-02 0.00000000e+00 7.07000000e+00 ..., 1.78000000e+01\n",
" 3.96900000e+02 9.14000000e+00]\n",
" [ 2.72900000e-02 0.00000000e+00 7.07000000e+00 ..., 1.78000000e+01\n",
" 3.92830000e+02 4.03000000e+00]\n",
" ..., \n",
" [ 6.07600000e-02 0.00000000e+00 1.19300000e+01 ..., 2.10000000e+01\n",
" 3.96900000e+02 5.64000000e+00]\n",
" [ 1.09590000e-01 0.00000000e+00 1.19300000e+01 ..., 2.10000000e+01\n",
" 3.93450000e+02 6.48000000e+00]\n",
" [ 4.74100000e-02 0.00000000e+00 1.19300000e+01 ..., 2.10000000e+01\n",
" 3.96900000e+02 7.88000000e+00]]\n",
"(506, 13)\n"
]
}
],
"source": [
"# data looks probably looks like what we are interested in. Let's see what it has\n",
"print boston.data\n",
"# So this is a matrix of data points. \n",
"# You can quickly see how many columns and rows are in the matrix by using the shape property\n",
"print boston.data.shape\n",
"# We have 506 rows (sometimes called observations) and 13 columns."
]
},
{
"cell_type": "code",
"execution_count": 101,
"metadata": {
"collapsed": false
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Boston House Prices dataset\n",
"\n",
"Notes\n",
"------\n",
"Data Set Characteristics: \n",
"\n",
" :Number of Instances: 506 \n",
"\n",
" :Number of Attributes: 13 numeric/categorical predictive\n",
" \n",
" :Median Value (attribute 14) is usually the target\n",
"\n",
" :Attribute Information (in order):\n",
" - CRIM per capita crime rate by town\n",
" - ZN proportion of residential land zoned for lots over 25,000 sq.ft.\n",
" - INDUS proportion of non-retail business acres per town\n",
" - CHAS Charles River dummy variable (= 1 if tract bounds river; 0 otherwise)\n",
" - NOX nitric oxides concentration (parts per 10 million)\n",
" - RM average number of rooms per dwelling\n",
" - AGE proportion of owner-occupied units built prior to 1940\n",
" - DIS weighted distances to five Boston employment centres\n",
" - RAD index of accessibility to radial highways\n",
" - TAX full-value property-tax rate per $10,000\n",
" - PTRATIO pupil-teacher ratio by town\n",
" - B 1000(Bk - 0.63)^2 where Bk is the proportion of blacks by town\n",
" - LSTAT % lower status of the population\n",
" - MEDV Median value of owner-occupied homes in $1000's\n",
"\n",
" :Missing Attribute Values: None\n",
"\n",
" :Creator: Harrison, D. and Rubinfeld, D.L.\n",
"\n",
"This is a copy of UCI ML housing dataset.\n",
"http://archive.ics.uci.edu/ml/datasets/Housing\n",
"\n",
"\n",
"This dataset was taken from the StatLib library which is maintained at Carnegie Mellon University.\n",
"\n",
"The Boston house-price data of Harrison, D. and Rubinfeld, D.L. 'Hedonic\n",
"prices and the demand for clean air', J. Environ. Economics & Management,\n",
"vol.5, 81-102, 1978. Used in Belsley, Kuh & Welsch, 'Regression diagnostics\n",
"...', Wiley, 1980. N.B. Various transformations are used in the table on\n",
"pages 244-261 of the latter.\n",
"\n",
"The Boston house-price data has been used in many machine learning papers that address regression\n",
"problems. \n",
" \n",
"**References**\n",
"\n",
" - Belsley, Kuh & Welsch, 'Regression diagnostics: Identifying Influential Data and Sources of Collinearity', Wiley, 1980. 244-261.\n",
" - Quinlan,R. (1993). Combining Instance-Based and Model-Based Learning. In Proceedings on the Tenth International Conference of Machine Learning, 236-243, University of Massachusetts, Amherst. Morgan Kaufmann.\n",
" - many more! (see http://archive.ics.uci.edu/ml/datasets/Housing)\n",
"\n"
]
}
],
"source": [
"# Lets see if we can learn more about what these 506 rows actually mean.\n",
"print boston.DESCR"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 3. Data Preparation\n",
"\n",
"The data preparation phase covers all activities to construct the final dataset (data that will be fed into the modeling tool(s)) from the initial raw data. Data preparation tasks are likely to be performed multiple times, and not in any prescribed order. Tasks include table, record, and attribute selection as well as transformation and cleaning of data for modeling tools.\n",
"\n",
"In this example the data has already mostly been prepared for us. In this step it is common to consider some of the following. \n",
"\n",
"* Do we have any missing fields?\n",
"* Do we need to convert any categoricals to dummy variables?\n",
"* Are there any outliers that need to be examined and/or removed?\n",
"* Do we need to create any precomputed fields?\n",
"* Do we need to scale our data so that it isn't thrown off by the algorithm we choose?\n",
"\n",
"We will be skipping these steps for now but they are important things to think about during this phase."
]
},
{
"cell_type": "code",
"execution_count": 102,
"metadata": {
"collapsed": false
},
"outputs": [
{
"data": {
"text/html": [
"<div>\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th></th>\n",
" <th>0</th>\n",
" <th>1</th>\n",
" <th>2</th>\n",
" <th>3</th>\n",
" <th>4</th>\n",
" <th>5</th>\n",
" <th>6</th>\n",
" <th>7</th>\n",
" <th>8</th>\n",
" <th>9</th>\n",
" <th>10</th>\n",
" <th>11</th>\n",
" <th>12</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>0</th>\n",
" <td>0.00632</td>\n",
" <td>18</td>\n",
" <td>2.31</td>\n",
" <td>0</td>\n",
" <td>0.538</td>\n",
" <td>6.575</td>\n",
" <td>65.2</td>\n",
" <td>4.0900</td>\n",
" <td>1</td>\n",
" <td>296</td>\n",
" <td>15.3</td>\n",
" <td>396.90</td>\n",
" <td>4.98</td>\n",
" </tr>\n",
" <tr>\n",
" <th>1</th>\n",
" <td>0.02731</td>\n",
" <td>0</td>\n",
" <td>7.07</td>\n",
" <td>0</td>\n",
" <td>0.469</td>\n",
" <td>6.421</td>\n",
" <td>78.9</td>\n",
" <td>4.9671</td>\n",
" <td>2</td>\n",
" <td>242</td>\n",
" <td>17.8</td>\n",
" <td>396.90</td>\n",
" <td>9.14</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2</th>\n",
" <td>0.02729</td>\n",
" <td>0</td>\n",
" <td>7.07</td>\n",
" <td>0</td>\n",
" <td>0.469</td>\n",
" <td>7.185</td>\n",
" <td>61.1</td>\n",
" <td>4.9671</td>\n",
" <td>2</td>\n",
" <td>242</td>\n",
" <td>17.8</td>\n",
" <td>392.83</td>\n",
" <td>4.03</td>\n",
" </tr>\n",
" <tr>\n",
" <th>3</th>\n",
" <td>0.03237</td>\n",
" <td>0</td>\n",
" <td>2.18</td>\n",
" <td>0</td>\n",
" <td>0.458</td>\n",
" <td>6.998</td>\n",
" <td>45.8</td>\n",
" <td>6.0622</td>\n",
" <td>3</td>\n",
" <td>222</td>\n",
" <td>18.7</td>\n",
" <td>394.63</td>\n",
" <td>2.94</td>\n",
" </tr>\n",
" <tr>\n",
" <th>4</th>\n",
" <td>0.06905</td>\n",
" <td>0</td>\n",
" <td>2.18</td>\n",
" <td>0</td>\n",
" <td>0.458</td>\n",
" <td>7.147</td>\n",
" <td>54.2</td>\n",
" <td>6.0622</td>\n",
" <td>3</td>\n",
" <td>222</td>\n",
" <td>18.7</td>\n",
" <td>396.90</td>\n",
" <td>5.33</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"text/plain": [
" 0 1 2 3 4 5 6 7 8 9 10 11 \\\n",
"0 0.00632 18 2.31 0 0.538 6.575 65.2 4.0900 1 296 15.3 396.90 \n",
"1 0.02731 0 7.07 0 0.469 6.421 78.9 4.9671 2 242 17.8 396.90 \n",
"2 0.02729 0 7.07 0 0.469 7.185 61.1 4.9671 2 242 17.8 392.83 \n",
"3 0.03237 0 2.18 0 0.458 6.998 45.8 6.0622 3 222 18.7 394.63 \n",
"4 0.06905 0 2.18 0 0.458 7.147 54.2 6.0622 3 222 18.7 396.90 \n",
"\n",
" 12 \n",
"0 4.98 \n",
"1 9.14 \n",
"2 4.03 \n",
"3 2.94 \n",
"4 5.33 "
]
},
"execution_count": 102,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"boston_df = pd.DataFrame(boston.data)\n",
"boston_df.head()"
]
},
{
"cell_type": "code",
"execution_count": 103,
"metadata": {
"collapsed": false
},
"outputs": [
{
"data": {
"text/html": [
"<div>\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th></th>\n",
" <th>CRIM</th>\n",
" <th>ZN</th>\n",
" <th>INDUS</th>\n",
" <th>CHAS</th>\n",
" <th>NOX</th>\n",
" <th>RM</th>\n",
" <th>AGE</th>\n",
" <th>DIS</th>\n",
" <th>RAD</th>\n",
" <th>TAX</th>\n",
" <th>PTRATIO</th>\n",
" <th>B</th>\n",
" <th>LSTAT</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>0</th>\n",
" <td>0.00632</td>\n",
" <td>18</td>\n",
" <td>2.31</td>\n",
" <td>0</td>\n",
" <td>0.538</td>\n",
" <td>6.575</td>\n",
" <td>65.2</td>\n",
" <td>4.0900</td>\n",
" <td>1</td>\n",
" <td>296</td>\n",
" <td>15.3</td>\n",
" <td>396.90</td>\n",
" <td>4.98</td>\n",
" </tr>\n",
" <tr>\n",
" <th>1</th>\n",
" <td>0.02731</td>\n",
" <td>0</td>\n",
" <td>7.07</td>\n",
" <td>0</td>\n",
" <td>0.469</td>\n",
" <td>6.421</td>\n",
" <td>78.9</td>\n",
" <td>4.9671</td>\n",
" <td>2</td>\n",
" <td>242</td>\n",
" <td>17.8</td>\n",
" <td>396.90</td>\n",
" <td>9.14</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2</th>\n",
" <td>0.02729</td>\n",
" <td>0</td>\n",
" <td>7.07</td>\n",
" <td>0</td>\n",
" <td>0.469</td>\n",
" <td>7.185</td>\n",
" <td>61.1</td>\n",
" <td>4.9671</td>\n",
" <td>2</td>\n",
" <td>242</td>\n",
" <td>17.8</td>\n",
" <td>392.83</td>\n",
" <td>4.03</td>\n",
" </tr>\n",
" <tr>\n",
" <th>3</th>\n",
" <td>0.03237</td>\n",
" <td>0</td>\n",
" <td>2.18</td>\n",
" <td>0</td>\n",
" <td>0.458</td>\n",
" <td>6.998</td>\n",
" <td>45.8</td>\n",
" <td>6.0622</td>\n",
" <td>3</td>\n",
" <td>222</td>\n",
" <td>18.7</td>\n",
" <td>394.63</td>\n",
" <td>2.94</td>\n",
" </tr>\n",
" <tr>\n",
" <th>4</th>\n",
" <td>0.06905</td>\n",
" <td>0</td>\n",
" <td>2.18</td>\n",
" <td>0</td>\n",
" <td>0.458</td>\n",
" <td>7.147</td>\n",
" <td>54.2</td>\n",
" <td>6.0622</td>\n",
" <td>3</td>\n",
" <td>222</td>\n",
" <td>18.7</td>\n",
" <td>396.90</td>\n",
" <td>5.33</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"text/plain": [
" CRIM ZN INDUS CHAS NOX RM AGE DIS RAD TAX PTRATIO \\\n",
"0 0.00632 18 2.31 0 0.538 6.575 65.2 4.0900 1 296 15.3 \n",
"1 0.02731 0 7.07 0 0.469 6.421 78.9 4.9671 2 242 17.8 \n",
"2 0.02729 0 7.07 0 0.469 7.185 61.1 4.9671 2 242 17.8 \n",
"3 0.03237 0 2.18 0 0.458 6.998 45.8 6.0622 3 222 18.7 \n",
"4 0.06905 0 2.18 0 0.458 7.147 54.2 6.0622 3 222 18.7 \n",
"\n",
" B LSTAT \n",
"0 396.90 4.98 \n",
"1 396.90 9.14 \n",
"2 392.83 4.03 \n",
"3 394.63 2.94 \n",
"4 396.90 5.33 "
]
},
"execution_count": 103,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"boston_df.columns = boston.feature_names\n",
"boston_df.head()\n",
"# Where is price?"
]
},
{
"cell_type": "code",
"execution_count": 104,
"metadata": {
"collapsed": false
},
"outputs": [
{
"data": {
"text/html": [
"<div>\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th></th>\n",
" <th>CRIM</th>\n",
" <th>ZN</th>\n",
" <th>INDUS</th>\n",
" <th>CHAS</th>\n",
" <th>NOX</th>\n",
" <th>RM</th>\n",
" <th>AGE</th>\n",
" <th>DIS</th>\n",
" <th>RAD</th>\n",
" <th>TAX</th>\n",
" <th>PTRATIO</th>\n",
" <th>B</th>\n",
" <th>LSTAT</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>count</th>\n",
" <td>506.000000</td>\n",
" <td>506.000000</td>\n",
" <td>506.000000</td>\n",
" <td>506.000000</td>\n",
" <td>506.000000</td>\n",
" <td>506.000000</td>\n",
" <td>506.000000</td>\n",
" <td>506.000000</td>\n",
" <td>506.000000</td>\n",
" <td>506.000000</td>\n",
" <td>506.000000</td>\n",
" <td>506.000000</td>\n",
" <td>506.000000</td>\n",
" </tr>\n",
" <tr>\n",
" <th>mean</th>\n",
" <td>3.593761</td>\n",
" <td>11.363636</td>\n",
" <td>11.136779</td>\n",
" <td>0.069170</td>\n",
" <td>0.554695</td>\n",
" <td>6.284634</td>\n",
" <td>68.574901</td>\n",
" <td>3.795043</td>\n",
" <td>9.549407</td>\n",
" <td>408.237154</td>\n",
" <td>18.455534</td>\n",
" <td>356.674032</td>\n",
" <td>12.653063</td>\n",
" </tr>\n",
" <tr>\n",
" <th>std</th>\n",
" <td>8.596783</td>\n",
" <td>23.322453</td>\n",
" <td>6.860353</td>\n",
" <td>0.253994</td>\n",
" <td>0.115878</td>\n",
" <td>0.702617</td>\n",
" <td>28.148861</td>\n",
" <td>2.105710</td>\n",
" <td>8.707259</td>\n",
" <td>168.537116</td>\n",
" <td>2.164946</td>\n",
" <td>91.294864</td>\n",
" <td>7.141062</td>\n",
" </tr>\n",
" <tr>\n",
" <th>min</th>\n",
" <td>0.006320</td>\n",
" <td>0.000000</td>\n",
" <td>0.460000</td>\n",
" <td>0.000000</td>\n",
" <td>0.385000</td>\n",
" <td>3.561000</td>\n",
" <td>2.900000</td>\n",
" <td>1.129600</td>\n",
" <td>1.000000</td>\n",
" <td>187.000000</td>\n",
" <td>12.600000</td>\n",
" <td>0.320000</td>\n",
" <td>1.730000</td>\n",
" </tr>\n",
" <tr>\n",
" <th>25%</th>\n",
" <td>0.082045</td>\n",
" <td>0.000000</td>\n",
" <td>5.190000</td>\n",
" <td>0.000000</td>\n",
" <td>0.449000</td>\n",
" <td>5.885500</td>\n",
" <td>45.025000</td>\n",
" <td>2.100175</td>\n",
" <td>4.000000</td>\n",
" <td>279.000000</td>\n",
" <td>17.400000</td>\n",
" <td>375.377500</td>\n",
" <td>6.950000</td>\n",
" </tr>\n",
" <tr>\n",
" <th>50%</th>\n",
" <td>0.256510</td>\n",
" <td>0.000000</td>\n",
" <td>9.690000</td>\n",
" <td>0.000000</td>\n",
" <td>0.538000</td>\n",
" <td>6.208500</td>\n",
" <td>77.500000</td>\n",
" <td>3.207450</td>\n",
" <td>5.000000</td>\n",
" <td>330.000000</td>\n",
" <td>19.050000</td>\n",
" <td>391.440000</td>\n",
" <td>11.360000</td>\n",
" </tr>\n",
" <tr>\n",
" <th>75%</th>\n",
" <td>3.647423</td>\n",
" <td>12.500000</td>\n",
" <td>18.100000</td>\n",
" <td>0.000000</td>\n",
" <td>0.624000</td>\n",
" <td>6.623500</td>\n",
" <td>94.075000</td>\n",
" <td>5.188425</td>\n",
" <td>24.000000</td>\n",
" <td>666.000000</td>\n",
" <td>20.200000</td>\n",
" <td>396.225000</td>\n",
" <td>16.955000</td>\n",
" </tr>\n",
" <tr>\n",
" <th>max</th>\n",
" <td>88.976200</td>\n",
" <td>100.000000</td>\n",
" <td>27.740000</td>\n",
" <td>1.000000</td>\n",
" <td>0.871000</td>\n",
" <td>8.780000</td>\n",
" <td>100.000000</td>\n",
" <td>12.126500</td>\n",
" <td>24.000000</td>\n",
" <td>711.000000</td>\n",
" <td>22.000000</td>\n",
" <td>396.900000</td>\n",
" <td>37.970000</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"text/plain": [
" CRIM ZN INDUS CHAS NOX RM \\\n",
"count 506.000000 506.000000 506.000000 506.000000 506.000000 506.000000 \n",
"mean 3.593761 11.363636 11.136779 0.069170 0.554695 6.284634 \n",
"std 8.596783 23.322453 6.860353 0.253994 0.115878 0.702617 \n",
"min 0.006320 0.000000 0.460000 0.000000 0.385000 3.561000 \n",
"25% 0.082045 0.000000 5.190000 0.000000 0.449000 5.885500 \n",
"50% 0.256510 0.000000 9.690000 0.000000 0.538000 6.208500 \n",
"75% 3.647423 12.500000 18.100000 0.000000 0.624000 6.623500 \n",
"max 88.976200 100.000000 27.740000 1.000000 0.871000 8.780000 \n",
"\n",
" AGE DIS RAD TAX PTRATIO B \\\n",
"count 506.000000 506.000000 506.000000 506.000000 506.000000 506.000000 \n",
"mean 68.574901 3.795043 9.549407 408.237154 18.455534 356.674032 \n",
"std 28.148861 2.105710 8.707259 168.537116 2.164946 91.294864 \n",
"min 2.900000 1.129600 1.000000 187.000000 12.600000 0.320000 \n",
"25% 45.025000 2.100175 4.000000 279.000000 17.400000 375.377500 \n",
"50% 77.500000 3.207450 5.000000 330.000000 19.050000 391.440000 \n",
"75% 94.075000 5.188425 24.000000 666.000000 20.200000 396.225000 \n",
"max 100.000000 12.126500 24.000000 711.000000 22.000000 396.900000 \n",
"\n",
" LSTAT \n",
"count 506.000000 \n",
"mean 12.653063 \n",
"std 7.141062 \n",
"min 1.730000 \n",
"25% 6.950000 \n",
"50% 11.360000 \n",
"75% 16.955000 \n",
"max 37.970000 "
]
},
"execution_count": 104,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"boston_df.describe()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Make sure you really understand what each variable means!\n",
"\n",
"Eventually you will be making decisions based on this data. Make sure you know what each variable means so you don't make incorrect assumptions. You are in the process of turning data into information and finally into insight.\n",
"\n",
">Data! Data! Data! I can’t make bricks without clay! - Sir Arthur Conan Doyle\n",
"\n",
"Lets look at the data again to really understand it\n",
"\n",
"* What does CRIM mean?\n",
"* What does ZN mean?\n",
"* What does INDUS mean?\n",
"* What does CHAS mean?\n",
"* What does RAD mean?\n",
"* What does TAX mean?\n",
"* What does B mean?\n",
"* What does LSTAT mean?"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 4. Modeling\n",
"\n",
"In this phase, various modeling techniques are selected and applied, and their parameters are calibrated to optimal values. Typically, there are several techniques for the same data mining problem type. Some techniques have specific requirements on the form of data. Therefore, stepping back to the data preparation phase is often needed.\n",
"\n",
"In this example we will only be looking at the [LinearRegression](http://scikit-learn.org/stable/modules/generated/sklearn.linear_model.LinearRegression.html) model to understand the concepts behind regression. \n",
"\n",
"* X is used as a variable to represent a matrix of known variables \n",
"* y is used to domonstrate the known values which are the target values (or the labels)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Understand the algorithm\n",
"\n",
"Most people are familiar with the equation of a line:\n",
"\n",
"$$y = mx + b$$\n",
"\n",
"Let's say we own a lemonade stand. We could make a really simple model of our lemonade stand by saying that the lemonade's revenue is equal to the price, sales, and rent. We could simplify this to a linear equation that looks like this\n",
"\n",
"$$PredictedRevenue = (Sales * Price) - Rent$$\n",
"\n",
"But there is more to selling lemonade than just sales and price. What if we could factor in other variables like price changes, sales, temperature, and foot traffic. We could create a more complex model that would look something like this.\n",
"\n",
"$$PredictedRevenue = (Sales * Weight) + ( Price * Weight) + (Temperature * Weight) + (FootTraffic * Weight) - Rent$$\n",
"\n",
"The weights in the example above are known as coefficients. Using [Multiple Linear Regression](https://en.wikipedia.org/wiki/Linear_regression) we can calculate the coefficiens of the different factors given a target. \n",
"\n",
"So what this is saying is that we can string together all of these coefficients and create an equation to predict the price of a house given these 13 variables. It would look like this:\n",
"\n",
"$$\\hat{Y} = \\beta_0 + \\beta_1 x_1 + \\beta_2 x_2 + \\beta_3 x_3 + ... \\beta_n N$$\n",
"\n",
"Which in english is\n",
"\n",
"$$PredictedPrice = Intercept + (Known CRIM * coefficient) + (Known ZN * coefficient) + ... (Known N * coefficient)$$"
]
},
{
"cell_type": "code",
"execution_count": 105,
"metadata": {
"collapsed": false
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Estimated intercept coefficent: 36.4911032804\n",
"Number of coefficients: 13\n"
]
}
],
"source": [
"X = boston_df\n",
"y = boston.target\n",
"\n",
"from sklearn.linear_model import LinearRegression\n",
"lm = LinearRegression()\n",
"\n",
"lm.fit(X, y)\n",
"print 'Estimated intercept coefficent:', lm.intercept_\n",
"print 'Number of coefficients:', len(lm.coef_)"
]
},
{
"cell_type": "code",
"execution_count": 106,
"metadata": {
"collapsed": false
},
"outputs": [
{
"data": {
"text/html": [
"<div>\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th></th>\n",
" <th>feature</th>\n",
" <th>coefficient</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>0</th>\n",
" <td>CRIM</td>\n",
" <td>-0.107171</td>\n",
" </tr>\n",
" <tr>\n",
" <th>1</th>\n",
" <td>ZN</td>\n",
" <td>0.046395</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2</th>\n",
" <td>INDUS</td>\n",
" <td>0.020860</td>\n",
" </tr>\n",
" <tr>\n",
" <th>3</th>\n",
" <td>CHAS</td>\n",
" <td>2.688561</td>\n",
" </tr>\n",
" <tr>\n",
" <th>4</th>\n",
" <td>NOX</td>\n",
" <td>-17.795759</td>\n",
" </tr>\n",
" <tr>\n",
" <th>5</th>\n",
" <td>RM</td>\n",
" <td>3.804752</td>\n",
" </tr>\n",
" <tr>\n",
" <th>6</th>\n",
" <td>AGE</td>\n",
" <td>0.000751</td>\n",
" </tr>\n",
" <tr>\n",
" <th>7</th>\n",
" <td>DIS</td>\n",
" <td>-1.475759</td>\n",
" </tr>\n",
" <tr>\n",
" <th>8</th>\n",
" <td>RAD</td>\n",
" <td>0.305655</td>\n",
" </tr>\n",
" <tr>\n",
" <th>9</th>\n",
" <td>TAX</td>\n",
" <td>-0.012329</td>\n",
" </tr>\n",
" <tr>\n",
" <th>10</th>\n",
" <td>PTRATIO</td>\n",
" <td>-0.953464</td>\n",
" </tr>\n",
" <tr>\n",
" <th>11</th>\n",
" <td>B</td>\n",
" <td>0.009393</td>\n",
" </tr>\n",
" <tr>\n",
" <th>12</th>\n",
" <td>LSTAT</td>\n",
" <td>-0.525467</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"text/plain": [
" feature coefficient\n",
"0 CRIM -0.107171\n",
"1 ZN 0.046395\n",
"2 INDUS 0.020860\n",
"3 CHAS 2.688561\n",
"4 NOX -17.795759\n",
"5 RM 3.804752\n",
"6 AGE 0.000751\n",
"7 DIS -1.475759\n",
"8 RAD 0.305655\n",
"9 TAX -0.012329\n",
"10 PTRATIO -0.953464\n",
"11 B 0.009393\n",
"12 LSTAT -0.525467"
]
},
"execution_count": 106,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"pd.DataFrame(zip(boston_df.columns, lm.coef_), columns=['feature', 'coefficient'])"
]
},
{
"cell_type": "code",
"execution_count": 107,
"metadata": {
"collapsed": false
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Predicted House price 28020.7131978\n",
"Equation house price 28020.7131978\n",
"Target price 26600.0\n",
"Residual price 1420.71319781\n",
"R^2 = 0.740607742865\n"
]
}
],
"source": [
"# def predict_house(crim, zn, indus, chas, nox, rm, age, dis, rad, tax, ptratio, b, lstat):\n",
"# return lm.intercept_ + lm.coef_[0] * crim \\\n",
"# + zn * lm.coef_[1] \\\n",
"# + indus * lm.coef_[2] \\\n",
"# + chas * lm.coef_[3] \\\n",
"# + nox * lm.coef_[4] \\\n",
"# + rm * lm.coef_[5] \\\n",
"# + age * lm.coef_[6] \\\n",
"# + dist * lm.coef_[7] \\\n",
"# + rad * lm.coef_[8] \\\n",
"# + tax * lm.coef_[9] \\\n",
"# + ptratio * lm.coef_[10] \\\n",
"# + b * lm.coef_[11] \\\n",
"# + lstat * lm.coef_[12]\n",
" \n",
" \n",
"# print X.iloc[[41]].values\n",
"# print y[41]\n",
"print \"Predicted House price\", lm.predict(X)[41] * 1000\n",
"print \"Equation house price\", (lm.intercept_ + np.dot(lm.coef_, X.iloc[[41]].values[0])) * 1000\n",
"print \"Target price\", y[41] * 1000\n",
"\n",
"print \"Residual price\", (lm.predict(X)[41] - y[41]) * 1000\n",
"\n",
"print \"R^2 =\", lm.score(X, y)\n"
]
},
{
"cell_type": "code",
"execution_count": 108,
"metadata": {
"collapsed": false,
"scrolled": true
},
"outputs": [
{
"data": {
"text/plain": [
"[]"
]
},
"execution_count": 108,
"metadata": {},
"output_type": "execute_result"
},
{
"data": {
"image/png": "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\nN+eyYcN6+vTpx/btbwG9McrjFCCTSKRJgXXQi0Nubi4+n++A6rBYjgR2X3XwYK9C+C7QGdMLVXb3\npbFrbfZoYj0SLJM89tgTCgZP0a7opxtkJup9I/hWjtNIo0a9mF8+Oztbbdp0VjD4L0FVQSv5/cfL\n48mbnDfE9T2sizIx9VIgkKBQqJFgnEwakfIya4GcIPhKJq9Q3sS/8oI+MmG1T8tM7kuRichqIZPK\n5D3XVPV/2hVxlddeV3Xq1FVJSWnaFX0lmaitNjr11O5KTm4lM/HQK8jKLxMMXq1nnnmmSPcwEolo\n0qRJuvvuu3XUUcfJ4/EpObmyJkyYWNKPy2I56FCKPpBcCs4+z+HgzUSvDazE2DM2R+337LadR6yf\nQ5nk4ov7uH6DvE72a5lQ1rztCQUWypk+fboSEk6QcZRfr7wUGiZEd7Pb4Ye1K5RXMnmmgrvtu0zw\nmMycjzsFT8hEY1V0P5UET0WVHy+TK6um6x85X9DVVRzHCx51FcKX8vuT9OuvvyopqYqMczyvjisE\n8bruuhsUDFZwFVgrmUmKEcFSBYNV9NVXX+3XvcvNzdVHH32kjh27ynEaC/q68t0t+EqOk6pffvml\ntB6dxXJQoIgKpCgmrFiN0xOACUB/jLKKplQ15uHCwoUL+fTTT4EM/P53yMnpg3n0EynoQvqDcuUS\nyc7OZsOGDWzcuJGsrEzgf0AF4CPMILAjHk8DHKcpO3ZEgFOBOzGZ/mdjlq6Nj6o3ADwKbMKYqBKB\n7kBfYArwAgUfo9ctu9mV80PMu8JSzBK0ZwK34/M5nHRSO0aMeJa2bU9k6tQzgGFuuelAhDvuGEQ4\nnMR//nMsxgT2b0wi6Sx69+5Dy5b/PKUpJyeHLl168OWXi8jI+BtjbksA/sL4cW7E4zmdL774goYN\ny+ICnRZL6VCWI6nALHA9AXgNY8ICWIcxXa0FqmD+i/dg2LBh+d87duxIx44dS1HMssuHH37I+ef3\nxuM5G49nJcHgb2zfXgNIxnTQW/F4BuLx+AiFXuL00+8lJaUKOTlecnN3kp1dFbMG+SrgEmAyoVAG\nZ511Gn/99QezZjXA+DPewCgGHybW4lzgIUysw9uYtchTgarAL8CrbtkOGMV0j3s8iFk/vAnm0WcC\np9C9e32mT29BfHxVYAMDBgzhP/95gY8/Po2PP34b45LzAsOB04FbqFr1eWrUqMF9993N008/xc6d\n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\n3jmPlgAAAABJRU5ErkJggg==\n",
"text/plain": [
"<matplotlib.figure.Figure at 0x10bd30210>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"plt.scatter(y, lm.predict(X))\n",
"plt.xlabel('Prices: $Y_i$')\n",
"plt.ylabel('PredictedPrices: $\\hat{Y}_i$')\n",
"plt.title('Actual vs Predicted')\n",
"plt.plot()"
]
},
{
"cell_type": "code",
"execution_count": 109,
"metadata": {
"collapsed": false
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Features that Minimize Error\n",
"------------------------------\n",
"LSTAT \t38.4829672299\n",
"RM \t43.6005517712\n",
"PTRATIO \t62.6522000138\n",
"INDUS \t64.6662216411\n",
"TAX \t65.8872753368\n",
"NOX \t69.0042883554\n",
"CRIM \t71.8523466653\n",
"RAD \t72.1248118808\n",
"AGE \t72.423980929\n",
"ZN \t73.4516960948\n",
"B \t75.0324292075\n",
"DIS \t79.1463415861\n",
"CHAS \t81.8265141193\n"
]
}
],
"source": [
"errors = {}\n",
"for feature in boston.feature_names:\n",
" lm = LinearRegression()\n",
" lm.fit(X[[feature]], y)\n",
" mean_squared_error = np.mean((y - lm.predict(X[[feature]])) ** 2)\n",
" errors[feature] = mean_squared_error\n",
"errors = sorted(errors.items(), key=lambda x: x[1])\n",
"\n",
"print \"Features that Minimize Error\"\n",
"print 30 * \"-\"\n",
"for e in errors:\n",
" print e[0], \"\\t\", e[1]"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 5. Evaluation\n",
"\n",
"At this stage in the project you have built a model (or models) that appears to have high quality, from a data analysis perspective. Before proceeding to final deployment of the model, it is important to more thoroughly evaluate the model, and review the steps executed to construct the model, to be certain it properly achieves the business objectives. A key objective is to determine if there is some important business issue that has not been sufficiently considered. At the end of this phase, a decision on the use of the data mining results should be reached.\n",
"\n",
"Let's look at the business objectives again:\n",
"\n",
"* ~~What is a fair price for a house?~~ - We now have a model that will give us a projected price. It might not be perfectly accurate but it will give us \n",
"* ~~Identify what makes a property valuable?~~ We know that the the features that minimized the error were LSTAT, RM, PTRATIO"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 6. Deployment\n",
"\n",
"Creation of the model is generally not the end of the project. Even if the purpose of the model is to increase knowledge of the data, the knowledge gained will need to be organized and presented in a way that is useful to the customer. Depending on the requirements, the deployment phase can be as simple as generating a report or as complex as implementing a repeatable data scoring (e.g. segment allocation) or data mining process. In many cases it will be the customer, not the data analyst, who will carry out the deployment steps. Even if the analyst deploys the model it is important for the customer to understand up front the actions which will need to be carried out in order to actually make use of the created models.\n",
"\n",
"\n",
"* What would deploying this model look like?\n",
"* Where would we deploy this model? Excel, Website, App?\n",
"* Should we deploy this model?\n",
"* What is the cost of inaccuracy? "
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Conclusion\n",
"\n",
"I hope this was a helpful overview to teach you more about Linear Regression by using the Cross Industry Standard Process for Data Mining. There are a lot more topics to cover but I feel like this gives you good insight into a simple regression model.\n",
"\n",
"If you have questions feel free to reach me jeff.potter6(at)gmail.com or [@jpotts18](https://twitter.com/jpotts18)"
]
}
],
"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
}
@comckay
Copy link

comckay commented Dec 7, 2016

You have an error in your formulation of $$\hat{Y} = \beta_0 + \beta_1 x_1 + \beta_2 x_2 + \beta_3 x_3 + ... \beta_n N$$
it should be $$\hat{Y} = \beta_0 + \beta_1 x_1 + \beta_2 x_2 + \beta_3 x_3 + ... \beta_n x_n$$

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment