1. Introduction

a. What the dataset is

This dataset provides comprehensive information about Airbnb listings in Columbus, Ohio, as of September 21, 2022. It encompasses a wide range of variables, capturing essential details of the listings. These variables range from basic attributes like room type, listing ID, and listing name, to more intricate features such as the geographic coordinates, specifically the longitude and latitude of each listing. The dataset is a source of information for exploring and analyzing the facets of Airbnb accommodations in the Columbus area.

b. Important variables

Some variables that can be helpful in analyzing the data include ‘price,’ which is the primary target for prediction and is hypothesized to be influenced by various factors. ‘Room_type’ categorizes accommodations, offering insights into the nature of the listing. Spatial characteristics are represented by ‘bedrooms,’ ‘beds,’ and the unique ‘bathrooms_text.’ Geographic context is provided by ‘neighbourhood_cleansed,’ ‘longitude,’ and ‘latitude.’ ‘Amenities’ showcase the offered conveniences, while ‘accommodates’ denotes guest capacity. ‘Review_scores_rating’ measures guest satisfaction, and ‘host_is_superhost’ signifies the host’s commitment to excellence.

c. Research questions

  • What factors affect listing prices in Columbus? In other words, are there relationships between the factors given (and not given)?

  • If there are relationships in Columbus, will the same relationships appear in other cities around the US?

  • What does Airbnb pricing mechanism and algorithm look like? What factors do they take into account?

  • Can prices affect price? To be more specific, since the Host can determine prices and since Airbnb can also determine it, can prices set too high or low affect how Airbnb prices it?

  • Is there a self-correcting mechanism in which if prices are set too high or low by Hosts can result in mismatch of demand, pushing Hosts to set prices nearer equilibrium?

d. Ethical concerns

  • Stakeholders in the analysis: Hosts, renters, Airbnb (including its employees, stockholders, and investors), residents in the area, and individuals in the local rental market.

  • This analysis primarily relies on data posted by hosts. While the probability of leaking sensitive or personal data about listings is relatively low, there is a risk of disclosing private locations, which can have serious implications for privacy and safety. Therefore, responsible data handling is essential to prevent the misuse or mishandling of sensitive information.

  • The Northeastern University study has shown that the transient nature of short-term rentals, such as those on Airbnb, can potentially lead to a spike in certain types of crime. The disruption caused by Airbnb listings can weaken the social fabric of neighborhoods, making them less adept at naturally managing criminal activities. This finding underscores the importance of addressing broader ethical concerns associated with short-term rental platforms.

2. Data Exploration

# A lot of set up and data wrangling


library(devtools)
library(tidyverse)
#devtools::install_github("stadiamaps/ggmap", force = TRUE)
library(sp)
library(ggmap)
library(GGally)
library(ggfortify)
library(MASS)
library(lindia)
library(stringr)
colum <- read.csv("columbus-listings-2022.csv")

library(dplyr)
colum_sel <- colum |>
  dplyr::select(price, room_type, bedrooms, beds, bathrooms_text, neighbourhood_cleansed, longitude, latitude, amenities, accommodates, review_scores_rating, host_is_superhost
  )

### Mutating the values for the "price" variables
colum_sel <- colum_sel |>
  mutate(
    price_num = as.numeric(str_remove_all(price, "[$,]")),
    .before = 1
  )

colum_sel <- colum_sel |>
  mutate(bathroom_num = as.numeric(str_extract(bathrooms_text, "\\d+\\.?\\d*")))
# Create an empty vector to store the distances
distances_to_center <- numeric(nrow(colum_sel))

# Central coordinates of Columbus
central_lat <- median(colum_sel$latitude)
central_lon <- mean(colum_sel$longitude)


# Loop through each row of the dataset
for (i in 1:nrow(colum_sel)) {
  point_lat <- colum_sel$latitude[i]
  point_lon <- colum_sel$longitude[i]
  
  # Calculate the distance using the Euclidean distance formula
  distances_to_center[i] <- sqrt((point_lat - central_lat)^2 + (point_lon - central_lon)^2)
}

# Add the distances to the dataset
colum_sel$distance_to_center <- distances_to_center

# Furthest distance and base value
furthest_distance <- max(colum_sel$distance_to_center)

