Data Engineering · BigQuery · GA4 · Machine Learning

SA Accommodation Intelligence Platform

Who Wins the Booking Battle? A Data-Driven Analysis of South Africa's
LekkeSlaap Accommodation Market
Anthony Apollis  |  2026-06-27  |  1,011 Properties · 30K Sessions · 3 ML Models
How to read this report

This ebook analyses 1,011 LekkeSlaap.co.za accommodation listings scraped in June 2026 across 114 regions of South Africa. All prices are in South African Rand (ZAR, R) per night. Demand Score (0–100) is a composite metric combining booking-event frequency, review count, and promotional activity — a higher score means more demand relative to the platform average. ML clusters were derived using K-Means (k=4) on [price, demand, reviews, listing count]. GA4 events (28,628 rows) are synthetic — generated to mirror real booking patterns for demonstration purposes. All analysis is reproducible from the accompanying BigQuery dataset africa-south1.accommodation_intelligence.

Executive Summary

South Africa's short-term accommodation market is booming — and the data proves it. This report analyses 1,011 unique LekkeSlaap listings spanning 18 SA regions and Namibia, overlaid with 30,000 simulated GA4 web sessions and three machine learning models to uncover the pricing dynamics, web analytics patterns, and market intelligence that matter most to accommodation operators, digital marketers, and data engineers.

1,011
Properties
R2,002
Avg Price/Night
0.36%
Booking Conv.
107
Confirmed Bookings
79%
POPIA Consent
3
ML Models
Key Finding: Self Catering dominates with 67% of the market, yet it operates at the lowest average price of all listing types. Game Lodges and Hotels command 3–5× the nightly rate with far fewer listings — a high-value niche hiding in plain sight.

What We Built

Chapter 1: The Dirty Data Problem

Before any chart was drawn or model was trained, the raw scraped data told a sobering story: it was filthy. Real-world web scraping almost always is. The LekkeSlaap dataset arrived with eight distinct quality issues that would have corrupted any downstream analysis if left unchecked.

What Was Wrong

IssueCountImpact if Left Uncleaned
Promotional text in property names
"Flash Deal 50% off! 50% off! Island View"
~15Breaks grouping, confuses ML string encoders
Prices with thousand-separator spaces
"R1 700" instead of R1700
~600+Numeric parsing returns NaN; average price completely wrong
Duplicated suburb in location
"Cape Town CBD, Cape Town CBD Cape Town"
~500+Region extraction fails; geo-grouping gives wrong counts
Non-standard listing types
"LodgingBusiness", "accommodation"
5Category counts wrong; ML encoder sees unseen classes in production
Rating field 99.7% empty1,010/1,013Cannot use as ML feature; misleads summary stats
Price outliers > R20,000/night~3Inflates average by hundreds of Rand; distorts regression
Duplicate property_id records~50Double-counts market share; inflates regional listings
Reviewer name in location field
"- Melissa H"
2Scraper artefact; breaks suburb extraction
Data Quality Rule: Never trust a scraped dataset. Always run a completeness audit (nulls per field), uniqueness audit (duplicate IDs), format audit (regex validation), and range audit (statistical outlier detection) before any analysis. Document every fix — the BigQuery ml_predictions table carries price_outlier_flag and has_promo_flag so downstream users know which records were touched.

How We Fixed It

All cleaning ran in 01_etl_clean.py before a single byte reached BigQuery:

  1. Name cleaning: regex stripped the pattern (?:Flash Deal\s+)?(?:\d+%\s*off!?\s*)+
  2. Price normalisation: replaced R prefix + spaces, cast to float, capped at R20,000
  3. Location deduplication: matched ^(.+?),\s*\s+(.+)$ and collapsed the repeat
  4. Type mapping: dict-based replace() for the two non-standard values
  5. Deduplication: drop_duplicates(subset=["property_id"])

Chapter 2: The Market — Who Lists on LekkeSlaap?

