Um detector de visão computacional treinado do zero sobre imagens de satélite, combinado com amostragem estratificada e extrapolação estatística, para estimar quantas piscinas existem na maior cidade da América do Sul e revelar o que elas dizem sobre desigualdade. A computer-vision detector trained from scratch on satellite imagery, paired with stratified sampling and statistical extrapolation, to estimate how many pools exist in South America's largest city and reveal what they say about inequality.
Cada distrito pintado pela densidade estimada de piscinas. O ciano brilhante marca onde a água se concentra e ela desenha, quase perfeitamente, o mapa da renda da cidade. Every district shaded by its estimated pool density. Bright cyan marks where the water clusters tracing, almost perfectly, the city's income map.
Interativo passe o mouse sobre um distrito para ver piscinas estimadas, densidade e IPVS. Interactive hover a district for estimated pools, density, and IPVS.
Uma única célula de 500×500 m em Alto de Pinheiros. Cada caixa ciano é uma piscina encontrada pelo modelo sozinho, sem nenhuma marcação humana nesta imagem. A single 500×500 m cell in Alto de Pinheiros. Each cyan box is a pool the model found on its own, with no human labels on this image.
Ninguém sabe quantas piscinas São Paulo tem. Não há registro central. A pergunta parece trivial, mas responder exige unir três disciplinas. Nobody knows how many pools São Paulo has. There is no central registry. The question sounds trivial, but answering it means joining three disciplines.
Olhar a cidade inteira à mão é inviável: a malha urbana cabe em 6.094 células de 500×500 m. A solução é não olhar todas olhar uma amostra representativa, ensinar uma máquina a reconhecer piscinas nela, e projetar o resultado com uma margem de erro honesta. Inspecting the whole city by hand is impossible: its urban grid spans 6,094 cells of 500×500 m. The answer is to not look at all of them sample a representative subset, teach a machine to spot pools in it, and project the result with an honest margin of error.
A amostragem foi estratificada por distrito: piscinas se concentram em poucos bairros ricos, então sortear células uniformemente pela cidade daria uma estimativa péssima. O índice de vulnerabilidade social (IPVS) de cada distrito derivado de 27.301 setores censitários guiou onde amostrar mais. Sampling was stratified by district: pools cluster in a few wealthy neighborhoods, so uniform sampling would give a terrible estimate. Each district's social-vulnerability index (IPVS) derived from 27,301 census tracts guided where to sample more.
# cada célula herda o distrito onde cai seu centroide
grade["centro"] = grade.geometry.centroid
join = gpd.sjoin(centros, distritos, predicate="within")
# sorteia N células por distrito, guarda o peso de expansão
for distrito, grupo in grade.groupby("distrito"):
amostra = grupo.sample(n=25, random_state=42)
amostra["peso"] = len(grupo) / len(amostra) # N_h / n_h
O primeiro modelo era fraco. Cada versão atacou um gargalo específico, diagnosticado a partir dos números não por tentativa e erro cega. The first model was weak. Each version attacked a specific bottleneck, diagnosed from the numbers not by blind trial and error.
from ultralytics import YOLO
model = YOLO("yolo11s.pt") # transfer learning a partir do COCO
model.train(
data="data.yaml",
epochs=150,
imgsz=1024, # resolução maior → pega piscina pequena
patience=40, # early stopping: guarda o melhor modelo
)
# V3: mAP@50 = 0.71 | recall = 0.77 | precision = 0.72
Detectar piscinas é metade do trabalho. Transformar contagens numa estimativa honesta exige dois ajustes que a maioria dos projetos ignora. Detecting pools is half the work. Turning counts into an honest estimate needs two corrections most projects skip.
O modelo não é perfeito: acha 77% das piscinas (recall) e, do que aponta, 90% são reais (precision, medida à mão em 24 detecções). A contagem bruta é enviesada precisa ser corrigida antes de extrapolar. The model isn't perfect: it finds 77% of pools (recall) and, of what it flags, 90% are real (precision, hand-measured on 24 detections). Raw counts are biased they must be corrected before extrapolating.
Com 10 distritos medidos, a densidade de piscinas cai de forma quase linear conforme o IPVS sobe. Uma regressão captura essa relação e a projeta para os 96 distritos da cidade — zonas rurais vazias são filtradas por densidade populacional. Across 10 measured districts, pool density drops almost linearly as IPVS rises. A regression captures this and projects it across all 96 districts empty rural zones are filtered out by population density.
Variando as premissas (precision, recall, corte de renda), a estimativa fica entre 10.700 e 14.000. Reportar a faixa é o que separa uma medição honesta de um chute com aparência de precisão. Varying the assumptions (precision, recall, income cutoff), the estimate lands between 10,700 and 14,000. Reporting the range is what separates an honest measurement from a guess dressed as precision.
A densidade de piscinas segue a renda com uma nitidez quase linear. Do distrito mais rico ao mais pobre da amostra: Pool density tracks income with almost linear clarity. From the richest to the poorest sampled district:
Alto de Pinheiros (IPVS 1,1) tem cerca de 13× mais piscinas por área que Artur Alvim (IPVS 2,5). A água, vista do espaço, desenha o mapa da desigualdade.
Alto de Pinheiros (IPVS 1.1) has roughly 13× more pools per area than Artur Alvim (IPVS 2.5). Water, seen from space, draws the map of inequality.
A estimativa de ~12.000 piscinas é deliberadamente um piso. O que o método não vê: The estimate of ~12,000 pools is deliberately a floor. What the method doesn't see:
O resultado mais robusto não é o número absoluto é o padrão socioeconômico e um pipeline reprodutível que qualquer pessoa pode rodar e auditar. The most robust result isn't the absolute number it's the socioeconomic pattern and a reproducible pipeline anyone can run and audit.