# Create a new column for relative distances using mutate
colum_sel <- colum_sel %>% 
  mutate(relative_distance = distance_to_center/furthest_distance)
View(colum_sel)

Findings from the plots and maps made

From the plots and maps that’s coming up, there are a few key findings. Firstly, a certain type - entire homes/ apartments - of listing vastly outnumbers others. Secondly, distribution of prices are not very considerably different. It is also inconclusive due to the big differences in number of listings. Third, both of the maps show us the distribution of listings around Columbus, which tend to cluster to the center and become less numbered further from the center - regardless of if we’re catagorizing by price or type of listing. These findings can lead us to the next steps: Are there any correlation between distance to center and price? And what other variables might influence price?

Plot #1

colum_sel|>
  ggplot(
    aes(
      x = room_type
    )
  )+
  geom_bar()+
  labs(
    x = "Type of Room",
    y = "Count",
    title = "Number of Room by Type"
  )+
  geom_text(aes(label = ..count..), stat = "count", vjust = -1, colour = "black")+
  ylim(0,2000)

The bar plots show how many of each type of room is avaiable in the Columbus listing dataset. Listings for entire units (1779 units, or 81.0% of total listings) outnumber that of private rooms (18.8%). Both vastly outnumbers shared rooms (0.2%).

Plot #2

colum_sel|>
  ggplot(
    aes(
      x = price_num,
      fill = room_type
    )
  )+
  geom_density(alpha = 0.4)+
  labs(
    x = "Airbnb Price ($)",
    y = "Density",
    title = "Distribution of Price by Room Type"
  )+
  guides(fill = guide_legend(title = "Room Type"))+
  scale_x_log10()

This density plot show how prices for listing are distributed for each type of room offered.

First we’ll look into the biggest group - entire homes and apartments. The peak on the curve for this room type is at $100, meaning that there are the highest proportion of rooms at or very close to this value. The next peak occurs at around $175.

Next, for private rooms, the curve is more skewed to the left, with the peak at nearly $65.

Lastly, for shared rooms, the peak occurs at a price considerably lower compared to entire homes - at around $40. However, since there are only 6 shared rooms, the density can be more extreme compared to other room types. There aren’t enough numbers of rooms for the distribution to allow us to understand what the true distribution of price for shared rooms on the market might be.

Next, let’s see where these types of listings fall in the map to see if there’s any notable trend!

Map maker

register_stadiamaps("cc26c68c-9889-4213-abcb-668aa93280e5")
Columbus <- c(left=-83.2, bottom=39.8, right=-82.75, top=40.16)
columbus_map <- get_stadiamap(Columbus, zoom = 10)
ggmap(columbus_map) + 
  geom_point(data = colum_sel, alpha =.3, aes(x=longitude, y=latitude))+
  facet_wrap(~room_type)+
  labs(
    x = "Longitude",
    y = "Latitude",
    title = "Airbnb Distribution across Columbus by Room Type"
  )

These geographical maps show how different types of rooms are distributed around the Columbus area. First looking at listings for entire homes, we can see very dense distribution at and around the city center. The other listings are scattered around pretty equally, with darker spots in certain area, suggesting more listings there. Next, for private rooms, the trend is the same, with dense dots in the city center that get more sparse as we move away from it. Since the number of private rooms are many times smaller than the number of entire homes, there are fewer dots on the map. Lastly, for shared rooms, there are no visible trends. Most of the points are near the center, with one dark spot and three lighter spots. The dark spot represents three listings (since there are six in total).

Now we know more about rooms: How many of each there are, how much they tend to cost, and where they are in Columbus.

Next, let’s see the distribution of listings on the map by price:

colum_sel$price <- as.numeric(colum_sel$price)

library(tidyverse)
colum_sel<- colum_sel|>
  mutate(
    price_range = case_when(
      price_num < 100 ~ "0-100",
      price_num >= 100 & price_num < 300 ~ "100-300",
      price_num >= 300 & price_num < 600 ~ "300-600",
      price_num >= 600 & price_num < 1000 ~ "600-1000",
      price_num >= 1000 ~ ">1000"
    ),
    .before = 2
  )


View(colum_sel)


