2 · Entendimento dos dados¶
Números apurados por
src/airbnb/clean/pipeline.pyesrc/airbnb/eda/qualidade.pye gravados emdata/processed/_qualidade.json,_perguntas_equipe.jsone_correcoes_v0.json. São contagens sobre as bases inteiras — a única estimativa deste documento é a ocupação (§4), e ela vem com a validação do modelo.
1. Fontes primárias¶
| snapshot | fonte | arquivo | linhas × colunas | licença |
|---|---|---|---|---|
| 2019 (scrape de 2019-07-08) | Kaggle dgomonov/new-york-city-airbnb-open-data, v3 |
AB_NYC_2019.csv (formato resumo) |
48.895 × 16 | CC0 |
| 2026 (scrape de 2026-06-14) | Inside Airbnb | listings.csv.gz (detalhado) |
30.259 × 90 | CC BY 4.0 |
| 2026, conferência | Inside Airbnb | visualisations/listings.csv (resumo) |
30.555 × 19 | CC BY 4.0 |
| 2026, apoio | Inside Airbnb | avaliações (listing_id, date), polígonos e lista de bairros |
990.170 avaliações · 233 polígonos | CC BY 4.0 |
Proveniência, URL, bytes e SHA-256 de cada arquivo em
data/raw/FONTES.md;
a ingestão (python -m airbnb.ingest.baixar) confere o hash a cada execução e
aborta se um arquivo mudar.
Três fatos das fontes condicionam todo o resto:
- 2019 só existe no formato resumo. O Inside Airbnb publica para download apenas
os snapshots dos últimos 12 meses; o de 2019 responde HTTP 403. O Kaggle
republicou o resumo de julho de 2019 — 16 colunas, sem descrição do imóvel,
notas, amenidades, licença nem cotação. Toda comparação entre os anos usa só as
colunas comuns (
anuncios_resumo.parquet). - Em 2026, 12 colunas do detalhado vieram 100% vazias, entre elas
host_since,host_response_rate,host_acceptance_rateeinstant_bookable. Taxa de resposta e de aceitação do anfitrião não existem para este snapshot. - O
pricede 2026 não é a mesma grandeza dopricede 2019 (Q5). É o achado de maior consequência para a comparação de preços.
2. Perfil das bases¶
Depois da limpeza (Preparação dos dados); "preço válido"
exclui as linhas em quarentena de escopo preco.
| 2019 | 2026 | |
|---|---|---|
| anúncios | 48.895 | 30.257 |
anfitriões (host_id) |
37.457 | 16.472 |
| bairros com anúncio | 221 | 223 |
| células H3 r9 ocupadas | 3.515 | 3.432 |
| Manhattan · Brooklyn · Queens | 21.661 · 20.104 · 5.666 | 13.709 · 10.561 · 4.679 |
| Bronx · Staten Island | 1.091 · 373 | 976 · 332 |
| imóvel inteiro · quarto privativo | 52,0% · 45,7% | 55,5% · 42,0% |
| quarto compartilhado · quarto de hotel | 2,4% · — | 0,7% · 1,7% |
mínimo ≥ 30 noites (min30) |
9,2% | 81,7% |
| anúncios de anfitrião com mais de um anúncio | 33,9% | 56,1% |
| sem nenhuma avaliação | 20,6% | 28,3% |
calendário 100% fechado (availability_365 = 0) |
35,9% | 22,4% |
| preço mediano, mínimo < 30 noites | US$ 100 (n = 44.379) | US$ 308,50 (n = 5.012) |
| preço mediano, mínimo ≥ 30 noites | US$ 130 (n = 4.505) | US$ 144,36 (n = 16.102) |
7.516 anúncios de 2019 (15,4%) ainda existem em 2026, e 7.124 dos 37.457
anfitriões de 2019 ainda anunciam — base da análise de sobrevivência
(presente_2026).
Licença da OSE em 2026 (Local Law 18): 82,5% sem registro declarado, 9,8% "Exempt",
7,7% com número OSE-STRREG. O cruzamento com o mínimo de noites mostra a lei
funcionando como desenhada:
licenca_status |
mínimo < 30 | mínimo ≥ 30 |
|---|---|---|
| registrada | 2.268 | 61 |
| isenta | 2.905 | 51 |
| ausente | 367 | 24.605 |
Dos 5.540 anúncios de curta temporada, só 367 (6,6%) não declaram registro nem isenção.
3. As perguntas da equipe¶
As anotações de reports/v0/Análise.txt
viraram testes com número. Q1–Q3 rodam no bruto (antes da limpeza); Q4–Q6 na silver.
Q1 · "Id — único? Duplicados perfeitos?"¶
Único nos dois snapshots, e nenhuma duplicata perfeita — com ou sem o id.
| 2019 | 2026 | |
|---|---|---|
| linhas / ids distintos | 48.895 / 48.895 | 30.259 / 30.259 |
| duplicatas em todas as colunas | 0 | 0 |
| duplicatas em todas as colunas exceto o id | 0 | 0 |
| anúncios que dividem anfitrião e coordenada exata | 3 (1 grupo) | 3.638 (761 grupos; maior: 49) |
| … e também o preço | 2 | 2.064 |
| … e também o título | 0 | 466 |
| mesmo anfitrião com o mesmo título | 410 | 1.406 |
Os "duplicados semânticos" de 2026 não são duplicatas: são unidades distintas do mesmo prédio (1.957 imóveis inteiros, 1.212 quartos, 465 quartos de hotel), cada uma com id, calendário e avaliações próprios. Em 2019 isso quase não existia (3 anúncios), o que sugere que hoje o Airbnb publica a mesma coordenada para as unidades de um mesmo operador. Consequência para a modelagem: unidades do mesmo prédio em treino e teste inflariam a métrica — a validação cruzada por bloco H3 (ADR 0002) já as mantém juntas.
Q2 · "Campo vazio — excluídos?"¶
Nenhuma linha foi excluída por nulo. Os nulos de avaliação são estruturais:
| coluna | 2019 | 2026 | nulo ⟺ number_of_reviews = 0? |
|---|---|---|---|
last_review |
10.052 | 8.559 | sim, sem exceção |
reviews_per_month |
10.052 | 8.559 | sim, sem exceção |
first_review |
— | 8.559 | sim, sem exceção |
review_scores_rating |
— | 8.559 | sim, sem exceção |
review_scores_accuracy · _value |
— | 8.565 · 8.568 | quase: 6 e 9 anúncios avaliados sem a nota parcial |
Preencher reviews_per_month com 0, como a v0 fez, está certo: sem avaliação, a
taxa é zero. Já last_review não tem valor a imputar — fica nulo.
Outros nulos: em 2019, host_name (21) e name (16); em 2026, price (8.744 —
ver Q5), bathrooms (33,4%), bedrooms (36,3%), beds (31,1%), license (82,5%) e
os campos do anfitrião em 349 anúncios — 348 deles com has_availability = f
(anúncio desativado). A v0 excluiu as 16 linhas com name nulo sem necessidade:
todas tinham preço positivo, coordenada e bairro, e nenhuma análise usava name
(correção c, §4).
Q3 · "Host id — id do anfitrião; host_name — nome do anfitrião"¶
host_name não identifica ninguém; host_id sim.
| 2019 | 2026 | |
|---|---|---|
host_id distintos |
37.457 | 16.474 |
host_name distintos |
11.452 | 7.001 |
host_id com mais de um nome |
0 | 0 |
nomes usados por mais de um host_id |
3.125 (27,3% dos nomes) | 1.737 (24,8%) |
anúncios cujo host_name é compartilhado com outro anfitrião |
36.325 (74,3%) | 17.534 (58,0%) |
| anfitriões distintos com o nome mais comum | 335 | 154 |
Cada host_id tem um único nome, mas um mesmo primeiro nome cobre centenas de
anfitriões: agrupar por nome fundiria pessoas diferentes. Como é dado pessoal e não
serve de chave, host_name sai na limpeza (invariante 9). host_id fica na silver
— marcado pessoal, nunca publicado — porque mede concentração de oferta.
Q4 · "Latitude/longitude — mapa de calor, polígono do bairro"¶
Todos os pontos estão dentro de NYC e, na prática, dentro do polígono do bairro declarado — mas isso é tautológico.
| 2019 | 2026 | |
|---|---|---|
| dentro do envelope dos 5 distritos | 48.895 (100%) | 30.257 (100%) |
| dentro do polígono do bairro declarado | 48.878 (99,97%) | 30.257 (100%) |
| em outro bairro | 0 | 0 |
| fora de todos os polígonos (orla/água) | 17 — mediana de 84 m do bairro declarado, máx. 361 m | 0 |
| a menos de 150 m da fronteira do próprio bairro | 14.364 (29,4%) | 9.401 (31,1%) |
Por que quase nenhum ponto "cai em outro bairro": o Inside Airbnb atribui o bairro a partir da própria coordenada publicada — que já é a deslocada. Ponto e bairro não podem discordar, a não ser por diferença de versão dos polígonos (os 17 casos de 2019, todos na orla). O efeito do deslocamento de privacidade (0–450 pés, ~150 m, segundo https://insideairbnb.com/data-assumptions/) é sobre o endereço verdadeiro, que não observamos. O que dá para medir é o risco: ~30% dos anúncios estão a menos de 150 m de uma fronteira, e para eles o bairro real pode ser o vizinho. É o argumento quantitativo para a localização ser a célula H3 r9, não o ponto nem o bairro (ADR 0001), e para o "mapa de calor" pedido ser um coroplético de células H3 r8, não um heatmap de pontos.
O neighbourhoods.geojson tem 233 feições para 230 bairros (Bayswater, City Island e
Howard Beach vêm em duas partes) e 7 geometrias inválidas, corrigidas com
shapely.make_valid antes do cruzamento.
Q5 · "price — preço por noite?"¶
Em 2019, sim. Em 2026, é outra coisa.
2019 — diária anunciada pelo anfitrião, em dólares inteiros. Mediana US$ 106, média US$ 152,72, p99 US$ 799, máximo US$ 10.000; assimetria 19,1. Há 11 preços zero, nenhum entre US$ 1 e US$ 9, 3 anúncios a exatamente US$ 10.000 e 3 a US$ 9.999.
2026 — o price é uma cotação: o Inside Airbnb pede ao site o preço de uma
estadia de N noites a partir da primeira data livre e divide o total por N.
| evidência | resultado |
|---|---|
price = price_quote_price_per_night |
21.514 de 21.514 anúncios com os dois (100%) |
total da cotação = price × N |
100% |
| N = mínimo de noites do anúncio | 21.909 de 22.678 cotações (96,6%); mediana de N = 30 |
| check-in da cotação | mediana de 18 dias após o scrape |
| o total inclui | subtotal após desconto semanal/mensal, "Airbnb monthly stay savings" e ofertas; resort fee quando há; impostos em 58 cotações |
| o total não inclui | taxa de limpeza e taxa de serviço |
| cotações com algum desconto | 11.393 de 21.513 (53,0%) — mediana 0% (mín. < 30) e 4,3% (mín. ≥ 30); p90 de 22,9% no mín. ≥ 30; máximo 89,9% |
Consequência: para mínimo ≥ 30, o price de 2026 é a diária de um aluguel mensal
com desconto — não a diária de turista de 2019. Daí a coluna derivada preco_cheio
(a diária antes do desconto) e a regra de comparar só estratificado por mínimo de
noites e em dólar constante (ADR 0005,
invariante 8).
| mediana (preço válido) | mínimo < 30 | mínimo ≥ 30 |
|---|---|---|
2019, preco |
US$ 100 | US$ 130 |
2026, preco (com desconto) |
US$ 308,50 | US$ 144,36 |
2026, preco_cheio (sem desconto) |
US$ 313,00 | US$ 164,10 |
Por que há preço nulo (8.744 anúncios, 28,9%). 7.581 não têm cotação e 1.163 têm
cotação sem valor (datas indisponíveis). O nulo acompanha o calendário: é nulo em
6.790 dos 6.791 anúncios com availability_365 = 0 e em 8,3% dos demais — sem data
livre não há o que cotar.
Defeito da fonte: cotações de mais de 31 noites
Quando N passa de 31, o Airbnb devolve um total mensal ("Average monthly price") e o Inside Airbnb o divide por N noites. O preço por noite cai com N sem que o total mude:
| noites cotadas | anúncios | price mediano |
total mediano da cotação |
|---|---|---|---|
| 1–27 | 4.993 | US$ 308,50 | US$ 453 |
| 28–31 | 16.133 | US$ 144,57 | US$ 4.339 |
| 32–60 | 146 | US$ 89,98 | US$ 4.778 |
| 61–120 | 173 | US$ 61,35 | US$ 5.487 |
| 121–365 | 69 | US$ 25,62 | US$ 5.189 |
Um anúncio com mínimo de 365 noites aparece a US$ 4,58 a noite. Esses 388 anúncios com preço saem das análises de preço (regra P03), mas ficam na base.
Q6 · "reviews_per_month — é do host ou do anúncio? Por que tem mais que review per month?"¶
É do anúncio. Três testes:
Teste 1 — recalcular a partir do anúncio (2026). Avaliações do anúncio ÷ meses desde a primeira avaliação dele:
| definição | Pearson | concordância |
|---|---|---|
| total ÷ (dias desde a 1ª avaliação ÷ 30,44) | 0,978 | Spearman 0,999 |
number_of_reviews ÷ max(1; (last_scraped − first_review + 1 dia) ÷ 30) |
0,999998 | idêntico em 2 casas em 21.675 de 21.700 (99,9%); diferença ≤ 0,01 em 99,97% |
A segunda linha é a fórmula do Inside Airbnb, reconstruída: só usa dados do próprio anúncio.
Teste 2 — variação entre anúncios do mesmo anfitrião. Se a taxa fosse do anfitrião, seria constante entre os anúncios dele.
| 2019 | 2026 | |
|---|---|---|
| anfitriões com 2+ anúncios avaliados | 4.302 | 2.497 |
| com taxa diferente entre os anúncios | 4.234 (98,4%) | 2.468 (98,8%) |
Teste 3 — "tem mais que...". reviews_per_month maior que number_of_reviews:
0 casos nos dois snapshots, e é impossível por construção — o denominador tem
piso de 1 mês (1.558 anúncios em 2019 e 203 em 2026 têm a taxa igual ao total:
primeira avaliação há menos de um mês). O que parece "demais" são taxas acima de 30
avaliações/mês, mais de uma por dia, impossível para uma unidade só: 1 anúncio em 2019
(máx. 58,5) e 10 em 2026 (máx. 115,6; 7 quartos de hotel, 2 lofts, 1 pousada). São
anúncios que representam várias unidades — um tipo de quarto de hotel vendido como
um anúncio —, não agregação por anfitrião.
4. O que a v0 mediu e o que de fato mede¶
A v0 é uma boa leitura descritiva de 2019. Antes de comparar, o script dela (constante
PY_CODE do dashboard) foi reproduzido: 48.895 → 48.868 linhas (11 preços zero,
16 name nulos), ocupação geral de 69,1% — os mesmos números publicados.
(a) "Taxa de ocupação" = 1 − availability_365 ÷ 365¶
O que mede: a fração do calendário dos próximos 365 dias que está fechada — noite reservada e noite bloqueada pelo anfitrião, anúncio pausado, calendário que nunca foi aberto (invariante 7).
| evidência | 2019 | 2026 |
|---|---|---|
anúncios com availability_365 = 0 (a v0 os conta como 100% ocupados) |
17.533 (35,9%) | 6.789 (22,4%) |
| desses, com ocupação estimada zero (nenhuma avaliação em 12 meses) | — | 6.450 (95,0%) |
| ocupação estimada média desses anúncios | — | 1,5% |
correlação entre 1 − disponibilidade e a ocupação estimada |
— | Pearson −0,109 · Spearman −0,113 |
| "ocupação" média pela fórmula da v0 | 69,1% | 49,1% |
| ocupação média pelo modelo de avaliações | 28,7% | 14,4% (campo do Inside Airbnb) |
Em 2026, calendário 100% fechado é quase sempre anúncio parado, e a métrica da v0 anda na direção contrária da ocupação.
Como estimamos a ocupação. Modelo do Inside Airbnb (https://insideairbnb.com/data-assumptions/,
consultado em 2026-09-18): avaliações ÷ taxa de avaliação de 50% = reservas; reservas ×
estadia média (ou o mínimo de noites, se maior) = noites; teto de 70% do ano. A página
dá 3 noites como padrão para cidades sem dado público. Para NYC, o valor saiu do
próprio dado: estimated_occupancy_l365d de 2026 é reproduzido exatamente em
30.257 de 30.257 anúncios por min(round(avaliações_12m ÷ 0,5 × max(6,4; mínimo)); 255)
— estadia média de 6,4 noites, teto de 255 noites.
2019 não tem avaliações dos últimos 12 meses, só reviews_per_month (média da vida
inteira do anúncio). O proxy — a mesma fórmula com a taxa mensal × 12, zerada quando a
última avaliação tem mais de 365 dias — foi validado duas vezes:
| validação | proxy | referência | Spearman | Pearson | erro abs. médio |
|---|---|---|---|---|---|
2026, todos os anúncios (contra estimated_occupancy_l365d) |
18,9% | 14,4% | 0,977 | 0,886 | 5,6 p.p. |
| 2019, 7.516 sobreviventes (contra as avaliações de 12 meses reconstruídas do arquivo de 2026) | 29,5% | 25,5% | 0,938 | 0,887 | 6,8 p.p. |
| sem o corte de 365 dias (2026) | 30,6% | 14,4% | 0,622 | 0,618 | 17,3 p.p. |
O corte de atividade é o que faz o proxy funcionar; o viés residual é de +4,0 a +4,5 p.p. nas duas validações (quem já foi muito avaliado e desacelerou). Resultado para 2019:
| distrito | v0 (1 − disponibilidade) | modelo de avaliações |
|---|---|---|
| Manhattan | 69,3% | 26,5% |
| Brooklyn | 72,5% | 28,3% |
| Queens | 60,4% | 35,6% |
| Bronx | 54,6% | 37,6% |
| Staten Island | 45,3% | 41,3% |
| geral | 69,1% | 28,7% (mediana 16,4%; 40,4% dos anúncios com zero) |
A ordem se inverte: os distritos periféricos, que a v0 punha como os menos ocupados, são os de maior ocupação estimada por anúncio. Sensibilidade: com 3 noites de estadia média, 21,8%; sem o corte de atividade, 30,6% (6,4 noites) ou 23,1% (3 noites). Nenhuma variante chega perto de 69%.
O "rendimento potencial" (preço × ocupação) herda o problema:
| distrito | v0 (US$/noite) | preço × ocupação estimada (US$/noite) |
|---|---|---|
| Manhattan | 124,0 | 47,9 |
| Staten Island | 48,2 | 34,9 |
| Brooklyn | 86,3 | 33,7 |
| Queens | 57,7 | 32,4 |
| Bronx | 45,2 | 29,2 |
(b) drop do id antes do drop_duplicates¶
A v0 removeu id, host_name e last_review e só então procurou duplicatas. Sem a
chave, dois anúncios distintos com os mesmos atributos seriam fundidos. A verificação
certa é por id e, à parte, por todas as colunas exceto o id (regras B01 e B02). Efeito
nesta base: nenhum — 0 duplicatas por qualquer critério. Erro de método, não de número.
(c) dropna() por name¶
Depois de preencher reviews_per_month, só name ainda tinha nulo: o dropna() tirou
16 anúncios com preço, coordenada e bairro válidos por causa de um campo que
nenhuma análise usava. Esta versão os mantém.
(d) Pearson em variáveis de cauda pesada¶
A v0 usou df.corr() (Pearson). Com assimetria de 19,1 no preço, 21,0 no mínimo de
noites e 7,9 nos anúncios por anfitrião, o coeficiente é dominado pelos extremos.
Spearman (postos) mede a relação monotônica:
| par (2019, base da v0) | Pearson | Spearman |
|---|---|---|
| avaliações × avaliações/mês | 0,589 | 0,851 |
| anúncios do anfitrião × disponibilidade | 0,226 | 0,407 |
| preço × anúncios do anfitrião | +0,057 | −0,106 (inverte o sinal) |
| avaliações/mês × disponibilidade | 0,164 | 0,298 |
| mínimo de noites × avaliações/mês | −0,127 | −0,248 |
| preço × avaliações (insight 01 da v0) | −0,048 | −0,055 |
O insight 01 da v0 ("preço e procura praticamente não andam juntos") se sustenta com Spearman. Outras relações eram mais fortes do que a matriz mostrava, e uma trocava de sinal. Em 2026 (preço válido), a relação que mais muda é preço × mínimo de noites: −0,224 (Pearson) × −0,409 (Spearman) — a marca da cotação com desconto mensal.
O que a v0 acertou¶
"1 em cada 3 anúncios pertence a um anfitrião com outros imóveis" — 33,9%, confirmado. É fração de anúncios; de anfitriões são 13,8% em 2019. Em 2026: 56,1% dos anúncios e 19,4% dos anfitriões — a oferta se concentrou.
5. Onde os números moram¶
| arquivo (versionado) | conteúdo |
|---|---|
data/raw/_manifesto.json |
bytes, SHA-256, URL, data de acesso e licença de cada fonte |
data/processed/_qualidade.json |
regras de quarentena, cascata, nulos antes/depois, hash das saídas |
data/processed/_perguntas_equipe.json |
Q1–Q6 |
data/processed/_correcoes_v0.json |
(a)–(d), com a v0 reproduzida |
Nenhum deles contém nome, id de anúncio ou texto livre (invariante 9). Colunas e tipos: Dicionário de dados.