Cell 1 · Python
#Importing and configuring CSV.
#Dataset from Kaggle: https://www.kaggle.com/datasets/austinreese/craigslist-carstrucks-data?resource=download
import pandas as pd
import matplotlib.pyplot as plt
pd.set_option('display.max_columns', None)

df = pd.read_csv('vehicles.csv')
df
Saved output
id url region region_url price year manufacturer model condition cylinders fuel odometer title_status transmission VIN drive size type paint_color image_url description county state lat long posting_date
0 7222695916 https://prescott.craigslist.org/cto/d/prescott... prescott https://prescott.craigslist.org 6000 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN az NaN NaN NaN
1 7218891961 https://fayar.craigslist.org/ctd/d/bentonville... fayetteville https://fayar.craigslist.org 11900 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN ar NaN NaN NaN
2 7221797935 https://keys.craigslist.org/cto/d/summerland-k... florida keys https://keys.craigslist.org 21000 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN fl NaN NaN NaN
3 7222270760 https://worcester.craigslist.org/cto/d/west-br... worcester / central MA https://worcester.craigslist.org 1500 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN ma NaN NaN NaN
4 7210384030 https://greensboro.craigslist.org/cto/d/trinit... greensboro https://greensboro.craigslist.org 4900 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN nc NaN NaN NaN
... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ...
426875 7301591192 https://wyoming.craigslist.org/ctd/d/atlanta-2... wyoming https://wyoming.craigslist.org 23590 2019.0 nissan maxima s sedan 4d good 6 cylinders gas 32226.0 clean other 1N4AA6AV6KC367801 fwd NaN sedan NaN https://images.craigslist.org/00o0o_iiraFnHg8q... Carvana is the safer way to buy a car During t... NaN wy 33.786500 -84.445400 2021-04-04T03:21:31-0600
426876 7301591187 https://wyoming.craigslist.org/ctd/d/atlanta-2... wyoming https://wyoming.craigslist.org 30590 2020.0 volvo s60 t5 momentum sedan 4d good NaN gas 12029.0 clean other 7JR102FKXLG042696 fwd NaN sedan red https://images.craigslist.org/00x0x_15sbgnxCIS... Carvana is the safer way to buy a car During t... NaN wy 33.786500 -84.445400 2021-04-04T03:21:29-0600
426877 7301591147 https://wyoming.craigslist.org/ctd/d/atlanta-2... wyoming https://wyoming.craigslist.org 34990 2020.0 cadillac xt4 sport suv 4d good NaN diesel 4174.0 clean other 1GYFZFR46LF088296 NaN NaN hatchback white https://images.craigslist.org/00L0L_farM7bxnxR... Carvana is the safer way to buy a car During t... NaN wy 33.779214 -84.411811 2021-04-04T03:21:17-0600
426878 7301591140 https://wyoming.craigslist.org/ctd/d/atlanta-2... wyoming https://wyoming.craigslist.org 28990 2018.0 lexus es 350 sedan 4d good 6 cylinders gas 30112.0 clean other 58ABK1GG4JU103853 fwd NaN sedan silver https://images.craigslist.org/00z0z_bKnIVGLkDT... Carvana is the safer way to buy a car During t... NaN wy 33.786500 -84.445400 2021-04-04T03:21:11-0600
426879 7301591129 https://wyoming.craigslist.org/ctd/d/atlanta-2... wyoming https://wyoming.craigslist.org 30590 2019.0 bmw 4 series 430i gran coupe good NaN gas 22716.0 clean other WBA4J1C58KBM14708 rwd NaN coupe NaN https://images.craigslist.org/00Y0Y_lEUocjyRxa... Carvana is the safer way to buy a car During t... NaN wy 33.779214 -84.411811 2021-04-04T03:21:07-0600
Cell 2 · Python
#Selecting only relevant features for this study
df = df[['price', 'year', 'odometer', 'manufacturer','condition', 'title_status', 'type', 'state']]
Cell 3 · Python
df.info()
Saved output
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 426880 entries, 0 to 426879
Data columns (total 8 columns):
 #   Column        Non-Null Count   Dtype  
---  ------        --------------   -----  
 0   price         426880 non-null  int64  
 1   year          425675 non-null  float64
 2   odometer      422480 non-null  float64
 3   manufacturer  409234 non-null  object 
 4   condition     252776 non-null  object 
 5   title_status  418638 non-null  object 
 6   type          334022 non-null  object 
 7   state         426880 non-null  object 
