Five demos that geospatial data scientists get paid for in real estate — site scoring, neighbourhood typology, decomposition of price per m², crew allocation and a live proof of leakage through geography — plus a review of real deployments. The maps run on a synthetic city; the cases and coefficients are real, with links to primary sources.
What the map shows
What are we looking for
The preset sets the weights. After that turn the dials yourself — the map recomputes on every move.
Factor weights
Layers
Each hexagon is a cell roughly 400 m across, an analogue of the H3 grid (a custom implementation here, so the file works offline). In scoring mode the colour is the final score from 0 to 100 relative to the best cell in the city; in “Location premium” mode it is price per m² relative to the city median. A thin black outline marks the top 5, purple marks the selected cell. The weights on the left are coefficients of an interpretable scoring model: in production they are not set by hand but learned from outcomes (revenue, sales velocity), and only then do they become real feature importance. Semi-transparent cells fall under building restrictions: a heritage protection zone, an airport approach area and a water protection strip. They are excluded from the ranking.
An honest caveat about “Location premium” mode. The metro coefficient was measured on proximity to a station — for KB Strelka that is the first few hundred metres. Here it is extended linearly across the whole map, so in distant cells what is at work is no longer a measured relationship but an artificial floor of −18%. Such rows are tagged “extrapolation” in the cell breakdown, and there are . This is exactly the mistake hedonic models are criticised for most often: a coefficient pushed beyond the range it was estimated on stops measuring anything at all.
Cell breakdown
Top 5 sites
Scoring answers the question “where is better”. Clustering answers a different one: how many types of territory the city has at all, and which of them the market has not yet repriced. This is the pivot from “find the best site” to “understand where the headroom is” — the very gap between accessibility and price that people make money on.
Method
Ward agglomerative clustering on six neighbourhood features. The tree is built once, with no k as input — the number of clusters is chosen afterwards, by cutting it where the branches diverge far apart. But you still have to choose k, and that is the analyst’s call: move the slider and check that the conclusion does not flip.
A neighbourhood here is a 3×3 block of hexagons by grid index, so the borders come out stepped: in adjacent rows the hexagons are offset by half a cell. In a production task the parent H3 cell at a coarser resolution goes here — that is exactly what the grid hierarchy was invented for.
Parameters
Where the headroom is
Dendrogram and cut line
Horizontally — neighbourhoods; vertically — the z-distance at which they merged. The features are standardised, and the scale is the length of the divergence vector across all six at once: one unit means a combined divergence of one standard deviation, not one sigma on a single feature. The higher the merge, the more different the groups being joined. The dashed line is the current cut.
Cluster profiles: deviation from the city average
Right — above the city average, left — below. That is how you read the meaning of a cluster: “high accessibility, low price” is headroom the market has not reached yet; “high accessibility, high price” is a mature market where you buy in expensive. Exactly this technique was applied in a study of Dubai: neighbourhoods were clustered by accessibility to malls, density of points of attraction and median price, and then compared with a map of development projects already under way — which showed that construction goes either into saturated zones or out to the periphery, missing the cluster with a lower price and good accessibility. The author of that study is Elena Skrebkova, the work was done on Inessa Tregubova’s spatial analysis course.
Property parameters
What is nearby
Factor contributions to price per m²: the Bonus / Malus table
This is a SHAP-style decomposition: a city base price plus the contribution of each feature. In valuation practice such a table is called Bonus/Malus — it translates the model output into the language of the sales comparison approach, where the appraiser must justify every adjustment, as the IVS and RICS standards require. Without it a bank, a court and the tax authority will not rely on a number from a model. The GEO tag marks a feature that is not asked of the seller but computed from data: an isochrone over the street graph, a buffer over OSM polygons, distance to an industrial zone. Hover over a row — I will show where the feature comes from.
The reference point of 210,000 ₽/m² (≈ $2,500 at 83 ₽/$) is not the city average price but the value before any adjustments: every row is counted from it, which is why they add up to the total exactly. The coefficients are orders of magnitude from published research, not a valuation of your flat. The metro effect (+1.5% within a five-minute walk, falling away beyond 500 m) comes from the work of KB Strelka on a sample of 71,200 Moscow flats. Panoramic view: the agency Miel valued the premium for a panoramic view in Moscow at 10–15% — but that is a 2013 estimate with no published methodology, so a conservative 12% is used here. And the same remark as on the map: the “walk to metro” slider goes up to 30 minutes, while the coefficient was measured on the first few hundred metres, so the right half of the scale is extrapolation, not measurement. In a production model such coefficients are not entered by hand — they are pulled out of a trained boosting model via SHAP, and they differ for every neighbourhood. And one more honest caveat: contributions here are computed sequentially, off the accumulated price, so the sum depends on row order — real SHAP is additive and order-independent.
Problem formulation
Parameters
What came out
Load by crew
Three formulations give three different answers on one and the same map. p-median (Hakimi, 1965) minimises total weighted travel time — good for the economics, but it abandons the outskirts. p-center (Hakimi, 1964) cuts the worst case — that is about an SLA of “an engineer on site within N minutes”. MCLP (Church, ReVelle, 1974) maximises the share of jobs within the target for a fixed number of crews: it honestly admits that the budget will not cover everything. In a real project you then add crew capacity, skills and the daily supply route — that is, a VRP with time windows.
The same maths in urban redevelopment. Moscow’s renovation programme rehouses residents of ageing low-rise blocks into newly built ones, and it runs on the same constraint. The Law on the Status of the Capital (art. 7.3) requires that equivalent housing be provided in the same district of Moscow — the only exception is the Zelenogradsky, Troitsky and Novomoskovsky okrugs, where it is within the okrug. Add the programme’s operating scheme: starter site → resettlement → demolition → the next building on the freed-up land. What you get is an assignment problem with a schedule: which blocks to open first, which site serves which buildings, how to fit the master timeline into the annual completion cap. The price of the solution is the duration of the programme, the volume of temporary housing and the number of people who had to be moved out of their own neighbourhood after all.
The kitchen behind the first three tabs: how raw imagery and coordinates turn into a model, and where that model most often lies.
Pipeline: from imagery to decision
Leakage through geography
The classic geo-ML trap. If you split the sample at random, flats from the same building land in both training and test — the model memorises the price of the building, not the pattern. Turn the between-building spread and watch the metrics diverge.
Experiment parameters
Result
What the sliders do. Between-building spread sets how much buildings differ from one another, all else equal: at zero the colour changes smoothly across the map, at maximum every building becomes a separate blob — and it is that blob that later leaks through a random split. Neighbours in kNN changes the number of lines from the selected point: click any test point to see where the model gets its answer from. In a random split the neighbours turn out to be in the same building; in a split by building it has to reach into other ones. The radius of a test point is its prediction error.
The model is one and the same — kNN on coordinates, that is, exactly what any boosting model with geo-features effectively does.
Only the way the sample is split changes. With a random split every test flat has training neighbours on the same stairwell, and the model simply copies their price: MAPE looks wonderful.
A split by building moves an entire building into the test — and what is left is the honest error on a property the model has never seen. Set the between-building spread to zero: the gap collapses from over seven times to two or three, but it never reaches zero — this is the irreducible interpolation error on unfamiliar territory.
In production this is Spatial K-Fold: an entire building or a DBSCAN cluster goes into a fold. Map blocks are the next step, if the model is going to travel to an unfamiliar district. Only “cutting into blocks” does not yet mean “validating strictly”: below is a count of what each of the four schemes actually gives you, and where the trap is in them.
Two more checks that save months. First — a linear baseline: in a study of the Cagliari market on 1,153 listings a neural network won on metrics, but the margin over ordinary linear regression turned out to be small, and the authors state plainly that non-linear models gave no large advantage. Before defending a budget for boosting, count how much it actually wins back over regression. Second — missing values. Empty fields in a listing are not dropped and not filled with the mean, but coded as a separate category “not specified”: what the seller leaves out correlates with the market segment. If someone did not write in the state of the renovation — that is a feature too.
Four fold-cutting schemes — and why “in blocks” on its own guarantees nothing
Here it is the same model and the same 468 listings, but full cross-validation: every point lands in the test exactly once, so the arbitrary choice of “let us hold out this piece” is removed from the result. The sliders above act on this table too — turn the between-building spread and watch the row order change. The buttons to the left of the map show any of the four schemes on the map itself.
The block grid in the second and third rows is the same — 4 × 2 over the whole map, eight folds. The difference between them is one thing: where to assign a building whose courtyard the block border ran through. With the cut by points, some of its flats go to the test and some stay in training, and the test ones again get a neighbour from their own building — the very mechanism a random split cheats with, just at a smaller scale. With the cut by buildings a block is assembled from whole buildings, and there is no leakage: in the first row it is almost five neighbours out of five from the flat’s own building, in the second about one, in the last two exactly zero.
But comparing blocks with leave-one-building-out on a “which is stricter” basis is meaningless, and this cost me a rewritten paragraph in the article. The order of the last two rows changes together with the between-building spread, because the miss is made up of two different things: the model not knowing the building’s own premium, and it not knowing how price works in this part of the map. A block pushes the neighbours twice as far away and increases the second component, but the first one shrinks slightly, and in sum they partly cancel each other out — the figures in the verdict above are recomputed at every slider position. So you choose the scheme not by folklore but for the risk that actually scares you: an unfamiliar building in a familiar district, or an unfamiliar district as a whole. The one thing that does not depend on anything is the counter of neighbours from a flat’s own group. If it is not zero, the validation is measuring something other than what you think.