ggmap(columbus_map) + 
  geom_point(data = colum_sel, alpha =.3, aes(x=longitude, y=latitude))+
  facet_wrap(~price_range, labeller = labeller(price_range = function(labels) paste0("$", labels)))+
  labs(
    x = "Longitude",
    y = "Latitude",
    title = "Airbnb Price Distribution across Columbus"
  )

Overall, we can see that regardless of price — as with room type — most listings tend to be clustered nearer to the center and get sparser as we move away. Because distance to the center (assumed to be the point with the median latitude and longitude) doesn’t seem to correlate with both room type and prices (listings and prices tend to be more numerous near the center nonetheless), I want to see if there are any correlations, which will be done later in the lab.

3. Statistical Analysis and Interpretation

With the upcoming linear regression models, I’m trying to see what influences price - in which direction, by what magnitude, and with how much accuracy and validity. Let’s look at the first regression model and see the impact of changes in log of accommodates on the log of price:

Regression 1:

model6 <- lm(log(price_num) ~  log(accommodates), colum_sel)
summary(model6)
## 
## Call:
## lm(formula = log(price_num) ~ log(accommodates), data = colum_sel)
## 
## Residuals:
##      Min       1Q   Median       3Q      Max 
## -1.42538 -0.28773 -0.01906  0.24859  3.07613 
## 
## Coefficients:
##                   Estimate Std. Error t value Pr(>|t|)    
## (Intercept)        3.84652    0.02294  167.65   <2e-16 ***
## log(accommodates)  0.70697    0.01495   47.29   <2e-16 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 0.4406 on 2195 degrees of freedom
## Multiple R-squared:  0.5046, Adjusted R-squared:  0.5044 
## F-statistic:  2236 on 1 and 2195 DF,  p-value: < 2.2e-16
autoplot(model6)

This simple linear regression estimates how the logarithm of the listing price is influenced by the logarithm of the number of accommodates. The coefficient for log(accommodates) is 0.70697, indicating that for a one-unit increase in the logarithm of accommodates, we expect the logarithm of the price to increase by approximately 0.71 units. The standard error is 0.01495, or 2.11% of the estimated coefficient. This is a relatively small standard error, suggesting that there isn’t a lot of variability in the estimation of log of price using log of accommodates – in other words, the model is likely to be moderately accurate. The intercept is 3.84652, representing the estimated logarithm of the price when the logarithm of accommodates is zero.

exp(3.84652)
## [1] 46.82981

Using the exponential model on the intercept of the log of price, the intercept is transformed back to the original price scale. This means that when the the logarithm of accommodates is zero (meaning the number of accommodates is 1), the estimated price is approximately $46.83.

Next, let’s look at the confidence interval:

confint(model6, level=0.95)
##                       2.5 %   97.5 %
## (Intercept)       3.8015216 3.891509
## log(accommodates) 0.6776477 0.736285
  1. Intercept:

    • The 95% confidence interval for the intercept is [3.8015, 3.8915].

    • We are 95% confident that the true value of the intercept falls within this range.

    • This interval represents the estimated average log(price_num) when log(accommodates) is zero.

  2. log(accommodates):

    • The 95% confidence interval for the coefficient of log(accommodates) is [0.6776, 0.7363].

    • We are 95% confident that the true effect of a one-unit increase in log(accommodates) on log(price_num) falls within this range.

    • It suggests that, on average, a one-unit increase in log(accommodates) is associated with an increase in log(price_num) between 0.6776 and 0.7363.

Lastly, we can visualise this linear regression as below. The plot shows the same intercept as the model summary and we can see the positive slope, indicating the positive expected correlation between log of accommodates and log of price.

colum_sel|>
  ggplot(
    aes(
      x = log(accommodates),
      y = log(price_num)
    )
  )+
  geom_point()+
  geom_smooth(method = "lm")+
  labs(
    x = "Log of Accommodates",
    y = "Log of Price",
    title = "Log of Accommodates and Log of Prices Line Plot"
  )

Pairs plot & analysis: What are the implications of multilinearity

This multiple regression is between the log of price and bedrooms, beds, and relative distance to the median location of all the listings