dtypes: float64(2), int64(1), object(5)
memory usage: 26.1+ MB
Cell 4 · Python
#Lots of missing data in categories. We'll encode "missing" into the empty values later on in the project and see how the model performs without the data.
#Data will now be visualized to see outliers.
Cell 5 · Python
#Price
df['price'].plot(kind='hist', bins=50)
plt.xlabel('Price')
plt.ylabel('Count')
plt.title('Distribution of Price')
plt.show()
Saved output
Histogram of the original asking prices, including extreme outliers.
Cell 6 · Python
#Looks like we have some junk prices that need to be filtered out, we'll use quantile to filter out the high end and will make the floor $1,000 to remove the free entries.
prices = df[(df['price'] > 1000) & (df['price'] <= df['price'].quantile(0.99))]
prices['price'].plot(kind='hist', bins=50)
plt.xlabel('Price')
plt.ylabel('Count')
plt.title('Distribution of Price')
plt.show()
Saved output
Histogram of asking prices after filtering the lowest and highest entries.
Cell 7 · Python
#Looks better, now the dataset will be updated. 

df = df[(df['price'] > 1000) & (df['price'] <= df['price'].quantile(0.99))]
Cell 8 · Python
df['year'].plot(kind='hist', bins=50)
plt.xlabel('Year')
plt.ylabel('Count')
plt.title('Distribution of Vehicle Year')
plt.show()
Saved output
Histogram of vehicle model years.
Cell 9 · Python
#A few outliers, but this could include classic cars.
Cell 10 · Python
#Mileage
df['odometer'].plot(kind='hist', bins=50)
plt.xlabel('Miles')
plt.ylabel('Count')
plt.title('Distribution of Vehicle Mileage')
plt.show()
Saved output
Histogram of original odometer readings, including extreme outliers.
Cell 11 · Python
#More outliers.
quantile = df['odometer'].quantile(0.99)
miles = df[(df['odometer'] >= (0)) & (df['odometer'] <= (quantile))]
miles['odometer'].plot(kind='hist', bins=50)
plt.xlabel('Miles')
plt.ylabel('Count')
plt.title('Distribution of Vehicle Mileage')
plt.show()
Saved output
Histogram of odometer readings after filtering extreme mileage.
Cell 12 · Python
df = df[(df['odometer'] >= (0)) & (df['odometer'] <= (quantile))]
Cell 14 · Python
#Lots of missing values were spotted initially, let's visualize.
missing = df['manufacturer'].fillna('MISSING').value_counts()

missing.sort_values().plot(kind='barh')
plt.xlabel('Number of listings')
plt.ylabel('Manufacturer')
plt.title('Listings by manufacturer')
plt.tight_layout()
plt.show()
Saved output
Horizontal bar chart of listing counts by vehicle manufacturer.
Cell 15 · Python
#These values will be one-hot encoded later to have the unknown values be ignored when training.
Cell 16 · Python
#Fixing missing values
features = ['manufacturer', 'condition', 'title_status', 'type', 'state']

df[features] = df[features].fillna('unknown')

