Spatial Data Science Applied: ArcPy & Scikit learn for predicting Hotel Room prices.
Video showing the python toolbox functionality
1 – Objectives and Workflow
For this capstone project, we wanted to be able to estimate the price per night of hotel rooms in London. First, we had to gather data regarding the hotels and their prices, and also about features that could help us to explain that price.
In addition to this, we also wanted to develop a Machine Learning algorithm that could be easily distributed and reproducible by non-technical colleagues and clients. For this purpose, we will be creating a Python Toolbox that uses the XGBoost tree algorithm in the background.
As shown in the graphic below we used multiple data sources as well techniques for being able to predict hotel room prices. The main hotels' dataset was scraped using the Python libraries Scrapy and Selenium. For each hotel, we extracted the location, star rating, number, and reviews ranking as well as some qualitative information about hotel facilities such as internet, room service, swimming pool and so on.
The main driver of hotel room prices is the location so we also decided to include some of the more relevant characteristics around each hotel that could help us predict its value. Some of these variables are purchasing power of the population around each hotel, the number of housing transactions, distance to tourist points of interest, and communication to main airports as well as restaurant data (total number and reviews).
Once all the data was gathered we enriched our hotel dataset with these variables and using sci-kit learn and XGBoost algorithm we fit a model that was used to predict the hotel room prices. As mentioned before the final output is a Python Toolbox (to be used with ArcGIS Pro) that will allow users to run our findings without having a technical background.
2 – Data Engineering
Once the main data was gathered we had to 'join' each variable to the nearby hotels. For this, we first created an area of influence around each hotel of 500m and considered this as the vicinity of each hotel. As the graph shows then we computed a spatial join (ArcPy) between each of the variables and the hotel locations calculating different metrics depending on the feature. For the house transactions for example we calculated the median price and number of transactions.
Finally and as the below picture shows, we enriched the hotel dataset with demographic factors such as purchasing power, total population, or average household size. This data is accessible through the ArcGIS Online account through the function enrich_data.
3 – Clustering & EDA
As part of any Machine Learning project, we also performed an exploratory analysis to find which variables are important or correlate with our response variable as well as to transform our data if we identify any pattern that could affect the performance and reliability of our models.
The picture below shows the correlation matrix that allowed us to identify possible collinearity issues as well as the relation between the hotel room price and some of the variables.
As part of the EDA, we also identified that the hotel room price was skewed so we addressed this by applying a BoxCox transformation to some of the features. Also and in order to apply the Elastic Net linear model as well as unsupervised clustering methods we standardized the data.
To best understand the distribution of our data we also applied clustering using different clustering methods: K-Means clustering, DBSCAN, and HDBSCAN. Here we present the results of the DBSCAN algorithm which doesn't require each asset (hotel) to be assigned to one of the clusters, allows also some miss classified locations, reason why in this particular case we believe better fits the data. Below we present the main conclusions we extract from the clustering
- Initially, we create an elbow graph using the nearest neighbors that will allow us to determine the best epsilon for our DBSCAN model. The value of epsilon will ultimately determine the number of clusters we will have.
- We finally obtain a total of 6 clusters with some items miss classified (cluster -1). We see that clusters 1 and 3 with the highest price per room are located in areas with a great number of restaurants and in expensive residential areas.
- We also observe lower travel times to Tourist Points of Interest as well as a higher cost of Airbnb prices.
- The cluster englobes the non-classified hotels are located quite far from tourist locations and in what seems to be more family residential areas according to the average household size.
![]() |
![]() |
Here we show an interactive map showing the results of the different clusters together with the main characteristics of each filter. Access the map here.
4 – Machine Learning modelling
We decided to implement linear and tree modeling algorithms, Elastic Net from Scikit learn and XGBoost. For assessing the different models we split the dataset into 70% training set and 30% test set. Our main goal is not to get the greatest accuracy but to be able to create a model reproducible via an ArcGIS Python Toolbox.
After running several models we conclude that XGBoost is the one that better predicts the hotel room prices so this is the one that we finally will be using to deploy the tool.
- RMSE for train data: $20.5
- RMSE for test data: $45.9
The graph below shows how fro medium and low range prices the model predicts the room price quite well, when the room prices are higher the model is not performing that well.
5 – Tool deployment (Python Toolbox)
Once we have validated and tested different ML models we will implement them into an easy-to-use GUI for non-expert users to use. For this purpose, we will use ArcGIS Pro and ArcPy to create a Python Toolbox
These toolboxes can be distributed (as easy as sending a file), and users only need to indicate the input, output and other parameters of the model and the ML will be implemented on the desired data.
Below we have a small demo of how the tool works.