model7 <- lm(log(price_num) ~ bedrooms + beds + relative_distance, colum_sel)
summary(model7)
## 
## Call:
## lm(formula = log(price_num) ~ bedrooms + beds + relative_distance, 
##     data = colum_sel)
## 
## Residuals:
##      Min       1Q   Median       3Q      Max 
## -2.98730 -0.28276  0.02446  0.29478  2.41620 
## 
## Coefficients:
##                   Estimate Std. Error t value Pr(>|t|)    
## (Intercept)        4.22189    0.02367 178.345  < 2e-16 ***
## bedrooms           0.24031    0.01607  14.952  < 2e-16 ***
## beds               0.08758    0.01087   8.056 1.31e-15 ***
## relative_distance -0.35774    0.05227  -6.845 1.00e-11 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 0.4672 on 2114 degrees of freedom
##   (79 observations deleted due to missingness)
## Multiple R-squared:  0.4476, Adjusted R-squared:  0.4468 
## F-statistic: 570.9 on 3 and 2114 DF,  p-value: < 2.2e-16
autoplot(model7)

Before we analyse these outputs, let’s check the accuracy of our linear model by seeing if there are any multilinearity - relationships between these independent variables

colum_chose <- colum_sel |>
  dplyr::select(price_num, bedrooms, beds, accommodates, review_scores_rating, bathroom_num, relative_distance)
ggpairs(colum_chose[,-1])

There are some considerably large correlations between beds & bedrooms, accommodates & bedrooms, and accommodates & bed. All these correlations have values greater than 0.83, suggesting that having these independent variables in the same model can increase standard error in the model. On the other hand, if we omit these variables, the coefficients would be biased and most likely not capture the true effect of the other variables on price.

But since the correlation is relatively large, which affects the accuracy of the model, the next model will not include independent variables that have correlation values greater than 0.8.

Regression 2

Model validation

summary(model7)
## 
## Call:
## lm(formula = log(price_num) ~ log(accommodates) + log(relative_distance) + 
##     log(bathroom_num) + log(review_scores_rating), data = colum_sel)
## 
## Residuals:
##      Min       1Q   Median       3Q      Max 
## -1.36305 -0.25481 -0.00653  0.24538  1.93368 
## 
## Coefficients:
##                           Estimate Std. Error t value Pr(>|t|)    
## (Intercept)                3.29378    0.14586  22.582  < 2e-16 ***
## log(accommodates)          0.64727    0.01630  39.706  < 2e-16 ***
## log(relative_distance)    -0.07456    0.01249  -5.968 2.86e-09 ***
## log(bathroom_num)          0.15690    0.02316   6.775 1.65e-11 ***
## log(review_scores_rating)  0.28504    0.09008   3.164  0.00158 ** 
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 0.406 on 1935 degrees of freedom
##   (257 observations deleted due to missingness)
## Multiple R-squared:  0.5436, Adjusted R-squared:  0.5426 
## F-statistic: 576.1 on 4 and 1935 DF,  p-value: < 2.2e-16
autoplot(model7)

exp(3.29378)
## [1] 26.94452
confint(model7)
##                                 2.5 %      97.5 %
## (Intercept)                3.00772205  3.57984114
## log(accommodates)          0.61529584  0.67923623
## log(relative_distance)    -0.09906843 -0.05005938
## log(bathroom_num)          0.11148182  0.20232056
## log(review_scores_rating)  0.10837789  0.46171051

Interpretation

This multiple linear regression aims to understand how the logarithm of the listing price is influenced by various factors, including the logarithm of accommodates, relative distance, bathroom number, and review scores rating.

The intercept is 3.29378, indicating the estimated logarithm of the price when all predictor variables are zero. Using the exponential again, the intercept is transformed to 26.94452. This means that when all predictor variables are zero, the estimated price is approximately $27.

The coefficient for log(accommodates) is 0.64727, suggesting that, for a one-unit increase in the logarithm of accommodates, we expect the logarithm of the price to increase by approximately 0.65 units - or about 1.92 dollars. The standard error is relatively small, at around 2.52% of the estimate, indicating small variability in estimating the intercept. The positive coefficient for log(accommodates) suggests that an increase in the number of accommodates corresponds to a higher predicted price, which makes sense as larger properties or those accommodating more guests are generally associated with higher prices. Of course, there is an extent to which this is true. If the property, everything else holding constant, accommodates 100 people, a positive change in accommodates is not likely to bring the price up in real life.

