{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "## Introduction To The Data Set" ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [], "source": [ "import pandas as pd\n", "import numpy as np\n", "\n", "pd.options.display.max_columns = 99" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [], "source": [ "cols = ['symboling', 'normalized-losses', 'make', 'fuel-type', 'aspiration', 'num-of-doors', 'body-style', \n", " 'drive-wheels', 'engine-location', 'wheel-base', 'length', 'width', 'height', 'curb-weight', 'engine-type', \n", " 'num-of-cylinders', 'engine-size', 'fuel-system', 'bore', 'stroke', 'compression-rate', 'horsepower', 'peak-rpm', 'city-mpg', 'highway-mpg', 'price']\n", "cars = pd.read_csv('imports-85.data', names=cols)" ] }, { "cell_type": "code", "execution_count": 3, "metadata": { "scrolled": true }, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
symbolingnormalized-lossesmakefuel-typeaspirationnum-of-doorsbody-styledrive-wheelsengine-locationwheel-baselengthwidthheightcurb-weightengine-typenum-of-cylindersengine-sizefuel-systemborestrokecompression-ratehorsepowerpeak-rpmcity-mpghighway-mpgprice
03?alfa-romerogasstdtwoconvertiblerwdfront88.6168.864.148.82548dohcfour130mpfi3.472.689.01115000212713495
13?alfa-romerogasstdtwoconvertiblerwdfront88.6168.864.148.82548dohcfour130mpfi3.472.689.01115000212716500
21?alfa-romerogasstdtwohatchbackrwdfront94.5171.265.552.42823ohcvsix152mpfi2.683.479.01545000192616500
32164audigasstdfoursedanfwdfront99.8176.666.254.32337ohcfour109mpfi3.193.4010.01025500243013950
42164audigasstdfoursedan4wdfront99.4176.666.454.32824ohcfive136mpfi3.193.408.01155500182217450
.................................................................................
200-195volvogasstdfoursedanrwdfront109.1188.868.955.52952ohcfour141mpfi3.783.159.51145400232816845
201-195volvogasturbofoursedanrwdfront109.1188.868.855.53049ohcfour141mpfi3.783.158.71605300192519045
202-195volvogasstdfoursedanrwdfront109.1188.868.955.53012ohcvsix173mpfi3.582.878.81345500182321485
203-195volvodieselturbofoursedanrwdfront109.1188.868.955.53217ohcsix145idi3.013.4023.01064800262722470
204-195volvogasturbofoursedanrwdfront109.1188.868.955.53062ohcfour141mpfi3.783.159.51145400192522625
\n", "

205 rows × 26 columns

\n", "
" ], "text/plain": [ " symboling normalized-losses make fuel-type aspiration \\\n", "0 3 ? alfa-romero gas std \n", "1 3 ? alfa-romero gas std \n", "2 1 ? alfa-romero gas std \n", "3 2 164 audi gas std \n", "4 2 164 audi gas std \n", ".. ... ... ... ... ... \n", "200 -1 95 volvo gas std \n", "201 -1 95 volvo gas turbo \n", "202 -1 95 volvo gas std \n", "203 -1 95 volvo diesel turbo \n", "204 -1 95 volvo gas turbo \n", "\n", " num-of-doors body-style drive-wheels engine-location wheel-base \\\n", "0 two convertible rwd front 88.6 \n", "1 two convertible rwd front 88.6 \n", "2 two hatchback rwd front 94.5 \n", "3 four sedan fwd front 99.8 \n", "4 four sedan 4wd front 99.4 \n", ".. ... ... ... ... ... \n", "200 four sedan rwd front 109.1 \n", "201 four sedan rwd front 109.1 \n", "202 four sedan rwd front 109.1 \n", "203 four sedan rwd front 109.1 \n", "204 four sedan rwd front 109.1 \n", "\n", " length width height curb-weight engine-type num-of-cylinders \\\n", "0 168.8 64.1 48.8 2548 dohc four \n", "1 168.8 64.1 48.8 2548 dohc four \n", "2 171.2 65.5 52.4 2823 ohcv six \n", "3 176.6 66.2 54.3 2337 ohc four \n", "4 176.6 66.4 54.3 2824 ohc five \n", ".. ... ... ... ... ... ... \n", "200 188.8 68.9 55.5 2952 ohc four \n", "201 188.8 68.8 55.5 3049 ohc four \n", "202 188.8 68.9 55.5 3012 ohcv six \n", "203 188.8 68.9 55.5 3217 ohc six \n", "204 188.8 68.9 55.5 3062 ohc four \n", "\n", " engine-size fuel-system bore stroke compression-rate horsepower \\\n", "0 130 mpfi 3.47 2.68 9.0 111 \n", "1 130 mpfi 3.47 2.68 9.0 111 \n", "2 152 mpfi 2.68 3.47 9.0 154 \n", "3 109 mpfi 3.19 3.40 10.0 102 \n", "4 136 mpfi 3.19 3.40 8.0 115 \n", ".. ... ... ... ... ... ... \n", "200 141 mpfi 3.78 3.15 9.5 114 \n", "201 141 mpfi 3.78 3.15 8.7 160 \n", "202 173 mpfi 3.58 2.87 8.8 134 \n", "203 145 idi 3.01 3.40 23.0 106 \n", "204 141 mpfi 3.78 3.15 9.5 114 \n", "\n", " peak-rpm city-mpg highway-mpg price \n", "0 5000 21 27 13495 \n", "1 5000 21 27 16500 \n", "2 5000 19 26 16500 \n", "3 5500 24 30 13950 \n", "4 5500 18 22 17450 \n", ".. ... ... ... ... \n", "200 5400 23 28 16845 \n", "201 5300 19 25 19045 \n", "202 5500 18 23 21485 \n", "203 4800 26 27 22470 \n", "204 5400 19 25 22625 \n", "\n", "[205 rows x 26 columns]" ] }, "execution_count": 3, "metadata": {}, "output_type": "execute_result" } ], "source": [ "cars" ] }, { "cell_type": "code", "execution_count": 4, "metadata": { "scrolled": true }, "outputs": [], "source": [ "# Select only the columns with continuous values from - https://archive.ics.uci.edu/ml/machine-learning-databases/autos/imports-85.names\n", "continuous_values_cols = ['normalized-losses', 'wheel-base', 'length', 'width', 'height', 'curb-weight', 'bore', 'stroke', 'compression-rate', 'horsepower', 'peak-rpm', 'city-mpg', 'highway-mpg', 'price']\n", "numeric_cars = cars[continuous_values_cols]" ] }, { "cell_type": "code", "execution_count": 5, "metadata": { "scrolled": true }, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
normalized-losseswheel-baselengthwidthheightcurb-weightborestrokecompression-ratehorsepowerpeak-rpmcity-mpghighway-mpgprice
0?88.6168.864.148.825483.472.689.01115000212713495
1?88.6168.864.148.825483.472.689.01115000212716500
2?94.5171.265.552.428232.683.479.01545000192616500
316499.8176.666.254.323373.193.4010.01025500243013950
416499.4176.666.454.328243.193.408.01155500182217450
\n", "
" ], "text/plain": [ " normalized-losses wheel-base length width height curb-weight bore \\\n", "0 ? 88.6 168.8 64.1 48.8 2548 3.47 \n", "1 ? 88.6 168.8 64.1 48.8 2548 3.47 \n", "2 ? 94.5 171.2 65.5 52.4 2823 2.68 \n", "3 164 99.8 176.6 66.2 54.3 2337 3.19 \n", "4 164 99.4 176.6 66.4 54.3 2824 3.19 \n", "\n", " stroke compression-rate horsepower peak-rpm city-mpg highway-mpg price \n", "0 2.68 9.0 111 5000 21 27 13495 \n", "1 2.68 9.0 111 5000 21 27 16500 \n", "2 3.47 9.0 154 5000 19 26 16500 \n", "3 3.40 10.0 102 5500 24 30 13950 \n", "4 3.40 8.0 115 5500 18 22 17450 " ] }, "execution_count": 5, "metadata": {}, "output_type": "execute_result" } ], "source": [ "numeric_cars.head(5)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Data Cleaning" ] }, { "cell_type": "code", "execution_count": 6, "metadata": { "scrolled": true }, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
normalized-losseswheel-baselengthwidthheightcurb-weightborestrokecompression-ratehorsepowerpeak-rpmcity-mpghighway-mpgprice
0NaN88.6168.864.148.825483.472.689.01115000212713495
1NaN88.6168.864.148.825483.472.689.01115000212716500
2NaN94.5171.265.552.428232.683.479.01545000192616500
316499.8176.666.254.323373.193.4010.01025500243013950
416499.4176.666.454.328243.193.408.01155500182217450
.............................................
20095109.1188.868.955.529523.783.159.51145400232816845
20195109.1188.868.855.530493.783.158.71605300192519045
20295109.1188.868.955.530123.582.878.81345500182321485
20395109.1188.868.955.532173.013.4023.01064800262722470
20495109.1188.868.955.530623.783.159.51145400192522625
\n", "

205 rows × 14 columns

\n", "
" ], "text/plain": [ " normalized-losses wheel-base length width height curb-weight bore \\\n", "0 NaN 88.6 168.8 64.1 48.8 2548 3.47 \n", "1 NaN 88.6 168.8 64.1 48.8 2548 3.47 \n", "2 NaN 94.5 171.2 65.5 52.4 2823 2.68 \n", "3 164 99.8 176.6 66.2 54.3 2337 3.19 \n", "4 164 99.4 176.6 66.4 54.3 2824 3.19 \n", ".. ... ... ... ... ... ... ... \n", "200 95 109.1 188.8 68.9 55.5 2952 3.78 \n", "201 95 109.1 188.8 68.8 55.5 3049 3.78 \n", "202 95 109.1 188.8 68.9 55.5 3012 3.58 \n", "203 95 109.1 188.8 68.9 55.5 3217 3.01 \n", "204 95 109.1 188.8 68.9 55.5 3062 3.78 \n", "\n", " stroke compression-rate horsepower peak-rpm city-mpg highway-mpg price \n", "0 2.68 9.0 111 5000 21 27 13495 \n", "1 2.68 9.0 111 5000 21 27 16500 \n", "2 3.47 9.0 154 5000 19 26 16500 \n", "3 3.40 10.0 102 5500 24 30 13950 \n", "4 3.40 8.0 115 5500 18 22 17450 \n", ".. ... ... ... ... ... ... ... \n", "200 3.15 9.5 114 5400 23 28 16845 \n", "201 3.15 8.7 160 5300 19 25 19045 \n", "202 2.87 8.8 134 5500 18 23 21485 \n", "203 3.40 23.0 106 4800 26 27 22470 \n", "204 3.15 9.5 114 5400 19 25 22625 \n", "\n", "[205 rows x 14 columns]" ] }, "execution_count": 6, "metadata": {}, "output_type": "execute_result" } ], "source": [ "numeric_cars = numeric_cars.replace('?', np.nan)\n", "numeric_cars" ] }, { "cell_type": "code", "execution_count": 7, "metadata": { "scrolled": true }, "outputs": [ { "data": { "text/plain": [ "normalized-losses 41\n", "wheel-base 0\n", "length 0\n", "width 0\n", "height 0\n", "curb-weight 0\n", "bore 4\n", "stroke 4\n", "compression-rate 0\n", "horsepower 2\n", "peak-rpm 2\n", "city-mpg 0\n", "highway-mpg 0\n", "price 4\n", "dtype: int64" ] }, "execution_count": 7, "metadata": {}, "output_type": "execute_result" } ], "source": [ "numeric_cars = numeric_cars.astype('float')\n", "numeric_cars.isnull().sum()" ] }, { "cell_type": "code", "execution_count": 8, "metadata": { "scrolled": true }, "outputs": [ { "data": { "text/plain": [ "normalized-losses 37\n", "wheel-base 0\n", "length 0\n", "width 0\n", "height 0\n", "curb-weight 0\n", "bore 4\n", "stroke 4\n", "compression-rate 0\n", "horsepower 2\n", "peak-rpm 2\n", "city-mpg 0\n", "highway-mpg 0\n", "price 0\n", "dtype: int64" ] }, "execution_count": 8, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# Because `price` is the column we want to predict, let's remove any rows with missing `price` values.\n", "numeric_cars = numeric_cars.dropna(subset=['price'])\n", "numeric_cars.isnull().sum()" ] }, { "cell_type": "code", "execution_count": 9, "metadata": { "scrolled": true }, "outputs": [], "source": [ "# Replace missing values in other columns using column means.\n", "numeric_cars = numeric_cars.fillna(numeric_cars.mean())" ] }, { "cell_type": "code", "execution_count": 10, "metadata": { "scrolled": true }, "outputs": [ { "data": { "text/plain": [ "normalized-losses 0\n", "wheel-base 0\n", "length 0\n", "width 0\n", "height 0\n", "curb-weight 0\n", "bore 0\n", "stroke 0\n", "compression-rate 0\n", "horsepower 0\n", "peak-rpm 0\n", "city-mpg 0\n", "highway-mpg 0\n", "price 0\n", "dtype: int64" ] }, "execution_count": 10, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# Confirm that there's no more missing values!\n", "numeric_cars.isnull().sum()" ] }, { "cell_type": "code", "execution_count": 11, "metadata": { "scrolled": true }, "outputs": [], "source": [ "# Normalize all columnns to range from 0 to 1 except the target column.\n", "price_col = numeric_cars['price']\n", "numeric_cars = (numeric_cars - numeric_cars.min())/(numeric_cars.max() - numeric_cars.min())\n", "numeric_cars['price'] = price_col" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Univariate Model" ] }, { "cell_type": "code", "execution_count": 12, "metadata": { "scrolled": true }, "outputs": [ { "data": { "text/plain": [ "horsepower 4037.037713\n", "curb-weight 4401.118255\n", "highway-mpg 4630.026799\n", "width 4704.482590\n", "city-mpg 4766.422505\n", "length 5427.200961\n", "wheel-base 5461.553998\n", "compression-rate 6610.812153\n", "bore 6780.627785\n", "normalized-losses 7330.197653\n", "peak-rpm 7697.459696\n", "stroke 8006.529545\n", "height 8144.441043\n", "dtype: float64" ] }, "execution_count": 12, "metadata": {}, "output_type": "execute_result" } ], "source": [ "from sklearn.neighbors import KNeighborsRegressor\n", "from sklearn.metrics import mean_squared_error\n", "\n", "def knn_train_test(train_col, target_col, df):\n", " knn = KNeighborsRegressor()\n", " np.random.seed(1)\n", " \n", " # Randomize order of rows in data frame.\n", " shuffled_index = np.random.permutation(df.index)\n", " rand_df = df.reindex(shuffled_index)\n", "\n", " # Divide number of rows in half and round.\n", " last_train_row = int(len(rand_df) / 2)\n", " \n", " # Select the first half and set as training set.\n", " # Select the second half and set as test set.\n", " train_df = rand_df.iloc[0:last_train_row]\n", " test_df = rand_df.iloc[last_train_row:]\n", " \n", " # Fit a KNN model using default k value.\n", " knn.fit(train_df[[train_col]], train_df[target_col])\n", " \n", " # Make predictions using model.\n", " predicted_labels = knn.predict(test_df[[train_col]])\n", "\n", " # Calculate and return RMSE.\n", " mse = mean_squared_error(test_df[target_col], predicted_labels)\n", " rmse = np.sqrt(mse)\n", " return rmse\n", "\n", "rmse_results = {}\n", "train_cols = numeric_cars.columns.drop('price')\n", "\n", "# For each column (minus `price`), train a model, return RMSE value\n", "# and add to the dictionary `rmse_results`.\n", "for col in train_cols:\n", " rmse_val = knn_train_test(col, 'price', numeric_cars)\n", " rmse_results[col] = rmse_val\n", "\n", "# Create a Series object from the dictionary so \n", "# we can easily view the results, sort, etc\n", "rmse_results_series = pd.Series(rmse_results)\n", "rmse_results_series.sort_values()" ] }, { "cell_type": "code", "execution_count": 13, "metadata": { "scrolled": true }, "outputs": [ { "data": { "text/plain": [ "{'normalized-losses': {1: 7846.750605148984,\n", " 3: 7500.5698123109905,\n", " 5: 7330.197653434445,\n", " 7: 7756.421586234123,\n", " 9: 7688.096096891432},\n", " 'wheel-base': {1: 4493.734068810494,\n", " 3: 5120.161506064513,\n", " 5: 5461.553997873057,\n", " 7: 5448.1070513823315,\n", " 9: 5738.405685192312},\n", " 'length': {1: 4628.45550121557,\n", " 3: 5129.8358210721635,\n", " 5: 5427.2009608367125,\n", " 7: 5313.427720847974,\n", " 9: 5383.054514833446},\n", " 'width': {1: 4559.257297950061,\n", " 3: 4606.413692169901,\n", " 5: 4704.482589704386,\n", " 7: 4571.485046194653,\n", " 9: 4652.914172067787},\n", " 'height': {1: 8904.04645636071,\n", " 3: 8277.609643045525,\n", " 5: 8144.441042663747,\n", " 7: 7679.598124393773,\n", " 9: 7811.03606291223},\n", " 'curb-weight': {1: 5264.290230758878,\n", " 3: 5022.318011757233,\n", " 5: 4401.118254793124,\n", " 7: 4330.608104418053,\n", " 9: 4632.044474454401},\n", " 'bore': {1: 8602.58848450066,\n", " 3: 6984.239489480916,\n", " 5: 6780.627784685976,\n", " 7: 6878.097965921532,\n", " 9: 6866.808502038413},\n", " 'stroke': {1: 9116.495955406906,\n", " 3: 7338.68466990294,\n", " 5: 8006.529544647101,\n", " 7: 7803.937796804327,\n", " 9: 7735.554366079291},\n", " 'compression-rate': {1: 8087.205346523092,\n", " 3: 7375.063685578359,\n", " 5: 6610.812153159129,\n", " 7: 6732.801282941515,\n", " 9: 7024.485525463435},\n", " 'horsepower': {1: 4170.054848037801,\n", " 3: 4020.8492630885394,\n", " 5: 4037.0377131537603,\n", " 7: 4353.811860277134,\n", " 9: 4515.135617419103},\n", " 'peak-rpm': {1: 9511.480067750124,\n", " 3: 8537.550899973421,\n", " 5: 7697.4596964334805,\n", " 7: 7510.294160083481,\n", " 9: 7340.041341263401},\n", " 'city-mpg': {1: 5901.143574354764,\n", " 3: 4646.746408727155,\n", " 5: 4766.422505090134,\n", " 7: 5232.523034167316,\n", " 9: 5465.209492527533},\n", " 'highway-mpg': {1: 6025.594966720739,\n", " 3: 4617.305019788554,\n", " 5: 4630.026798588056,\n", " 7: 4796.061440186946,\n", " 9: 5278.358056953987}}" ] }, "execution_count": 13, "metadata": {}, "output_type": "execute_result" } ], "source": [ "def knn_train_test(train_col, target_col, df):\n", " np.random.seed(1)\n", " \n", " # Randomize order of rows in data frame.\n", " shuffled_index = np.random.permutation(df.index)\n", " rand_df = df.reindex(shuffled_index)\n", "\n", " # Divide number of rows in half and round.\n", " last_train_row = int(len(rand_df) / 2)\n", " \n", " # Select the first half and set as training set.\n", " # Select the second half and set as test set.\n", " train_df = rand_df.iloc[0:last_train_row]\n", " test_df = rand_df.iloc[last_train_row:]\n", " \n", " k_values = [1,3,5,7,9]\n", " k_rmses = {}\n", " \n", " for k in k_values:\n", " # Fit model using k nearest neighbors.\n", " knn = KNeighborsRegressor(n_neighbors=k)\n", " knn.fit(train_df[[train_col]], train_df[target_col])\n", "\n", " # Make predictions using model.\n", " predicted_labels = knn.predict(test_df[[train_col]])\n", "\n", " # Calculate and return RMSE.\n", " mse = mean_squared_error(test_df[target_col], predicted_labels)\n", " rmse = np.sqrt(mse)\n", " \n", " k_rmses[k] = rmse\n", " return k_rmses\n", "\n", "k_rmse_results = {}\n", "\n", "# For each column (minus `price`), train a model, return RMSE value\n", "# and add to the dictionary `rmse_results`.\n", "train_cols = numeric_cars.columns.drop('price')\n", "for col in train_cols:\n", " rmse_val = knn_train_test(col, 'price', numeric_cars)\n", " k_rmse_results[col] = rmse_val\n", "\n", "k_rmse_results" ] }, { "cell_type": "code", "execution_count": 14, "metadata": {}, "outputs": [ { "data": { "image/png": "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\n", "text/plain": [ "
" ] }, "metadata": { "needs_background": "light" }, "output_type": "display_data" } ], "source": [ "import matplotlib.pyplot as plt\n", "%matplotlib inline\n", "\n", "for k,v in k_rmse_results.items():\n", " x = list(v.keys())\n", " y = list(v.values())\n", " \n", " plt.plot(x,y)\n", " plt.xlabel('k value')\n", " plt.ylabel('RMSE')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Multivariate Model" ] }, { "cell_type": "code", "execution_count": 15, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "horsepower 4219.377860\n", "width 4618.910560\n", "curb-weight 4730.075815\n", "highway-mpg 5069.469256\n", "length 5176.394904\n", "city-mpg 5202.409003\n", "wheel-base 5252.392462\n", "compression-rate 7166.073599\n", "bore 7222.472445\n", "normalized-losses 7624.407151\n", "stroke 8000.240467\n", "peak-rpm 8119.365233\n", "height 8163.346266\n", "dtype: float64\n" ] } ], "source": [ "# Compute average RMSE across different `k` values for each feature.\n", "feature_avg_rmse = {}\n", "for k,v in k_rmse_results.items():\n", " avg_rmse = np.mean(list(v.values()))\n", " feature_avg_rmse[k] = avg_rmse\n", "series_avg_rmse = pd.Series(feature_avg_rmse)\n", "sorted_series_avg_rmse = series_avg_rmse.sort_values()\n", "print(sorted_series_avg_rmse)\n", "\n", "sorted_features = sorted_series_avg_rmse.index" ] }, { "cell_type": "code", "execution_count": 16, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "{'2 best features': {5: 3589.3132622073304},\n", " '3 best features': {5: 3305.9401397969677},\n", " '4 best features': {5: 3358.6915801682458},\n", " '5 best features': {5: 3665.546673045813},\n", " '6 best features': {5: 3628.261188214127}}" ] }, "execution_count": 16, "metadata": {}, "output_type": "execute_result" } ], "source": [ "def knn_train_test(train_cols, target_col, df):\n", " np.random.seed(1)\n", " \n", " # Randomize order of rows in data frame.\n", " shuffled_index = np.random.permutation(df.index)\n", " rand_df = df.reindex(shuffled_index)\n", "\n", " # Divide number of rows in half and round.\n", " last_train_row = int(len(rand_df) / 2)\n", " \n", " # Select the first half and set as training set.\n", " # Select the second half and set as test set.\n", " train_df = rand_df.iloc[0:last_train_row]\n", " test_df = rand_df.iloc[last_train_row:]\n", " \n", " k_values = [5]\n", " k_rmses = {}\n", " \n", " for k in k_values:\n", " # Fit model using k nearest neighbors.\n", " knn = KNeighborsRegressor(n_neighbors=k)\n", " knn.fit(train_df[train_cols], train_df[target_col])\n", "\n", " # Make predictions using model.\n", " predicted_labels = knn.predict(test_df[train_cols])\n", "\n", " # Calculate and return RMSE.\n", " mse = mean_squared_error(test_df[target_col], predicted_labels)\n", " rmse = np.sqrt(mse)\n", " \n", " k_rmses[k] = rmse\n", " return k_rmses\n", "\n", "k_rmse_results = {}\n", "\n", "for nr_best_feats in range(2,7):\n", " k_rmse_results['{} best features'.format(nr_best_feats)] = knn_train_test(\n", " sorted_features[:nr_best_feats],\n", " 'price',\n", " numeric_cars\n", " )\n", "\n", "k_rmse_results" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Hyperparameter Tuning" ] }, { "cell_type": "code", "execution_count": 17, "metadata": { "scrolled": true }, "outputs": [ { "data": { "text/plain": [ "{'3 best features': {1: 3013.0109985241875,\n", " 2: 2813.285969825997,\n", " 3: 3171.585284478674,\n", " 4: 3182.3137417981943,\n", " 5: 3305.9401397969677,\n", " 6: 3522.506848900376,\n", " 7: 3774.3772094554106,\n", " 8: 3978.969124021116,\n", " 9: 3992.923680588881,\n", " 10: 4076.2381473803043,\n", " 11: 4156.388331131807,\n", " 12: 4201.10713385948,\n", " 13: 4303.62676861325,\n", " 14: 4359.693296989702,\n", " 15: 4371.771103372868,\n", " 16: 4394.4846551644205,\n", " 17: 4510.399710057406,\n", " 18: 4584.310961865486,\n", " 19: 4636.62620477063,\n", " 20: 4664.465847866811,\n", " 21: 4724.096637428273,\n", " 22: 4752.535484102914,\n", " 23: 4808.703310452101,\n", " 24: 4858.9452710176065},\n", " '4 best features': {1: 2600.746383728188,\n", " 2: 2725.4325072335123,\n", " 3: 3108.8580314362966,\n", " 4: 3217.3135209486827,\n", " 5: 3358.6915801682458,\n", " 6: 3633.1687033129465,\n", " 7: 3896.127441396644,\n", " 8: 4002.8383900652543,\n", " 9: 4055.5309369929582,\n", " 10: 4128.67807741542,\n", " 11: 4249.827289347268,\n", " 12: 4344.035898237492,\n", " 13: 4402.995293166156,\n", " 14: 4424.314365328619,\n", " 15: 4442.943179452285,\n", " 16: 4528.57927503009,\n", " 17: 4572.28806185627,\n", " 18: 4604.034045947238,\n", " 19: 4660.524954508328,\n", " 20: 4735.352015758023,\n", " 21: 4742.329532242572,\n", " 22: 4763.606459864159,\n", " 23: 4807.076030845482,\n", " 24: 4848.127192424658},\n", " '5 best features': {1: 2773.8991269216394,\n", " 2: 2936.079965592973,\n", " 3: 3152.3415515178144,\n", " 4: 3488.57822210674,\n", " 5: 3665.546673045813,\n", " 6: 3563.9910249785435,\n", " 7: 3714.642677357888,\n", " 8: 3927.6655582704293,\n", " 9: 4074.724411578548,\n", " 10: 4202.692919892065,\n", " 11: 4228.8377103033245,\n", " 12: 4280.7222580306225,\n", " 13: 4323.694733441248,\n", " 14: 4341.598003940922,\n", " 15: 4381.910642108479,\n", " 16: 4462.210967318207,\n", " 17: 4512.666161759793,\n", " 18: 4549.02427742861,\n", " 19: 4625.542238703432,\n", " 20: 4680.4075341436155,\n", " 21: 4769.300287838951,\n", " 22: 4813.1714929806085,\n", " 23: 4871.956026848068,\n", " 24: 4922.889655107399}}" ] }, "execution_count": 17, "metadata": {}, "output_type": "execute_result" } ], "source": [ "def knn_train_test(train_cols, target_col, df):\n", " np.random.seed(1)\n", " \n", " # Randomize order of rows in data frame.\n", " shuffled_index = np.random.permutation(df.index)\n", " rand_df = df.reindex(shuffled_index)\n", "\n", " # Divide number of rows in half and round.\n", " last_train_row = int(len(rand_df) / 2)\n", " \n", " # Select the first half and set as training set.\n", " # Select the second half and set as test set.\n", " train_df = rand_df.iloc[0:last_train_row]\n", " test_df = rand_df.iloc[last_train_row:]\n", " \n", " k_values = [i for i in range(1, 25)]\n", " k_rmses = {}\n", " \n", " for k in k_values:\n", " # Fit model using k nearest neighbors.\n", " knn = KNeighborsRegressor(n_neighbors=k)\n", " knn.fit(train_df[train_cols], train_df[target_col])\n", "\n", " # Make predictions using model.\n", " predicted_labels = knn.predict(test_df[train_cols])\n", "\n", " # Calculate and return RMSE.\n", " mse = mean_squared_error(test_df[target_col], predicted_labels)\n", " rmse = np.sqrt(mse)\n", " \n", " k_rmses[k] = rmse\n", " return k_rmses\n", "\n", "k_rmse_results = {}\n", "\n", "for nr_best_feats in range(3,6):\n", " k_rmse_results['{} best features'.format(nr_best_feats)] = knn_train_test(\n", " sorted_features[:nr_best_feats],\n", " 'price',\n", " numeric_cars\n", " )\n", "\n", "k_rmse_results" ] }, { "cell_type": "code", "execution_count": 18, "metadata": {}, "outputs": [ { "data": { "image/png": "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\n", "text/plain": [ "
" ] }, "metadata": { "needs_background": "light" }, "output_type": "display_data" } ], "source": [ "for k,v in k_rmse_results.items():\n", " x = list(v.keys())\n", " y = list(v.values())\n", " \n", " plt.plot(x,y)\n", " plt.xlabel('k value')\n", " plt.ylabel('RMSE')" ] } ], "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.7.6" } }, "nbformat": 4, "nbformat_minor": 4 }