Skip to content

Latest commit

 

History

2 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

🏛️ Vienna Causal Pricing: Econometric Identification & Hedonic Gradient Analysis

Cross-Sectional Market Extraction & Spatial Hedonic Modeling in Municipal Vienna

Python SeleniumBase Proxy.py Pandas NumPy Statsmodels Jupyter uv License: MIT


An enterprise-grade causal inference and data engineering repository investigating hedonic price decay gradients and quality premiums within the municipal accommodation market of Vienna, Austria.

Engineered to demonstrate dual competency in rigorous econometrics (admissions standard for LSE/UCL causal data science programs) and production-grade software infrastructure (tech startup engineering standard).


🛠️ Technology & Software Stack

Category Technology / Package Target / Version Architectural Function
Language Python >= 3.12 Core computing environment & execution pipeline
Anti-Bot Driver SeleniumBase >= 4.30.0 Undetected Chromedriver (uc=True) bypassing Cloudflare / anti-bot challenges
Network Router proxy.py >= 2.4.0 Asynchronous local proxy tunnel isolating residential ISP footprint
HTML Parser BeautifulSoup4 + lxml >= 4.12.0 C-speed DOM parsing on instantaneous in-memory HTML snapshots
Econometric Engine Statsmodels >= 0.14.0 Hedonic OLS regressions, robust standard errors (HC3), parameter conditioning
Data Matrix Pandas & NumPy >= 2.0.0 Vectorized quality gates, array transformations, and cross-sectional audits
Data Visualization Seaborn & Matplotlib >= 3.7.0 Empirical density plots, hedonic spatial gradient scatter, box plots
Workflow Lab Jupyter Notebooks nbformat 4 Interactive modular research notebooks (causal-notebooks/)
Package Manager Astral uv Latest High-performance deterministic virtual environment manager
Configuration PyYAML >= 6.0 Decoupled YAML configuration separating code from parameters

🏛️ Executive Summary & Research Question

In urban economics and consumer search theory, spatial proximity to central commercial and cultural hubs commands a measurable pricing premium. However, estimating this gradient in digital accommodation markets introduces a critical identification hazard: the simultaneity and temporal price drift problem.

Modern online travel agencies (OTAs) utilize real-time algorithmic pricing engines that dynamically update rates based on demand, concurrent user sessions, and localized inventory shocks. If a data collection pipeline takes 30 minutes to paginate across a city, prices recorded at listing #1 and listing #400 reflect temporal market drift rather than true cross-sectional equilibrium prices.

Methodological Solution:

  • Anti-Drift Dynamic DOM Snapshotting: The extraction infrastructure hydrates 436+ municipal properties into a single active DOM instance and executes an instantaneous in-memory snapshot (driver.page_source). All listings are captured within a synchronized sub-second window, neutralizing algorithmic price drift.
  • Construct Validity: All distances are geodetically standardized to statutory radial miles from Vienna's Kilometre Zero (Stephansplatz: $48.2085^\circ\text{ N}, 16.3738^\circ\text{ E}$).

🗺️ Structural Hierarchy & System Map

This repository adheres to enterprise separation of concerns, isolating data collection mechanics from causal estimation pipelines:

📁 vienna-causal-pricing/
│
├── 📄 .gitignore                 ◄── Enterprise hygiene (blocks cache, venv, and raw data binaries)
├── 📄 LICENSE                    ◄── Open-source MIT License
├── 📄 README.md                  ◄── Executive pitch, architecture map, and replication guide
├── 📄 requirements.txt           ◄── Deterministic dependency locks (Pandas, Statsmodels, Seaborn)
│
├── 📁 infra-scraper/             ◄── THE COLLECTION LAB (Isolated Infrastructure)
│   ├── 📄 README.md              ──► Technical specs of the anti-drift acquisition loop
│   ├── 📄 pipeline_scraper.py    ──► Clean, parameterized collection code (SeleniumBase UC + proxy)
│   ├── 📄 config.yaml            ──► Local execution parameters (Git-ignored)
│   └── 📄 config.yaml.example    ──► Sanitized configuration template for external replication
│
├── 📁 data-warehouse/            ◄── MATRIX STORAGE (Git-Ignored Data Assets)
│   ├── 📄 .gitkeep               ──► Preserves folder structure in Git without committing binaries
│   └── 📄 hotels_vienna_scraped_raw.csv  ──► Local data asset (Git-ignored to avoid legal bloat)
│
└── 📁 causal-notebooks/          ◄── CAUSAL ESTIMATION PIPELINES (Chapter-by-Chapter)
    ├── 📄 phase1_module1_eda.ipynb   ──► Exploratory Data Analysis & Quality Audits
    ├── 📄 phase3_module3_ols.ipynb   ──► Hedonic Regression Conditioning Machine
    └── 📄 phase6_module6_did.ipynb   ──► Quasi-Experimental Policy Evaluator

🛡️ Legal & Security Hygiene Matrix

To prevent Legal/Terms of Service redistribution flags and credential leakage:

  • Zero Live Endpoints in Git: The scraper code (pipeline_scraper.py) is completely parameterized through config.yaml. No live URLs or tokens are hardcoded.
  • Scrubbed Template: Only config.yaml.example is tracked in version control.
  • Binary Isolation: Raw data files (*.csv, *.xlsx) are strictly git-ignored. Users store their raw matrices locally in data-warehouse/ while keeping the remote repository lightweight and compliant. Raw replication assets are archived on open-science platforms (e.g., Open Science Framework - OSF).

📊 Econometric Quality Gates & In-Line Assertions

The collection pipeline executes strict programmatic assertions prior to persisting datasets:

============================================================
RUNNING IN-LINE ECONOMETRIC QUALITY GATES
============================================================
PASS: df['hotel_id'].is_unique passed (436 unique records).
PASS: Sample size (436) meets critical threshold (>= 100).
PASS: B&K Econometric Benchmark achieved: 436 >= 428 properties.

MISSING VALUE REPORT:
  price:     0.00% (Zero missingness)
  distance:  0.00% (Zero missingness, normalized to statutory miles)
  rating:    3.90% (Newly listed/unreviewed boutique units)
  stars:    75.92% (Unrated apartments/pensions)

🚀 One-Click Replication Guide

1. Clone & Set Up Environment

git clone https://github.com/hashexplaindata/vienna-causal-pricing.git
cd vienna-causal-pricing

# Install pinned dependencies
pip install -r requirements.txt
# Alternatively, with uv:
uv pip install -r requirements.txt

2. Execute Causal EDA Notebook

Open and run causal-notebooks/phase1_module1_eda.ipynb in your favorite Jupyter environment:

jupyter lab causal-notebooks/phase1_module1_eda.ipynb

The notebook utilizes zero-config relative pathing (../data-warehouse/hotels_vienna_scraped_raw.csv) and runs out-of-the-box.

3. Re-Running the Collection Lab (Optional)

cd infra-scraper
cp config.yaml.example config.yaml

# Run live scraper with headed browser
python pipeline_scraper.py

⚖️ License

This project is licensed under the MIT License - see the LICENSE file for details.

Releases

Packages

Contributors

Languages