#Removing Duplicates
df = df.drop_duplicates()
Cell 17 · Python
#One Hot Encoding (Condition)
encoded_condition = pd.get_dummies(df['condition'], prefix='Condition', dtype=int)
df = df.drop('condition', axis=1)
df = pd.concat([df, encoded_condition], axis=1)
df
Saved output
price year odometer manufacturer title_status type state Condition_excellent Condition_fair Condition_good Condition_like new Condition_new Condition_salvage Condition_unknown
27 33590 2014.0 57923.0 gmc clean pickup al 0 0 1 0 0 0 0
28 22590 2010.0 71229.0 chevrolet clean pickup al 0 0 1 0 0 0 0
29 39590 2020.0 19160.0 chevrolet clean pickup al 0 0 1 0 0 0 0
30 30990 2017.0 41124.0 toyota clean pickup al 0 0 1 0 0 0 0
31 15000 2013.0 128000.0 ford clean truck al 1 0 0 0 0 0 0
... ... ... ... ... ... ... ... ... ... ... ... ... ... ...
426875 23590 2019.0 32226.0 nissan clean sedan wy 0 0 1 0 0 0 0
426876 30590 2020.0 12029.0 volvo clean sedan wy 0 0 1 0 0 0 0
426877 34990 2020.0 4174.0 cadillac clean hatchback wy 0 0 1 0 0 0 0
426878 28990 2018.0 30112.0 lexus clean sedan wy 0 0 1 0 0 0 0
426879 30590 2019.0 22716.0 bmw clean coupe wy 0 0 1 0 0 0 0
Cell 18 · Python
#One Hot Encoding (Title)
encoded_title_status = pd.get_dummies(df['title_status'], prefix='Title Status', dtype=int)
df = df.drop('title_status', axis=1)
df = pd.concat([df, encoded_title_status], axis=1)
df
Saved output
price year odometer manufacturer type state Condition_excellent Condition_fair Condition_good Condition_like new Condition_new Condition_salvage Condition_unknown Title Status_clean Title Status_lien Title Status_missing Title Status_parts only Title Status_rebuilt Title Status_salvage Title Status_unknown
27 33590 2014.0 57923.0 gmc pickup al 0 0 1 0 0 0 0 1 0 0 0 0 0 0
28 22590 2010.0 71229.0 chevrolet pickup al 0 0 1 0 0 0 0 1 0 0 0 0 0 0
29 39590 2020.0 19160.0 chevrolet pickup al 0 0 1 0 0 0 0 1 0 0 0 0 0 0
30 30990 2017.0 41124.0 toyota pickup al 0 0 1 0 0 0 0 1 0 0 0 0 0 0
31 15000 2013.0 128000.0 ford truck al 1 0 0 0 0 0 0 1 0 0 0 0 0 0
... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ...
426875 23590 2019.0 32226.0 nissan sedan wy 0 0 1 0 0 0 0 1 0 0 0 0 0 0
426876 30590 2020.0 12029.0 volvo sedan wy 0 0 1 0 0 0 0 1 0 0 0 0 0 0
426877 34990 2020.0 4174.0 cadillac hatchback wy 0 0 1 0 0 0 0 1 0 0 0 0 0 0
426878 28990 2018.0 30112.0 lexus sedan wy 0 0 1 0 0 0 0 1 0 0 0 0 0 0
426879 30590 2019.0 22716.0 bmw coupe wy 0 0 1 0 0 0 0 1 0 0 0 0 0 0
Cell 19 · Python
#One Hot Encoding (Vehicle Type)
encoded_type = pd.get_dummies(df['type'], prefix='Vehicle Type', dtype=int)
df = df.drop('type', axis=1)
df = pd.concat([df, encoded_type], axis=1)
df
Saved output
price year odometer manufacturer state Condition_excellent Condition_fair Condition_good Condition_like new Condition_new Condition_salvage Condition_unknown Title Status_clean Title Status_lien Title Status_missing Title Status_parts only Title Status_rebuilt Title Status_salvage Title Status_unknown Vehicle Type_SUV Vehicle Type_bus Vehicle Type_convertible Vehicle Type_coupe Vehicle Type_hatchback Vehicle Type_mini-van Vehicle Type_offroad Vehicle Type_other Vehicle Type_pickup Vehicle Type_sedan Vehicle Type_truck Vehicle Type_unknown Vehicle Type_van Vehicle Type_wagon
27 33590 2014.0 57923.0 gmc al 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0
28 22590 2010.0 71229.0 chevrolet al 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0
29 39590 2020.0 19160.0 chevrolet al 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0
30 30990 2017.0 41124.0 toyota al 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0
31 15000 2013.0 128000.0 ford al 1 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0
... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ...
426875 23590 2019.0 32226.0 nissan wy 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0
426876 30590 2020.0 12029.0 volvo wy 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0
426877 34990 2020.0 4174.0 cadillac wy 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0
426878 28990 2018.0 30112.0 lexus wy 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0
426879 30590 2019.0 22716.0 bmw wy 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0
Cell 20 · Python
#One Hot Encoding (State)
encoded_state = pd.get_dummies(df['state'], prefix='Vehicle State', dtype=int)
df = df.drop('state', axis=1)
df = pd.concat([df, encoded_state], axis=1)
df
Saved output
price year odometer manufacturer Condition_excellent Condition_fair Condition_good Condition_like new Condition_new Condition_salvage Condition_unknown Title Status_clean Title Status_lien Title Status_missing Title Status_parts only Title Status_rebuilt Title Status_salvage Title Status_unknown Vehicle Type_SUV Vehicle Type_bus Vehicle Type_convertible Vehicle Type_coupe Vehicle Type_hatchback Vehicle Type_mini-van Vehicle Type_offroad Vehicle Type_other Vehicle Type_pickup Vehicle Type_sedan Vehicle Type_truck Vehicle Type_unknown Vehicle Type_van Vehicle Type_wagon Vehicle State_ak Vehicle State_al Vehicle State_ar Vehicle State_az Vehicle State_ca Vehicle State_co Vehicle State_ct Vehicle State_dc Vehicle State_de Vehicle State_fl Vehicle State_ga Vehicle State_hi Vehicle State_ia Vehicle State_id Vehicle State_il Vehicle State_in Vehicle State_ks Vehicle State_ky Vehicle State_la Vehicle State_ma Vehicle State_md Vehicle State_me Vehicle State_mi Vehicle State_mn Vehicle State_mo Vehicle State_ms Vehicle State_mt Vehicle State_nc Vehicle State_nd Vehicle State_ne Vehicle State_nh Vehicle State_nj Vehicle State_nm Vehicle State_nv Vehicle State_ny Vehicle State_oh Vehicle State_ok Vehicle State_or Vehicle State_pa Vehicle State_ri Vehicle State_sc Vehicle State_sd Vehicle State_tn Vehicle State_tx Vehicle State_ut Vehicle State_va Vehicle State_vt Vehicle State_wa Vehicle State_wi Vehicle State_wv Vehicle State_wy
27 33590 2014.0 57923.0 gmc 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
28 22590 2010.0 71229.0 chevrolet 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
29 39590 2020.0 19160.0 chevrolet 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
30 30990 2017.0 41124.0 toyota 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
31 15000 2013.0 128000.0 ford 1 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ...
426875 23590 2019.0 32226.0 nissan 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1
426876 30590 2020.0 12029.0 volvo 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1
426877 34990 2020.0 4174.0 cadillac 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1
426878 28990 2018.0 30112.0 lexus 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1
426879 30590 2019.0 22716.0 bmw 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1
Cell 21 · Python
#One Hot Encoding (Manufacturer)
encoded_manufacturer = pd.get_dummies(df['manufacturer'], prefix='Vehicle Manufacturer', dtype=int)
df = df.drop('manufacturer', axis=1)
df = pd.concat([df, encoded_manufacturer], axis=1)
df
Saved output
price year odometer Condition_excellent Condition_fair Condition_good Condition_like new Condition_new Condition_salvage Condition_unknown Title Status_clean Title Status_lien Title Status_missing Title Status_parts only Title Status_rebuilt Title Status_salvage Title Status_unknown Vehicle Type_SUV Vehicle Type_bus Vehicle Type_convertible Vehicle Type_coupe Vehicle Type_hatchback Vehicle Type_mini-van Vehicle Type_offroad Vehicle Type_other Vehicle Type_pickup Vehicle Type_sedan Vehicle Type_truck Vehicle Type_unknown Vehicle Type_van Vehicle Type_wagon Vehicle State_ak Vehicle State_al Vehicle State_ar Vehicle State_az Vehicle State_ca Vehicle State_co Vehicle State_ct Vehicle State_dc Vehicle State_de Vehicle State_fl Vehicle State_ga Vehicle State_hi Vehicle State_ia Vehicle State_id Vehicle State_il Vehicle State_in Vehicle State_ks Vehicle State_ky Vehicle State_la Vehicle State_ma Vehicle State_md Vehicle State_me Vehicle State_mi Vehicle State_mn Vehicle State_mo Vehicle State_ms Vehicle State_mt Vehicle State_nc Vehicle State_nd Vehicle State_ne Vehicle State_nh Vehicle State_nj Vehicle State_nm Vehicle State_nv Vehicle State_ny Vehicle State_oh Vehicle State_ok Vehicle State_or Vehicle State_pa Vehicle State_ri Vehicle State_sc Vehicle State_sd Vehicle State_tn Vehicle State_tx Vehicle State_ut Vehicle State_va Vehicle State_vt Vehicle State_wa Vehicle State_wi Vehicle State_wv Vehicle State_wy Vehicle Manufacturer_acura Vehicle Manufacturer_alfa-romeo Vehicle Manufacturer_aston-martin Vehicle Manufacturer_audi Vehicle Manufacturer_bmw Vehicle Manufacturer_buick Vehicle Manufacturer_cadillac Vehicle Manufacturer_chevrolet Vehicle Manufacturer_chrysler Vehicle Manufacturer_datsun Vehicle Manufacturer_dodge Vehicle Manufacturer_ferrari Vehicle Manufacturer_fiat Vehicle Manufacturer_ford Vehicle Manufacturer_gmc Vehicle Manufacturer_harley-davidson Vehicle Manufacturer_honda Vehicle Manufacturer_hyundai Vehicle Manufacturer_infiniti Vehicle Manufacturer_jaguar Vehicle Manufacturer_jeep Vehicle Manufacturer_kia Vehicle Manufacturer_land rover Vehicle Manufacturer_lexus Vehicle Manufacturer_lincoln Vehicle Manufacturer_mazda Vehicle Manufacturer_mercedes-benz Vehicle Manufacturer_mercury Vehicle Manufacturer_mini Vehicle Manufacturer_mitsubishi Vehicle Manufacturer_morgan Vehicle Manufacturer_nissan Vehicle Manufacturer_pontiac Vehicle Manufacturer_porsche Vehicle Manufacturer_ram Vehicle Manufacturer_rover Vehicle Manufacturer_saturn Vehicle Manufacturer_subaru Vehicle Manufacturer_tesla Vehicle Manufacturer_toyota Vehicle Manufacturer_unknown Vehicle Manufacturer_volkswagen Vehicle Manufacturer_volvo
27 33590 2014.0 57923.0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
28 22590 2010.0 71229.0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
29 39590 2020.0 19160.0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
30 30990 2017.0 41124.0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0
31 15000 2013.0 128000.0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ...
426875 23590 2019.0 32226.0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0
426876 30590 2020.0 12029.0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1
426877 34990 2020.0 4174.0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
426878 28990 2018.0 30112.0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
426879 30590 2019.0 22716.0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
Cell 22 · Python
#Model Training