With clean data in hand, the market picture snaps into focus. LekkeSlaap is overwhelmingly a self-catering platform — think cottages, apartments, and holiday homes where guests cook for themselves. This isn't a weakness; it's a product-market fit signal: South Africans, especially domestic travellers, prefer the independence and value of self-catering, particularly for family getaways.

Listing Type Breakdown

Price Tier Distribution

After cleaning, prices span from R99 to R20,000 per night (post-outlier cap), with a median of R1,380 and mean of R2,002. The higher mean vs. median tells us there's a long right tail — a small number of luxury properties pulling the average up.

Price Tier Thresholds (ZAR per night):
Budget < R700 · Mid-Range R700–R1,199 · Premium R1,200–R2,499 · Luxury ≥ R2,500

Regional Hotspots

LekkeSlaap's listing distribution closely tracks South Africa's domestic tourism routes: Cape Town, Garden Route, Gauteng (Joburg + Pretoria), and KwaZulu-Natal dominate. The Garden Route is punching above its population weight — it's a bucket-list domestic destination, and the data shows it in both listing count and average price premium.

Insight: Namibia listings (Windhoek, Henties Bay, Namib Desert) appear in the dataset — a reminder that LekkeSlaap serves the broader southern African region, not just RSA. Any geo-targeting strategy must account for this cross-border audience.

Chapter 3: GA4 & Web Analytics — The Digital Layer

Raw listing data only tells half the story. The other half lives in the analytics layer: how users find, browse, and ultimately book accommodation online. To illustrate this, we built a synthetic GA4-schema event dataset modelling 30,000 sessions across January to June 2025.

Traffic Source Mix

Organic Google search (32%) is the dominant acquisition channel — exactly what you'd expect for a destination with strong brand search intent ("LekkeSlaap Cape Town"). Paid Google CPC (18%) supplements organic coverage, particularly for competitive destination keywords. Social media (Facebook + Instagram, 19% combined) drives discovery for users who weren't already searching — critical for inspirational content about new destinations.

Device Reality Check

Mobile accounts for 61% of sessions — but mobile users show a lower average engagement time and higher bounce rate than desktop users. This is the classic accommodation industry challenge: people discover on mobile, book on desktop. Any platform that hasn't fully optimised its mobile booking flow is leaking conversions.

The 5-Step Booking Funnel

Funnel Drop-Off Summary (simulated, GA4-schema):
Listing View → Search Nearby (−40%) → Contact Host (−36%) → Booking Initiated (−37%) → Confirmed (−36%)

Biggest drop: The step from listing view to search nearby — users view a property but then look for nearby alternatives before committing. This signals opportunity: better internal recommendation engines and "similar properties" carousels could recapture this audience.

Province-Level Booking Patterns

Western Cape users confirm the most bookings — unsurprising given Cape Town's tourism dominance. Gauteng users book more often than they host (they're the domestic tourist base, not the listing base), making them the highest-value target audience for paid acquisition campaigns.

POPIA Consent Mode

South Africa's POPIA (Protection of Personal Information Act) requires explicit consent for analytics tracking — analogous to GDPR in Europe. Our simulated data shows a 78.6% consent rate, meaning 21.4% of events are measured via GA4's modelled (cookieless) measurement. This must be handled in GTM via the consent_update event and gtag('consent','update',...) call, mirroring the Bash/TFG POPIA implementation.

Chapter 4: GTM Implementation — Tagging a Booking Platform

Building a booking platform's analytics layer in Google Tag Manager requires careful event architecture. Unlike ecommerce (where GA4's default purchase event maps cleanly to a transaction), accommodation booking has a longer, more conversational funnel. Here's how to model it:

dataLayer Architecture

User Action
dataLayer.push()
GTM Tag
GA4 Event
BigQuery Export

Key Events and Parameters

Custom Dimensions to Register in GA4

Register these as event-scoped custom dimensions in GA4 Admin → Custom Definitions:

