The mismatch between parking demand and parking space availability in big cities can easily cause frustrations for citizens. In Seattle, the business as usual approach for allocating street parking space is following the minimum requirement regulated by Seattle’s Land Use Code. However, the minimum requirement does not necessarily correspond to parking demand. Over and undersupply for parking spaces could lead to inefficient curbside management.

It is not rare that sometimes a car is parked on a bike lane because the driver cannot find a space to park, which can be dangerous for both drivers and cyclists. It will also be a waste of public space if the city oversupply street parking because spaces could be dedicated to bike lanes or public realm improvement. In order to help Seattle to minimize the gap between parking demand and supply and help Seattle to have a more efficient curbside management, we developed this model to predict the parking demand in Seattle’s CBD area.

Developing a model is not an easy process because parking is very dynamic. The demand for parking can change drastically based on time and location. Weekdays, holidays, events and weathers could all have an impact on people’s travel patterns and thus affect parking demand. In this model, we try to capture as many spatial and time components as we can. Socio-economic factors were also put into consideration different neighborhoods may have different travel patterns.

Our final model could explain about 79% of the variation in parking demand. When testing with the training set, the model as a mean absolute error of 1.6, which is relatively small. K-fold cross-validation was conducted to measure the model’s performance and to make sure the model is generalizable. Lastly, we also developed an application for this model, and hope the user case we developed could help Seattle to allocate street space more efficiently.

A quick introduction video about this project can be watched here: https://www.youtube.com/watch?v=Cur6h3eYHUk&feature=youtu.be

Map theme, plot theme, and function set-up.

mapTheme <- function(base_size = 12) {
    text = element_text( color = "black"),
    plot.title = element_text(size = 14,colour = "black"),
    axis.ticks = element_blank(),
    panel.background = element_blank(),
    axis.title = element_blank(),
    axis.text = element_blank(),
    axis.title.x = element_blank(),
    axis.title.y = element_blank(),
    panel.grid.minor = element_blank(),
    panel.border = element_rect(colour = "black", fill=NA, size=2)

plotTheme <- function(base_size = 12) {
    text = element_text( color = "black"),
    plot.title = element_text(size = 14,colour = "black"),
    plot.subtitle = element_text(face="italic"),
    plot.caption = element_text(hjust=0),
    axis.ticks = element_blank(),
    panel.background = element_blank(),
    panel.grid.major = element_line("grey80", size = 0.1),
    panel.grid.minor = element_blank(),
    panel.border = element_rect(colour = "black", fill=NA, size=2),
    strip.background = element_rect(fill = "grey80", color = "white"),
    strip.text = element_text(size=12),
    axis.title = element_text(size=12),
    axis.text = element_text(size=10),
    plot.background = element_blank(),
    legend.background = element_blank(),
    legend.title = element_text(colour = "black", face = "italic"),
    legend.text = element_text(colour = "black", face = "italic"),
    strip.text.x = element_text(size = 14)
paletteY <- c("#F9F871","#FFD364","#FFAF6D","#FF8F80","#F87895", "D16BA5")

qBr <- function(df, variable, rnd) {
  if (missing(rnd)) {
                          c(.01,.2,.4,.6,.8), na.rm=T))
  } else if (rnd == FALSE | rnd == F) {
    as.character(formatC(quantile(df[[variable]]), digits = 3),
                 c(.01,.2,.4,.6,.8), na.rm=T)

q5 <- function(variable) {as.factor(ntile(variable, 5))}


The primary dataset we use is the Annual Parking Study data, which is accessible in Seattle’s Open Data Portal. There are about 110,000 rows of information after we clean the dataset. Because the dataset is non-spatial, we must join the Seattle block face data to locate the street parking. The combined dataset comes with information on time, parking space available, total vehicle count and parking rate.

The predictive model we build is a linear regression model. The dependent variable for the model is the total vehicle count for a street parking segment. And we shortlisted XX independent variables to develop this model. They are factors that may have an impact on parking demand, and we divided them into 4 categories.

  • Street Parking Features: These are specific details about the parking space at the time it was recorded.
  • Spatial Features: Distance to or the number of amenities/land use types close to the parking segment.
  • Socio-economic Features: Demographics and commute pattern statistics at the census tract level.
  • Spatial and Time structure: : Spatial lag – Average occupancy rate of nearby road segments. Time lag – The vehicle counts at a similar or recent time period.