The coefficient for log(relative_distance) is -0.07456, signifying that as the logarithm of the relative distance increases by one unit, the logarithm of the price is expected to decrease by approximately 0.07 units, which translates to around 1.07 dollars. The standard error is moderately large, at around -16.78% of the estimate, indicating considerable variability in estimating the intercept or lower accuracy. The negative coefficient for log(relative_distance) is coherent with the idea that properties closer to popular attractions or city centers tend to have higher prices.

For log(bathroom_num), a one-unit increase in the logarithm of the bathroom number results in a predicted increase of approximately 0.16 units in the logarithm of the price - or around 1.17 dollards. The standard error is also moderately large, at around 14.75% of the estimate, indicating considerable variability and low accuracy. Similarly, the positive coefficient for log(bathroom_num) is sensible, indicating that listings with more bathrooms are associated with higher prices. Practically, again, there’s a limit to which this is true.

For log(review_scores_rating), the coefficient is 0.28504, indicating that a one-unit increase in the logarithm of the review scores rating is associated with an estimated increase of approximately 0.29 units in the logarithm of the price - or around 1.33 dollars. Similarly, the positive coefficient for log(bathroom_num) is sensible, indicating that listings with more bathrooms are associated with higher prices. But since the extent to which ratings can go is not great (a max of 5), the influence of ratings on the log of price is smaller than that of other independent variables. Indeed, the percentage standard error of the estimate for log(review_scores_rating) is 31.59%, suggesting high variability.

Looking at the confidence intervals, in this regression model, the intercept’s 95% confidence interval (3.0077, 3.5798) suggests the expected baseline logarithm of the listing price when all predictors are zero. The confidence interval for log(accommodates) (0.6153, 0.6792) indicates that each additional unit in the logarithm of accommodates is associated with a price increase in the range. The range for log(relative_distance) (-0.0991, -0.0501) suggests a negative association between increased distance and price. Log(bathroom_num) (0.1115, 0.2023) implies that more bathrooms are associated with a higher price within the range. Finally, log(review_scores_rating) (0.1084, 0.4617) suggests a positive association between higher ratings and listing price within this range.The confidence intervals are relatively small with the exception of review scores rating. These confidence intervals help understand the average effects of predictor variables on listing prices with a 95% level of confidence.

The overall model has a multiple R-squared of 0.5436, suggesting that these variables collectively explain 54.36% of the variability in the logarithm of the listing price. The adjusted R-squared, accounting for the number of predictors, is 0.5426. This means there’s a significant portion of variability unaccounted for.

Not less importantly, the p-values of the estimates are all smaller than 0.001, with one exception (estimation for coefficient of log of review scores has a p-value of less than 0.01). This small value suggest that the variable is likely to be a meaningful predictor of the response variable. And overall, the results of the regression model make intuitive sense in the context of real-world scenarios, but there are definitely limits to which the predictions can go.

Model validation

  1. Residuals vs Fitted: Checking the linear relationship assumption:
  1. Normal Q-Q: Examining whether the residuals are normally distributed
residuals_model7 <- residuals(model7)
hist(residuals_model7, main = "Histogram of Residuals (Model 7)", xlab = "Residuals")

Voila! The distribution of residuals in this model exhibits some characteristics of a normal distribution, with the majority of residuals centered around 0. The fact that the smallest residual value is -1.5 and the largest is 2 indicates the range of variation in the residuals. While the residuals may not perfectly conform to a normal distribution, the observed patterns do help consolidate the model’s assumption for residuals’ normal distribution.

  1. Scale - Location: Checking the homogeneity of the variance of the residuals
  1. Residuals vs Leverage: Checking for outliers

4. Prediction and Conclusions

Based on the correlations observed, an increase in the logarithm of accommodates is expected to positively influence the logarithm of the listing price, indicating that properties accommodating more guests tend to have higher prices. Additionally, a decrease in the logarithm of the relative distance, an increase in the logarithm of the bathroom number, and higher logarithm of review scores rating are associated with higher logarithm of prices, reflecting the impact of proximity to attractions, additional bathrooms, and positive reviews on pricing in the Airbnb listings. We’ll test these predictions out using the predict function:

