feat(scoring): Market Score v3 → v4 — fix Spain underscoring
- Lower count gate threshold: 5 → 3 venues (3 establishes a market pattern) - Lower density ceiling: LN(21) → LN(11) (10/100k is reachable for mature markets) - Better demand fallback: 0.4 → 0.65 multiplier + 0.3 floor (venues = demand evidence) - Fix economic context: income/200 → income/25000 (actual discrimination vs free 10 pts) Expected: Spain avg market score rises from ~54 to ~65-75. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -5,15 +5,18 @@
|
|||||||
--
|
--
|
||||||
-- Two scores per location:
|
-- Two scores per location:
|
||||||
--
|
--
|
||||||
-- Padelnomics Market Score (Marktreife-Score v3, 0–100):
|
-- Padelnomics Market Score (Marktreife-Score v4, 0–100):
|
||||||
-- "How mature/established is this padel market?"
|
-- "How mature/established is this padel market?"
|
||||||
-- Only meaningful for locations matched to a dim_cities row (city_slug IS NOT NULL)
|
-- Only meaningful for locations matched to a dim_cities row (city_slug IS NOT NULL)
|
||||||
-- with padel venues. 0 for all other locations.
|
-- with padel venues. 0 for all other locations.
|
||||||
--
|
--
|
||||||
-- 40 pts supply development — log-scaled density (LN ceiling 20/100k) × count gate
|
-- v4 changes: lower count gate (5→3), lower density ceiling (LN(21)→LN(11)),
|
||||||
-- 25 pts demand evidence — occupancy when available; 40% density proxy otherwise
|
-- better demand fallback (0.4→0.65 with 0.3 floor), economic context discrimination (200→25K).
|
||||||
|
--
|
||||||
|
-- 40 pts supply development — log-scaled density (LN ceiling 10/100k) × count gate (3)
|
||||||
|
-- 25 pts demand evidence — occupancy when available; 65% density proxy + 0.3 floor otherwise
|
||||||
-- 15 pts addressable market — log-scaled population, ceiling 1M
|
-- 15 pts addressable market — log-scaled population, ceiling 1M
|
||||||
-- 10 pts economic context — income PPS normalised to 200 ceiling
|
-- 10 pts economic context — income PPS normalised to 25,000 ceiling
|
||||||
-- 10 pts data quality — completeness discount
|
-- 10 pts data quality — completeness discount
|
||||||
--
|
--
|
||||||
-- Padelnomics Opportunity Score (Marktpotenzial-Score v4, 0–100):
|
-- Padelnomics Opportunity Score (Marktpotenzial-Score v4, 0–100):
|
||||||
@@ -146,34 +149,38 @@ market_scored AS (
|
|||||||
WHEN population > 0 OR COALESCE(city_padel_venue_count, 0) > 0 THEN 0.5
|
WHEN population > 0 OR COALESCE(city_padel_venue_count, 0) > 0 THEN 0.5
|
||||||
ELSE 0.0
|
ELSE 0.0
|
||||||
END AS data_confidence,
|
END AS data_confidence,
|
||||||
-- ── Market Score (Marktreife-Score v3) ──────────────────────────────────
|
-- ── Market Score (Marktreife-Score v4) ──────────────────────────────────
|
||||||
-- 0 when no city match or no venues (city_padel_venue_count NULL or 0)
|
-- 0 when no city match or no venues (city_padel_venue_count NULL or 0)
|
||||||
CASE WHEN COALESCE(city_padel_venue_count, 0) > 0 THEN
|
CASE WHEN COALESCE(city_padel_venue_count, 0) > 0 THEN
|
||||||
ROUND(
|
ROUND(
|
||||||
-- Supply development (40 pts)
|
-- Supply development (40 pts)
|
||||||
|
-- density ceiling 10/100k (LN(11)), count gate 3 venues
|
||||||
40.0 * LEAST(1.0, LN(
|
40.0 * LEAST(1.0, LN(
|
||||||
COALESCE(
|
COALESCE(
|
||||||
CASE WHEN population > 0
|
CASE WHEN population > 0
|
||||||
THEN COALESCE(city_padel_venue_count, 0)::DOUBLE / population * 100000
|
THEN COALESCE(city_padel_venue_count, 0)::DOUBLE / population * 100000
|
||||||
ELSE 0 END
|
ELSE 0 END
|
||||||
, 0) + 1) / LN(21))
|
, 0) + 1) / LN(11))
|
||||||
* LEAST(1.0, COALESCE(city_padel_venue_count, 0) / 5.0)
|
* LEAST(1.0, COALESCE(city_padel_venue_count, 0) / 3.0)
|
||||||
-- Demand evidence (25 pts)
|
-- Demand evidence (25 pts)
|
||||||
|
-- with occupancy: scale to 65% target. Without: 65% of supply proxy + 0.3 floor
|
||||||
|
-- (existence of venues IS evidence of demand)
|
||||||
+ 25.0 * CASE
|
+ 25.0 * CASE
|
||||||
WHEN median_occupancy_rate IS NOT NULL
|
WHEN median_occupancy_rate IS NOT NULL
|
||||||
THEN LEAST(1.0, median_occupancy_rate / 0.65)
|
THEN LEAST(1.0, median_occupancy_rate / 0.65)
|
||||||
ELSE 0.4 * LEAST(1.0, LN(
|
ELSE GREATEST(0.3, 0.65 * LEAST(1.0, LN(
|
||||||
COALESCE(
|
COALESCE(
|
||||||
CASE WHEN population > 0
|
CASE WHEN population > 0
|
||||||
THEN COALESCE(city_padel_venue_count, 0)::DOUBLE / population * 100000
|
THEN COALESCE(city_padel_venue_count, 0)::DOUBLE / population * 100000
|
||||||
ELSE 0 END
|
ELSE 0 END
|
||||||
, 0) + 1) / LN(21))
|
, 0) + 1) / LN(11))
|
||||||
* LEAST(1.0, COALESCE(city_padel_venue_count, 0) / 5.0)
|
* LEAST(1.0, COALESCE(city_padel_venue_count, 0) / 3.0))
|
||||||
END
|
END
|
||||||
-- Addressable market (15 pts)
|
-- Addressable market (15 pts)
|
||||||
+ 15.0 * LEAST(1.0, LN(GREATEST(population, 1)) / LN(1000000))
|
+ 15.0 * LEAST(1.0, LN(GREATEST(population, 1)) / LN(1000000))
|
||||||
-- Economic context (10 pts)
|
-- Economic context (10 pts)
|
||||||
+ 10.0 * LEAST(1.0, COALESCE(median_income_pps, 100) / 200.0)
|
-- ceiling 25,000 PPS discriminates between wealthy and poorer markets
|
||||||
|
+ 10.0 * LEAST(1.0, COALESCE(median_income_pps, 15000) / 25000.0)
|
||||||
-- Data quality (10 pts)
|
-- Data quality (10 pts)
|
||||||
+ 10.0 * CASE
|
+ 10.0 * CASE
|
||||||
WHEN population > 0 AND COALESCE(city_padel_venue_count, 0) > 0 THEN 1.0
|
WHEN population > 0 AND COALESCE(city_padel_venue_count, 0) > 0 THEN 1.0
|
||||||
|
|||||||
Reference in New Issue
Block a user