# Create X and y Dataframes for SKL
X= df.drop('price', axis=1)
y= df['price']
Cell 23 · Python
import sklearn
from sklearn.ensemble import RandomForestRegressor
from sklearn.model_selection import train_test_split

X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42) #Test size 20% of data

# Random Forrest Classifier
model = RandomForestRegressor(n_estimators=100, random_state=42, n_jobs=-1)
model.fit(X_train, y_train)
y_pred = model.predict(X_test)
Cell 24 · Python
import numpy as np
import seaborn as sns
# Sample of 5,000 points to maintain readability
sample = np.random.RandomState(42).choice(len(y_test), 5000, replace=False)

plt.figure(figsize=(8, 6))
sns.scatterplot(x=y_test.iloc[sample], y=y_pred[sample], alpha=0.3, s=10)
plt.plot([0, y_test.max()], [0, y_test.max()], 'r--', label='Regression Line')
plt.xlabel('Actual Price ($)')
plt.ylabel('Predicted Price ($)')
plt.title('Predicted vs Actual Price')
plt.legend()
plt.show()
Saved output
Scatterplot of predicted versus actual asking prices with a reference line.
Cell 25 · Python
from sklearn.metrics import mean_absolute_error, r2_score
print('Mean Absolute Error:', mean_absolute_error(y_test, y_pred))
print('R^2:', r2_score(y_test, y_pred))
print('Baseline MAE:', mean_absolute_error(y_test, [y_train.median()] * len(y_test)))
Saved output
Mean Absolute Error: 3656.616633110759
R^2: 0.7834092710869567
Baseline MAE: 10145.964302942595
Cell 26 · Python
import matplotlib.pyplot as plt

# Get feature importances from the trained model
importances = pd.Series(model.feature_importances_, index=X_train.columns)

# Combine one-hot columns back into their original feature since original graph was showing all features making it unreadable.
grouped = importances.groupby(lambda col: col.split('_')[0]).sum()
grouped = grouped.sort_values()

# Plot the feature importances
plt.figure(figsize=(10, 6))
plt.barh(grouped.index, grouped.values)
plt.xlabel('Feature Importance')
plt.ylabel('Feature')
plt.title('Feature Importances in Random Forest')
plt.show()
Saved output
Horizontal bar chart of grouped feature importance in the random forest model.