Using the predict() function

lower_price <- data.frame(accommodates=1, relative_distance=0.95, bathroom_num=1, review_scores_rating=4)
lower_predicted <- predict(model7, lower_price)
lower_predicted
##        1 
## 3.692761
exp(lower_predicted)
##        1 
## 40.15558
medium_price <- data.frame(accommodates=3, relative_distance=0.7, bathroom_num=2, review_scores_rating=4)
medium_predicted <- predict(model7, medium_price)
medium_predicted
##        1 
## 4.535382
exp(medium_predicted)
##        1 
## 93.25912
higher_price <- data.frame(accommodates=7, relative_distance=0.5, bathroom_num=4, review_scores_rating=5)

higher_predicted <- predict (model7, higher_price)
higher_predicted
##        1 
## 5.281259
exp(higher_predicted)
##        1 
## 196.6173

Testing these predictions using the predict function provides insightful outputs. For a basic scenario with one accommodation, a relatively large distance to city center (0.95, where 1 is the maximum), minimal bathrooms, and a decent review score (4), the predicted price is approximately 40.16 dollars. Moving to a moderate-sized accommodation with improved amenities and more proximity to the center, the predicted price is estimated to be 93.26 dollars. Finally, for a larger accommodation with more facilities and a high review score (5), the predicted price is around $196.62. These results align with the expected trends.

5. Conclusions

My final regression model (Model 7) uncovers insights into the factors influencing Airbnb listing prices in Columbus. The model suggests that, on average, increasing the number of accommodates, having a closer distance to the city center, more bathrooms, and higher review scores are associated with higher listing prices. The confidence intervals provide a range for these effects, offering a 95% level of confidence in the average impact of each predictor variable on the price.

The model validation steps, including the residual analysis and diagnostic plots, indicate that the assumptions of linearity, normal distribution of residuals, and homoscedasticity are reasonably met. The predictions based on the model align with expectations, demonstrating the practical applicability of the analysis for potential hosts - although only to a certain extent.

However, it’s crucial to note some limitations. The model explains around 54.36% of the variability in listing prices, leaving a portion unexplained. Factors not included in the model may contribute to this unexplained variability. Additionally, while the model captures associations, causation cannot be inferred. Hosts should be cautious not to solely rely on these predictions, as individual circumstances and unique property features can significantly impact pricing.

In conclusion, this analysis provides an understanding of the key factors influencing Airbnb prices in Columbus, empowering potential hosts to make informed decisions.

6. Articles

In the first article, a new study from Northeastern University reveals unexpected findings about the relationship between Airbnb and neighborhood crime. The study, which analyzed nearly a decade’s worth of data, challenged the assumption that Airbnb primarily attracts tourists and leads to increased crime rates. Instead, the research showed that the number of buildings with Airbnb listings, rather than the volume of tourists, was a more accurate predictor of higher crime rates. The hypothesis behind this discovery is rooted in criminology, suggesting that Airbnb’s transient nature disrupts the social fabric of neighborhoods, making them less capable of naturally managing crime. The study focused on Boston and identified a significant increase in public violence, but not in public social disorder. The findings may lead to policy changes in the future. Airbnb has countered the study’s claims, but the research emphasizes the importance of addressing the broader neighborhood challenges posed by short-term rentals.

The second article delves into the impact of Airbnb on neighborhoods, focusing on the situation in Galveston, Texas. It shows the changing landscape, as traditional long-term residents are replaced by short-term visitors, leading to an eerie and somewhat lifeless atmosphere in these once-vibrant communities. The economic implications are evident, with lucrative opportunities for homeowners to cash in on their properties. However, this shift has also had considerable consequences, such as the loss of diversity and community cohesion. The discussion extends to how these changes might affect the community’s resilience to storms, given the loss of long-time residents who once played vital roles in disaster recovery efforts. It’s a complex issue that warrants thoughtful solutions, including potential restrictions on short-term rentals to maintain the delicate balance between economic growth and community well-being.

References

https://www.airbnb.com/help/article/125#:~:text=The%20total%20price%20of%20your,may%20include%20taxes%20as%20well.