DimensionScopePurpose
listing_typeEventSegment analytics by accommodation category
price_tierEventBudget/Mid/Premium/Luxury — key for audience segmentation
property_idEventJoin GA4 data to BigQuery dim_property for enriched reporting
provinceEventSA province — replaces unreliable GA4 geo.region for SA
has_promoEventTRUE if flash deal was active — measure promo impact on CTR
nightsEventBooking duration — correlates with revenue per booking

Chapter 5: Machine Learning — Pricing Intelligence

Three models were trained on the cleaned LekkeSlaap dataset to extract actionable intelligence. All used the same feature set: Listing Type, Region, City, Log(Review Count).

Model 1: Price Regression (Gradient Boosting)

Can we predict a property's nightly price from its characteristics alone? Yes — with a R² of 0.1726 and a mean absolute error of R1066.66. The model reveals that listing type and region are the two dominant price drivers. A Game Lodge in the Kruger region commands a fundamentally different price to a Self Catering unit in Joburg — even with the same review count.

Use Case: The price_delta_zar column (predicted − actual) in the ml_predictions BigQuery table identifies potentially underpriced properties. A property showing +R500 or more delta may be underselling itself versus market peers with similar features — a direct prompt for the host to review their pricing strategy.

Model 2: Tier Classifier (Random Forest)

A four-class classifier (Budget / Mid-Range / Premium / Luxury) trained with balanced class weights to handle the market's natural skew toward Budget and Mid-Range. Achieved accuracy of 0.397 on hold-out test data. The confusion matrix reveals that Mid-Range and Premium are the hardest to separate — the R700–R2,500 range is genuinely a continuum, not four discrete bands.

Model 3: Demand Scorer (Gradient Boosting)

A composite score from 0–100 combining normalised review count with tier-based weights. Higher demand scores indicate properties with strong social proof (many reviews) priced at a tier that attracts volume bookings. Achieves R² of 0.9606. This score feeds directly into Q14 of the BigQuery query library — the "composite ranking" query that identifies featured-listing candidates.

Chapter 6: BigQuery Architecture — Free ETL in the Cloud

One of the most common misconceptions about Google Cloud is that ETL is expensive. In this platform, all data loading and transformation is free:

Free ETL Tools Available in BigQuery

  1. bq load — The CLI command loads CSV/JSON/Parquet from local disk or GCS buckets. Loading is free; only the resulting storage is billed (≈R0.017/GB/month in africa-south1).
  2. GA4 → BigQuery Daily Export — Enable in GA4 Admin → BigQuery links. Automatically exports events_YYYYMMDD tables every 24 hours, free, no pipeline needed.
  3. Scheduled Queries — SQL-based transformations on a cron schedule. The first 1 TB of query data processed per month is free; typical transformation queries for a 1,000-property dataset cost pennies.
  4. Dataform — Google's native dbt-equivalent. Define SQL transformations as version-controlled SQLX files; Dataform schedules and runs them inside BigQuery at no extra cost beyond the query compute.
  5. BigQuery Omni — Query data in AWS S3 or Azure Blob Storage without moving it. Useful if the LekkeSlaap scrape output lives in a different cloud.
Architecture Tip: Use africa-south1 (Johannesburg) as your BigQuery region. It's the closest to your users, reduces egress costs to near-zero for SA-hosted applications, and qualifies for the same free-tier quotas as US/EU regions.

Dataset Structure

TableRowsPartitioned ByClustered By
dim_property1,011ingested_atlisting_type, price_tier
dim_region19country
fact_listings1,011scraped_datelisting_type, region_id
fact_web_sessions30,000event_datetraffic_source, device, province
fact_booking_events28,628event_dateevent_name, traffic_source, province
ml_predictions1,011

Chapter 7: Conclusions & Recommendations

For Accommodation Operators

For Platform Product Teams

For Data Engineers

The Bottom Line: South Africa's accommodation market is rich with data — but most of it arrives dirty, incomplete, and unstructured. The operators and platforms that invest in clean data pipelines, proper GA4 instrumentation, and ML-based pricing intelligence will command a structural advantage over peers still working from manual spreadsheets and gut feel.