diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 55c4809f..3a2c2a9e 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -48,8 +48,8 @@ jobs: python -m pip install --upgrade pip pip install -e .[dev] - - name: Generate databases - run: python cities/utils/csv_to_db_pipeline.py + # - name: Generate databases + # run: python cities/utils/csv_to_db_pipeline.py - name: Test diff --git a/.gitignore b/.gitignore index 0cbf1626..df8277e4 100644 --- a/.gitignore +++ b/.gitignore @@ -30,6 +30,12 @@ tests/.coverage .vscode/launch.json data/sql/counties_database.db data/sql/msa_database.db +docs/experimental_notebooks/zoning/interactions_preds.dill +docs/experimental_notebooks/zoning/population_preds.dill +docs/experimental_notebooks/zoning/waic_dict_7.pkl +docs/experimental_notebooks/zoning/waic_dict_13.pkl +docs/experimental_notebooks/zoning/waic_dict_14.pkl + .Rproj.user **/*.RData @@ -42,6 +48,8 @@ data/minneapolis/sourced/demographic/** data/minneapolis/preds/** data/minneapolis/sourced/parcel_to_census_tract_mappings/** data/minneapolis/sourced/parcel_to_parking_info_mappings/** + +data/minneapolis/.pgpass cities/deployment/tracts_minneapolis/tracts_model_guide.pkl cities/deployment/tracts_minneapolis/tracts_model_params.pth build/cities/deployment/tracts_minneapolis/tracts_model_guide.pkl diff --git a/Makefile b/Makefile index 62670a78..3fff98ae 100755 --- a/Makefile +++ b/Makefile @@ -1,10 +1,20 @@ format: FORCE ./scripts/clean.sh + +path ?= . + +format_path: FORCE + ./scripts/clean_path.sh $(path) + lint: FORCE ./scripts/lint.sh test: FORCE + ./scripts/test.sh + +test_all: FORCE + ./scripts/clean.sh ./scripts/lint.sh ./scripts/test.sh ./scripts/test_notebooks.sh diff --git a/build/.env b/build/.env new file mode 100644 index 00000000..c1e54d7a --- /dev/null +++ b/build/.env @@ -0,0 +1,10 @@ +GOOGLE_CLOUD_PROJECT=cities-429602 +GOOGLE_CLOUD_BUCKET=minneapolis-basis + +ENV=dev +INSTANCE_CONNECTION_NAME=cities-429602:us-central1:cities-devel +DB_SEARCH_PATH=dev,public +HOST=34.123.100.76 +SCHEMA=minneapolis +DATABASE=cities +DB_USERNAME=postgres diff --git a/build/Dockerfile b/build/Dockerfile new file mode 100644 index 00000000..cb1144de --- /dev/null +++ b/build/Dockerfile @@ -0,0 +1,10 @@ +FROM python:3 + +WORKDIR /usr/src/app + +COPY requirements.txt ./ +RUN pip install --no-cache-dir -r requirements.txt + +COPY . . + +CMD [ "python", "main.py" ] diff --git a/build/api/Dockerfile b/build/api/Dockerfile new file mode 100644 index 00000000..cb1144de --- /dev/null +++ b/build/api/Dockerfile @@ -0,0 +1,10 @@ +FROM python:3 + +WORKDIR /usr/src/app + +COPY requirements.txt ./ +RUN pip install --no-cache-dir -r requirements.txt + +COPY . . + +CMD [ "python", "main.py" ] diff --git a/build/api/main.py b/build/api/main.py new file mode 100644 index 00000000..fbfcea0b --- /dev/null +++ b/build/api/main.py @@ -0,0 +1,235 @@ +import os + +from typing import Annotated + +from dotenv import load_dotenv +from fastapi import FastAPI, Depends, Query +from fastapi.middleware.gzip import GZipMiddleware +import uvicorn + +import psycopg2 +from psycopg2.pool import ThreadedConnectionPool + +load_dotenv() + +ENV = os.getenv("ENV") +USERNAME = os.getenv("DB_USERNAME") +PASSWORD = os.getenv("PASSWORD") +HOST = os.getenv("HOST") +DATABASE = os.getenv("DATABASE") +DB_SEARCH_PATH = os.getenv("DB_SEARCH_PATH") +INSTANCE_CONNECTION_NAME = os.getenv("INSTANCE_CONNECTION_NAME") + +app = FastAPI() + +if ENV == "dev": + from fastapi.middleware.cors import CORSMiddleware + + origins = [ + "http://localhost", + "http://localhost:5000", + ] + app.add_middleware(CORSMiddleware, allow_origins=origins, allow_credentials=True) + +app.add_middleware(GZipMiddleware, minimum_size=1000, compresslevel=5) + + +if ENV == "dev": + host = HOST +else: + host = f"/cloudsql/{INSTANCE_CONNECTION_NAME}" + +pool = ThreadedConnectionPool( + 1, + 10, + user=USERNAME, + password=PASSWORD, + host=HOST, + database=DATABASE, + options=f"-csearch_path={DB_SEARCH_PATH}", +) + + +def get_db() -> psycopg2.extensions.connection: + db = pool.getconn() + try: + yield db + finally: + pool.putconn(db) + + +predictor = None + + +def get_predictor(db: psycopg2.extensions.connection = Depends(get_db)): + from cities.deployment.tracts_minneapolis.predict import TractsModelPredictor + + global predictor + if predictor is None: + predictor = TractsModelPredictor(db) + return predictor + + +Limit = Annotated[float, Query(ge=0, le=1)] +Radius = Annotated[float, Query(ge=0)] +Year = Annotated[int, Query(ge=2000, le=2030)] + + +@app.middleware("http") +async def add_cache_control_header(request, call_next): + response = await call_next(request) + response.headers["Cache-Control"] = "public, max-age=300" + return response + + +if ENV == "dev": + + @app.middleware("http") + async def add_acess_control_header(request, call_next): + response = await call_next(request) + response.headers["Access-Control-Allow-Origin"] = "*" + return response + + +@app.get("/demographics") +async def read_demographics( + category: Annotated[str, Query(max_length=100)], db=Depends(get_db) +): + with db.cursor() as cur: + cur.execute( + """ + select tract_id, "2011", "2012", "2013", "2014", "2015", "2016", "2017", "2018", "2019", "2020", "2021", "2022" + from api__demographics where description = %s + """, + (category,), + ) + return [[desc[0] for desc in cur.description]] + cur.fetchall() + + +@app.get("/census-tracts") +async def read_census_tracts(year: Year, db=Depends(get_db)): + with db.cursor() as cur: + cur.execute("select * from api__census_tracts where year_ = %s", (year,)) + row = cur.fetchone() + + return row[1] if row is not None else None + + +@app.get("/high-frequency-transit-lines") +async def read_high_frequency_transit_lines(year: Year, db=Depends(get_db)): + with db.cursor() as cur: + cur.execute( + """ + select line_geom_json + from api__high_frequency_transit_lines + where '%s-01-01'::date <@ valid + """, + (year,), + ) + row = cur.fetchone() + + return row[0] if row is not None else None + + +@app.get("/high-frequency-transit-stops") +async def read_high_frequency_transit_stops(year: Year, db=Depends(get_db)): + with db.cursor() as cur: + cur.execute( + """ + select stop_geom_json + from api__high_frequency_transit_lines + where '%s-01-01'::date <@ valid + """, + (year,), + ) + row = cur.fetchone() + + return row[0] if row is not None else None + + +@app.get("/yellow-zone") +async def read_yellow_zone( + year: Year, line_radius: Radius, stop_radius: Radius, db=Depends(get_db) +): + with db.cursor() as cur: + cur.execute( + """ + select + st_asgeojson(st_transform(st_union(st_buffer(line_geom, %s, 'quad_segs=4'), st_buffer(stop_geom, %s, 'quad_segs=4')), 4269))::json + from api__high_frequency_transit_lines + where '%s-01-01'::date <@ valid + """, + (line_radius, stop_radius, year), + ) + row = cur.fetchone() + + if row is None: + return None + + return { + "type": "FeatureCollection", + "features": [ + {"type": "Feature", "properties": {"id": "0"}, "geometry": row[0]} + ], + } + + +@app.get("/blue-zone") +async def read_blue_zone(year: Year, radius: Radius, db=Depends(get_db)): + with db.cursor() as cur: + cur.execute( + """ + select st_asgeojson(st_transform(st_buffer(line_geom, %s, 'quad_segs=4'), 4269))::json + from api__high_frequency_transit_lines + where '%s-01-01'::date <@ valid + """, + (radius, year), + ) + row = cur.fetchone() + + if row is None: + return None + + return { + "type": "FeatureCollection", + "features": [ + {"type": "Feature", "properties": {"id": "0"}, "geometry": row[0]} + ], + } + + +@app.get("/predict") +async def read_predict( + blue_zone_radius: Radius, + yellow_zone_line_radius: Radius, + yellow_zone_stop_radius: Radius, + blue_zone_limit: Limit, + yellow_zone_limit: Limit, + year: Year, + db=Depends(get_db), + predictor=Depends(get_predictor), +): + result = predictor.predict_cumulative( + db, + intervention=( + { + "radius_blue": blue_zone_radius, + "limit_blue": blue_zone_limit, + "radius_yellow_line": yellow_zone_line_radius, + "radius_yellow_stop": yellow_zone_stop_radius, + "limit_yellow": yellow_zone_limit, + "reform_year": year, + } + ), + ) + return { + "census_tracts": [str(t) for t in result["census_tracts"]], + "housing_units_factual": [t.item() for t in result["housing_units_factual"]], + "housing_units_counterfactual": [ + t.tolist() for t in result["housing_units_counterfactual"] + ], + } + + +if __name__ == "__main__": + uvicorn.run(app, host="0.0.0.0", port=int(os.getenv("PORT", 8000))) diff --git a/build/api/postgrest.conf b/build/api/postgrest.conf new file mode 100644 index 00000000..ddb71965 --- /dev/null +++ b/build/api/postgrest.conf @@ -0,0 +1,107 @@ +## Admin server used for checks. It's disabled by default unless a port is specified. +# admin-server-port = 3001 + +## The database role to use when no client authentication is provided +db-anon-role = "web_anon" + +## Notification channel for reloading the schema cache +db-channel = "pgrst" + +## Enable or disable the notification channel +db-channel-enabled = true + +## Enable in-database configuration +db-config = true + +## Function for in-database configuration +## db-pre-config = "postgrest.pre_config" + +## Extra schemas to add to the search_path of every request +db-extra-search-path = "public" + +## Limit rows in response +# db-max-rows = 1000 + +## Allow getting the EXPLAIN plan through the `Accept: application/vnd.pgrst.plan` header +# db-plan-enabled = false + +## Number of open connections in the pool +db-pool = 10 + +## Time in seconds to wait to acquire a slot from the connection pool +# db-pool-acquisition-timeout = 10 + +## Time in seconds after which to recycle pool connections +# db-pool-max-lifetime = 1800 + +## Time in seconds after which to recycle unused pool connections +# db-pool-max-idletime = 30 + +## Allow automatic database connection retrying +# db-pool-automatic-recovery = true + +## Stored proc to exec immediately after auth +# db-pre-request = "stored_proc_name" + +## Enable or disable prepared statements. disabling is only necessary when behind a connection pooler. +## When disabled, statements will be parametrized but won't be prepared. +db-prepared-statements = true + +## The name of which database schema to expose to REST clients +db-schemas = "api" + +## How to terminate database transactions +## Possible values are: +## commit (default) +## Transaction is always committed, this can not be overriden +## commit-allow-override +## Transaction is committed, but can be overriden with Prefer tx=rollback header +## rollback +## Transaction is always rolled back, this can not be overriden +## rollback-allow-override +## Transaction is rolled back, but can be overriden with Prefer tx=commit header +db-tx-end = "commit" + +## The standard connection URI format, documented at +## https://www.postgresql.org/docs/current/libpq-connect.html#LIBPQ-CONNSTRING +db-uri = "postgresql://postgres@34.123.100.76:5432/cities" + +# jwt-aud = "your_audience_claim" + +## Jspath to the role claim key +jwt-role-claim-key = ".role" + +## Choose a secret, JSON Web Key (or set) to enable JWT auth +## (use "@filename" to load from separate file) +# jwt-secret = "secret_with_at_least_32_characters" +jwt-secret-is-base64 = false + +## Enables and set JWT Cache max lifetime, disables caching with 0 +# jwt-cache-max-lifetime = 0 + +## Logging level, the admitted values are: crit, error, warn, info and debug. +log-level = "error" + +## Determine if the OpenAPI output should follow or ignore role privileges or be disabled entirely. +## Admitted values: follow-privileges, ignore-privileges, disabled +openapi-mode = "follow-privileges" + +## Base url for the OpenAPI output +openapi-server-proxy-uri = "" + +## Configurable CORS origins +# server-cors-allowed-origins = "" + +server-host = "!4" +server-port = 3001 + +## Allow getting the request-response timing information through the `Server-Timing` header +server-timing-enabled = true + +## Unix socket location +## if specified it takes precedence over server-port +# server-unix-socket = "/tmp/pgrst.sock" + +## Unix socket file mode +## When none is provided, 660 is applied by default +# server-unix-socket-mode = "660" diff --git a/build/api/requirements.txt b/build/api/requirements.txt new file mode 100644 index 00000000..95cd7505 --- /dev/null +++ b/build/api/requirements.txt @@ -0,0 +1,183 @@ +# +# This file is autogenerated by pip-compile with Python 3.12 +# by the following command: +# +# pip-compile --extra=api --output-file=api/requirements.txt +# +annotated-types==0.7.0 + # via pydantic +anyio==4.4.0 + # via + # httpx + # starlette + # watchfiles +certifi==2024.8.30 + # via + # httpcore + # httpx +chirho @ git+https://github.com/BasisResearch/chirho.git + # via cities (setup.py) +click==8.1.7 + # via + # typer + # uvicorn +contourpy==1.3.0 + # via matplotlib +cycler==0.12.1 + # via matplotlib +dill==0.3.8 + # via cities (setup.py) +dnspython==2.6.1 + # via email-validator +email-validator==2.2.0 + # via fastapi +fastapi[standard]==0.114.0 + # via cities (setup.py) +fastapi-cli[standard]==0.0.5 + # via fastapi +filelock==3.16.0 + # via torch +fonttools==4.53.1 + # via matplotlib +fsspec==2024.9.0 + # via torch +h11==0.14.0 + # via + # httpcore + # uvicorn +httpcore==1.0.5 + # via httpx +httptools==0.6.1 + # via uvicorn +httpx==0.27.2 + # via fastapi +idna==3.8 + # via + # anyio + # email-validator + # httpx +jinja2==3.1.4 + # via + # fastapi + # torch +joblib==1.4.2 + # via scikit-learn +kiwisolver==1.4.7 + # via matplotlib +markdown-it-py==3.0.0 + # via rich +markupsafe==2.1.5 + # via jinja2 +matplotlib==3.9.2 + # via cities (setup.py) +mdurl==0.1.2 + # via markdown-it-py +mpmath==1.3.0 + # via sympy +networkx==3.3 + # via torch +numpy==2.1.1 + # via + # cities (setup.py) + # contourpy + # matplotlib + # opt-einsum + # pandas + # pyro-ppl + # scikit-learn + # scipy +opt-einsum==3.3.0 + # via pyro-ppl +packaging==24.1 + # via + # matplotlib + # plotly +pandas==2.2.2 + # via cities (setup.py) +pillow==10.4.0 + # via matplotlib +plotly==5.24.0 + # via cities (setup.py) +psycopg2==2.9.9 + # via cities (setup.py) +pydantic==2.9.1 + # via fastapi +pydantic-core==2.23.3 + # via pydantic +pygments==2.18.0 + # via rich +pyparsing==3.1.4 + # via matplotlib +pyro-api==0.1.2 + # via pyro-ppl +pyro-ppl==1.8.6 + # via + # chirho + # cities (setup.py) +python-dateutil==2.9.0.post0 + # via + # matplotlib + # pandas +python-dotenv==1.0.1 + # via uvicorn +python-multipart==0.0.9 + # via fastapi +pytz==2024.1 + # via pandas +pyyaml==6.0.2 + # via uvicorn +rich==13.8.0 + # via typer +scikit-learn==1.5.1 + # via cities (setup.py) +scipy==1.14.1 + # via scikit-learn +shellingham==1.5.4 + # via typer +six==1.16.0 + # via python-dateutil +sniffio==1.3.1 + # via + # anyio + # httpx +sqlalchemy==2.0.34 + # via cities (setup.py) +starlette==0.38.5 + # via fastapi +sympy==1.13.2 + # via torch +tenacity==9.0.0 + # via plotly +threadpoolctl==3.5.0 + # via scikit-learn +torch==2.4.1 + # via + # cities (setup.py) + # pyro-ppl +tqdm==4.66.5 + # via pyro-ppl +typer==0.12.5 + # via fastapi-cli +typing-extensions==4.12.2 + # via + # fastapi + # pydantic + # pydantic-core + # sqlalchemy + # torch + # typer +tzdata==2024.1 + # via pandas +uvicorn[standard]==0.30.6 + # via + # fastapi + # fastapi-cli +uvloop==0.20.0 + # via uvicorn +watchfiles==0.24.0 + # via uvicorn +websockets==13.0.1 + # via uvicorn + +# The following packages are considered to be unsafe in a requirements file: +# setuptools diff --git a/build/api/schema.sql b/build/api/schema.sql new file mode 100644 index 00000000..2285c2b7 --- /dev/null +++ b/build/api/schema.sql @@ -0,0 +1,67 @@ +begin; +drop schema if exists api cascade; + +create schema api; + +create view api.demographics as ( + select * from api__demographics +); + +create view api.census_tracts as ( + select * from api__census_tracts +); + +create function api.high_frequency_transit_lines() returns setof dev.api__high_frequency_transit_lines as $$ + select * from dev.api__high_frequency_transit_lines +$$ language sql; + +create function api.high_frequency_transit_lines( + blue_zone_radius double precision, + yellow_zone_line_radius double precision, + yellow_zone_stop_radius double precision +) returns table ( + valid daterange, + geom geometry(LineString, 4269), + blue_zone_geom geometry(LineString, 4269), + yellow_zone_geom geometry(Geometry, 4269) +) as $$ + with + lines as (select * from dev.stg_high_frequency_transit_lines_union), + stops as (select * from dev.high_frequency_transit_stops), + lines_and_stops as ( + select + lines.valid * stops.valid as valid, + lines.geom as line_geom, + stops.geom as stop_geom + from lines inner join stops on lines.valid && stops.valid + ) + select + valid, + st_transform(line_geom, 4269) as geom, + st_transform(st_buffer(line_geom, blue_zone_radius), 4269) as blue_zone_geom, + st_transform(st_union(st_buffer(line_geom, yellow_zone_line_radius), st_buffer(stop_geom, yellow_zone_stop_radius)), 4269) as yellow_zone_geom + from lines_and_stops +$$ language sql; + +do $$ +begin +create role web_anon nologin; +exception when duplicate_object then raise notice '%, skipping', sqlerrm using errcode = sqlstate; +end +$$; + +grant all on schema public to web_anon; +grant all on schema dev to web_anon; +grant select on table public.spatial_ref_sys TO web_anon; +grant usage on schema api to web_anon; +grant all on all tables in schema api to web_anon; +grant all on all functions in schema api to web_anon; +grant all on schema api to web_anon; +GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA dev TO web_anon; +GRANT ALL PRIVILEGES ON ALL functions IN SCHEMA dev TO web_anon; +GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA api TO web_anon; +GRANT ALL PRIVILEGES ON ALL functions IN SCHEMA api TO web_anon; +GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA public TO web_anon; +GRANT ALL PRIVILEGES ON ALL functions IN SCHEMA public TO web_anon; +grant web_anon to postgres; +commit; diff --git a/build/cities/__init__.py b/build/cities/__init__.py new file mode 100644 index 00000000..f993e182 --- /dev/null +++ b/build/cities/__init__.py @@ -0,0 +1,6 @@ +"""**cities** + +Project short description. +""" + +__version__ = "0.0.1" diff --git a/build/cities/deployment/tracts_minneapolis/.gitignore b/build/cities/deployment/tracts_minneapolis/.gitignore new file mode 100644 index 00000000..5304474d --- /dev/null +++ b/build/cities/deployment/tracts_minneapolis/.gitignore @@ -0,0 +1,2 @@ +*.pth +*.pkl \ No newline at end of file diff --git a/build/cities/deployment/tracts_minneapolis/__init__.py b/build/cities/deployment/tracts_minneapolis/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/build/cities/deployment/tracts_minneapolis/generate_torch_loader.py b/build/cities/deployment/tracts_minneapolis/generate_torch_loader.py new file mode 100644 index 00000000..c07d8107 --- /dev/null +++ b/build/cities/deployment/tracts_minneapolis/generate_torch_loader.py @@ -0,0 +1,87 @@ +import os +import time + +import sqlalchemy +import torch +from dotenv import load_dotenv + +from cities.utils.data_grabber import find_repo_root +from cities.utils.data_loader import ZoningDataset, select_from_sql + +load_dotenv() + +local_user = os.getenv("USER") +if local_user == "rafal": + load_dotenv(os.path.expanduser("~/.env_pw")) +# local torch loader is needed for subsampling in evaluation, comparison to the previous dataset and useful for ED +DB_USERNAME = os.getenv("DB_USERNAME") +HOST = os.getenv("HOST") +DATABASE = os.getenv("DATABASE") +PASSWORD = os.getenv("PASSWORD") + + +##################### +# data load and prep +##################### + +kwargs = { + "categorical": ["year", "census_tract"], + "continuous": { + "housing_units", + "housing_units_original", + "total_value", + "total_value_original", + "median_value", + "mean_limit_original", + "median_distance", + "income", + "segregation_original", + "white_original", + "parcel_sqm", + }, + "outcome": "housing_units", +} + +load_start = time.time() +with sqlalchemy.create_engine( + f"postgresql://{DB_USERNAME}:{PASSWORD}@{HOST}/{DATABASE}" +).connect() as conn: + subset = select_from_sql( + "select * from dev.tracts_model__census_tracts order by census_tract, year", + conn, + kwargs, + ) +load_end = time.time() +print(f"Data loaded in {load_end - load_start} seconds") + + +columns_to_standardize = [ + "housing_units_original", + "total_value_original", +] + +new_standardization_dict = {} + +for column in columns_to_standardize: + new_standardization_dict[column] = { + "mean": subset["continuous"][column].mean(), + "std": subset["continuous"][column].std(), + } + + +assert "parcel_sqm" in subset["continuous"].keys() + +root = find_repo_root() + +pg_census_tracts_dataset = ZoningDataset( + subset["categorical"], + subset["continuous"], + standardization_dictionary=new_standardization_dict, +) +assert "parcel_sqm" in subset["continuous"].keys() + +pg_census_tracts_data_path = os.path.join( + root, "data/minneapolis/processed/pg_census_tracts_dataset.pt" +) + +torch.save(pg_census_tracts_dataset, pg_census_tracts_data_path) diff --git a/build/cities/deployment/tracts_minneapolis/predict.py b/build/cities/deployment/tracts_minneapolis/predict.py new file mode 100644 index 00000000..8ae4ac43 --- /dev/null +++ b/build/cities/deployment/tracts_minneapolis/predict.py @@ -0,0 +1,343 @@ +import copy +import os + +import dill +import pandas as pd +import pyro +import torch +from chirho.counterfactual.handlers import MultiWorldCounterfactual +from chirho.indexed.ops import IndexSet, gather +from chirho.interventional.handlers import do +from dotenv import load_dotenv +from pyro.infer import Predictive + +# from cities.modeling.zoning_models.zoning_tracts_sqm_model import ( +# TractsModelSqm as TractsModel, +# ) + +from cities.modeling.zoning_models.zoning_tracts_continuous_interactions_model import ( + TractsModelContinuousInteractions as TractsModel, +) +from cities.utils.data_grabber import find_repo_root +from cities.utils.data_loader import select_from_data, select_from_sql + +load_dotenv() + +local_user = os.getenv("USER") +if local_user == "rafal": + load_dotenv(os.path.expanduser("~/.env_pw")) + + +class TractsModelPredictor: + kwargs = { + "categorical": ["year", "year_original", "census_tract",], + "continuous": { + "housing_units", + "housing_units_original", + "total_value", + "median_value", + "mean_limit_original", + "median_distance", + "income", + "segregation_original", + "white_original", + "parcel_sqm", + 'downtown_overlap', + 'university_overlap', + }, + "outcome": "housing_units", + } + + kwargs_subset = { + "categorical": ["year", "year_original", "census_tract"], + "continuous": { + "housing_units", + "total_value", + "median_value", + "mean_limit_original", + "median_distance", + "income", + "segregation_original", + "white_original", + "parcel_sqm", + 'downtown_overlap', + 'university_overlap', + }, + "outcome": "housing_units", + } + + + + parcel_intervention_sql = """ + select + census_tract, + year_, + case + when downtown_yn then 0 + when not downtown_yn + and year_ >= %(reform_year)s + and distance_to_transit <= %(radius_blue)s + then %(limit_blue)s + when not downtown_yn + and year_ >= %(reform_year)s + and distance_to_transit > %(radius_blue)s + and (distance_to_transit_line <= %(radius_yellow_line)s + or distance_to_transit_stop <= %(radius_yellow_stop)s) + then %(limit_yellow)s + when not downtown_yn + and year_ >= %(reform_year)s + and distance_to_transit_line > %(radius_yellow_line)s + and distance_to_transit_stop > %(radius_yellow_stop)s + then 1 + else limit_con + end as intervention + from tracts_model__parcels + """ + + tracts_intervention_sql = f""" + with parcel_interventions as ({parcel_intervention_sql}) + select + census_tract, + year_, + avg(intervention) as intervention + from parcel_interventions + group by census_tract, year_ + order by census_tract, year_ + """ + + def __init__(self, conn): + self.conn = conn + + root = find_repo_root() + deploy_path = os.path.join(root, "cities/deployment/tracts_minneapolis") + + guide_path = os.path.join(deploy_path, "tracts_model_guide.pkl") + self.param_path = os.path.join(deploy_path, "tracts_model_params.pth") + + need_to_train_flag = False + if not os.path.isfile(guide_path): + need_to_train_flag = True + print(f"Warning: '{guide_path}' does not exist.") + if not os.path.isfile(self.param_path): + need_to_train_flag = True + print(f"Warning: '{self.param_path}' does not exist.") + + if need_to_train_flag: + print("Please run 'train_model.py' to generate the required files.") + + with open(guide_path, "rb") as file: + guide = dill.load(file) + + self.data = select_from_sql( + "select * from tracts_model__census_tracts order by census_tract, year", + conn, + TractsModelPredictor.kwargs, + ) + + + # set to zero whenever the university overlap is above 1 + # TODO this should be handled at the data processing stage + self.data['continuous']['mean_limit_original'] = torch.where(self.data['continuous']['university_overlap'] > 1, + torch.zeros_like(self.data['continuous']['mean_limit_original']), + self.data['continuous']['mean_limit_original']) + + + self.subset = select_from_data(self.data, TractsModelPredictor.kwargs_subset) + + + self.years = self.data["categorical"]["year_original"] + self.year_ids = self.data['categorical']["year"] + self.tracts = self.data["categorical"]["census_tract"] + + + categorical_levels = { + "year": torch.unique(self.subset["categorical"]["year"]), + "year_original": torch.unique(self.subset["categorical"]["year_original"]), + "census_tract": torch.unique(self.subset["categorical"]["census_tract"]), + } + + self.housing_units_std = self.data["continuous"]["housing_units_original"].std() + self.housing_units_mean = self.data["continuous"][ + "housing_units_original" + ].mean() + + #interaction_pairs + ins = [ + ("university_overlap", "limit"), + ("downtown_overlap", "limit"), + ("distance", "downtown_overlap"), + ("distance", "university_overlap"), + ("distance", "limit"), + ("median_value", "segregation"), + ("distance", "segregation"), + ("limit", "sqm"), + ("segregation", "sqm"), + ("distance", "white"), + ("income", "limit"), + ("downtown_overlap", "median_value"), + ("downtown_overlap", "segregation"), + ("median_value", "white"), + ("distance", "income"), + ] + + + model = TractsModel(**self.subset, categorical_levels=categorical_levels, + housing_units_continuous_interaction_pairs=ins) + + self.predictive = Predictive(model=model, guide=guide, num_samples=100) + + # these are at the tracts level + def _tracts_intervention( + self, + conn, + radius_blue, + limit_blue, + radius_yellow_line, + radius_yellow_stop, + limit_yellow, + reform_year, + ): + params = { + "reform_year": reform_year, + "radius_blue": radius_blue, + "limit_blue": limit_blue, + "radius_yellow_line": radius_yellow_line, + "radius_yellow_stop": radius_yellow_stop, + "limit_yellow": limit_yellow, + } + df = pd.read_sql( + TractsModelPredictor.tracts_intervention_sql, conn, params=params + ) + return torch.tensor(df["intervention"].values, dtype=torch.float32) + + def predict_cumulative(self, conn, intervention): + """Predict the total number of housing units built from 2011-2020 under intervention. + + Returns a dictionary with keys: + - 'census_tracts': the tracts considered + - 'housing_units_factual': total housing units built according to real housing data + - 'housing_units_counterfactual': samples from prediction of total housing units built + """ + pyro.clear_param_store() + pyro.get_param_store().load(self.param_path) + + subset_for_preds = copy.deepcopy(self.subset) + subset_for_preds["continuous"]["housing_units"] = None + + limit_intervention = self._tracts_intervention(conn, **intervention) + + limit_intervention = torch.where(self.data['continuous']['university_overlap'] > 2, + torch.zeros_like(limit_intervention), + limit_intervention) + + limit_intervention = torch.where(self.data['continuous']['downtown_overlap'] > 1, + torch.zeros_like(limit_intervention), + limit_intervention) + + with MultiWorldCounterfactual() as mwc: + with do(actions={"limit": limit_intervention}): + result_all = self.predictive(**subset_for_preds)["housing_units"] + with mwc: + result_f = gather( + result_all, IndexSet(**{"limit": {0}}), event_dims=0 + ).squeeze() + result_cf = gather( + result_all, IndexSet(**{"limit": {1}}), event_dims=0 + ).squeeze() + + obs_housing_units = self.data["continuous"]["housing_units_original"] + f_housing_units = (result_f * self.housing_units_std + self.housing_units_mean)#.clamp(min = 0) + cf_housing_units = (result_cf * self.housing_units_std + self.housing_units_mean)#.clamp(min = 0) + + + # calculate cumulative housing units (factual) + obs_cumsums = {} + f_cumsums = {} + cf_cumsums = {} + for key in self.tracts.unique(): + obs_units = [] + f_units = [] + cf_units = [] + for year in self.years.unique(): + obs_units.append(obs_housing_units[(self.tracts == key) & (self.years == year)]) + f_units.append(f_housing_units[:,(self.tracts == key) & (self.years == year)]) + cf_units.append(cf_housing_units[:,(self.tracts == key) & (self.years == year)]) + + obs_cumsum = torch.cumsum(torch.stack(obs_units), dim = 0).flatten() + f_cumsum = torch.cumsum(torch.stack(f_units), dim = 0).squeeze() + cf_cumsum = torch.cumsum(torch.stack(cf_units), dim = 0).squeeze() + + obs_cumsums[key] = obs_cumsum + f_cumsums[key] = f_cumsum + cf_cumsums[key] = cf_cumsum + + + # presumably outdated + + tracts = self.data["categorical"]["census_tract"] + + # calculate cumulative housing units (factual) + f_totals = {} + for i in range(tracts.shape[0]): + key = tracts[i].item() + if key not in f_totals: + f_totals[key] = 0 + f_totals[key] += obs_housing_units[i] + + # calculate cumulative housing units (counterfactual) + cf_totals = {} + for i in range(tracts.shape[0]): + year = self.years[i].item() + key = tracts[i].item() + if key not in cf_totals: + cf_totals[key] = 0 + if year < intervention["reform_year"]: + cf_totals[key] += obs_housing_units[i] + else: + cf_totals[key] = cf_totals[key] + cf_housing_units[:, i] + cf_totals = {k: torch.clamp(v, 0) for k, v in cf_totals.items()} + + census_tracts = list(cf_totals.keys()) + f_housing_units = [f_totals[k] for k in census_tracts] + cf_housing_units = [cf_totals[k] for k in census_tracts] + + + + return {"obs_cumsums": obs_cumsums, "f_cumsums": f_cumsums, "cf_cumsums": cf_cumsums, + "limit_intervention": limit_intervention, + # presumably outdated + "census_tracts": census_tracts, + "housing_units_factual": f_housing_units, + "housing_units_counterfactual": cf_housing_units,} + + + # return { + # "census_tracts": census_tracts, + # "housing_units_factual": f_housing_units, + # "housing_units_counterfactual": cf_housing_units, + # "limit_intervention": limit_intervention, + # } + + +if __name__ == "__main__": + import time + + from cities.utils.data_loader import db_connection + + with db_connection() as conn: + predictor = TractsModelPredictor(conn) + start = time.time() + + result = predictor.predict_cumulative( + conn, + intervention={ + "radius_blue": 106.7, + "limit_blue": 0, + "radius_yellow_line": 402.3, + "radius_yellow_stop": 804.7, + "limit_yellow": 0.5, + "reform_year": 2015, + }, + ) + end = time.time() + print(f"Counterfactual in {end - start} seconds") diff --git a/build/cities/deployment/tracts_minneapolis/tracts_model_overview/tracts_dag_plot_high_density.png b/build/cities/deployment/tracts_minneapolis/tracts_model_overview/tracts_dag_plot_high_density.png new file mode 100644 index 00000000..e6e5f6cc Binary files /dev/null and b/build/cities/deployment/tracts_minneapolis/tracts_model_overview/tracts_dag_plot_high_density.png differ diff --git a/build/cities/deployment/tracts_minneapolis/tracts_model_overview/tracts_model_overview.ipynb b/build/cities/deployment/tracts_minneapolis/tracts_model_overview/tracts_model_overview.ipynb new file mode 100644 index 00000000..18b68ce0 --- /dev/null +++ b/build/cities/deployment/tracts_minneapolis/tracts_model_overview/tracts_model_overview.ipynb @@ -0,0 +1,86 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": { + "vscode": { + "languageId": "plaintext" + } + }, + "source": [ + "## What is this project about?\n", + "\n", + "We use state-of-the-art Bayesian causal modeling tools ([ChiRho](https://github.com/BasisResearch/chirho)) to investigate the role of parking zoning reform in Minneapolis on the development of new housing units, at a relatively fine-grained level of census tracts. Minneapolis is an example of a city which somewhat sucessfuly navigates the housing crisis, and a parking zoning reform has been claimed to be connected to this outcome (see for example [here](https://reason.com/2024/02/27/fear-loathing-and-zoning-reform-in-minnesota/) and [here](https://www.strongtowns.org/journal/2023/9/15/ending-minimum-parking-requirements-was-a-policy-win-for-the-twin-cities)).\n", + "\n", + "\n", + "%TODO Someone should perhaps check if there are better links to include here\n", + "\n", + "Whether this is so, to what extent and with what uncertainty has been unclear. Yes, the number of housing units in the city increased faster after the reform. But it is not ovious whether this isn't a mere correlation arising from other variables being causally responsible, or random variation. We decided to take a deep dive and connect detailed census tracts data with demographic variables within a carefully devised causal model to investigate. Due to data availability limitations, we start at year 2010. Since a major world-wide event changed too many things in 2020, this is where our data collection stops, to be able to separate the zoning concerns from the complex and unprecedented events that follow. It turns out that even with 10 years of data only, causal modelling allows us to offer some (admittedly, uncertain) answers." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Why this is not a typical machine learning project\n", + "\n", + "A typical predictive project in machine learning tends to use as much data as possible and algorithms to identify patters, focusing only on predictive accuracy. While such an approach is useful, the key limitation is that such models have a hard time distinguishing accidental correlations from causal connections, and therefore are not realiable guides to counterfactual predictions and causal effect estimation. Moreover, a typical model often disregards information that humans use heavily: temporal, spatial or causal structures, which are needed to generalize well outside the training data.\n", + "\n", + "Instead, we use our core open source technology, [ChiRho](https://github.com/BasisResearch/chirho) to build **bayesian causal models** using hand-picked relevant variables. This way, we can work with humans and in the loop. The fact that we use Bayesian methods, allows for the injection of human understanding of the causal dependecies, which then are made work in symbiosis with the data, even if the latter is somewhat limited, and for honest assessment of the resulting uncertainties. The fact that the models is causal gives us a chance to address counterfactual queries involving alternative interventions.\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "\n", + "\n", + "## Why care about different types of questions?\n", + "\n", + "Once we start thinking in causal terms, there are **multiple types of queries** that we can distinguish and answer using the model, and such questions typically have different answers. While assosciative information is often useful or revealing, equally often we wwant to be able to evaluate potential consequences of acting one way or another, and in this mode of reflection, we rather turn to thinking in terms of interventions and counterfactuals.\n", + "\n", + "- *Association*. Example: Is there a correlation between increased green spaces and decreased crime rate in an area? Perhaps, areas with more green spaces do tend to have lower crime rates for various reasons.\n", + "\n", + "- *Intervention* If the city implements a zoning change to create more green spaces, how would this impact the crime rate in the area? The answer might differ here: factors other than the policy change probably influence crime rates to a large extent.\n", + "\n", + "- *Counterfactual* Suppose you did create more green spaces and the crime rate in the area did go down. Are you to be thanked? This depends on whether the crime rate would have gone down had you not created more green space in the area. Would it?\n", + "\n", + "\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Counterfactual modeling of the zoning reform\n", + "\n", + "In the case at hand, we allow you, the user, to investigate predicted counterfactual outcomes of a zoning reform, specifed in terms of where the two zones start, what parking limits are to be imposed in different zones, and what year the reform has been introduced. From among the available variables we hand-picked the ones that are most useful and meaningfully causally connected. The model simultaneously learns the strenghts of over 30 causal connections and uses this information to inform its counterfactual predictions. The structural assumptions we have made at a high level can be described by the diagram below. However, a moderately competent user can use our [open source codebase](https://github.com/BasisResearch/cities) to tweak or modify these assumptions and invesigate the consequences of doing so.\n", + " " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "\"DAG\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## How does the model perform?\n", + "\n", + "The causal layer, nevertheless, should not take place at the cost of predictive power. The models went through a battery of tests on split data, each time being able to account for around 25-30% variation in the data (which for such noisy problems is fairly decent peformance), effectively on average improving predictions of new housing units appearing in each of census tracts at each of a given years by the count of 35-40 over a null model. A detailed notebook with model testing is also available at our open source codebase. " + ] + } + ], + "metadata": { + "language_info": { + "name": "python" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/build/cities/deployment/tracts_minneapolis/train_model.py b/build/cities/deployment/tracts_minneapolis/train_model.py new file mode 100644 index 00000000..82a95eab --- /dev/null +++ b/build/cities/deployment/tracts_minneapolis/train_model.py @@ -0,0 +1,114 @@ +import os +import time + +import dill +import pyro +import torch +from dotenv import load_dotenv + +from cities.modeling.svi_inference import run_svi_inference +from cities.modeling.zoning_models.zoning_tracts_continuous_interactions_model import ( + TractsModelContinuousInteractions as TractsModel, +) +from cities.utils.data_grabber import find_repo_root +from cities.utils.data_loader import db_connection, select_from_sql + +# from cities.modeling.zoning_models.zoning_tracts_model import TractsModel +# from cities.modeling.zoning_models.zoning_tracts_sqm_model import ( +# TractsModelSqm as TractsModel, +# ) + + +n_steps = 2000 + +load_dotenv() + +local_user = os.getenv("USER") +if local_user == "rafal": + load_dotenv(os.path.expanduser("~/.env_pw")) + +##################### +# data load and prep +##################### + +kwargs = { + "categorical": ["year", "census_tract"], + "continuous": { + "housing_units", + "housing_units_original", + "total_value", + "median_value", + "mean_limit_original", + "median_distance", + "income", + "segregation_original", + "white_original", + "parcel_sqm", + "downtown_overlap", + "university_overlap", + }, + "outcome": "housing_units", +} + +load_start = time.time() +with db_connection() as conn: + subset = select_from_sql( + "select * from dev.tracts_model__census_tracts order by census_tract, year", + conn, + kwargs, + ) +load_end = time.time() +print(f"Data loaded in {load_end - load_start} seconds") + +############################# +# instantiate and train model +############################# + +# interaction terms +ins = [ + ("university_overlap", "limit"), + ("downtown_overlap", "limit"), + ("distance", "downtown_overlap"), + ("distance", "university_overlap"), + ("distance", "limit"), + ("median_value", "segregation"), + ("distance", "segregation"), + ("limit", "sqm"), + ("segregation", "sqm"), + ("distance", "white"), + ("income", "limit"), + ("downtown_overlap", "median_value"), + ("downtown_overlap", "segregation"), + ("median_value", "white"), + ("distance", "income"), +] + +# model +tracts_model = TractsModel( + **subset, + categorical_levels={ + "year": torch.unique(subset["categorical"]["year"]), + "census_tract": torch.unique(subset["categorical"]["census_tract"]), + }, + housing_units_continuous_interaction_pairs=ins, +) + +pyro.clear_param_store() + +guide = run_svi_inference(tracts_model, n_steps=n_steps, lr=0.03, plot=False, **subset) + +########################################## +# save guide and params in the same folder +########################################## +root = find_repo_root() + +deploy_path = os.path.join(root, "cities/deployment/tracts_minneapolis") +guide_path = os.path.join(deploy_path, "tracts_model_guide.pkl") +param_path = os.path.join(deploy_path, "tracts_model_params.pth") + +serialized_guide = dill.dumps(guide) +with open(guide_path, "wb") as file: + file.write(serialized_guide) + +with open(param_path, "wb") as file: + pyro.get_param_store().save(param_path) diff --git a/build/cities/modeling/__init__.py b/build/cities/modeling/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/build/cities/modeling/evaluation.py b/build/cities/modeling/evaluation.py new file mode 100644 index 00000000..5613ca54 --- /dev/null +++ b/build/cities/modeling/evaluation.py @@ -0,0 +1,300 @@ +import copy +import os +from typing import Any, Callable, Dict, Optional, Tuple, Union + +import matplotlib.pyplot as plt +import pyro +import seaborn as sns +import torch +from pyro.infer import Predictive +from torch.utils.data import DataLoader, random_split + +from cities.modeling.svi_inference import run_svi_inference +from cities.utils.data_grabber import find_repo_root +from cities.utils.data_loader import select_from_data + +root = find_repo_root() + + +def prep_data_for_test( + data_path: Optional[str] = None, train_size: float = 0.8 +) -> Tuple[DataLoader, DataLoader, list]: + + if data_path is None: + data_path = os.path.join(root, "data/minneapolis/processed/zoning_dataset.pt") + zoning_dataset_read = torch.load(data_path) + + train_size = int(train_size * len(zoning_dataset_read)) + test_size = len(zoning_dataset_read) - train_size + + train_dataset, test_dataset = random_split( + zoning_dataset_read, [train_size, test_size] + ) + + train_loader = DataLoader(train_dataset, batch_size=train_size, shuffle=True) + test_loader = DataLoader(test_dataset, batch_size=test_size, shuffle=False) + + categorical_levels = zoning_dataset_read.categorical_levels + + return train_loader, test_loader, categorical_levels + + +def recode_categorical( + kwarg_names: Dict[str, Any], train_loader: DataLoader, test_loader: DataLoader +) -> Tuple[Dict[str, Dict[str, torch.Tensor]], Dict[str, Dict[str, torch.Tensor]]]: + + assert all( + item in kwarg_names.keys() for item in ["categorical", "continuous", "outcome"] + ) + + train_data = next(iter(train_loader)) + test_data = next(iter(test_loader)) + + _train_data = select_from_data(train_data, kwarg_names) + _test_data = select_from_data(test_data, kwarg_names) + + #################################################### + # eliminate test categories not in the training data + #################################################### + def apply_mask(data, mask): + return {key: val[mask] for key, val in data.items()} + + mask = torch.ones(len(_test_data["outcome"]), dtype=torch.bool) + for key, value in _test_data["categorical"].items(): + mask = mask * torch.isin( + _test_data["categorical"][key], (_train_data["categorical"][key].unique()) + ) + + _test_data["categorical"] = apply_mask(_test_data["categorical"], mask) + _test_data["continuous"] = apply_mask(_test_data["continuous"], mask) + _test_data["outcome"] = _test_data["outcome"][mask] + + for key in _test_data["categorical"].keys(): + assert _test_data["categorical"][key].shape[0] == mask.sum() + for key in _test_data["continuous"].keys(): + assert _test_data["continuous"][key].shape[0] == mask.sum() + + # raise error if sum(mask) < .5 * len(test_data['outcome']) + if sum(mask) < 0.5 * len(_test_data["outcome"]): + raise ValueError( + "Sampled test data has too many new categorical levels, consider decreasing train size" + ) + + # #################################### + # recode categorical variables to have + # no index gaps in the training data + # #################################### + + mappings = {} + for name in _train_data["categorical"].keys(): + unique_train = torch.unique(_train_data["categorical"][name]) + mappings[name] = {v.item(): i for i, v in enumerate(unique_train)} + _train_data["categorical"][name] = torch.tensor( + [mappings[name][x.item()] for x in _train_data["categorical"][name]] + ) + _test_data["categorical"][name] = torch.tensor( + [mappings[name][x.item()] for x in _test_data["categorical"][name]] + ) + + return _train_data, _test_data + + +def test_performance( + model_or_class: Union[Callable[..., Any], Any], + kwarg_names: Dict[str, Any], + train_loader: DataLoader, + test_loader: DataLoader, + categorical_levels: Dict[str, torch.Tensor], + outcome_type: str = "outcome", + outcome_name: str = "outcome", + n_steps: int = 600, + plot: bool = True, + lim: Optional[Tuple[float, float]] = None, + is_class: bool = True, +) -> Dict[str, float]: + + _train_data, _test_data = recode_categorical(kwarg_names, train_loader, test_loader) + + pyro.clear_param_store() + + ###################### + # train and test + ###################### + + if is_class: + model = model_or_class(**_train_data) + + else: + model = model_or_class + + guide = run_svi_inference( + model, n_steps=n_steps, lr=0.01, verbose=True, **_train_data + ) + + predictive = Predictive(model, guide=guide, num_samples=1000) + + categorical_levels = model.categorical_levels + + _train_data_for_preds = copy.deepcopy(_train_data) + _test_data_for_preds = copy.deepcopy(_test_data) + + if outcome_type != "outcome": + _train_data_for_preds[outcome_type][outcome_name] = None # type: ignore + _test_data_for_preds[outcome_type][outcome_name] = None # type: ignore + + else: + _train_data_for_preds[outcome_type] = None # type: ignore + + samples_train = predictive( + **_train_data_for_preds, + categorical_levels=categorical_levels, + ) + + samples_test = predictive( + **_test_data_for_preds, + categorical_levels=categorical_levels, + ) + + train_predicted_mean = samples_train[outcome_name].squeeze().mean(dim=0) + train_predicted_lower = samples_train[outcome_name].squeeze().quantile(0.05, dim=0) + train_predicted_upper = samples_train[outcome_name].squeeze().quantile(0.95, dim=0) + + coverage_training = ( + _train_data[outcome_type][outcome_name] + .squeeze() + .gt(train_predicted_lower) + .float() + * _train_data[outcome_type][outcome_name] + .squeeze() + .lt(train_predicted_upper) + .float() + ) + + null_residuals_train = ( + _train_data[outcome_type][outcome_name].squeeze() + - _train_data[outcome_type][outcome_name].squeeze().mean() + ) + + null_mae_train = torch.abs(null_residuals_train).mean().item() + + residuals_train = ( + _train_data[outcome_type][outcome_name].squeeze() - train_predicted_mean + ) + mae_train = torch.abs(residuals_train).mean().item() + + rsquared_train = ( + 1 + - residuals_train.var() + / _train_data[outcome_type][outcome_name].squeeze().var() + ) + + test_predicted_mean = samples_test[outcome_name].squeeze().mean(dim=0) + test_predicted_lower = samples_test[outcome_name].squeeze().quantile(0.05, dim=0) + test_predicted_upper = samples_test[outcome_name].squeeze().quantile(0.95, dim=0) + + coverage_test = ( + _test_data[outcome_type][outcome_name] + .squeeze() + .gt(test_predicted_lower) + .float() + * _test_data[outcome_type][outcome_name] + .squeeze() + .lt(test_predicted_upper) + .float() + ) + + null_residuals_test = ( + _test_data[outcome_type][outcome_name].squeeze() + - _test_data[outcome_type][outcome_name].squeeze().mean() + ) + + null_mae_test = torch.abs(null_residuals_test).mean().item() + + residuals_test = ( + _test_data[outcome_type][outcome_name].squeeze() - test_predicted_mean + ) + mae_test = torch.abs(residuals_test).mean().item() + + rsquared_test = ( + 1 + - residuals_test.var() / _test_data[outcome_type][outcome_name].squeeze().var() + ) + + print(rsquared_train, rsquared_test) + + if plot: + fig, axs = plt.subplots(2, 2, figsize=(14, 10)) + + axs[0, 0].scatter( + x=_train_data[outcome_type][outcome_name], + y=train_predicted_mean, + s=6, + alpha=0.5, + ) + axs[0, 0].set_title( + "Training data, ratio of outcomes within 95% CI: {:.2f}".format( + coverage_training.mean().item() + ) + ) + + if lim is not None: + axs[0, 0].set_xlim(lim) + axs[0, 0].set_ylim(lim) + axs[0, 0].set_xlabel("observed values") + axs[0, 0].set_ylabel("mean predicted values") + + axs[0, 1].hist(residuals_train, bins=50) + + axs[0, 1].set_title( + "Training set residuals, MAE (null): {:.2f} ({:.2f}), Rsquared: {:.2f}".format( + mae_train, null_mae_train, rsquared_train.item() + ) + ) + axs[0, 1].set_xlabel("residuals") + axs[0, 1].set_ylabel("frequency") + + axs[1, 0].scatter( + x=_test_data[outcome_type][outcome_name], + y=test_predicted_mean, + s=6, + alpha=0.5, + ) + axs[1, 0].set_title( + "Test data, ratio of outcomes within 95% CI: {:.2f}".format( + coverage_test.mean().item() + ) + ) + axs[1, 0].set_xlabel("true values") + axs[1, 0].set_ylabel("mean predicted values") + if lim is not None: + axs[1, 0].set_xlim(lim) + axs[1, 0].set_ylim(lim) + + axs[1, 1].hist(residuals_test, bins=50) + + axs[1, 1].set_title( + "Test set residuals, MAE (null): {:.2f} ({:.2f}), Rsquared: {:.2f}".format( + mae_test, null_mae_test, rsquared_test.item() + ) + ) + + axs[1, 1].set_xlabel("residuals") + axs[1, 1].set_ylabel("frequency") + + plt.tight_layout(rect=(0, 0, 1, 0.96)) + sns.despine() + + fig.suptitle("Model evaluation", fontsize=16) + + plt.show() + + return { + "mae_null_train": null_mae_train, + "mae_null_test": null_mae_test, + "mae_train": mae_train, + "mae_test": mae_test, + "rsquared_train": rsquared_train, + "rsquared_test": rsquared_test, + "coverage_train": coverage_training.mean().item(), + "coverage_test": coverage_test.mean().item(), + } diff --git a/build/cities/modeling/model_components.py b/build/cities/modeling/model_components.py new file mode 100644 index 00000000..c914bb41 --- /dev/null +++ b/build/cities/modeling/model_components.py @@ -0,0 +1,351 @@ +from typing import Dict, List, Optional, Tuple + +import pyro +import pyro.distributions as dist +import torch + + +def get_n(categorical: Dict[str, torch.Tensor], continuous: Dict[str, torch.Tensor]): + N_categorical = len(categorical) + N_continuous = len(continuous) + + # a but convoluted, but groups might be missing and sometimes + # vars are allowed to be None + n_cat = None + if N_categorical > 0: + for value in categorical.values(): + if value is not None: + n_cat = value.shape[0] + break + + n_con = None + if N_continuous > 0: + for value in continuous.values(): + if value is not None: + n_con = value.shape[0] + break + + if N_categorical > 0 and N_continuous > 0: + if n_cat != n_con: + raise ValueError( + "The number of categorical and continuous data points must be the same" + ) + + n = n_cat if n_cat is not None else n_con + + if n is None: + raise ValueError("Both categorical and continuous dictionaries are empty.") + + return N_categorical, N_continuous, n + + +def check_categorical_is_subset_of_levels(categorical, categorical_levels): + + assert set(categorical.keys()).issubset(set(categorical_levels.keys())) + + # # TODO should these be subsets or can we only check lengths? + + return True + + +def get_categorical_levels(categorical): + """ + Assumes that no levels are missing from the categorical data, and constructs the levels from the unique values. + This should only be used with supersets of all data (so that every data subset will have its levels represented + in the levels returned here. + """ + return {name: torch.unique(categorical[name]) for name in categorical.keys()} + + +def categorical_contribution( + categorical: Dict[str, torch.Tensor], + child_name: str, + leeway: float, + categorical_levels: Dict[str, torch.Tensor], +) -> torch.Tensor: + + check_categorical_is_subset_of_levels(categorical, categorical_levels) + + categorical_names = list(categorical.keys()) + + weights_categorical_outcome = {} + objects_cat_weighted = {} + + for name in categorical_names: + weights_categorical_outcome[name] = pyro.sample( + f"weights_categorical_{name}_{child_name}", + dist.Normal(0.0, leeway).expand(categorical_levels[name].shape).to_event(1), + ) + + if len(weights_categorical_outcome[name].shape) > 1: + weights_categorical_outcome[name] = weights_categorical_outcome[ + name + ].squeeze(-2) + + final_nonevent_shape = torch.broadcast_shapes( + categorical[name].shape[:-1], weights_categorical_outcome[name].shape[:-1] + ) + expanded_weight_indices = categorical[name].expand(*final_nonevent_shape, -1) + expanded_weights = weights_categorical_outcome[name].expand( + *final_nonevent_shape, -1 + ) + + objects_cat_weighted[name] = torch.gather( + expanded_weights, dim=-1, index=expanded_weight_indices + ) + + # weight_indices = categorical[name].expand( + # *weights_categorical_outcome[name].shape[:-1], -1 + # ) + + # objects_cat_weighted[name] = torch.gather( + # weights_categorical_outcome[name], dim=-1, index=weight_indices + # ) + + values = list(objects_cat_weighted.values()) + + categorical_contribution_outcome = torch.stack(values, dim=0).sum(dim=0) + + return categorical_contribution_outcome + + +def continuous_contribution( + continuous: Dict[str, torch.Tensor], + child_name: str, + leeway: float, +) -> torch.Tensor: + + contributions = torch.zeros(1) + + bias_continuous = pyro.sample( + f"bias_continuous_{child_name}", + dist.Normal(0.0, leeway), + ) + + for key, value in continuous.items(): + + weight_continuous = pyro.sample( + f"weight_continuous_{key}_to_{child_name}", + dist.Normal(0.0, leeway), + ) + + contribution = weight_continuous * value + contributions = contribution + contributions + + contributions = bias_continuous + contributions + + return contributions + + +def add_linear_component( + child_name: str, + child_continuous_parents: Dict[str, torch.Tensor], + child_categorical_parents: Dict[str, torch.Tensor], + leeway: float, + data_plate, + categorical_levels: Dict[str, torch.Tensor], + observations: Optional[torch.Tensor] = None, +) -> torch.Tensor: + + sigma_child = pyro.sample( + f"sigma_{child_name}", dist.Exponential(1.0) + ) # type: ignore + + continuous_contribution_to_child = continuous_contribution( + child_continuous_parents, child_name, leeway=leeway + ) + + categorical_contribution_to_child = categorical_contribution( + child_categorical_parents, + child_name, + leeway, + categorical_levels=categorical_levels, + ) + + with data_plate: + + mean_prediction_child = pyro.deterministic( # type: ignore + f"mean_outcome_prediction_{child_name}", + continuous_contribution_to_child + categorical_contribution_to_child, + event_dim=0, + ) + + child_observed = pyro.sample( # type: ignore + f"{child_name}", + dist.Normal(mean_prediction_child, sigma_child), + obs=observations, + ) + + return child_observed + + +def add_linear_component_continuous_interactions( + child_name: str, + child_continuous_parents: Dict[str, torch.Tensor], + child_categorical_parents: Dict[str, torch.Tensor], + continous_interaction_pairs: List[Tuple[str, str]], + leeway: float, + data_plate, + categorical_levels: Dict[str, torch.Tensor], + observations: Optional[torch.Tensor] = None, +) -> torch.Tensor: + + if continous_interaction_pairs == [("all", "all")]: + continous_interaction_pairs = [ + (key1, key2) + for key1 in child_continuous_parents.keys() + for key2 in child_continuous_parents.keys() + if key1 != key2 + ] + + for interaction_pair in continous_interaction_pairs: + assert interaction_pair[0] in child_continuous_parents.keys() + assert interaction_pair[1] in child_continuous_parents.keys() + + interaction_name = f"{interaction_pair[0]}_x_{interaction_pair[1]}_to_{child_name}" + + with data_plate: + child_continuous_parents[interaction_name] = pyro.deterministic( + interaction_name, + child_continuous_parents[interaction_pair[0]] + * child_continuous_parents[interaction_pair[1]], + event_dim=0, + ) + + child_observed = add_linear_component( + child_name=child_name, + child_continuous_parents=child_continuous_parents, + child_categorical_parents=child_categorical_parents, + leeway=leeway, + data_plate=data_plate, + categorical_levels=categorical_levels, + observations=observations, + ) + + return child_observed + + +def add_logistic_component( + child_name: str, + child_continuous_parents: Dict[str, torch.Tensor], + child_categorical_parents: Dict[str, torch.Tensor], + leeway: float, + data_plate, + categorical_levels: Dict[str, torch.Tensor], + observations: Optional[torch.Tensor] = None, +) -> torch.Tensor: + + continuous_contribution_to_child = continuous_contribution( + child_continuous_parents, child_name, leeway + ) + + categorical_contribution_to_child = categorical_contribution( + child_categorical_parents, + child_name, + leeway, + categorical_levels=categorical_levels, + ) + + with data_plate: + + mean_prediction_child = pyro.deterministic( # type: ignore + f"mean_outcome_prediction_{child_name}", + categorical_contribution_to_child + continuous_contribution_to_child, + event_dim=0, + ) + + child_probs = pyro.deterministic( + f"child_probs_{child_name}", + torch.sigmoid(mean_prediction_child), + event_dim=0, + ) + + child_observed = pyro.sample( + f"{child_name}", + dist.Bernoulli(child_probs), + obs=observations, + ) + + return child_observed + + +def add_ratio_component( + child_name: str, + child_continuous_parents: Dict[str, torch.Tensor], + child_categorical_parents: Dict[str, torch.Tensor], + leeway: float, + data_plate, + categorical_levels: Dict[str, torch.Tensor], + observations: Optional[torch.Tensor] = None, +) -> torch.Tensor: + + continuous_contribution_to_child = continuous_contribution( + child_continuous_parents, child_name, leeway + ) + + categorical_contribution_to_child = categorical_contribution( + child_categorical_parents, + child_name, + leeway, + categorical_levels=categorical_levels, + ) + + sigma_child = pyro.sample(f"sigma_{child_name}", dist.Exponential(40.0)) + + with data_plate: + + mean_prediction_child = pyro.deterministic( # type: ignore + f"mean_outcome_prediction_{child_name}", + categorical_contribution_to_child + continuous_contribution_to_child, + event_dim=0, + ) + + child_probs = pyro.deterministic( + f"child_probs_{child_name}", + torch.sigmoid(mean_prediction_child), + event_dim=0, + ) + + child_observed = pyro.sample( + child_name, dist.Normal(child_probs, sigma_child), obs=observations + ) + + return child_observed + + +def add_ratio_component_continuous_interactions( + child_name: str, + child_continuous_parents: Dict[str, torch.Tensor], + child_categorical_parents: Dict[str, torch.Tensor], + continous_interaction_pairs: List[Tuple[str, str]], + leeway: float, + data_plate, + categorical_levels: Dict[str, torch.Tensor], + observations: Optional[torch.Tensor] = None, +) -> torch.Tensor: + + for interaction_pair in continous_interaction_pairs: + assert interaction_pair[0] in child_continuous_parents.keys() + assert interaction_pair[1] in child_continuous_parents.keys() + + interaction_name = f"{interaction_pair[0]}_x_{interaction_pair[1]}_to_{child_name}" + + with data_plate: + child_continuous_parents[interaction_name] = pyro.deterministic( + interaction_name, + child_continuous_parents[interaction_pair[0]] + * child_continuous_parents[interaction_pair[1]], + event_dim=0, + ) + + child_observed = add_ratio_component( + child_name=child_name, + child_continuous_parents=child_continuous_parents, + child_categorical_parents=child_categorical_parents, + leeway=leeway, + data_plate=data_plate, + categorical_levels=categorical_levels, + observations=observations, + ) + + return child_observed diff --git a/build/cities/modeling/model_interactions.py b/build/cities/modeling/model_interactions.py new file mode 100644 index 00000000..2446d6d5 --- /dev/null +++ b/build/cities/modeling/model_interactions.py @@ -0,0 +1,181 @@ +import logging +import os +from typing import Optional + +import dill +import pyro +import pyro.distributions as dist +import torch + +from cities.modeling.modeling_utils import ( + prep_wide_data_for_inference, + train_interactions_model, +) +from cities.utils.data_grabber import DataGrabber, find_repo_root + + +class InteractionsModel: + def __init__( + self, + outcome_dataset: str, + intervention_dataset: str, + intervention_variable: Optional[str] = None, + forward_shift: int = 2, + num_iterations: int = 1500, + num_samples: int = 1000, + plot_loss: bool = False, + ): + self.outcome_dataset = outcome_dataset + self.intervention_dataset = intervention_dataset + self.forward_shift = forward_shift + self.num_iterations = num_iterations + self.num_samples = num_samples + self.plot_loss = plot_loss + self.root = find_repo_root() + + if intervention_variable: + self.intervention_variable = intervention_variable + else: + _dg = DataGrabber() + _dg.get_features_std_long([intervention_dataset]) + self.intervention_variable = _dg.std_long[intervention_dataset].columns[-1] + + self.data = prep_wide_data_for_inference( + outcome_dataset=self.outcome_dataset, + intervention_dataset=self.intervention_dataset, + forward_shift=self.forward_shift, + ) + + self.model = model_cities_interaction + + self.model_args = self.data["model_args"] + + self.model_conditioned = pyro.condition( # type: ignore + self.model, + data={"T": self.data["t"], "Y": self.data["y"], "X": self.data["x"]}, + ) + + self.model_rendering = pyro.render_model( # type: ignore + self.model, model_args=self.model_args, render_distributions=True + ) + + def train_interactions_model(self): + self.guide = train_interactions_model( + conditioned_model=self.model_conditioned, + model_args=self.model_args, + num_iterations=self.num_iterations, + plot_loss=self.plot_loss, + ) + + def sample_from_guide(self): + predictive = pyro.infer.Predictive( + model=self.model, + guide=self.guide, + num_samples=self.num_samples, + parallel=False, + ) + self.samples = predictive(*self.model_args) + + def save_guide(self): + guide_name = ( + f"{self.intervention_dataset}_{self.outcome_dataset}_{self.forward_shift}" + ) + serialized_guide = dill.dumps(self.guide) + file_path = os.path.join( + self.root, "data/model_guides", f"{guide_name}_guide.pkl" + ) + with open(file_path, "wb") as file: + file.write(serialized_guide) + param_path = os.path.join( + self.root, "data/model_guides", f"{guide_name}_params.pth" + ) + pyro.get_param_store().save(param_path) + + logging.info( + f"Guide and params for {self.intervention_dataset}", + f"{self.outcome_dataset} with shift {self.forward_shift}", + "has been saved.", + ) + + +def model_cities_interaction( + N_t, + N_cov, + N_s, + N_u, + state_index, + unit_index, + leeway=0.9, +): + bias_Y = pyro.sample("bias_Y", dist.Normal(0, leeway)) + bias_T = pyro.sample("bias_T", dist.Normal(0, leeway)) + + weight_TY = pyro.sample("weight_TY", dist.Normal(0, leeway)) + + sigma_T = pyro.sample("sigma_T", dist.Exponential(1)) + sigma_Y = pyro.sample("sigma_Y", dist.Exponential(1)) + + counties_plate = pyro.plate("counties_plate", N_u, dim=-1) + states_plate = pyro.plate("states_plate", N_s, dim=-2) + covariates_plate = pyro.plate("covariates_plate", N_cov, dim=-3) + time_plate = pyro.plate("time_plate", N_t, dim=-4) + + with covariates_plate: + bias_X = pyro.sample("bias_X", dist.Normal(0, leeway)) + sigma_X = pyro.sample("sigma_X", dist.Exponential(1)) + weight_XT = pyro.sample("weight_XT", dist.Normal(0, leeway)) + weight_XY = pyro.sample("weight_XY", dist.Normal(0, leeway)) + + with states_plate: + bias_stateT = pyro.sample("bias_stateT", dist.Normal(0, leeway)) + bias_stateY = pyro.sample("bias_stateY", dist.Normal(0, leeway)) + + with covariates_plate: + bias_stateX = pyro.sample("bias_stateX", dist.Normal(0, leeway)) + + with time_plate: + bias_timeT = pyro.sample("bias_timeT", dist.Normal(0, leeway)) + bias_timeY = pyro.sample("bias_timeY", dist.Normal(0, leeway)) + + with counties_plate: + with covariates_plate: + mean_X = pyro.deterministic( + "mean_X", + torch.einsum( + "...xdd,...xcd->...xdc", bias_X, bias_stateX[..., state_index, :] + ), + ) + + X = pyro.sample("X", dist.Normal(mean_X[..., unit_index], sigma_X)) + + XT_weighted = torch.einsum( + "...xdc, ...xdd -> ...dc", X, weight_XT + ).unsqueeze(-2) + XY_weighted = torch.einsum( + "...xdc, ...xdd -> ...dc", X, weight_XY + ).unsqueeze(-2) + + with time_plate: + bias_stateT_tiled = pyro.deterministic( + "bias_stateT_tiled", + torch.einsum("...cd -> ...dc", bias_stateT[..., state_index, :]), + ) + + mean_T = pyro.deterministic( + "mean_T", bias_T + bias_timeT + bias_stateT_tiled + XT_weighted + ) + + T = pyro.sample("T", dist.Normal(mean_T, sigma_T)) + + bias_stateY_tiled = pyro.deterministic( + "bias_stateY_tiled", + torch.einsum("...cd -> ...dc", bias_stateY[..., state_index, :]), + ) + + mean_Y = pyro.deterministic( + "mean_Y", + bias_Y + bias_timeY + bias_stateY_tiled + XY_weighted + weight_TY * T, + ) + Y = pyro.sample("Y", dist.Normal(mean_Y, sigma_Y)) + + return Y diff --git a/build/cities/modeling/modeling_utils.py b/build/cities/modeling/modeling_utils.py new file mode 100644 index 00000000..55aaccc6 --- /dev/null +++ b/build/cities/modeling/modeling_utils.py @@ -0,0 +1,403 @@ +from typing import Callable + +import matplotlib.pyplot as plt +import pandas as pd +import pyro +import torch +from pyro.infer import SVI, Trace_ELBO +from pyro.infer.autoguide import AutoNormal +from pyro.optim import Adam # type: ignore +from scipy.stats import spearmanr + +from cities.utils.data_grabber import ( + DataGrabber, + list_available_features, + list_tensed_features, +) + + +def drop_high_correlation(df, threshold=0.85): + df_var = df.iloc[:, 2:].copy() + correlation_matrix, _ = spearmanr(df_var) + + high_correlation_pairs = [ + (df_var.columns[i], df_var.columns[j]) + for i in range(df_var.shape[1]) + for j in range(i + 1, df_var.shape[1]) + if abs(correlation_matrix[i, j]) > threshold + and abs(correlation_matrix[i, j]) < 1.0 + ] + high_correlation_pairs = [ + (var1, var2) for var1, var2 in high_correlation_pairs if var1 != var2 + ] + + removed = set() + print( + f"Highly correlated pairs: {high_correlation_pairs}, second elements will be dropped" + ) + for var1, var2 in high_correlation_pairs: + assert var2 in df_var.columns + for var1, var2 in high_correlation_pairs: + if var2 in df_var.columns: + removed.add(var2) + df_var.drop(var2, axis=1, inplace=True) + + result = pd.concat([df.iloc[:, :2], df_var], axis=1) + print(f"Removed {removed} due to correlation > {threshold}") + return result + + +def prep_wide_data_for_inference( + outcome_dataset: str, intervention_dataset: str, forward_shift: int +): + """ + Prepares wide-format data for causal inference modeling. + + Parameters: + - outcome_dataset (str): Name of the outcome variable. + - intervention_dataset (str): Name of the intervention variable. + - forward_shift (int): Number of time steps to shift the outcome variable for prediction. + + Returns: + dict: A dictionary containing the necessary inputs for causal inference modeling. + + The function performs the following steps: + 1. Identifies available device (GPU if available, otherwise CPU), to be used with tensors. + 2. Uses a DataGrabber class to obtain standardized wide-format data. + 3. Separates covariate datasets into time series (tensed) and fixed covariates. + 4. Loads the required transformed features. + 5. Merges fixed covariates into a joint dataframe based on a common ID column. + 6. Ensures that the GeoFIPS (geographical identifier) is consistent across datasets. + 7. Extracts common years for which both intervention and outcome data are available. + 8. Shifts the outcome variable forward by the specified number of time steps. + 9. Prepares tensors for input features (x), interventions (t), and outcomes (y). + 10. Creates indices for states and units, preparing them as tensors. + 11. Validates the shapes of the tensors. + 12. Constructs a dictionary containing model arguments and prepared tensors. + + Example usage: + prep_data = prep_wide_data_for_inference("outcome_data", "intervention_data", 2) + """ + if torch.cuda.is_available(): + device = torch.device("cuda") + else: + device = torch.device("cpu") + + dg = DataGrabber() + + tensed_covariates_datasets = [ + var + for var in list_tensed_features() + if var not in [outcome_dataset, intervention_dataset] + ] + fixed_covariates_datasets = [ + var + for var in list_available_features() + if var + not in tensed_covariates_datasets + [outcome_dataset, intervention_dataset] + ] + + features_needed = [ + outcome_dataset, + intervention_dataset, + ] + fixed_covariates_datasets + + dg.get_features_std_wide(features_needed) + + intervention = dg.std_wide[intervention_dataset] + outcome = dg.std_wide[outcome_dataset] + + # put covariates in one df as columns, dropping repeated ID columns + f_covariates = { + dataset: dg.std_wide[dataset] for dataset in fixed_covariates_datasets + } + f_covariates_joint = f_covariates[fixed_covariates_datasets[0]] + for dataset in f_covariates.keys(): + if dataset != fixed_covariates_datasets[0]: + if "GeoName" in f_covariates[dataset].columns: + f_covariates[dataset] = f_covariates[dataset].drop(columns=["GeoName"]) + f_covariates_joint = f_covariates_joint.merge( + f_covariates[dataset], on=["GeoFIPS"] + ) + + f_covariates_joint = drop_high_correlation(f_covariates_joint) + + assert f_covariates_joint["GeoFIPS"].equals(intervention["GeoFIPS"]) + + # extract data for which intervention and outcome overlap + year_min = max( + intervention.columns[2:].astype(int).min(), + outcome.columns[2:].astype(int).min(), + ) + + year_max = min( + intervention.columns[2:].astype(int).max(), + outcome.columns[2:].astype(int).max(), + ) + + assert all(intervention["GeoFIPS"] == outcome["GeoFIPS"]) + + outcome_years_to_keep = [ + year + for year in outcome.columns[2:] + if year_min <= int(year) <= year_max + forward_shift + ] + + outcome_years_to_keep = [ + year for year in outcome_years_to_keep if year in intervention.columns[2:] + ] + + outcome = outcome[outcome_years_to_keep] + + # shift outcome `forward_shift` steps ahead + # for the prediction task + outcome_shifted = outcome.copy() + + for i in range(len(outcome_years_to_keep) - forward_shift): + outcome_shifted.iloc[:, i] = outcome_shifted.iloc[:, i + forward_shift] + + years_to_drop = [ + f"{year}" for year in range(year_max - forward_shift + 1, year_max + 1) + ] + outcome_shifted.drop(columns=years_to_drop, inplace=True) + + intervention.drop(columns=["GeoFIPS", "GeoName"], inplace=True) + intervention = intervention[outcome_shifted.columns] + + assert intervention.shape == outcome_shifted.shape + + years_available = outcome_shifted.columns.astype(int).values + + unit_index = pd.factorize(f_covariates_joint["GeoFIPS"].values)[0] + state_index = pd.factorize(f_covariates_joint["GeoFIPS"].values // 1000)[0] + + # prepare tensors + x = torch.tensor( + f_covariates_joint.iloc[:, 2:].values, dtype=torch.float32, device=device + ) + x = x.unsqueeze(1).unsqueeze(1).permute(2, 3, 1, 0) + + t = torch.tensor(intervention.values, dtype=torch.float32, device=device) + t = t.unsqueeze(1).unsqueeze(1).permute(3, 1, 2, 0) + + y = torch.tensor(outcome_shifted.values, dtype=torch.float32, device=device) + y = y.unsqueeze(1).unsqueeze(1).permute(3, 1, 2, 0) + + state_index = torch.tensor(state_index, dtype=torch.int, device=device) + unit_index = torch.tensor(unit_index, dtype=torch.int, device=device) + + N_t = y.shape[0] + N_cov = x.shape[1] + N_s = state_index.unique().shape[0] + N_u = unit_index.unique().shape[0] + + assert x.shape == (1, N_cov, 1, N_u) + assert y.shape == (N_t, 1, 1, N_u) + assert t.shape == (N_t, 1, 1, N_u) + + model_args = (N_t, N_cov, N_s, N_u, state_index, unit_index) + + return { + "model_args": model_args, + "x": x, + "t": t, + "y": y, + "years_available": years_available, + "outcome_years": outcome_years_to_keep, + "covariates_df": f_covariates_joint, + } + + +def train_interactions_model( + conditioned_model: Callable, + model_args, + num_iterations: int = 1000, + plot_loss: bool = True, + print_interval: int = 100, + lr: float = 0.01, +): + guide = None + pyro.clear_param_store() # type: ignore + + guide = AutoNormal(conditioned_model) + + svi = SVI( + model=conditioned_model, guide=guide, optim=Adam({"lr": lr}), loss=Trace_ELBO() + ) + + losses = [] + for step in range(num_iterations): + loss = svi.step(*model_args) + losses.append(loss) + if step % print_interval == 0: + print("[iteration %04d] loss: %.4f" % (step + 1, loss)) + + if plot_loss: + plt.plot(range(num_iterations), losses, label="Loss") + plt.show() + + return guide + + +def prep_data_for_interaction_inference( + outcome_dataset, intervention_dataset, intervention_variable, forward_shift +): + dg = DataGrabber() + + tensed_covariates_datasets = [ + var + for var in list_tensed_features() + if var not in [outcome_dataset, intervention_dataset] + ] + fixed_covariates_datasets = [ + var + for var in list_available_features() + if var + not in tensed_covariates_datasets + [outcome_dataset, intervention_dataset] + ] + + dg.get_features_std_long(list_available_features()) + dg.get_features_std_wide(list_available_features()) + + year_min = max( + dg.std_long[intervention_dataset]["Year"].min(), + dg.std_long[outcome_dataset]["Year"].min(), + ) + year_max = min( + dg.std_long[intervention_dataset]["Year"].max(), + dg.std_long[outcome_dataset]["Year"].max(), + ) + outcome_df = dg.std_long[outcome_dataset].sort_values(by=["GeoFIPS", "Year"]) + + # now we adding forward shift to the outcome + # cleaning up and puting intervention/outcome in one df + # and fixed covariates in another + + outcome_df[f"{outcome_dataset}_shifted_by_{forward_shift}"] = None + + geo_subsets = [] + for geo_fips in outcome_df["GeoFIPS"].unique(): + geo_subset = outcome_df[outcome_df["GeoFIPS"] == geo_fips].copy() + # Shift the 'Value' column `forward_shift` in a new column + geo_subset[f"{outcome_dataset}_shifted_by_{forward_shift}"] = geo_subset[ + "Value" + ].shift(-forward_shift) + geo_subsets.append(geo_subset) + + outcome_df = pd.concat(geo_subsets).reset_index(drop=True) + + outcome = outcome_df[ + (outcome_df["Year"] >= year_min) + & (outcome_df["Year"] <= year_max + forward_shift) + ] + + intervention = dg.std_long[intervention_dataset][ + (dg.std_long[intervention_dataset]["Year"] >= year_min) + & (dg.std_long[intervention_dataset]["Year"] <= year_max) + ] + f_covariates = { + dataset: dg.std_wide[dataset] for dataset in fixed_covariates_datasets + } + f_covariates_joint = f_covariates[fixed_covariates_datasets[0]] + for dataset in f_covariates.keys(): + if dataset != fixed_covariates_datasets[0]: + if "GeoName" in f_covariates[dataset].columns: + f_covariates[dataset] = f_covariates[dataset].drop(columns=["GeoName"]) + f_covariates_joint = f_covariates_joint.merge( + f_covariates[dataset], on=["GeoFIPS"] + ) + + i_o_data = pd.merge(outcome, intervention, on=["GeoFIPS", "Year"]) + + if "GeoName_x" in i_o_data.columns: + i_o_data.rename(columns={"GeoName_x": "GeoName"}, inplace=True) + columns_to_drop = i_o_data.filter(regex=r"^GeoName_[a-zA-Z]$") + i_o_data.drop(columns=columns_to_drop.columns, inplace=True) + + i_o_data.rename(columns={"Value": outcome_dataset}, inplace=True) + + i_o_data["state"] = [code // 1000 for code in i_o_data["GeoFIPS"]] + + N_s = len(i_o_data["state"].unique()) # number of states + i_o_data.dropna(inplace=True) + + i_o_data["unit_index"] = pd.factorize(i_o_data["GeoFIPS"].values)[0] + i_o_data["state_index"] = pd.factorize(i_o_data["state"].values)[0] + i_o_data["time_index"] = pd.factorize(i_o_data["Year"].values)[0] + + assert i_o_data["GeoFIPS"].isin(f_covariates_joint["GeoFIPS"]).all() + + f_covariates_joint.drop(columns=["GeoName"], inplace=True) + data = i_o_data.merge(f_covariates_joint, on="GeoFIPS", how="left") + + assert not data.isna().any().any() + + time_index_idx = data.columns.get_loc("time_index") + covariates_df = data.iloc[:, time_index_idx + 1 :].copy() + covariates_df_sparse = covariates_df.copy() + covariates_df_sparse["unit_index"] = data["unit_index"] + covariates_df_sparse["state_index"] = data["state_index"] + covariates_df_sparse.drop_duplicates(inplace=True) + assert set(covariates_df_sparse["unit_index"]) == set(data["unit_index"]) + + # get tensors + + if torch.cuda.is_available(): + device = torch.device("cuda") + else: + device = torch.device("cpu") + + y = data[f"{outcome_dataset}_shifted_by_{forward_shift}"] + y = torch.tensor(y, dtype=torch.float32, device=device) + + unit_index = torch.tensor(data["unit_index"], dtype=torch.int, device=device) + unit_index_sparse = torch.tensor( + covariates_df_sparse["unit_index"], dtype=torch.int + ) + + state_index = torch.tensor(data["state_index"], dtype=torch.int, device=device) + state_index_sparse = torch.tensor( + covariates_df_sparse["state_index"], dtype=torch.int + ) + + time_index = torch.tensor(data["time_index"], dtype=torch.int, device=device) + intervention = torch.tensor( + data[intervention_variable], dtype=torch.float32, device=device + ) + + covariates = torch.tensor(covariates_df.values, dtype=torch.float32, device=device) + + covariates_df_sparse.drop(columns=["unit_index", "state_index"], inplace=True) + covariates_sparse = torch.tensor( + covariates_df_sparse.values, dtype=torch.float32, device=device + ) + + N_cov = covariates.shape[1] # number of covariates + N_u = covariates_sparse.shape[0] # number of units (counties) + N_obs = len(y) # number of observations + N_t = len(time_index.unique()) # number of time points + N_s = len(state_index.unique()) # number of states + + assert len(intervention) == len(y) + assert len(unit_index) == len(y) + assert len(state_index) == len(unit_index) + assert len(time_index) == len(unit_index) + assert covariates.shape[1] == covariates_sparse.shape[1] + assert len(unit_index_sparse) == N_u + + return { + "N_t": N_t, + "N_cov": N_cov, + "N_s": N_s, + "N_u": N_u, + "N_obs": N_obs, + "unit_index": unit_index, + "state_index": state_index, + "time_index": time_index, + "unit_index_sparse": unit_index_sparse, + "state_index_sparse": state_index_sparse, + "covariates": covariates, + "covariates_sparse": covariates_sparse, + "intervention": intervention, + "y": y, + } diff --git a/build/cities/modeling/svi_inference.py b/build/cities/modeling/svi_inference.py new file mode 100644 index 00000000..8ccef03c --- /dev/null +++ b/build/cities/modeling/svi_inference.py @@ -0,0 +1,44 @@ +import matplotlib.pyplot as plt +import pyro +import torch +from pyro.infer.autoguide import AutoMultivariateNormal, init_to_mean + + +def run_svi_inference( + model, + verbose=True, + lr=0.03, + vi_family=AutoMultivariateNormal, + guide=None, + hide=[], + n_steps=500, + ylim=None, + plot=True, + **model_kwargs +): + losses = [] + if guide is None: + guide = vi_family( + pyro.poutine.block(model, hide=hide), init_loc_fn=init_to_mean + ) + elbo = pyro.infer.Trace_ELBO()(model, guide) + + elbo(**model_kwargs) + adam = torch.optim.Adam(elbo.parameters(), lr=lr) + + for step in range(1, n_steps + 1): + adam.zero_grad() + loss = elbo(**model_kwargs) + loss.backward() + losses.append(loss.item()) + adam.step() + if (step % 50 == 0) or (step == 1) & verbose: + print("[iteration %04d] loss: %.4f" % (step, loss)) + + if plot: + plt.plot(losses) + if ylim: + plt.ylim(ylim) + plt.show() + + return guide diff --git a/build/cities/modeling/tau_caching_pipeline.py b/build/cities/modeling/tau_caching_pipeline.py new file mode 100644 index 00000000..b517d522 --- /dev/null +++ b/build/cities/modeling/tau_caching_pipeline.py @@ -0,0 +1,88 @@ +import logging +import os +import time + +from cities.queries.causal_insight import CausalInsight +from cities.utils.data_grabber import ( + DataGrabber, + find_repo_root, + list_interventions, + list_outcomes, +) + +root = find_repo_root() +log_dir = os.path.join(root, "data", "tau_samples") +log_file_path = os.path.join(log_dir, ".sampling.log") +os.makedirs(log_dir, exist_ok=True) + +logging.basicConfig( + filename=log_file_path, + filemode="w", + format="%(asctime)s → %(name)s → %(levelname)s: %(message)s", + datefmt="%Y-%m-%d %H:%M:%S", + level=logging.INFO, +) + + +session_start = time.time() + + +num_samples = 1000 + +data = DataGrabber() + +interventions = list_interventions() +outcomes = list_outcomes() + + +N_combinations_samples = len(interventions) * len(outcomes) + + +files = [f for f in os.listdir(log_dir) if os.path.isfile(os.path.join(log_dir, f))] +num_files = len(files) + +logging.info( + f"{(num_files-2)} sample dictionaries already exist. " + f"Starting to obtain {N_combinations_samples - (num_files -2)}" + f" out of {N_combinations_samples} sample dictionaries needed." +) +remaining = N_combinations_samples - (num_files - 2) +for intervention in interventions: + for outcome in outcomes: + tau_samples_path = os.path.join( + root, + "data/tau_samples", + f"{intervention}_{outcome}_{num_samples}_tau.pkl", + ) + + if not os.path.exists(tau_samples_path): + start_time = time.time() + logging.info(f"Sampling {outcome}/{intervention} pair now.") + ci = CausalInsight( + outcome_dataset=outcome, + intervention_dataset=intervention, + num_samples=num_samples, + ) + + ci.generate_tensed_samples() + end_time = time.time() + duration = end_time - start_time + files = [ + f + for f in os.listdir(log_dir) + if os.path.isfile(os.path.join(log_dir, f)) + ] + num_files = len(files) + remaining -= 1 + logging.info( + f"Done sampling {outcome}/{intervention} pair, completed in {duration:.2f} seconds." + f" {remaining} out of {N_combinations_samples} samples remain." + ) + + +session_ends = time.time() + +logging.info( + f"All samples are now available." + f"Sampling took {session_ends - session_start:.2f} seconds, or {(session_ends - session_start)/60:.2f} minutes." +) diff --git a/build/cities/modeling/training_pipeline.py b/build/cities/modeling/training_pipeline.py new file mode 100644 index 00000000..3f4ebc72 --- /dev/null +++ b/build/cities/modeling/training_pipeline.py @@ -0,0 +1,90 @@ +import logging +import os +import sys +import time + +from cities.modeling.model_interactions import InteractionsModel +from cities.utils.data_grabber import find_repo_root, list_interventions, list_outcomes + +if __name__ != "__main__": + sys.exit() + +root = find_repo_root() +log_dir = os.path.join(root, "data", "model_guides") +log_file_path = os.path.join(log_dir, ".training.log") +os.makedirs(log_dir, exist_ok=True) + +logging.basicConfig( + filename=log_file_path, + filemode="w", + format="%(asctime)s → %(name)s → %(levelname)s: %(message)s", + datefmt="%Y-%m-%d %H:%M:%S", + level=logging.INFO, +) + + +# if you need to train from scratch +# clean data/model_guides folder manually +# automatic fresh start is not implemented +# for security reasons + +num_iterations = 4000 + +interventions = list_interventions() +outcomes = list_outcomes() +shifts = [1, 2, 3] + + +N_combinations = len(interventions) * len(outcomes) * len(shifts) + +files = [f for f in os.listdir(log_dir) if os.path.isfile(os.path.join(log_dir, f))] +num_files = len(files) + + +logging.info( + f"{(num_files-2)/2} guides already exist. " + f"Starting to train {N_combinations - (num_files -2)/2} out of {N_combinations} guides needed." +) + +remaining = N_combinations - (num_files - 2) / 2 +for intervention_dataset in interventions: + for outcome_dataset in outcomes: + for forward_shift in shifts: + # check if the corresponding guide already exists + # existing_guides = 0 seems rendundant, remove if all works + guide_name = f"{intervention_dataset}_{outcome_dataset}_{forward_shift}" + guide_path = os.path.join( + root, "data/model_guides", f"{guide_name}_guide.pkl" + ) + if not os.path.exists(guide_path): + # existing_guides += 1 seems redundat remove if all works + + logging.info(f"Training {guide_name} for {num_iterations} iterations.") + + start_time = time.time() + model = InteractionsModel( + outcome_dataset=outcome_dataset, + intervention_dataset=intervention_dataset, + forward_shift=forward_shift, + num_iterations=num_iterations, + plot_loss=False, + ) + + model.train_interactions_model() + model.save_guide() + + end_time = time.time() + duration = end_time - start_time + files = [ + f + for f in os.listdir(log_dir) + if os.path.isfile(os.path.join(log_dir, f)) + ] + num_files = len(files) + remaining -= 1 + logging.info( + f"Training of {guide_name} completed in {duration:.2f} seconds. " + f"{int(remaining)} out of {N_combinations} guides remain to be trained." + ) + +logging.info("All guides are now available.") diff --git a/build/cities/modeling/waic.py b/build/cities/modeling/waic.py new file mode 100644 index 00000000..cf388ee5 --- /dev/null +++ b/build/cities/modeling/waic.py @@ -0,0 +1,69 @@ +from typing import Any, Callable, Dict, Optional + +import pyro +import torch +from pyro.infer.enum import get_importance_trace + + +def compute_waic( + model: Callable[..., Any], + guide: Callable[..., Any], + num_particles: int, + max_plate_nesting: int, + sites: Optional[list[str]] = None, + *args: Any, + **kwargs: Any +) -> Dict[str, Any]: + + def vectorize(fn: Callable[..., Any]) -> Callable[..., Any]: + def _fn(*args: Any, **kwargs: Any) -> Any: + with pyro.plate( + "num_particles_vectorized", num_particles, dim=-max_plate_nesting + ): + return fn(*args, **kwargs) + + return _fn + + model_trace, _ = get_importance_trace( + "flat", max_plate_nesting, vectorize(model), vectorize(guide), args, kwargs + ) + + def site_filter_is_observed(site_name: str) -> bool: + return model_trace.nodes[site_name]["is_observed"] + + def site_filter_in_sites(site_name: str) -> bool: + return sites is not None and site_name in sites + + if sites is None: + site_filter = site_filter_is_observed + else: + site_filter = site_filter_in_sites + + observed_nodes = { + name: node for name, node in model_trace.nodes.items() if site_filter(name) + } + + log_p_post = { + key: observed_nodes[key]["log_prob"].mean(dim=0) # sum(axis = 0)/num_particles + for key in observed_nodes.keys() + } + + lppd = torch.stack([log_p_post[key] for key in log_p_post.keys()]).sum() + + var_log_p_post = { + key: (observed_nodes[key]["log_prob"]).var(axis=0) + for key in observed_nodes.keys() + } + + p_waic = torch.stack([var_log_p_post[key] for key in var_log_p_post.keys()]).sum() + + waic = -2 * (lppd - p_waic) + + return { + "waic": waic, + "nodes": observed_nodes, + "log_p_post": log_p_post, + "var_log_p_post": var_log_p_post, + "lppd": lppd, + "p_waic": p_waic, + } diff --git a/build/cities/modeling/zoning_models/distance_causal_model.py b/build/cities/modeling/zoning_models/distance_causal_model.py new file mode 100644 index 00000000..57f4fc31 --- /dev/null +++ b/build/cities/modeling/zoning_models/distance_causal_model.py @@ -0,0 +1,202 @@ +from typing import Any, Dict, Optional + +import pyro +import pyro.distributions as dist +import torch + +from cities.modeling.zoning_models.units_causal_model import add_linear_component, get_n + + +class DistanceCausalModel(pyro.nn.PyroModule): + def __init__( + self, + categorical: Dict[str, torch.Tensor], + continuous: Dict[str, torch.Tensor], + outcome: Optional[ + torch.Tensor + ] = None, # init args kept for uniformity, consider deleting + categorical_levels: Optional[Dict[str, Any]] = None, + leeway=0.9, + ): + super().__init__() + + self.leeway = leeway + + self.N_categorical, self.N_continuous, n = get_n(categorical, continuous) + + # you might need and pass further the original + # categorical levels of the training data + if self.N_categorical > 0 and categorical_levels is None: + self.categorical_levels = dict() + for name in categorical.keys(): + self.categorical_levels[name] = torch.unique(categorical[name]) + else: + self.categorical_levels = categorical_levels # type: ignore + + def forward( + self, + categorical: Dict[str, torch.Tensor], + continuous: Dict[str, torch.Tensor], + outcome: Optional[torch.Tensor] = None, + categorical_levels: Optional[Dict[str, torch.Tensor]] = None, + leeway=0.9, + ): + if categorical_levels is None: + categorical_levels = self.categorical_levels + + _N_categorical, _N_continuous, n = get_n(categorical, continuous) + + data_plate = pyro.plate("data", size=n, dim=-1) + + ################# + # register + ################# + with data_plate: + + year = pyro.sample( + "year", + dist.Categorical(torch.ones(len(categorical_levels["year"]))), + obs=categorical["year"], + ) + + month = pyro.sample( + "month", + dist.Categorical(torch.ones(len(categorical_levels["month"]))), + obs=categorical["month"], + ) + + zone_id = pyro.sample( + "zone_id", + dist.Categorical(torch.ones(len(categorical_levels["zone_id"]))), + obs=categorical["zone_id"], + ) + + neighborhood_id = pyro.sample( + "neighborhood_id", + dist.Categorical( + torch.ones(len(categorical_levels["neighborhood_id"])) + ), + obs=categorical["neighborhood_id"], + ) + + ward_id = pyro.sample( + "ward_id", + dist.Categorical(torch.ones(len(categorical_levels["ward_id"]))), + obs=categorical["ward_id"], + ) + + past_reform = pyro.sample( + "past_reform", dist.Normal(0, 1), obs=categorical["past_reform"] + ) + + # past_reform_by_zone = pyro.deterministic( + # "past_reform_by_zone", + # categorical_interaction_variable([past_reform, zone_id])[0], + # ) + # categorical_levels["past_reform_by_zone"] = torch.unique( + # past_reform_by_zone + # ) + + # ___________________________________ + # deterministic def of actual limits + # ___________________________________ + + with data_plate: + limit_con = pyro.deterministic( + "limit_con", + torch.where( + zone_id == 0, + torch.tensor(0.0), + torch.where( + zone_id == 1, + 1.0 - past_reform, + torch.where( + zone_id == 2, 1.0 - 0.5 * past_reform, torch.tensor(1.0) + ), + ), + ), + event_dim=0, + ) + + # __________________________________ + # regression for distance to transit + # __________________________________ + + distance_to_transit_continuous_parents = {} # type: ignore + distance_to_transit_categorical_parents = { + "zone_id": zone_id, + } + distance_to_transit = add_linear_component( + child_name="distance_to_transit", + child_continuous_parents=distance_to_transit_continuous_parents, + child_categorical_parents=distance_to_transit_categorical_parents, + leeway=leeway, + data_plate=data_plate, + observations=continuous["distance_to_transit"], + categorical_levels=categorical_levels, + ) + + # ___________________________ + # regression for parcel area + # ___________________________ + parcel_area_continuous_parents = {"distance_to_transit": distance_to_transit} # type: ignore + parcel_are_categorical_parents = { + "zone_id": zone_id, + "neighborhood_id": neighborhood_id, + } + parcel_area = add_linear_component( + child_name="parcel_area", + child_continuous_parents=parcel_area_continuous_parents, + child_categorical_parents=parcel_are_categorical_parents, + leeway=leeway, + data_plate=data_plate, + observations=continuous["parcel_area"], + categorical_levels=categorical_levels, + ) + + # ___________________________ + # regression for limit suspended in light of pyro.deterministic + # ___________________________ + + # limit_con_categorical_parents = {"past_reform_by_zone": past_reform_by_zone} + + # # TODO consider using a `pyro.deterministic` statement if safe to assume what the + # # rules are and hard code them + # limit_con = add_linear_component( + # child_name="limit_con", + # child_continuous_parents={}, + # child_categorical_parents=limit_con_categorical_parents, + # leeway=leeway, + # data_plate=data_plate, + # observations=continuous["limit_con"], + # categorical_levels=categorical_levels, + # ) + + # _____________________________ + # regression for housing units + # _____________________________ + + housing_units_continuous_parents = { + "limit_con": limit_con, + "parcel_area": parcel_area, + "distance_to_transit": distance_to_transit, + } + housing_units_categorical_parents = { + "year": year, + "month": month, + "zone_id": zone_id, + "neighborhood_id": neighborhood_id, + "ward_id": ward_id, + } + + housing_units = add_linear_component( + child_name="housing_units", + child_continuous_parents=housing_units_continuous_parents, + child_categorical_parents=housing_units_categorical_parents, + leeway=leeway, + data_plate=data_plate, + observations=outcome, + categorical_levels=categorical_levels, + ) + + return housing_units diff --git a/build/cities/modeling/zoning_models/missingness_only_model.py b/build/cities/modeling/zoning_models/missingness_only_model.py new file mode 100644 index 00000000..76fd7e82 --- /dev/null +++ b/build/cities/modeling/zoning_models/missingness_only_model.py @@ -0,0 +1,173 @@ +from typing import Any, Dict, Optional + +import pyro +import pyro.distributions as dist +import torch + +from cities.modeling.zoning_models.units_causal_model import ( + categorical_contribution, + continuous_contribution, + get_n, +) + +# see A WEAKLY INFORMATIVE DEFAULT PRIOR DISTRIBUTION FOR +# LOGISTIC AND OTHER REGRESSION MODELS +# B Y A NDREW G ELMAN , A LEKS JAKULIN , M ARIA G RAZIA +# P ITTAU AND Y U -S UNG S +# they recommed Cauchy with 2.5 scale for coefficient priors + +# see also zoning_missingness_only.ipynb for a normal approximation + + +def add_logistic_component( + child_name: "str", + child_continuous_parents, + child_categorical_parents, + leeway, + data_plate, + observations=None, + categorical_levels=None, +): + + continuous_contribution_to_child = continuous_contribution( + child_continuous_parents, child_name, leeway + ) + + categorical_contribution_to_child = categorical_contribution( + child_categorical_parents, + child_name, + leeway, + categorical_levels=categorical_levels, + ) + + with data_plate: + + mean_prediction_child = pyro.deterministic( # type: ignore + f"mean_outcome_prediction_{child_name}", + categorical_contribution_to_child + continuous_contribution_to_child, + event_dim=0, + ) + + child_probs = pyro.deterministic( + f"child_probs_{child_name}_{child_name}", + torch.sigmoid(mean_prediction_child), + event_dim=0, + ) + + child_observed = pyro.sample( + f"{child_name}", + dist.Bernoulli(child_probs), + obs=observations, + ) + + # TODO consider a gamma-like distro here + + return child_observed + + +class MissingnessOnlyModel(pyro.nn.PyroModule): + def __init__( + self, + categorical: Dict[str, torch.Tensor], + continuous: Dict[str, torch.Tensor], + outcome: Optional[ + torch.Tensor + ] = None, # init args kept for uniformity, consider deleting + categorical_levels: Optional[Dict[str, Any]] = None, + leeway=0.9, + ): + super().__init__() + + self.leeway = leeway + + self.N_categorical, self.N_continuous, n = get_n(categorical, continuous) + + # you might need and pass further the original + # categorical levels of the training data + if self.N_categorical > 0 and categorical_levels is None: + self.categorical_levels = dict() + for name in categorical.keys(): + self.categorical_levels[name] = torch.unique(categorical[name]) + else: + self.categorical_levels = categorical_levels # type: ignore + + def forward( + self, + categorical: Dict[str, torch.Tensor], + continuous: Dict[str, torch.Tensor], + outcome: Optional[torch.Tensor] = None, + categorical_levels: Optional[Dict[str, torch.Tensor]] = None, + leeway=0.9, + ): + if categorical_levels is None: + categorical_levels = self.categorical_levels + + _N_categorical, _N_continuous, n = get_n(categorical, continuous) + + data_plate = pyro.plate("data", size=n, dim=-1) + + ################# + # register + ################# + with data_plate: + + year = pyro.sample( + "year", + dist.Categorical(torch.ones(len(categorical_levels["year"]))), + obs=categorical["year"], + ) + + value = pyro.sample("value", dist.Normal(0, 1), obs=continuous["value"]) + + # month = pyro.sample( + # "month", + # dist.Categorical(torch.ones(len(categorical_levels["month"]))), + # obs=categorical["month"], + # ) + + # zone_id = pyro.sample( + # "zone_id", + # dist.Categorical(torch.ones(len(categorical_levels["zone_id"]))), + # obs=categorical["zone_id"], + # ) + + # neighborhood_id = pyro.sample( + # "neighborhood_id", + # dist.Categorical( + # torch.ones(len(categorical_levels["neighborhood_id"])) + # ), + # obs=categorical["neighborhood_id"], + # ) + + # ward_id = pyro.sample( + # "ward_id", + # dist.Categorical(torch.ones(len(categorical_levels["ward_id"]))), + # obs=categorical["ward_id"], + # ) + + # past_reform = pyro.sample( + # "past_reform", dist.Normal(0, 1), obs=categorical["past_reform"] + # ) + + # ___________________________ + # logistic regression for applied + # ___________________________ + + applied_continuous_parents = { + "value": value, + } + applied_categorical_parents = { + "year": year, + } + + applied = add_logistic_component( + child_name="applied", + child_continuous_parents=applied_continuous_parents, + child_categorical_parents=applied_categorical_parents, + leeway=11.57, + data_plate=data_plate, + observations=categorical["applied"], + categorical_levels=categorical_levels, + ) + + return applied diff --git a/build/cities/modeling/zoning_models/tracts_model.py b/build/cities/modeling/zoning_models/tracts_model.py new file mode 100644 index 00000000..f4f8dc45 --- /dev/null +++ b/build/cities/modeling/zoning_models/tracts_model.py @@ -0,0 +1,703 @@ +from typing import Any, Dict, Optional + +import pyro +import pyro.distributions as dist +import torch + +from cities.modeling.zoning_models.units_causal_model import ( + add_linear_component, + categorical_contribution, + continuous_contribution, + get_n, +) + + +def add_ratio_component( + child_name: "str", + child_continuous_parents, + child_categorical_parents, + leeway, + data_plate, + observations=None, + categorical_levels=None, +): + + continuous_contribution_to_child = continuous_contribution( + child_continuous_parents, child_name, leeway + ) + + categorical_contribution_to_child = categorical_contribution( + child_categorical_parents, + child_name, + leeway, + categorical_levels=categorical_levels, + ) + + sigma_child = pyro.sample(f"sigma_{child_name}", dist.Exponential(40.0)) + + with data_plate: + + mean_prediction_child = pyro.deterministic( # type: ignore + f"mean_outcome_prediction_{child_name}", + categorical_contribution_to_child + continuous_contribution_to_child, + event_dim=0, + ) + + child_probs = pyro.deterministic( + f"child_probs_{child_name}_{child_name}", + torch.sigmoid(mean_prediction_child), + event_dim=0, + ) + + child_observed = pyro.sample( + child_name, dist.Normal(child_probs, sigma_child), obs=observations + ) + + return child_observed + + +def add_poisson_component( + child_name: str, + child_continuous_parents: Dict[str, torch.Tensor], + child_categorical_parents: Dict[str, torch.Tensor], + leeway: float, + data_plate, + observations: Optional[torch.Tensor] = None, + categorical_levels: Optional[Dict[str, torch.Tensor]] = None, +) -> torch.Tensor: + + continuous_contribution_to_child = continuous_contribution( + child_continuous_parents, child_name, leeway + ) + + categorical_contribution_to_child = categorical_contribution( + child_categorical_parents, + child_name, + leeway, + categorical_levels=categorical_levels, + ) + + with data_plate: + + mean_prediction_child = pyro.deterministic( + f"mean_outcome_prediction_{child_name}", + torch.exp( + categorical_contribution_to_child + continuous_contribution_to_child + ), + event_dim=0, + ) + + child_observed = pyro.sample( + child_name, dist.Poisson(mean_prediction_child), obs=observations + ) + + return child_observed + + +class TractsModelNoRatios(pyro.nn.PyroModule): + def __init__( + self, + categorical: Dict[str, torch.Tensor], + continuous: Dict[str, torch.Tensor], + outcome: Optional[ + torch.Tensor + ] = None, # init args kept for uniformity, consider deleting + categorical_levels: Optional[Dict[str, Any]] = None, + leeway=0.9, + ): + super().__init__() + + self.leeway = leeway + + self.N_categorical, self.N_continuous, n = get_n(categorical, continuous) + + # you might need and pass further the original + # categorical levels of the training data + if self.N_categorical > 0 and categorical_levels is None: + self.categorical_levels = dict() + for name in categorical.keys(): + self.categorical_levels[name] = torch.unique(categorical[name]) + else: + self.categorical_levels = categorical_levels # type: ignore + + def forward( + self, + categorical: Dict[str, torch.Tensor], + continuous: Dict[str, torch.Tensor], + outcome: Optional[torch.Tensor] = None, + categorical_levels: Optional[Dict[str, torch.Tensor]] = None, + leeway=0.9, + ): + if categorical_levels is None: + categorical_levels = self.categorical_levels + + _N_categorical, _N_continuous, n = get_n(categorical, continuous) + + data_plate = pyro.plate("data", size=n, dim=-1) + + # ################# + # # register + # ################# + with data_plate: + + year = pyro.sample( + "year", + dist.Categorical(torch.ones(len(categorical_levels["year"]))), + obs=categorical["year"], + ) + + distance = pyro.sample( + "distance", dist.Normal(0, 1), obs=continuous["median_distance"] + ) + + # past_reform = pyro.sample( + # "past_reform", + # dist.Categorical(torch.ones(len(categorical_levels["past_reform"]))), + # obs=categorical["past_reform"], + # ) + + # ___________________________ + # regression for white + # ___________________________ + + white_continuous_parents = { + "distance": distance, + } + + white_categorical_parents = { + "year": year, + } + + white = add_linear_component( + child_name="white", + child_continuous_parents=white_continuous_parents, + child_categorical_parents=white_categorical_parents, + leeway=0.9, + data_plate=data_plate, + observations=continuous["white"], + ) + + # ___________________________ + # regression for segregation + # ___________________________ + + segregation_continuous_parents = { + "distance": distance, + "white": white, + } + + segregation_categorical_parents = { + "year": year, + } + + segregation = add_linear_component( + child_name="segregation", + child_continuous_parents=segregation_continuous_parents, + child_categorical_parents=segregation_categorical_parents, + leeway=0.9, + data_plate=data_plate, + observations=continuous["segregation"], + ) + + # ___________________________ + # regression for income + # ___________________________ + + income_continuous_parents = { + "distance": distance, + "white": white, + "segregation": segregation, + } + + income_categorical_parents = { + "year": year, + } + + income = add_linear_component( + child_name="income", + child_continuous_parents=income_continuous_parents, + child_categorical_parents=income_categorical_parents, + leeway=0.9, + data_plate=data_plate, + observations=continuous["income"], + ) + + # _____________________________ + # regression for limit + # _____________________________ + + limit_continuous_parents = { + "distance": distance, + } + + limit_categorical_parents = { + "year": year, + } + + limit = add_linear_component( + child_name="limit", + child_continuous_parents=limit_continuous_parents, + child_categorical_parents=limit_categorical_parents, + leeway=0.9, + data_plate=data_plate, + observations=continuous["mean_limit"], + ) + + # _____________________________ + # regression for median value + # _____________________________ + + value_continuous_parents = { + "distance": distance, + "limit": limit, + "income": income, + "white": white, + "segregation": segregation, + } + + value_categorical_parents = { + "year": year, + } + + median_value = add_linear_component( + child_name="median_value", + child_continuous_parents=value_continuous_parents, + child_categorical_parents=value_categorical_parents, + leeway=0.9, + data_plate=data_plate, + observations=continuous["median_value"], + ) + + # ___________________________ + # regression for housing units + # ___________________________ + + housing_units_continuous_parents = { + "median_value": median_value, + "distance": distance, + "income": income, + "white": white, + "limit": limit, + "segregation": segregation, + } + + housing_units_categorical_parents = { + "year": year, + } + + housing_units = add_linear_component( + child_name="housing_units", + child_continuous_parents=housing_units_continuous_parents, + child_categorical_parents=housing_units_categorical_parents, + leeway=0.9, + data_plate=data_plate, + observations=continuous["housing_units"], + ) + + return housing_units + + +class TractsModel(pyro.nn.PyroModule): + def __init__( + self, + categorical: Dict[str, torch.Tensor], + continuous: Dict[str, torch.Tensor], + outcome: Optional[ + torch.Tensor + ] = None, # init args kept for uniformity, consider deleting + categorical_levels: Optional[Dict[str, Any]] = None, + leeway=0.9, + ): + super().__init__() + + self.leeway = leeway + + self.N_categorical, self.N_continuous, n = get_n(categorical, continuous) + + # you might need and pass further the original + # categorical levels of the training data + if self.N_categorical > 0 and categorical_levels is None: + self.categorical_levels = dict() + for name in categorical.keys(): + self.categorical_levels[name] = torch.unique(categorical[name]) + else: + self.categorical_levels = categorical_levels # type: ignore + + def forward( + self, + categorical: Dict[str, torch.Tensor], + continuous: Dict[str, torch.Tensor], + outcome: Optional[torch.Tensor] = None, + categorical_levels: Optional[Dict[str, torch.Tensor]] = None, + leeway=0.9, + ): + if categorical_levels is None: + categorical_levels = self.categorical_levels + + _N_categorical, _N_continuous, n = get_n(categorical, continuous) + + data_plate = pyro.plate("data", size=n, dim=-1) + + # ################# + # # register + # ################# + with data_plate: + + year = pyro.sample( + "year", + dist.Categorical(torch.ones(len(categorical_levels["year"]))), + obs=categorical["year"], + ) + + distance = pyro.sample( + "distance", dist.Normal(0, 1), obs=continuous["median_distance"] + ) + + # past_reform = pyro.sample( + # "past_reform", + # dist.Categorical(torch.ones(len(categorical_levels["past_reform"]))), + # obs=categorical["past_reform"], + # ) + + # ___________________________ + # regression for white + # ___________________________ + + white_continuous_parents = { + "distance": distance, + } + + white_categorical_parents = { + "year": year, + } + + white = add_ratio_component( + child_name="white", + child_continuous_parents=white_continuous_parents, + child_categorical_parents=white_categorical_parents, + leeway=11.57, + data_plate=data_plate, + observations=continuous["white_original"], + ) + + # ___________________________ + # regression for segregation + # ___________________________ + + segregation_continuous_parents = { + "distance": distance, + "white": white, + } + + segregation_categorical_parents = { + "year": year, + } + + segregation = add_ratio_component( + child_name="segregation", + child_continuous_parents=segregation_continuous_parents, + child_categorical_parents=segregation_categorical_parents, + leeway=11.57, + data_plate=data_plate, + observations=continuous["segregation_original"], + ) + + # ___________________________ + # regression for income + # ___________________________ + + income_continuous_parents = { + "distance": distance, + "white": white, + "segregation": segregation, + } + + income_categorical_parents = { + "year": year, + } + + income = add_linear_component( + child_name="income", + child_continuous_parents=income_continuous_parents, + child_categorical_parents=income_categorical_parents, + leeway=0.9, + data_plate=data_plate, + observations=continuous["income"], + ) + + # _____________________________ + # regression for limit + # _____________________________ + + limit_continuous_parents = { + "distance": distance, + } + + limit_categorical_parents = { + "year": year, + } + + limit = add_ratio_component( + child_name="limit", + child_continuous_parents=limit_continuous_parents, + child_categorical_parents=limit_categorical_parents, + leeway=11.57, + data_plate=data_plate, + observations=continuous["mean_limit_original"], + ) + + # _____________________________ + # regression for median value + # _____________________________ + + value_continuous_parents = { + "distance": distance, + "limit": limit, + "income": income, + "white": white, + "segregation": segregation, + } + + value_categorical_parents = { + "year": year, + } + + median_value = add_linear_component( + child_name="median_value", + child_continuous_parents=value_continuous_parents, + child_categorical_parents=value_categorical_parents, + leeway=0.9, + data_plate=data_plate, + observations=continuous["median_value"], + ) + + # ___________________________ + # regression for housing units + # ___________________________ + + housing_units_continuous_parents = { + "median_value": median_value, + "distance": distance, + "income": income, + "white": white, + "limit": limit, + "segregation": segregation, + } + + housing_units_categorical_parents = { + "year": year, + } + + housing_units = add_linear_component( + child_name="housing_units", + child_continuous_parents=housing_units_continuous_parents, + child_categorical_parents=housing_units_categorical_parents, + leeway=0.9, + data_plate=data_plate, + observations=continuous["housing_units"], + ) + + return housing_units + + +class TractsModelPoisson(pyro.nn.PyroModule): + def __init__( + self, + categorical: Dict[str, torch.Tensor], + continuous: Dict[str, torch.Tensor], + outcome: Optional[ + torch.Tensor + ] = None, # init args kept for uniformity, consider deleting + categorical_levels: Optional[Dict[str, Any]] = None, + leeway=0.9, + ): + super().__init__() + + self.leeway = leeway + + self.N_categorical, self.N_continuous, n = get_n(categorical, continuous) + + # you might need and pass further the original + # categorical levels of the training data + if self.N_categorical > 0 and categorical_levels is None: + self.categorical_levels = dict() + for name in categorical.keys(): + self.categorical_levels[name] = torch.unique(categorical[name]) + else: + self.categorical_levels = categorical_levels # type: ignore + + def forward( + self, + categorical: Dict[str, torch.Tensor], + continuous: Dict[str, torch.Tensor], + outcome: Optional[torch.Tensor] = None, + categorical_levels: Optional[Dict[str, torch.Tensor]] = None, + leeway=0.9, + ): + if categorical_levels is None: + categorical_levels = self.categorical_levels + + _N_categorical, _N_continuous, n = get_n(categorical, continuous) + + data_plate = pyro.plate("data", size=n, dim=-1) + + # ################# + # # register + # ################# + with data_plate: + + year = pyro.sample( + "year", + dist.Categorical(torch.ones(len(categorical_levels["year"]))), + obs=categorical["year"], + ) + + distance = pyro.sample( + "distance", dist.Normal(0, 1), obs=continuous["median_distance"] + ) + + # past_reform = pyro.sample( + # "past_reform", + # dist.Categorical(torch.ones(len(categorical_levels["past_reform"]))), + # obs=categorical["past_reform"], + # ) + + # ___________________________ + # regression for white + # ___________________________ + + white_continuous_parents = { + "distance": distance, + } + + white_categorical_parents = { + "year": year, + } + + white = add_ratio_component( + child_name="white", + child_continuous_parents=white_continuous_parents, + child_categorical_parents=white_categorical_parents, + leeway=11.57, + data_plate=data_plate, + observations=continuous["white_original"], + ) + + # ___________________________ + # regression for segregation + # ___________________________ + + segregation_continuous_parents = { + "distance": distance, + "white": white, + } + + segregation_categorical_parents = { + "year": year, + } + + segregation = add_ratio_component( + child_name="segregation", + child_continuous_parents=segregation_continuous_parents, + child_categorical_parents=segregation_categorical_parents, + leeway=11.57, + data_plate=data_plate, + observations=continuous["segregation_original"], + ) + + # ___________________________ + # regression for income + # ___________________________ + + income_continuous_parents = { + "distance": distance, + "white": white, + "segregation": segregation, + } + + income_categorical_parents = { + "year": year, + } + + income = add_linear_component( + child_name="income", + child_continuous_parents=income_continuous_parents, + child_categorical_parents=income_categorical_parents, + leeway=0.9, + data_plate=data_plate, + observations=continuous["income"], + ) + + # #_____________________________ + # # regression for limit + # #_____________________________ + + limit_continuous_parents = { + "distance": distance, + } + + limit_categorical_parents = { + "year": year, + } + + limit = add_ratio_component( + child_name="limit", + child_continuous_parents=limit_continuous_parents, + child_categorical_parents=limit_categorical_parents, + leeway=11.57, + data_plate=data_plate, + observations=continuous["mean_limit_original"], + ) + + # # _____________________________ + # # regression for median value + # # _____________________________ + + value_continuous_parents = { + "distance": distance, + "limit": limit, + "income": income, + "white": white, + "segregation": segregation, + } + + value_categorical_parents = { + "year": year, + } + + median_value = add_linear_component( + child_name="median_value", + child_continuous_parents=value_continuous_parents, + child_categorical_parents=value_categorical_parents, + leeway=0.9, + data_plate=data_plate, + observations=continuous["median_value"], + ) + + # # ___________________________ + # # regression for housing units + # # ___________________________ + + housing_units_continuous_parents = { + "median_value": median_value, + "distance": distance, + "income": income, + "white": white, + "limit": limit, + "segregation": segregation, + } + + housing_units_categorical_parents = { + "year": year, + } + + housing_units = add_poisson_component( + child_name="housing_units_original", + child_continuous_parents=housing_units_continuous_parents, + child_categorical_parents=housing_units_categorical_parents, + leeway=11.57, + data_plate=data_plate, + observations=continuous["housing_units_original"], + ) + + return housing_units diff --git a/build/cities/modeling/zoning_models/units_causal_model.py b/build/cities/modeling/zoning_models/units_causal_model.py new file mode 100644 index 00000000..27035096 --- /dev/null +++ b/build/cities/modeling/zoning_models/units_causal_model.py @@ -0,0 +1,289 @@ +from typing import Any, Dict, List, Optional + +import pyro +import pyro.distributions as dist +import torch + + +def get_n(categorical: Dict[str, torch.Tensor], continuous: Dict[str, torch.Tensor]): + N_categorical = len(categorical.keys()) + N_continuous = len(continuous.keys()) + + if N_categorical > 0: + n = len(next(iter(categorical.values()))) + elif N_continuous > 0: + n = len(next(iter(continuous.values()))) + + return N_categorical, N_continuous, n + + +def categorical_contribution(categorical, child_name, leeway, categorical_levels=None): + + categorical_names = list(categorical.keys()) + + if categorical_levels is None: + categorical_levels = { + name: torch.unique(categorical[name]) for name in categorical_names + } + + weights_categorical_outcome = {} + objects_cat_weighted = {} + + for name in categorical_names: + weights_categorical_outcome[name] = pyro.sample( + f"weights_categorical_{name}_{child_name}", + dist.Normal(0.0, leeway).expand(categorical_levels[name].shape).to_event(1), + ) + + objects_cat_weighted[name] = weights_categorical_outcome[name][ + ..., categorical[name] + ] + + values = list(objects_cat_weighted.values()) + for i in range(1, len(values)): + values[i] = values[i].view(values[0].shape) + + categorical_contribution_outcome = torch.stack(values, dim=0).sum(dim=0) + + return categorical_contribution_outcome + + +def continuous_contribution(continuous, child_name, leeway): + + contributions = torch.zeros(1) + + for key, value in continuous.items(): + bias_continuous = pyro.sample( + f"bias_continuous_{key}_{child_name}", + dist.Normal(0.0, leeway), + ) + + weight_continuous = pyro.sample( + f"weight_continuous_{key}_{child_name}", + dist.Normal(0.0, leeway), + ) + + contribution = bias_continuous + weight_continuous * value + contributions = contribution + contributions + + return contributions + + +def add_linear_component( + child_name: "str", + child_continuous_parents, + child_categorical_parents, + leeway, + data_plate, + observations=None, + categorical_levels=None, +): + + sigma_child = pyro.sample( + f"sigma_{child_name}", dist.Exponential(1.0) + ) # type: ignore + + continuous_contribution_to_child = continuous_contribution( + child_continuous_parents, child_name, leeway + ) + + categorical_contribution_to_child = categorical_contribution( + child_categorical_parents, + child_name, + leeway, + categorical_levels=categorical_levels, + ) + + with data_plate: + + mean_prediction_child = pyro.deterministic( # type: ignore + f"mean_outcome_prediction_{child_name}", + categorical_contribution_to_child + continuous_contribution_to_child, + event_dim=0, + ) + + child_observed = pyro.sample( # type: ignore + f"{child_name}", + dist.Normal(mean_prediction_child, sigma_child), + obs=observations, + ) + + # TODO consider a gamma-like distro here + + return child_observed + + +def categorical_interaction_variable(interaction_list: List[torch.Tensor]): + + assert len(interaction_list) > 1 + + for tensor in interaction_list: + assert tensor.shape == interaction_list[0].shape + + stacked_tensor = torch.stack(interaction_list, dim=-1) + + unique_pairs, inverse_indices = torch.unique( + stacked_tensor, return_inverse=True, dim=0 + ) + + unique_combined_tensor = inverse_indices.reshape(interaction_list[0].shape) + + indexing_dictionary = { + tuple(pair.tolist()): i for i, pair in enumerate(unique_pairs) + } + + return unique_combined_tensor, indexing_dictionary + + +class UnitsCausalModel(pyro.nn.PyroModule): + def __init__( + self, + categorical: Dict[str, torch.Tensor], + continuous: Dict[str, torch.Tensor], + outcome: Optional[ + torch.Tensor + ] = None, # init args kept for uniformity, consider deleting + categorical_levels: Optional[Dict[str, Any]] = None, + leeway=0.9, + ): + super().__init__() + + self.leeway = leeway + + self.N_categorical, self.N_continuous, n = get_n(categorical, continuous) + + # you might need and pass further the original + # categorical levels of the training data + if self.N_categorical > 0 and categorical_levels is None: + self.categorical_levels = dict() + for name in categorical.keys(): + self.categorical_levels[name] = torch.unique(categorical[name]) + else: + self.categorical_levels = categorical_levels # type: ignore + + def forward( + self, + categorical: Dict[str, torch.Tensor], + continuous: Dict[str, torch.Tensor], + outcome: Optional[torch.Tensor] = None, + categorical_levels: Optional[Dict[str, torch.Tensor]] = None, + leeway=0.9, + ): + if categorical_levels is None: + categorical_levels = self.categorical_levels + + _N_categorical, _N_continuous, n = get_n(categorical, continuous) + + data_plate = pyro.plate("data", size=n, dim=-1) + + ################# + # register + ################# + with data_plate: + + year = pyro.sample( + "year", + dist.Categorical(torch.ones(len(categorical_levels["year"]))), + obs=categorical["year"], + ) + + month = pyro.sample( + "month", + dist.Categorical(torch.ones(len(categorical_levels["month"]))), + obs=categorical["month"], + ) + + zone_id = pyro.sample( + "zone_id", + dist.Categorical(torch.ones(len(categorical_levels["zone_id"]))), + obs=categorical["zone_id"], + ) + + neighborhood_id = pyro.sample( + "neighborhood_id", + dist.Categorical( + torch.ones(len(categorical_levels["neighborhood_id"])) + ), + obs=categorical["neighborhood_id"], + ) + + ward_id = pyro.sample( + "ward_id", + dist.Categorical(torch.ones(len(categorical_levels["ward_id"]))), + obs=categorical["ward_id"], + ) + + past_reform = pyro.sample( + "past_reform", dist.Normal(0, 1), obs=categorical["past_reform"] + ) + + past_reform_by_zone = pyro.deterministic( + "past_reform_by_zone", + categorical_interaction_variable([past_reform, zone_id])[0], + ) + categorical_levels["past_reform_by_zone"] = torch.unique( + past_reform_by_zone + ) + # ___________________________ + # regression for parcel area + # ___________________________ + parcel_area_continuous_parents = {} # type: ignore + parcel_are_categorical_parents = { + "zone_id": zone_id, + "neighborhood_id": neighborhood_id, + } + parcel_area = add_linear_component( + child_name="parcel_area", + child_continuous_parents=parcel_area_continuous_parents, + child_categorical_parents=parcel_are_categorical_parents, + leeway=leeway, + data_plate=data_plate, + observations=continuous["parcel_area"], + categorical_levels=categorical_levels, + ) + + # ___________________________ + # regression for limit + # ___________________________ + + limit_con_categorical_parents = {"past_reform_by_zone": past_reform_by_zone} + + # TODO consider using a `pyro.deterministic` statement if safe to assume what the + # rules are and hard code them + limit_con = add_linear_component( + child_name="limit_con", + child_continuous_parents={}, + child_categorical_parents=limit_con_categorical_parents, + leeway=leeway, + data_plate=data_plate, + observations=continuous["limit_con"], + categorical_levels=categorical_levels, + ) + + # _____________________________ + # regression for housing units + # _____________________________ + + housing_units_continuous_parents = { + "limit_con": limit_con, + "parcel_area": parcel_area, + } + housing_units_categorical_parents = { + "year": year, + "month": month, + "zone_id": zone_id, + "neighborhood_id": neighborhood_id, + "ward_id": ward_id, + } + + housing_units = add_linear_component( + child_name="housing_units", + child_continuous_parents=housing_units_continuous_parents, + child_categorical_parents=housing_units_categorical_parents, + leeway=leeway, + data_plate=data_plate, + observations=outcome, + categorical_levels=categorical_levels, + ) + + return housing_units diff --git a/build/cities/modeling/zoning_models/zoning_tracts_continuous_interactions_model.py b/build/cities/modeling/zoning_models/zoning_tracts_continuous_interactions_model.py new file mode 100644 index 00000000..69bd017a --- /dev/null +++ b/build/cities/modeling/zoning_models/zoning_tracts_continuous_interactions_model.py @@ -0,0 +1,301 @@ +import warnings +from typing import Any, Dict, Optional + +import pyro +import pyro.distributions as dist +import torch + +from cities.modeling.model_components import ( + add_linear_component, + add_linear_component_continuous_interactions, + add_ratio_component_continuous_interactions, + add_ratio_component, + check_categorical_is_subset_of_levels, + get_categorical_levels, + get_n, +) + + +class TractsModelContinuousInteractions(pyro.nn.PyroModule): + def __init__( + self, + categorical: Dict[str, torch.Tensor], + continuous: Dict[str, torch.Tensor], + outcome: Optional[ + torch.Tensor + ] = None, # init args kept for uniformity, consider deleting + categorical_levels: Optional[Dict[str, Any]] = None, + leeway=0.9, + housing_units_continuous_interaction_pairs=[], + limit_continuous_interaction_pairs=[], + ): + """ + + :param categorical: dict of categorical data + :param continuous: dict of continuous data + :param outcome: outcome data (unused, todo remove) + :param categorical_levels: dict of unique categorical values. If this is not passed, it will be computed from + the provided categorical data. Importantly, if categorical is a subset of the full dataset, this automated + computation may omit categorical levels that are present in the full dataset but not in the subset. + """ + super().__init__() + + self.leeway = leeway + self.housing_units_continuous_interaction_pairs = ( + housing_units_continuous_interaction_pairs + ) + self.limit_continuous_interaction_pairs = limit_continuous_interaction_pairs + + self.N_categorical, self.N_continuous, n = get_n(categorical, continuous) + + if self.N_categorical > 0 and categorical_levels is None: + self.categorical_levels = get_categorical_levels(categorical) + else: + self.categorical_levels = categorical_levels + + def forward( + self, + categorical: Dict[str, torch.Tensor], + continuous: Dict[str, torch.Tensor], + outcome: Optional[torch.Tensor] = None, + leeway=0.9, + categorical_levels=None, + n=None, + ): + if categorical_levels is not None: + warnings.warn( + "Passed categorical_levels will no longer override the levels passed to or computed during" + " model initialization. The argument will be ignored." + ) + + categorical_levels = self.categorical_levels + assert check_categorical_is_subset_of_levels(categorical, categorical_levels) + + if n is None: + _, _, n = get_n(categorical, continuous) + + data_plate = pyro.plate("data", size=n, dim=-1) + + # _________ + # register + # _________ + + with data_plate: + + year = pyro.sample( + "year", + dist.Categorical(torch.ones(len(categorical_levels["year"]))), + obs=categorical["year"], + ) + + distance = pyro.sample( + "distance", dist.Normal(0, 1), obs=continuous["median_distance"] + ) + + downtown_overlap = pyro.sample( + "downtown_overlap", + dist.Normal(0, 1), + obs=continuous["downtown_overlap"], + ) + + university_overlap = pyro.sample( + "university_overlap", + dist.Normal(0, 1), + obs=continuous["university_overlap"], + ) + + # ______________________ + # regression for sqm + # ______________________ + + sqm_continuous_parents = { + "distance": distance, + } + + sqm_categorical_parents = { + "year": year, + } + + sqm = add_linear_component( + child_name="sqm", + child_continuous_parents=sqm_continuous_parents, + child_categorical_parents=sqm_categorical_parents, + leeway=0.5, + data_plate=data_plate, + observations=continuous["parcel_sqm"], + categorical_levels=self.categorical_levels, + ) + + # _______________________ + # regression for limit + # _______________________ + + limit_continuous_parents = { + "distance": distance, + "downtown_overlap": downtown_overlap, + "university_overlap": university_overlap, + } + + limit_categorical_parents = { + "year": year, + } + + + + limit = add_ratio_component( + child_name="limit", + child_continuous_parents=limit_continuous_parents, + child_categorical_parents=limit_categorical_parents, + leeway=8, # , + data_plate=data_plate, + observations=continuous["mean_limit_original"], + categorical_levels=self.categorical_levels, + ) + + + # limit = add_ratio_component( + # child_name="limit", + # child_continuous_parents=limit_continuous_parents, + # child_categorical_parents=limit_categorical_parents, + # leeway=8, # , + # data_plate=data_plate, + # observations=continuous["mean_limit_original"], + # categorical_levels=self.categorical_levels, + # ) + + # _____________________ + # regression for white + # _____________________ + + white_continuous_parents = { + "distance": distance, + "sqm": sqm, + "limit": limit, + } + + white_categorical_parents = { + "year": year, + } + + white = add_ratio_component( + child_name="white", + child_continuous_parents=white_continuous_parents, + child_categorical_parents=white_categorical_parents, + leeway=8, # 11.57, + data_plate=data_plate, + observations=continuous["white_original"], + categorical_levels=self.categorical_levels, + ) + + # ___________________________ + # regression for segregation + # ___________________________ + + segregation_continuous_parents = { + "distance": distance, + "white": white, + "sqm": sqm, + "limit": limit, + } + + segregation_categorical_parents = { + "year": year, + } + + segregation = add_ratio_component( + child_name="segregation", + child_continuous_parents=segregation_continuous_parents, + child_categorical_parents=segregation_categorical_parents, + leeway=8, # 11.57, + data_plate=data_plate, + observations=continuous["segregation_original"], + categorical_levels=self.categorical_levels, + ) + + # ______________________ + # regression for income + # ______________________ + + income_continuous_parents = { + "distance": distance, + "white": white, + "segregation": segregation, + "sqm": sqm, + "limit": limit, + } + + income_categorical_parents = { + "year": year, + } + + income = add_linear_component( + child_name="income", + child_continuous_parents=income_continuous_parents, + child_categorical_parents=income_categorical_parents, + leeway=0.5, + data_plate=data_plate, + observations=continuous["income"], + categorical_levels=self.categorical_levels, + ) + + # _____________________________ + # regression for median value + # _____________________________ + + value_continuous_parents = { + "distance": distance, + "income": income, + "white": white, + "segregation": segregation, + "sqm": sqm, + "limit": limit, + } + + value_categorical_parents = { + "year": year, + } + + median_value = add_linear_component( + child_name="median_value", + child_continuous_parents=value_continuous_parents, + child_categorical_parents=value_categorical_parents, + leeway=0.5, + data_plate=data_plate, + observations=continuous["median_value"], + categorical_levels=self.categorical_levels, + ) + + # ______________________________ + # regression for housing units + # ______________________________ + + housing_units_continuous_parents = { + "median_value": median_value, + "distance": distance, + "income": income, + "white": white, + "limit": limit, + "segregation": segregation, + "sqm": sqm, + "downtown_overlap": downtown_overlap, + "university_overlap": university_overlap, + } + + housing_units_categorical_parents = { + "year": year, + # "university_index": university_index, + # "downtown_index": downtown_index, + } + + housing_units = add_linear_component_continuous_interactions( + child_name="housing_units", + child_continuous_parents=housing_units_continuous_parents, + child_categorical_parents=housing_units_categorical_parents, + continous_interaction_pairs=self.housing_units_continuous_interaction_pairs, + leeway=0.5, + data_plate=data_plate, + observations=continuous["housing_units"], + categorical_levels=self.categorical_levels, + ) + + return housing_units diff --git a/build/cities/modeling/zoning_models/zoning_tracts_model.py b/build/cities/modeling/zoning_models/zoning_tracts_model.py new file mode 100644 index 00000000..0357bdc4 --- /dev/null +++ b/build/cities/modeling/zoning_models/zoning_tracts_model.py @@ -0,0 +1,234 @@ +import warnings +from typing import Any, Dict, Optional + +import pyro +import pyro.distributions as dist +import torch + +from cities.modeling.model_components import ( + add_linear_component, + add_ratio_component, + check_categorical_is_subset_of_levels, + get_categorical_levels, + get_n, +) + + +class TractsModel(pyro.nn.PyroModule): + + def __init__( + self, + categorical: Dict[str, torch.Tensor], + continuous: Dict[str, torch.Tensor], + outcome: Optional[ + torch.Tensor + ] = None, # init args kept for uniformity, consider deleting + categorical_levels: Optional[Dict[str, Any]] = None, + leeway=0.9, + ): + """ + + :param categorical: dict of categorical data + :param continuous: dict of continuous data + :param outcome: outcome data (unused, todo remove) + :param categorical_levels: dict of unique categorical values. If this is not passed, it will be computed from + the provided categorical data. Importantly, if categorical is a subset of the full dataset, this automated + computation may omit categorical levels that are present in the full dataset but not in the subset. + """ + super().__init__() + + self.leeway = leeway + + self.N_categorical, self.N_continuous, n = get_n(categorical, continuous) + + # you might need and pass further the original + # categorical levels of the training data + if self.N_categorical > 0 and categorical_levels is None: + self.categorical_levels = get_categorical_levels(categorical) + else: + self.categorical_levels = categorical_levels # type: ignore + + def forward( + self, + categorical: Dict[str, torch.Tensor], + continuous: Dict[str, torch.Tensor], + outcome: Optional[torch.Tensor] = None, + leeway=0.9, + categorical_levels=None, + n=None, + ): + if categorical_levels is not None: + warnings.warn( + "Passed categorical_levels will no longer override the levels passed to or computed during" + " model initialization. The argument will be ignored." + ) + + categorical_levels = self.categorical_levels + assert check_categorical_is_subset_of_levels(categorical, categorical_levels) + + if n is None: + _, _, n = get_n(categorical, continuous) + + data_plate = pyro.plate("data", size=n, dim=-1) + + # _________ + # register + # _________ + + with data_plate: + + year = pyro.sample( + "year", + dist.Categorical(torch.ones(len(categorical_levels["year"]))), + obs=categorical["year"], + ) + + distance = pyro.sample( + "distance", dist.Normal(0, 1), obs=continuous["median_distance"] + ) + + # _____________________ + # regression for white + # _____________________ + + white_continuous_parents = { + "distance": distance, + } + + white_categorical_parents = { + "year": year, + } + + white = add_ratio_component( + child_name="white", + child_continuous_parents=white_continuous_parents, + child_categorical_parents=white_categorical_parents, + leeway=11.57, + data_plate=data_plate, + observations=continuous["white_original"], + categorical_levels=self.categorical_levels, + ) + + # ___________________________ + # regression for segregation + # ___________________________ + + segregation_continuous_parents = { + "distance": distance, + "white": white, + } + + segregation_categorical_parents = { + "year": year, + } + + segregation = add_ratio_component( + child_name="segregation", + child_continuous_parents=segregation_continuous_parents, + child_categorical_parents=segregation_categorical_parents, + leeway=11.57, + data_plate=data_plate, + observations=continuous["segregation_original"], + categorical_levels=self.categorical_levels, + ) + + # ______________________ + # regression for income + # ______________________ + + income_continuous_parents = { + "distance": distance, + "white": white, + "segregation": segregation, + } + + income_categorical_parents = { + "year": year, + } + + income = add_linear_component( + child_name="income", + child_continuous_parents=income_continuous_parents, + child_categorical_parents=income_categorical_parents, + leeway=0.9, + data_plate=data_plate, + observations=continuous["income"], + categorical_levels=self.categorical_levels, + ) + + # _______________________ + # regression for limit + # _______________________ + + limit_continuous_parents = { + "distance": distance, + } + + limit_categorical_parents = { + "year": year, + } + + limit = add_ratio_component( + child_name="limit", + child_continuous_parents=limit_continuous_parents, + child_categorical_parents=limit_categorical_parents, + leeway=11.57, + data_plate=data_plate, + observations=continuous["mean_limit_original"], + categorical_levels=self.categorical_levels, + ) + + # _____________________________ + # regression for median value + # _____________________________ + + value_continuous_parents = { + "distance": distance, + "limit": limit, + "income": income, + "white": white, + "segregation": segregation, + } + + value_categorical_parents = { + "year": year, + } + + median_value = add_linear_component( + child_name="median_value", + child_continuous_parents=value_continuous_parents, + child_categorical_parents=value_categorical_parents, + leeway=0.9, + data_plate=data_plate, + observations=continuous["median_value"], + categorical_levels=self.categorical_levels, + ) + + # ______________________________ + # regression for housing units + # ______________________________ + + housing_units_continuous_parents = { + "median_value": median_value, + "distance": distance, + "income": income, + "white": white, + "limit": limit, + "segregation": segregation, + } + + housing_units_categorical_parents = { + "year": year, + } + + housing_units = add_linear_component( + child_name="housing_units", + child_continuous_parents=housing_units_continuous_parents, + child_categorical_parents=housing_units_categorical_parents, + leeway=0.9, + data_plate=data_plate, + observations=continuous["housing_units"], + categorical_levels=self.categorical_levels, + ) + + return housing_units diff --git a/build/cities/modeling/zoning_models/zoning_tracts_sqm_model.py b/build/cities/modeling/zoning_models/zoning_tracts_sqm_model.py new file mode 100644 index 00000000..5634a52f --- /dev/null +++ b/build/cities/modeling/zoning_models/zoning_tracts_sqm_model.py @@ -0,0 +1,261 @@ +import warnings +from typing import Any, Dict, Optional + +import pyro +import pyro.distributions as dist +import torch + +from cities.modeling.model_components import ( + add_linear_component, + add_ratio_component, + check_categorical_is_subset_of_levels, + get_categorical_levels, + get_n, +) + + +class TractsModelSqm(pyro.nn.PyroModule): + def __init__( + self, + categorical: Dict[str, torch.Tensor], + continuous: Dict[str, torch.Tensor], + outcome: Optional[ + torch.Tensor + ] = None, # init args kept for uniformity, consider deleting + categorical_levels: Optional[Dict[str, Any]] = None, + leeway=0.9, + ): + """ + + :param categorical: dict of categorical data + :param continuous: dict of continuous data + :param outcome: outcome data (unused, todo remove) + :param categorical_levels: dict of unique categorical values. If this is not passed, it will be computed from + the provided categorical data. Importantly, if categorical is a subset of the full dataset, this automated + computation may omit categorical levels that are present in the full dataset but not in the subset. + """ + super().__init__() + + self.leeway = leeway + + self.N_categorical, self.N_continuous, n = get_n(categorical, continuous) + + if self.N_categorical > 0 and categorical_levels is None: + self.categorical_levels = get_categorical_levels(categorical) + else: + self.categorical_levels = categorical_levels + + def forward( + self, + categorical: Dict[str, torch.Tensor], + continuous: Dict[str, torch.Tensor], + outcome: Optional[torch.Tensor] = None, + leeway=0.9, + categorical_levels=None, + n=None, + ): + if categorical_levels is not None: + warnings.warn( + "Passed categorical_levels will no longer override the levels passed to or computed during" + " model initialization. The argument will be ignored." + ) + + categorical_levels = self.categorical_levels + assert check_categorical_is_subset_of_levels(categorical, categorical_levels) + + if n is None: + _, _, n = get_n(categorical, continuous) + + data_plate = pyro.plate("data", size=n, dim=-1) + + # _________ + # register + # _________ + + with data_plate: + + year = pyro.sample( + "year", + dist.Categorical(torch.ones(len(categorical_levels["year"]))), + obs=categorical["year"], + ) + + distance = pyro.sample( + "distance", dist.Normal(0, 1), obs=continuous["median_distance"] + ) + + # ______________________ + # regression for sqm + # ______________________ + + sqm_continuous_parents = { + "distance": distance, + } + + sqm_categorical_parents = { + "year": year, + } + + sqm = add_linear_component( + child_name="sqm", + child_continuous_parents=sqm_continuous_parents, + child_categorical_parents=sqm_categorical_parents, + leeway=0.5, + data_plate=data_plate, + observations=continuous["parcel_sqm"], + categorical_levels=self.categorical_levels, + ) + + # _______________________ + # regression for limit + # _______________________ + + limit_continuous_parents = { + "distance": distance, + } + + limit_categorical_parents = { + "year": year, + } + + limit = add_ratio_component( + child_name="limit", + child_continuous_parents=limit_continuous_parents, + child_categorical_parents=limit_categorical_parents, + leeway=8, # , + data_plate=data_plate, + observations=continuous["mean_limit_original"], + categorical_levels=self.categorical_levels, + ) + + # _____________________ + # regression for white + # _____________________ + + white_continuous_parents = { + "distance": distance, + "sqm": sqm, + "limit": limit, + } + + white_categorical_parents = { + "year": year, + } + + white = add_ratio_component( + child_name="white", + child_continuous_parents=white_continuous_parents, + child_categorical_parents=white_categorical_parents, + leeway=8, # 11.57, + data_plate=data_plate, + observations=continuous["white_original"], + categorical_levels=self.categorical_levels, + ) + + # ___________________________ + # regression for segregation + # ___________________________ + + segregation_continuous_parents = { + "distance": distance, + "white": white, + "sqm": sqm, + "limit": limit, + } + + segregation_categorical_parents = { + "year": year, + } + + segregation = add_ratio_component( + child_name="segregation", + child_continuous_parents=segregation_continuous_parents, + child_categorical_parents=segregation_categorical_parents, + leeway=8, # 11.57, + data_plate=data_plate, + observations=continuous["segregation_original"], + categorical_levels=self.categorical_levels, + ) + + # ______________________ + # regression for income + # ______________________ + + income_continuous_parents = { + "distance": distance, + "white": white, + "segregation": segregation, + "sqm": sqm, + "limit": limit, + } + + income_categorical_parents = { + "year": year, + } + + income = add_linear_component( + child_name="income", + child_continuous_parents=income_continuous_parents, + child_categorical_parents=income_categorical_parents, + leeway=0.5, + data_plate=data_plate, + observations=continuous["income"], + categorical_levels=self.categorical_levels, + ) + + # _____________________________ + # regression for median value + # _____________________________ + + value_continuous_parents = { + "distance": distance, + "income": income, + "white": white, + "segregation": segregation, + "sqm": sqm, + "limit": limit, + } + + value_categorical_parents = { + "year": year, + } + + median_value = add_linear_component( + child_name="median_value", + child_continuous_parents=value_continuous_parents, + child_categorical_parents=value_categorical_parents, + leeway=0.5, + data_plate=data_plate, + observations=continuous["median_value"], + categorical_levels=self.categorical_levels, + ) + + # ______________________________ + # regression for housing units + # ______________________________ + + housing_units_continuous_parents = { + "median_value": median_value, + "distance": distance, + "income": income, + "white": white, + "limit": limit, + "segregation": segregation, + "sqm": sqm, + } + + housing_units_categorical_parents = { + "year": year, + } + + housing_units = add_linear_component( + child_name="housing_units", + child_continuous_parents=housing_units_continuous_parents, + child_categorical_parents=housing_units_categorical_parents, + leeway=0.5, + data_plate=data_plate, + observations=continuous["housing_units"], + categorical_levels=self.categorical_levels, + ) + + return housing_units diff --git a/build/cities/queries/__init__.py b/build/cities/queries/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/build/cities/queries/causal_insight.py b/build/cities/queries/causal_insight.py new file mode 100644 index 00000000..7a7a7e98 --- /dev/null +++ b/build/cities/queries/causal_insight.py @@ -0,0 +1,585 @@ +import os + +import dill +import matplotlib.pyplot as plt +import numpy as np +import pandas as pd +import plotly.graph_objects as go +import pyro +import torch +from sklearn.preprocessing import StandardScaler + +from cities.modeling.model_interactions import model_cities_interaction +from cities.modeling.modeling_utils import prep_wide_data_for_inference +from cities.utils.cleaning_utils import ( + revert_prediction_df, + revert_standardize_and_scale_scaler, + sigmoid, +) +from cities.utils.data_grabber import DataGrabber, find_repo_root +from cities.utils.percentiles import transformed_intervention_from_percentile + + +class CausalInsight: + def __init__( + self, + outcome_dataset, + intervention_dataset, + num_samples=1000, + sites=None, + smoke_test=None, + ): + self.outcome_dataset = outcome_dataset + self.intervention_dataset = intervention_dataset + self.root = find_repo_root() + self.num_samples = num_samples + self.data = None + self.smoke_test = smoke_test + + self.device = torch.device("cuda" if torch.cuda.is_available() else "cpu") + + self.tau_samples_path = os.path.join( + self.root, + "data/tau_samples", + f"{self.intervention_dataset}_{self.outcome_dataset}_{self.num_samples}_tau.pkl", + ) + + # these are loaded/computed as need be + + self.guide = None + self.data = None + self.fips_id = None + self.name = None + self.model = None + self.model_args = None + self.predictive = None + self.samples = None + self.tensed_samples = None + self.tensed_tau_samples = None + + self.intervened_value = None # possibly in the transformed scale + self.intervention_is_percentile = None # flag for the sort of input + self.intervened_percentile = None # possible passed at input + self.intervened_value_percentile = ( + None # calculated if input was on the transformed scale + ) + self.intervened_value_original = None # in the original scale + self.observed_intervention = None # in the transformed scale + self.observed_intervention_original = None # in the original scale + self.observed_intervention_percentile = None # calculated if input + # was on the transformed scale + self.observed_outcomes = None + self.intervention_diff = ( + None # difference between observed and counterfactual value of the + ) + # intervention variable + self.intervention_impact = None # dictionary with preds for each shift + self.predictions = None # df with preds, can be passed to plotting + self.prediction_original = None # df with preds on the original scale + # can be passed to plotting + self.fips_observed_data = None # to be used for plotting in + # contrast with the counterfactual prediction + self.year_id = None # year of intervention as index in the outcome years + self.prediction_years = None + + # these are used in posterior predictive checks + self.average_predictions = None + self.r_squared = None + + def load_guide(self, forward_shift): + pyro.clear_param_store() + guide_name = ( + f"{self.intervention_dataset}_{self.outcome_dataset}_{forward_shift}" + ) + guide_path = os.path.join( + self.root, "data/model_guides", f"{guide_name}_guide.pkl" + ) + + with open(guide_path, "rb") as file: + self.guide = dill.load(file) + param_path = os.path.join( + self.root, "data/model_guides", f"{guide_name}_params.pth" + ) + + pyro.get_param_store().load(param_path) + + self.forward_shift = forward_shift + + def generate_samples(self): + self.data = prep_wide_data_for_inference( + outcome_dataset=self.outcome_dataset, + intervention_dataset=self.intervention_dataset, + forward_shift=self.forward_shift, + ) + self.model = model_cities_interaction + + self.model_args = self.data["model_args"] + + self.predictive = pyro.infer.Predictive( + model=self.model, + guide=self.guide, + num_samples=self.num_samples, + parallel=True, + # return_sites=self.sites, + ) + self.samples = self.predictive(*self.model_args) + + # idexing and gathering with mwc in this context + # seems to fail, calculating the expected diff made by the intervention manually + # wrt to actual observed outcomes rather than predicting outcomes themselves + # effectively keeping the noise fixed and focusing on a counterfactual claim + + # TODO possible delete in the current strategy deemed uncontroversial + # else: + # if not isinstance(intervened_value, torch.Tensor): + # intervened_value = torch.tensor(intervened_value, device=self.device) + # intervened_expanded = intervened_value.expand_as(self.data['t']) + + # with MultiWorldCounterfactual(first_available_dim=-6) as mwc: + # with do(actions = dict(T = intervened_expanded)): + # self.predictive = pyro.infer.Predictive(model=self.model, guide=self.guide, + # num_samples=self.num_samples, parallel=True) + # self.samples = self.predictive(*self.model_args) + # self.mwc = mwc + + def generate_tensed_samples(self): + self.tensed_samples = {} + self.tensed_tau_samples = {} + + for shift in [1, 2, 3]: + self.load_guide(shift) + self.generate_samples() + self.tensed_samples[shift] = self.samples + self.tensed_tau_samples[shift] = ( + self.samples["weight_TY"].squeeze().detach().numpy() + ) + + if not self.smoke_test: + if not os.path.exists(self.tau_samples_path): + with open(self.tau_samples_path, "wb") as file: + dill.dump(self.tensed_tau_samples, file) + + def get_tau_samples(self): + if os.path.exists(self.tau_samples_path): + with open(self.tau_samples_path, "rb") as file: + self.tensed_tau_samples = dill.load(file) + else: + raise ValueError("No tau samples found. Run generate_tensed_samples first.") + + """Returns the intervened and observed value, in the original scale""" + + def slider_values_to_interventions(self, intervened_percent, year): + try: + original_column = dg.wide[self.intervention_dataset][ + str(year) + ].values.reshape(-1, 1) + except NameError: + dg = DataGrabber() + dg.get_features_wide([self.intervention_dataset]) + original_column = dg.wide[self.intervention_dataset][ + str(year) + ].values.reshape(-1, 1) + + max = original_column.max() + + intervened_original = intervened_percent * max / 100 + + scaler = StandardScaler() + scaler.fit(original_column) + + intervened_scaled = scaler.transform(intervened_original.reshape(-1, 1)) + intervened_transformed = sigmoid(intervened_scaled, scale=1 / 3) + + # TODO this output is a bit verbose + # consider deleting what ends up not needed in the frontend + percent_calcs = { + "max": max, + "intervened_percent": intervened_percent, + "intervened_original": intervened_original, + "intervened_scaled": intervened_scaled[0, 0], + "intervened_transformed": intervened_transformed[0, 0], + } + + return percent_calcs + + def get_intervened_and_observed_values_original_scale( + self, fips, intervened_value, year + ): + dg = DataGrabber() + dg.get_features_std_wide([self.intervention_dataset, self.outcome_dataset]) + dg.get_features_wide([self.intervention_dataset]) + + # intervened value, in the original scale + intervened_original_scale = revert_standardize_and_scale_scaler( + intervened_value, year, self.intervention_dataset + ) + + fips_id = ( + dg.std_wide[self.intervention_dataset] + .loc[dg.std_wide[self.intervention_dataset]["GeoFIPS"] == fips] + .index[0] + ) + + # observed value, in the original scale + observed_original_scale = dg.wide[self.intervention_dataset].iloc[fips_id][ + str(year) + ] + + return (intervened_original_scale[0], observed_original_scale) + + def get_fips_predictions( + self, fips, intervened_value, year=None, intervention_is_percentile=False + ): + self.fips = fips + + if self.data is None: + self.data = prep_wide_data_for_inference( + outcome_dataset=self.outcome_dataset, + intervention_dataset=self.intervention_dataset, + forward_shift=3, # shift doesn't matter here, as long as data exists + ) + + # start with the latest year possible by default + if year is None: + year = self.data["years_available"][-1] + assert year in self.data["years_available"] + + self.year = year + + if intervention_is_percentile: + self.intervened_percentile = intervened_value + intervened_value = transformed_intervention_from_percentile( + self.intervention_dataset, year, intervened_value + ) + + self.intervened_value = intervened_value + + # find years for prediction + outcome_years = self.data["outcome_years"] + year_id = [int(x) for x in outcome_years].index(year) + self.year_id = year_id + + self.prediction_years = outcome_years[(year_id) : (year_id + 4)] + + # find fips unit index + dg = DataGrabber() + dg.get_features_std_wide([self.intervention_dataset, self.outcome_dataset]) + dg.get_features_wide([self.intervention_dataset]) + interventions_this_year_original = dg.wide[self.intervention_dataset][str(year)] + + self.intervened_value_original = revert_standardize_and_scale_scaler( + self.intervened_value, self.year, self.intervention_dataset + ) + + self.intervened_value_percentile = round( + ( + np.mean( + interventions_this_year_original.values + <= self.intervened_value_original + ) + * 100 + ), + 3, + ) + + self.fips_id = ( + dg.std_wide[self.intervention_dataset] + .loc[dg.std_wide[self.intervention_dataset]["GeoFIPS"] == fips] + .index[0] + ) + + self.name = dg.std_wide[self.intervention_dataset]["GeoName"].iloc[self.fips_id] + + # get observed values at the prediction times + self.observed_intervention = dg.std_wide[self.intervention_dataset].iloc[ + self.fips_id + ][str(year)] + + self.observed_intervention_original = dg.wide[self.intervention_dataset].iloc[ + self.fips_id + ][str(year)] + + if intervention_is_percentile: + self.observed_intervention_percentile = round( + ( + np.mean( + interventions_this_year_original.values + <= self.observed_intervention_original + ) + * 100 + ), + 1, + ) + + self.observed_outcomes = dg.std_wide[self.outcome_dataset].iloc[self.fips_id][ + outcome_years[year_id : (year_id + 4)] + ] + self.intervention_diff = self.intervened_value - self.observed_intervention + + self.intervention_impact = {} + self.intervention_impact_mean = [] + self.intervention_impact_low = [] + self.intervention_impact_high = [] + for shift in [1, 2, 3]: + self.intervention_impact[shift] = ( + self.tensed_tau_samples[shift] * self.intervention_diff + ) + self.intervention_impact_mean.append( + np.mean(self.intervention_impact[shift]) + ) + self.intervention_impact_low.append( + np.percentile(self.intervention_impact[shift], 2.5) + ) + self.intervention_impact_high.append( + np.percentile(self.intervention_impact[shift], 97.5) + ) + + predicted_mean = [self.observed_outcomes.iloc[0]] + ( + self.intervention_impact_mean + self.observed_outcomes.iloc[1:] + ).tolist() + predicted_low = [self.observed_outcomes.iloc[0]] + ( + self.intervention_impact_low + self.observed_outcomes.iloc[1:] + ).tolist() + predicted_high = [self.observed_outcomes.iloc[0]] + ( + self.intervention_impact_high + self.observed_outcomes.iloc[1:] + ).tolist() + + self.predictions = pd.DataFrame( + { + "year": self.prediction_years, + "observed": self.observed_outcomes, + "mean": predicted_mean, + "low": predicted_low, + "high": predicted_high, + } + ) + + self.predictions_original = revert_prediction_df( + self.predictions, self.outcome_dataset + ) + + # TODO for some reason indexing using gather doesn't pick the right indices + # look into this some time, do this by hand for now + # with self.mwc: + # self.tau_samples = self.samples['weight_TY'].squeeze().detach().numpy() + # self.tensed_observed_samples[shift] = self.tensed_intervened_samples[shift] = gather( + # self.samples['Y'], IndexSet(**{"T": {0}}), + # event_dim=0,).squeeze() + # self.tensed_intervened_samples[shift] = gather( + # self.samples['Y'], IndexSet(**{"T": {1}}), + # event_dim=0,).squeeze()#[:,self.fips_id] + + # self.tensed_outcome_difference[shift] = ( + # self.tensed_intervened_samples[shift] - self.tensed_observed_samples[shift] + # ) + return + + def plot_predictions( + self, range_multiplier=1.5, show_figure=True, scaling="transformed" + ): + assert scaling in ["transformed", "original"] + + dg = DataGrabber() + + if scaling == "transformed": + dg.get_features_std_long([self.outcome_dataset]) + plot_data = dg.std_long[self.outcome_dataset] + self.fips_observed_data = plot_data[ + plot_data["GeoFIPS"] == self.fips + ].copy() + + y_min = ( + min( + self.fips_observed_data["Value"].min(), + self.predictions["low"].min(), + ) + - 0.05 + ) + y_max = ( + max( + self.fips_observed_data["Value"].max(), + self.predictions["high"].max(), + ) + + 0.05 + ) + else: + dg.get_features_long([self.outcome_dataset]) + plot_data = dg.long[self.outcome_dataset] + + self.fips_observed_data = plot_data[ + plot_data["GeoFIPS"] == self.fips + ].copy() + + y_min = 0.8 * min( + self.fips_observed_data["Value"].min(), + self.predictions_original["low"].min(), + ) + y_max = 1.3 * max( + self.fips_observed_data["Value"].max(), + self.predictions_original["high"].max(), + ) + + fig = go.Figure() + + fig.add_trace( + go.Scatter( + x=self.fips_observed_data["Year"], + y=self.fips_observed_data["Value"], + mode="lines+markers", + name=self.fips_observed_data["GeoName"].iloc[0], + line=dict(color="darkred", width=3), + text=self.fips_observed_data["GeoName"].iloc[0], + textposition="top right", + showlegend=False, + ) + ) + + if scaling == "transformed": + fig.add_trace( + go.Scatter( + x=self.predictions["year"], + y=self.predictions["mean"], + mode="lines", + line=dict(color="blue", width=2), + name="mean prediction", + text=self.predictions["mean"], + ) + ) + + credible_interval_trace = go.Scatter( + x=pd.concat([self.predictions["year"], self.predictions["year"][::-1]]), + y=pd.concat([self.predictions["high"], self.predictions["low"][::-1]]), + fill="toself", + fillcolor="rgba(0,100,80,0.2)", + line=dict(color="rgba(255,255,255,0)"), + name="95% credible interval around mean", + ) + + else: + fig.add_trace( + go.Scatter( + x=self.predictions_original["year"], + y=self.predictions_original["mean"], + mode="lines", + line=dict(color="blue", width=2), + name="mean prediction", + text=self.predictions_original["mean"], + ) + ) + + credible_interval_trace = go.Scatter( + x=pd.concat( + [ + self.predictions_original["year"], + self.predictions_original["year"][::-1], + ] + ), + y=pd.concat( + [ + self.predictions_original["high"], + self.predictions_original["low"][::-1], + ] + ), + fill="toself", + fillcolor="rgba(255, 255, 255, 0.31)", + line=dict(color="rgba(255,255,255,0)"), + name="95% credible interval around mean", + ) + + fig.add_trace(credible_interval_trace) + + if hasattr(self, "intervened_percentile"): + intervened_value = self.intervened_percentile + observed_intervention = self.observed_intervention_percentile + + else: + intervened_value = round(self.intervened_value, 3) + observed_intervention = round(self.observed_intervention, 3) + + if scaling == "transformed": + title = ( + f"Predicted {self.outcome_dataset} in {self.name} under intervention {intervened_value} " + f"in year {self.year}
" + f"compared to the observed values under observed intervention " + f"{observed_intervention}." + ) + + else: + title = ( + f"Predicted {self.outcome_dataset} in {self.name}
" + f"under intervention {self.intervened_value_original}" + f" in year {self.year}
" + f"{self.intervened_value_percentile}% of counties received a lower intervention
" + f"observed intervention: {self.observed_intervention_original}" + ) + + fig.update_yaxes(range=[y_min, y_max]) + + fig.update_layout( + title=title, + title_font=dict(size=12), + xaxis_title="Year", + yaxis_title="Value", + template="simple_white", + legend=dict(x=0.05, y=1, traceorder="normal", orientation="h"), + ) + + self.predictions_plot = fig + + if show_figure: + fig.show() + else: + return fig + + def plot_residuals(self): + predictions = self.samples["Y"].squeeze() + self.average_predictions = torch.mean(predictions, dim=0) + plt.hist(self.average_predictions - self.data["y"].squeeze(), bins=70) + plt.xlabel("residuals") + plt.ylabel("counts") + plt.text( + 0.7, + -0.1, + "(colored by year)", + ha="left", + va="bottom", + transform=plt.gca().transAxes, + ) + plt.show() + + def predictive_check(self): + y_flat = self.data["y"].view(-1) + observed_mean = torch.mean(y_flat) + tss = torch.sum((y_flat - observed_mean) ** 2) + average_predictions_flat = self.average_predictions.view(-1) + rss = torch.sum((y_flat - average_predictions_flat) ** 2) + r_squared = 1 - (rss / tss) + self.r_squared = r_squared + rounded_r_squared = np.round(r_squared.item(), 2) + plt.scatter(y=average_predictions_flat, x=y_flat) + plt.title( + f"{self.intervention_dataset}, {self.outcome_dataset}, " + f"R2={rounded_r_squared}" + ) + plt.ylabel("average prediction") + plt.xlabel("observed outcome") + plt.show + + def estimate_ATE(self): + tau_samples = self.samples["weight_TY"].squeeze().detach().numpy() + plt.hist(tau_samples, bins=70) + plt.axvline( + x=tau_samples.mean(), + color="red", + linestyle="dashed", + linewidth=2, + label=f"mean = {tau_samples.mean():.3f}", + ) + plt.title( + f"ATE for {self.intervention_dataset} and {self.outcome_dataset} " + f"with forward shift = {self.forward_shift}" + ) + plt.ylabel("counts") + plt.xlabel("ATE") + plt.legend() + plt.show() diff --git a/build/cities/queries/causal_insight_slim.py b/build/cities/queries/causal_insight_slim.py new file mode 100644 index 00000000..3efc6d09 --- /dev/null +++ b/build/cities/queries/causal_insight_slim.py @@ -0,0 +1,681 @@ +import os + +import dill +import numpy as np +import pandas as pd +import plotly.graph_objects as go +from sklearn.preprocessing import StandardScaler + +from cities.utils.cleaning_utils import ( + revert_prediction_df, + revert_standardize_and_scale_scaler, + sigmoid, +) +from cities.utils.data_grabber import DataGrabber, find_repo_root +from cities.utils.percentiles import transformed_intervention_from_percentile + + +class CausalInsightSlim: + def __init__( + self, + outcome_dataset, + intervention_dataset, + num_samples=1000, + sites=None, + smoke_test=None, + ): + self.outcome_dataset = outcome_dataset + self.intervention_dataset = intervention_dataset + self.root = find_repo_root() + self.num_samples = num_samples + self.smoke_test = smoke_test + self.data = None + + self.tau_samples_path = os.path.join( + self.root, + "data/tau_samples", + f"{self.intervention_dataset}_{self.outcome_dataset}_{self.num_samples}_tau.pkl", + ) + + def get_tau_samples(self): + if os.path.exists(self.tau_samples_path): + with open(self.tau_samples_path, "rb") as file: + self.tensed_tau_samples = dill.load(file) + else: + raise ValueError("No tau samples found. Run generate_tensed_samples first.") + + def slider_values_to_interventions(self, intervened_percent, year): + try: + original_column = dg.wide[self.intervention_dataset][ + str(year) + ].values.reshape(-1, 1) + except NameError: + dg = DataGrabber() + dg.get_features_wide([self.intervention_dataset]) + original_column = dg.wide[self.intervention_dataset][ + str(year) + ].values.reshape(-1, 1) + + max = original_column.max() + + intervened_original = intervened_percent * max / 100 + + scaler = StandardScaler() + scaler.fit(original_column) + + intervened_scaled = scaler.transform(intervened_original.reshape(-1, 1)) + intervened_transformed = sigmoid(intervened_scaled, scale=1 / 3) + + # TODO this output is a bit verbose + # consider deleting what ends up not needed in the frontend + percent_calcs = { + "max": max, + "intervened_percent": intervened_percent, + "intervened_original": intervened_original, + "intervened_scaled": intervened_scaled[0, 0], + "intervened_transformed": intervened_transformed[0, 0], + } + + return percent_calcs + + def get_intervened_and_observed_values_original_scale( + self, fips, intervened_value, year + ): + dg = DataGrabber() + dg.get_features_std_wide([self.intervention_dataset, self.outcome_dataset]) + dg.get_features_wide([self.intervention_dataset]) + + # intervened value, in the original scale + intervened_original_scale = revert_standardize_and_scale_scaler( + intervened_value, year, self.intervention_dataset + ) + + fips_id = ( + dg.std_wide[self.intervention_dataset] + .loc[dg.std_wide[self.intervention_dataset]["GeoFIPS"] == fips] + .index[0] + ) + + # observed value, in the original scale + observed_original_scale = dg.wide[self.intervention_dataset].iloc[fips_id][ + str(year) + ] + + return (intervened_original_scale[0], observed_original_scale) + + def get_group_predictions( + self, + group, + intervened_value, + year=None, + intervention_is_percentile=False, + produce_original=True, + ): + self.group_clean = list(set(group)) + self.group_clean.sort() + self.produce_original = produce_original + + if self.data is None: + file_path = os.path.join( + self.root, + "data/years_available", + f"{self.intervention_dataset}_{self.outcome_dataset}.pkl", + ) + with open(file_path, "rb") as file: + self.data = dill.load(file) + + if year is None: + year = self.data["years_available"][-1] + assert year in self.data["years_available"] + + self.year = year + + if intervention_is_percentile: + self.intervened_percentile = intervened_value + intervened_value = transformed_intervention_from_percentile( + self.intervention_dataset, year, intervened_value + ) + + self.intervened_value = intervened_value + + # find years for prediction + outcome_years = self.data["outcome_years"] + year_id = [int(x) for x in outcome_years].index(year) + self.year_id = year_id + + self.prediction_years = outcome_years[(year_id) : (year_id + 4)] + + dg = DataGrabber() + dg.get_features_std_wide([self.intervention_dataset, self.outcome_dataset]) + dg.get_features_wide([self.intervention_dataset, self.outcome_dataset]) + interventions_this_year_original = dg.wide[self.intervention_dataset][str(year)] + + self.intervened_value_original = revert_standardize_and_scale_scaler( + self.intervened_value, self.year, self.intervention_dataset + ) + + self.intervened_value_percentile = round( + ( + np.mean( + interventions_this_year_original.values + <= self.intervened_value_original + ) + * 100 + ), + 3, + ) + + # note: ids will be inceasingly sorted + self.fips_ids = ( + dg.std_wide[self.intervention_dataset] + .loc[ + dg.std_wide[self.intervention_dataset]["GeoFIPS"].isin(self.group_clean) + ] + .index.tolist() + ) + + assert len(self.fips_ids) == len(self.group_clean) + assert set( + dg.std_wide[self.intervention_dataset]["GeoFIPS"].iloc[self.fips_ids] + ) == set(self.group_clean) + + self.names = dg.std_wide[self.intervention_dataset]["GeoName"].iloc[ + self.fips_ids + ] + + self.observed_interventions = dg.std_wide[self.intervention_dataset].iloc[ + self.fips_ids + ][str(year)] + + self.observed_interventions_original = ( + dg.wide[self.intervention_dataset].iloc[self.fips_ids][str(year)].copy() + ) + + # + if intervention_is_percentile: + self.observed_interventions_percentile = ( + np.round( + [ + np.mean(interventions_this_year_original.values <= obs) + for obs in self.observed_interventions_original + ], + 3, + ) + * 100 + ) + + self.observed_outcomes = dg.std_wide[self.outcome_dataset].iloc[self.fips_ids][ + outcome_years[year_id : (year_id + 4)] + ] + + self.observed_outcomes_original = dg.wide[self.outcome_dataset].iloc[ + self.fips_ids + ][outcome_years[year_id : (year_id + 4)]] + + self.intervention_diffs = self.intervened_value - self.observed_interventions + + self.intervention_impacts = {} + self.intervention_impacts_means = [] + self.intervention_impacts_lows = [] + self.intervention_impacts_highs = [] + for shift in [1, 2, 3]: + self.intervention_impacts[shift] = np.outer( + self.tensed_tau_samples[shift], self.intervention_diffs + ) + self.intervention_impacts_means.append( + np.mean(self.intervention_impacts[shift], axis=0) + ) + self.intervention_impacts_lows.append( + np.percentile(self.intervention_impacts[shift], axis=0, q=2.5) + ) + self.intervention_impacts_highs.append( + np.percentile(self.intervention_impacts[shift], axis=0, q=97.5) + ) + + intervention_impacts_means_array = np.column_stack( + self.intervention_impacts_means + ) + intervention_impacts_lows_array = np.column_stack( + self.intervention_impacts_lows + ) + intervention_impacts_highs_array = np.column_stack( + self.intervention_impacts_highs + ) + + future_predicted_means = ( + self.observed_outcomes.iloc[:, 1:] + intervention_impacts_means_array + ) + # predicted_means = np.insert( + # future_predicted_means, 0, self.observed_outcomes.iloc[:, 0], axis=1 + # ) #TODO delete if the new version raises no index error + + predicted_means = np.column_stack( + [self.observed_outcomes.iloc[:, 0], future_predicted_means] + ) + + future_predicted_lows = ( + self.observed_outcomes.iloc[:, 1:] + intervention_impacts_lows_array + ) + predicted_lows = np.column_stack( + [self.observed_outcomes.iloc[:, 0], future_predicted_lows] + ) + # predicted_lows = np.insert( + # future_predicted_lows, 0, self.observed_outcomes.iloc[:, 0], axis=1 + # ) #TODO as above + + future_predicted_highs = ( + self.observed_outcomes.iloc[:, 1:] + intervention_impacts_highs_array + ) + # predicted_highs = np.insert( + # future_predicted_highs, 0, self.observed_outcomes.iloc[:, 0], axis=1 + # ) #TODO as above + + predicted_highs = np.column_stack( + [self.observed_outcomes.iloc[:, 0], future_predicted_highs] + ) + + if self.produce_original: + pred_means_reverted = [] + pred_lows_reverted = [] + pred_highs_reverted = [] + obs_out_reverted = [] + for i in range(predicted_means.shape[1]): + y = self.prediction_years[i] + obs_out_reverted.append( + revert_standardize_and_scale_scaler( + self.observed_outcomes.iloc[:, i], y, self.outcome_dataset + ) + ) + pred_means_reverted.append( + revert_standardize_and_scale_scaler( + predicted_means[:, i], y, self.outcome_dataset + ) + ) + + pred_lows_reverted.append( + revert_standardize_and_scale_scaler( + predicted_lows[:, i], y, self.outcome_dataset + ) + ) + + pred_highs_reverted.append( + revert_standardize_and_scale_scaler( + predicted_highs[:, i], y, self.outcome_dataset + ) + ) + + obs_out_reverted = np.column_stack(obs_out_reverted) + diff = obs_out_reverted - self.observed_outcomes_original + diff = np.array(diff) + obs_out_corrected = obs_out_reverted - diff + pred_means_reverted = np.column_stack(pred_means_reverted) + pred_means_corrected = pred_means_reverted - diff + pred_lows_reverted = np.column_stack(pred_lows_reverted) + pred_lows_corrected = pred_lows_reverted - diff + pred_highs_reverted = np.column_stack(pred_highs_reverted) + pred_highs_corrected = pred_highs_reverted - diff + + self.observed_outcomes_corrected = pd.DataFrame(obs_out_corrected) + self.observed_outcomes_corrected.index = self.observed_outcomes.index + + assert predicted_means.shape == pred_means_corrected.shape + assert predicted_lows.shape == pred_lows_corrected.shape + assert predicted_highs.shape == pred_highs_corrected.shape + + assert int(predicted_means.shape[0]) == len(self.group_clean) + assert int(predicted_means.shape[1]) == 4 + assert int(predicted_lows.shape[0]) == len(self.group_clean) + assert int(predicted_lows.shape[1]) == 4 + assert int(predicted_highs.shape[0]) == len(self.group_clean) + assert int(predicted_highs.shape[1]) == 4 + + self.group_predictions = { + self.group_clean[i]: pd.DataFrame( + { + "year": self.prediction_years, + "observed": self.observed_outcomes.loc[self.fips_ids[i]], + "mean": predicted_means[i,], + "low": predicted_lows[i,], + "high": predicted_highs[i,], + } + ) + for i in range(len(self.group_clean)) + } + + if self.produce_original: + self.group_predictions_original = { + self.group_clean[i]: pd.DataFrame( + { + "year": self.prediction_years, + "observed": self.observed_outcomes_corrected.loc[ + self.fips_ids[i] + ], + "mean": pred_means_corrected[i,], + "low": pred_lows_corrected[i,], + "high": pred_highs_corrected[i,], + } + ) + for i in range(len(self.group_clean)) + } + + def get_fips_predictions( + self, fips, intervened_value, year=None, intervention_is_percentile=False + ): + self.fips = fips + + if self.data is None: + file_path = os.path.join( + self.root, + "data/years_available", + f"{self.intervention_dataset}_{self.outcome_dataset}.pkl", + ) + with open(file_path, "rb") as file: + self.data = dill.load(file) + + # start with the latest year possible by default + if year is None: + year = self.data["years_available"][-1] + assert year in self.data["years_available"] + + self.year = year + + if intervention_is_percentile: + self.intervened_percentile = intervened_value + intervened_value = transformed_intervention_from_percentile( + self.intervention_dataset, year, intervened_value + ) + + self.intervened_value = intervened_value + + # find years for prediction + outcome_years = self.data["outcome_years"] + year_id = [int(x) for x in outcome_years].index(year) + self.year_id = year_id + + self.prediction_years = outcome_years[(year_id) : (year_id + 4)] + + dg = DataGrabber() + dg.get_features_std_wide([self.intervention_dataset, self.outcome_dataset]) + dg.get_features_wide([self.intervention_dataset, self.outcome_dataset]) + interventions_this_year_original = dg.wide[self.intervention_dataset][str(year)] + + self.intervened_value_original = revert_standardize_and_scale_scaler( + self.intervened_value, self.year, self.intervention_dataset + ) + + self.intervened_value_percentile = round( + ( + np.mean( + interventions_this_year_original.values + <= self.intervened_value_original + ) + * 100 + ), + 3, + ) + + self.fips_id = ( + dg.std_wide[self.intervention_dataset] + .loc[dg.std_wide[self.intervention_dataset]["GeoFIPS"] == fips] + .index[0] + ) + + self.name = dg.std_wide[self.intervention_dataset]["GeoName"].iloc[self.fips_id] + + # get observed values at the prediction times + self.observed_intervention = dg.std_wide[self.intervention_dataset].iloc[ + self.fips_id + ][str(year)] + + self.observed_intervention_original = dg.wide[self.intervention_dataset].iloc[ + self.fips_id + ][str(year)] + + if intervention_is_percentile: + self.observed_intervention_percentile = round( + ( + np.mean( + interventions_this_year_original.values + <= self.observed_intervention_original + ) + * 100 + ), + 1, + ) + + self.observed_outcomes = dg.std_wide[self.outcome_dataset].iloc[self.fips_id][ + outcome_years[year_id : (year_id + 4)] + ] + + # added + self.observed_outcomes_original = dg.wide[self.outcome_dataset].iloc[ + self.fips_id + ][outcome_years[year_id : (year_id + 4)]] + + self.intervention_diff = self.intervened_value - self.observed_intervention + + self.intervention_impact = {} + self.intervention_impact_mean = [] + self.intervention_impact_low = [] + self.intervention_impact_high = [] + for shift in [1, 2, 3]: + self.intervention_impact[shift] = ( + self.tensed_tau_samples[shift] * self.intervention_diff + ) + self.intervention_impact_mean.append( + np.mean(self.intervention_impact[shift]) + ) + self.intervention_impact_low.append( + np.percentile(self.intervention_impact[shift], 2.5) + ) + self.intervention_impact_high.append( + np.percentile(self.intervention_impact[shift], 97.5) + ) + + predicted_mean = [self.observed_outcomes.iloc[0]] + ( + self.intervention_impact_mean + self.observed_outcomes.iloc[1:] + ).tolist() + predicted_low = [self.observed_outcomes.iloc[0]] + ( + self.intervention_impact_low + self.observed_outcomes.iloc[1:] + ).tolist() + predicted_high = [self.observed_outcomes.iloc[0]] + ( + self.intervention_impact_high + self.observed_outcomes.iloc[1:] + ).tolist() + + self.predictions = pd.DataFrame( + { + "year": self.prediction_years, + "observed": self.observed_outcomes, + "mean": predicted_mean, + "low": predicted_low, + "high": predicted_high, + } + ) + + self.predictions_original = revert_prediction_df( + self.predictions, self.outcome_dataset + ) + + # this corrects for rever transformation perturbations + difference = ( + self.predictions_original["observed"] - self.observed_outcomes_original + ) + self.predictions_original[["observed", "mean", "low", "high"]] = ( + self.predictions_original[["observed", "mean", "low", "high"]].sub( + difference, axis=0 + ) + ) + + def plot_predictions( + self, range_multiplier=1.5, show_figure=True, scaling="transformed", fips=None + ): + assert scaling in ["transformed", "original"] + + # you need to pass fips + # and grab the appropriate predictions + # if you started with group predictions + if fips is not None: + self.fips = fips + self.predictions = self.group_predictions[fips] + self.predictions_original = self.group_predictions_original[fips] + + self.observed_intervention = self.observed_interventions[ + self.fips_ids[self.group_clean.index(fips)] + ] + self.observed_intervention_original = self.observed_interventions_original[ + self.fips_ids[self.group_clean.index(fips)] + ] + + self.name = self.names[self.fips_ids[self.group_clean.index(fips)]] + + dg = DataGrabber() + + if scaling == "transformed": + dg.get_features_std_long([self.outcome_dataset]) + plot_data = dg.std_long[self.outcome_dataset] + self.fips_observed_data = plot_data[ + plot_data["GeoFIPS"] == self.fips + ].copy() + + y_min = ( + min( + self.fips_observed_data["Value"].min(), + self.predictions["low"].min(), + ) + - 0.05 + ) + y_max = ( + max( + self.fips_observed_data["Value"].max(), + self.predictions["high"].max(), + ) + + 0.05 + ) + else: + dg.get_features_long([self.outcome_dataset]) + plot_data = dg.long[self.outcome_dataset] + + self.fips_observed_data = plot_data[ + plot_data["GeoFIPS"] == self.fips + ].copy() + + y_min = 0.8 * min( + self.fips_observed_data["Value"].min(), + self.predictions_original["low"].min(), + ) + y_max = 1.3 * max( + self.fips_observed_data["Value"].max(), + self.predictions_original["high"].max(), + ) + + fig = go.Figure() + + fig.add_trace( + go.Scatter( + x=self.fips_observed_data["Year"], + y=self.fips_observed_data["Value"], + mode="lines+markers", + name=self.fips_observed_data["GeoName"].iloc[0], + line=dict(color="darkred", width=3), + text=self.fips_observed_data["GeoName"].iloc[0], + textposition="top right", + showlegend=False, + ) + ) + + if scaling == "transformed": + fig.add_trace( + go.Scatter( + x=self.predictions["year"], + y=self.predictions["mean"], + mode="lines", + line=dict(color="blue", width=2), + name="mean prediction", + text=self.predictions["mean"], + ) + ) + + credible_interval_trace = go.Scatter( + x=pd.concat([self.predictions["year"], self.predictions["year"][::-1]]), + y=pd.concat([self.predictions["high"], self.predictions["low"][::-1]]), + fill="toself", + fillcolor="rgba(0,100,80,0.2)", + line=dict(color="rgba(255,255,255,0)"), + name="95% credible interval around mean", + ) + + else: + fig.add_trace( + go.Scatter( + x=self.predictions_original["year"], + y=self.predictions_original["mean"], + mode="lines", + line=dict(color="blue", width=2), + name="mean prediction", + text=self.predictions_original["mean"], + ) + ) + + credible_interval_trace = go.Scatter( + x=pd.concat( + [ + self.predictions_original["year"], + self.predictions_original["year"][::-1], + ] + ), + y=pd.concat( + [ + self.predictions_original["high"], + self.predictions_original["low"][::-1], + ] + ), + fill="toself", + fillcolor="rgba(255, 255, 255, 0.31)", + line=dict(color="rgba(255,255,255,0)"), + name="95% credible interval around mean", + ) + + fig.add_trace(credible_interval_trace) + + if hasattr(self, "intervened_percentile"): + intervened_value = self.intervened_percentile + observed_intervention = self.observed_intervention_percentile + + else: + intervened_value = round(self.intervened_value, 3) + observed_intervention = round(self.observed_intervention, 3) + + if scaling == "transformed": + title = ( + f"Predicted {self.outcome_dataset} in {self.name} under intervention {intervened_value} " + f"in year {self.year}
" + f"compared to the observed values under observed intervention " + f"{observed_intervention}." + ) + + else: + title = ( + f"Predicted {self.outcome_dataset} in {self.name}
" + f"under intervention {self.intervened_value_original}" + f" in year {self.year}
" + f"{self.intervened_value_percentile}% of counties received a lower intervention
" + f"observed intervention: {self.observed_intervention_original}" + ) + + fig.update_yaxes(range=[y_min, y_max]) + + fig.update_layout( + title=title, + title_font=dict(size=12), + xaxis_title="Year", + yaxis_title="Value", + template="simple_white", + legend=dict(x=0.05, y=1, traceorder="normal", orientation="h"), + ) + + self.predictions_plot = fig + + if show_figure: + fig.show() + else: + return fig diff --git a/build/cities/queries/fips_query.py b/build/cities/queries/fips_query.py new file mode 100644 index 00000000..5d6a14f3 --- /dev/null +++ b/build/cities/queries/fips_query.py @@ -0,0 +1,797 @@ +import numpy as np +import pandas as pd +import plotly.graph_objects as go + +from cities.utils.data_grabber import ( + DataGrabber, + MSADataGrabber, + check_if_tensed, + list_available_features, +) +from cities.utils.similarity_utils import ( + compute_weight_array, + generalized_euclidean_distance, + plot_weights, + slice_with_lag, +) + +# from scipy.spatial import distance + + +class FipsQuery: + """ + Class for querying and analyzing jurisdiction data for a specific FIPS code, + in terms of specified feature groups, outcome variable, time lag, and other, listed parameters. + """ + + def __init__( + self, + fips, + outcome_var=None, + feature_groups_with_weights=None, + lag=0, + top=5, + time_decay=1.08, + outcome_comparison_period=None, + outcome_percentile_range=None, + ): + """ + Initialize the FipsQuery instance. + + :param fips: the FIPS code of interest. + :param outcome_var: the outcome variable for analysis (optional, defaults to None). + :param feature_groups_with_weights: a dictionary specifying feature groups and their weights + (weights should beint between -4 and 4). + :param lag: time lag for comparing outcomes with historical data (int between 0 and 6). + :param top: the number of top locations to consider in comparisons (defaults to 5). + :param time_decay: adjusts the weight decay over time in the generalized Euclidean distance calculation + (default is 1.08, giving somewhat more weight to more recent data). + :param outcome_comparison_period: specifies the years to consider for the outcome comparison, + can be used only when lag=0 (defaults to None). + :param outcome_percentile_range: percentile range for filtering locations based on the most recent value + of the outcome variable (defaults to None). + """ + + if feature_groups_with_weights is None and outcome_var: + feature_groups_with_weights = {outcome_var: 4} + + if outcome_var: + outcome_var_dict = { + outcome_var: feature_groups_with_weights.pop(outcome_var) + } + outcome_var_dict.update(feature_groups_with_weights) + feature_groups_with_weights = outcome_var_dict + + assert not ( + lag > 0 and outcome_var is None + ), "lag will be idle with no outcome variable" + + assert not ( + lag > 0 and outcome_comparison_period is not None + ), "outcome_comparison_period is only used when lag = 0" + + assert not ( + outcome_var is None and outcome_comparison_period is not None + ), "outcome_comparison_period requires an outcome variable" + + assert not ( + outcome_var is None and outcome_percentile_range is not None + ), "outcome_percentile_range requires an outcome variable" + + self.all_available_features = list_available_features() + + feature_groups = list(feature_groups_with_weights.keys()) + + assert feature_groups, "You need to specify at least one feature group" + + assert all( + isinstance(value, int) and -4 <= value <= 4 + for value in feature_groups_with_weights.values() + ), "Feature weights need to be integers between -4 and 4" + + self.feature_groups_with_weights = feature_groups_with_weights + self.feature_groups = feature_groups + self.data = DataGrabber() + self.repo_root = self.data.repo_root + self.fips = fips + self.lag = lag + self.top = top + self.gdp_var = "gdp" + + # it's fine if they're None (by default) + self.outcome_var = outcome_var + self.outcome_comparison_period = outcome_comparison_period + + self.time_decay = time_decay + + if self.gdp_var not in self.feature_groups: + self.all_features = [self.gdp_var] + feature_groups + else: + self.all_features = feature_groups + + self.data.get_features_std_wide(self.all_features) + self.data.get_features_wide(self.all_features) + + assert ( + fips in self.data.std_wide[self.gdp_var]["GeoFIPS"].values + ), "FIPS not found in the data set." + self.name = self.data.std_wide[self.gdp_var]["GeoName"][ + self.data.std_wide[self.gdp_var]["GeoFIPS"] == self.fips + ].values[0] + + assert ( + self.lag >= 0 and self.lag < 6 and isinstance(self.lag, int) + ), "lag must be an iteger between 0 and 5" + assert ( + self.top > 0 + and isinstance(self.top, int) + and self.top + < 2800 # TODO Make sure the number makes sense once we add all datasets we need + ), "top must be a positive integer smaller than the number of locations in the dataset" + + if outcome_var: + assert check_if_tensed( + self.data.std_wide[self.outcome_var] + ), "Outcome needs to be a time series." + + self.outcome_with_percentiles = self.data.std_wide[self.outcome_var].copy() + most_recent_outcome = self.data.wide[self.outcome_var].iloc[:, -1].values + self.outcome_with_percentiles["percentile"] = ( + most_recent_outcome < most_recent_outcome[:, np.newaxis] + ).sum(axis=1) / most_recent_outcome.shape[0] + self.outcome_with_percentiles["percentile"] = round( + self.outcome_with_percentiles["percentile"] * 100, 2 + ) + self.outcome_percentile_range = outcome_percentile_range + + def compare_my_outcome_to_others(self, range_multiplier=2, sample_size=250): + """ + Compare the outcome of the selected location to a sample of other locations. + + This method generates a plot comparing the outcome of the current location to a + random sample of other locations. The plot creates a line for the current location + and lines for the sampled locations, providing a visual comparison. + It also marks the precentile at which the current location falls among *all* locations. + + :param range_multiplier: multiplier for adjusting the y-axis range (defaults to 2). + :param sample_size: random sample size of other locations (defaults to 250). + """ + + assert self.outcome_var, "Outcome comparison requires an outcome variable." + + self.data.get_features_long([self.outcome_var]) + plot_data = self.data.long[self.outcome_var] + my_plot_data = plot_data[plot_data["GeoFIPS"] == self.fips].copy() + my_percentile = self.outcome_with_percentiles["percentile"][ + self.outcome_with_percentiles["GeoFIPS"] == self.fips + ].values[0] + + others_plot_data = plot_data[plot_data["GeoFIPS"] != self.fips] + + fips = others_plot_data["GeoFIPS"].unique() + sampled_fips = np.random.choice(fips, sample_size, replace=False) + others_sampled_plot_data = plot_data[plot_data["GeoFIPS"].isin(sampled_fips)] + + y_min = my_plot_data["Value"].mean() - ( + range_multiplier * my_plot_data["Value"].std() + ) + y_max = my_plot_data["Value"].mean() + ( + range_multiplier * my_plot_data["Value"].std() + ) + + fig = go.Figure(layout_yaxis_range=[y_min, y_max]) + + for i, geoname in enumerate(others_sampled_plot_data["GeoName"].unique()): + subset = others_plot_data[others_plot_data["GeoName"] == geoname] + # line_color = shades_of_grey[i % len(shades_of_grey)] + # line_color = pastel_colors[i % len(pastel_colors)] + line_color = "lightgray" + fig.add_trace( + go.Scatter( + x=subset["Year"], + y=subset["Value"], + mode="lines", + name=subset["GeoName"].iloc[0], + line_color=line_color, + text=subset["GeoName"].iloc[0], + textposition="top right", + showlegend=False, + opacity=0.4, + ) + ) + + fig.add_trace( + go.Scatter( + x=my_plot_data["Year"], + y=my_plot_data["Value"], + mode="lines", + name=my_plot_data["GeoName"].iloc[0], + line=dict(color="darkred", width=3), + text=my_plot_data["GeoName"].iloc[0], + textposition="top right", + showlegend=False, + ) + ) + + label_x = my_plot_data["Year"].iloc[-1] - 2 + label_y = my_plot_data["Value"].iloc[-1] * 1.2 + fig.add_annotation( + text=f"Location recent percentile: {my_percentile}%", + x=label_x, + y=label_y, + showarrow=False, + font=dict(size=12, color="darkred"), + ) + + title = f"{self.outcome_var} of {self.name}, compared to {sample_size} random other locations" + fig.update_layout( + title=title, + xaxis_title="Year", + yaxis_title=f"{self.outcome_var}", + template="simple_white", + ) + + fig.show() + + def find_euclidean_kins(self): + """ + Find Euclidean kin locations based on the specified features, weights and outcome variable. + + This method calculates the Euclidean distance between the specified location and other + locations in the dataset based on the selected feature groups and outcome variable. It + adds information about the distance and the percentiles of the outcome variable to the + resulting dataframe, allowing for the identification of similar locations. + """ + + # cut the relevant years from the outcome variable + if self.outcome_comparison_period and self.outcome_var: + start_year, end_year = self.outcome_comparison_period + + outcome_df = self.data.std_wide[self.outcome_var].copy() + + condition = (outcome_df.columns[2:].copy().astype(int) >= start_year) & ( + outcome_df.columns[2:].copy().astype(int) <= end_year + ) + selected_columns = outcome_df.columns[2:][condition].copy() + filtered_dataframe = outcome_df[selected_columns] + + restricted_df = pd.concat( + [outcome_df.iloc[:, :2].copy(), filtered_dataframe], axis=1 + ) + + elif self.outcome_var: + restricted_df = self.data.std_wide[self.outcome_var].copy() + + if self.outcome_var: + self.restricted_outcome_df = restricted_df + + # apply lag in different directions to you and other locations + # to the outcome variable + if self.outcome_var: + self.outcome_slices = slice_with_lag(restricted_df, self.fips, self.lag) + + self.my_array = np.array(self.outcome_slices["my_array"]) + self.other_arrays = np.array(self.outcome_slices["other_arrays"]) + + assert self.my_array.shape[1] == self.other_arrays.shape[1] + + self.my_df = self.data.wide[self.outcome_var][ + self.data.wide[self.outcome_var]["GeoFIPS"] == self.fips + ].copy() + + self.other_df = self.outcome_slices["other_df"] + self.other_df = self.data.wide[self.outcome_var][ + self.data.wide[self.outcome_var]["GeoFIPS"] != self.fips + ].copy() + else: + self.my_df = pd.DataFrame( + self.data.wide[self.gdp_var][ + self.data.wide[self.gdp_var]["GeoFIPS"] == self.fips + ].iloc[:, :2] + ) + self.other_df = pd.DataFrame( + self.data.wide[self.gdp_var][ + self.data.wide[self.gdp_var]["GeoFIPS"] != self.fips + ].iloc[:, :2] + ) + + # add data on other features to the arrays + # prior to distance computation + + if self.outcome_var: + before_shape = self.other_df.shape + + my_features_arrays = np.array([]) + others_features_arrays = np.array([]) + feature_column_count = 0 + for feature in self.feature_groups: + if feature != self.outcome_var: + _extracted_df = self.data.wide[feature].copy() + feature_column_count += _extracted_df.shape[1] - 2 + _extracted_my_df = _extracted_df[_extracted_df["GeoFIPS"] == self.fips] + _extracted_other_df = _extracted_df[ + _extracted_df["GeoFIPS"] != self.fips + ] + + _extracted_other_df.columns = [ + f"{col}_{feature}" if col not in ["GeoFIPS", "GeoName"] else col + for col in _extracted_other_df.columns + ] + + _extracted_my_df.columns = [ + f"{col}_{feature}" if col not in ["GeoFIPS", "GeoName"] else col + for col in _extracted_my_df.columns + ] + + assert ( + _extracted_df.shape[1] + == _extracted_my_df.shape[1] + == _extracted_other_df.shape[1] + ) + + self.my_df = pd.concat( + (self.my_df, _extracted_my_df.iloc[:, 2:]), axis=1 + ) + + self.other_df = pd.concat( + (self.other_df, _extracted_other_df.iloc[:, 2:]), axis=1 + ) + + if self.outcome_var is None: + assert ( + self.my_df.shape[1] + == self.other_df.shape[1] + == feature_column_count + 2 + ) + + if self.outcome_var: + after_shape = self.other_df.shape + assert ( + before_shape[0] == after_shape[0] + ), "Feature merging went wrong!" + + _extracted_df_std = self.data.std_wide[feature].copy() + _extracted_other_array = np.array( + _extracted_df_std[_extracted_df_std["GeoFIPS"] != self.fips].iloc[ + :, 2: + ] + ) + _extracted_my_array = np.array( + _extracted_df_std[_extracted_df_std["GeoFIPS"] == self.fips].iloc[ + :, 2: + ] + ) + + if my_features_arrays.size == 0: + my_features_arrays = _extracted_my_array + else: + my_features_arrays = np.hstack( + (my_features_arrays, _extracted_my_array) + ) + + if others_features_arrays.size == 0: + others_features_arrays = _extracted_other_array + else: + others_features_arrays = np.hstack( + (others_features_arrays, _extracted_other_array) + ) + + if len(self.feature_groups) > 1 and self.outcome_var: + self.my_array = np.hstack((self.my_array, my_features_arrays)) + self.other_arrays = np.hstack((self.other_arrays, others_features_arrays)) + elif self.outcome_var is None: + self.my_array = my_features_arrays.copy() + self.other_arrays = others_features_arrays.copy() + + if self.outcome_var is None: + assert ( + feature_column_count + == self.my_array.shape[1] + == self.other_arrays.shape[1] + ) + assert my_features_arrays.shape == self.my_array.shape + assert others_features_arrays.shape == self.other_arrays.shape + + compute_weight_array(self, self.time_decay) + + diff = self.all_weights.shape[0] - self.other_arrays.shape[1] + self.all_weights = self.all_weights[diff:] + + # if self.outcome_var: + assert ( + self.other_arrays.shape[1] == self.all_weights.shape[0] + ), "Weights and arrays are misaligned" + + distances = [] + featurewise_contributions = [] + for vector in self.other_arrays: + _ge = generalized_euclidean_distance( + np.squeeze(self.my_array), vector, self.all_weights + ) + distances.append(_ge["distance"]) + featurewise_contributions.append(_ge["featurewise_contributions"]) + + # keep weighted distance contribution of each individual feature + featurewise_contributions_array = np.vstack(featurewise_contributions) + + assert featurewise_contributions_array.shape[1] == len(self.all_weights) + + # turn into df, add ID columns and sort by distance + featurewise_contributions_df = pd.DataFrame( + featurewise_contributions_array, columns=self.all_columns + ) + featurewise_contributions_df[f"distance to {self.fips}"] = distances + featurewise_contributions_df = pd.concat( + [self.other_df[["GeoFIPS", "GeoName"]], featurewise_contributions_df], + axis=1, + ) + featurewise_contributions_df.sort_values( + by=featurewise_contributions_df.columns[-1], inplace=True + ) + + # isolate ID columns with distance, tensed columns, atemporal columns + tensed_column_names = [ + col for col in featurewise_contributions_df.columns if col[:4].isdigit() + ] + atemporal_column_names = [ + col for col in featurewise_contributions_df.columns if not col[:4].isdigit() + ] + id_column_names = atemporal_column_names[0:2] + [atemporal_column_names[-1]] + atemporal_column_names = [ + col for col in atemporal_column_names if col not in id_column_names + ] + + id_df = featurewise_contributions_df[id_column_names] + tensed_featurewise_contributions_df = featurewise_contributions_df[ + tensed_column_names + ] + atemporal_featurewise_contributions_df = featurewise_contributions_df[ + atemporal_column_names + ] + + # aggregate tensed features (sum across years) + aggregated_tensed_featurewise_contributions_df = ( + tensed_featurewise_contributions_df.T.groupby( + tensed_featurewise_contributions_df.columns.str[5:] + ) + .sum() + .T + ) + + # aggregate atemporal features (sum across official feature list) + atemporal_aggregated_dict = {} + for feature in list(self.all_available_features): + _selected = [ + col + for col in atemporal_featurewise_contributions_df.columns + if col.endswith(feature) + ] + if _selected: + atemporal_aggregated_dict[feature] = ( + atemporal_featurewise_contributions_df[_selected].sum(axis=1) + ) + + aggregated_atemporal_featurewise_contributions_df = pd.DataFrame( + atemporal_aggregated_dict + ) + + self.featurewise_contributions = featurewise_contributions_df + + # put together the aggregated featurewise contributions + # and normalize row-wise + # numbers now mean: "percentage of contribution to the distance" + self.aggregated_featurewise_contributions = pd.concat( + [ + id_df, + aggregated_tensed_featurewise_contributions_df, + aggregated_atemporal_featurewise_contributions_df, + ], + axis=1, + ) + columns_to_normalize = self.aggregated_featurewise_contributions.iloc[:, 3:] + self.aggregated_featurewise_contributions.iloc[:, 3:] = ( + columns_to_normalize.div(columns_to_normalize.sum(axis=1), axis=0) + ) + + # some sanity checks + count = sum([1 for distance in distances if distance == 0]) + + assert ( + len(distances) == self.other_arrays.shape[0] + ), "Distances and arrays are misaligned" + assert ( + len(distances) == self.other_df.shape[0] + ), "Distances and df are misaligned" + + # #self.other_df[f"distance to {self.fips}"] = distances #remove soon if no errors + self.other_df.loc[:, f"distance to {self.fips}"] = distances + + count_zeros = (self.other_df[f"distance to {self.fips}"] == 0).sum() + assert count_zeros == count, "f{count_zeros} zeros in alien distances!" + + # sort and put together euclidean kins + self.other_df.sort_values(by=self.other_df.columns[-1], inplace=True) + + self.my_df[f"distance to {self.fips}"] = 0 + + self.euclidean_kins = pd.concat((self.my_df, self.other_df), axis=0) + + if self.outcome_var: + self.euclidean_kins = self.euclidean_kins.merge( + self.outcome_with_percentiles[["GeoFIPS", "percentile"]], + on="GeoFIPS", + how="left", + ) + + if self.outcome_var and self.outcome_percentile_range is not None: + myself = self.euclidean_kins.iloc[:1] + self.euclidean_kins = self.euclidean_kins[ + self.euclidean_kins["percentile"] >= self.outcome_percentile_range[0] + ] + self.euclidean_kins = self.euclidean_kins[ + self.euclidean_kins["percentile"] <= self.outcome_percentile_range[1] + ] + self.euclidean_kins = pd.concat([myself, self.euclidean_kins]) + + def plot_weights(self): + """ + This method calls the external function `plot_weights` to visualize the feature weights. + + """ + plot_weights(self) + + def plot_kins_other_var(self, var, fips_top_custom=None): + """ + For a specified variable plot the time series for the current location and its Euclidean kin locations. + + Parameters: + - var (str): The variable for which the time series will be plotted. + - fips_top_custom (list or None): Custom list of FIPS codes to use instead of the top Euclidean kin locations. + + Returns: + - fig: Plotly figure object. + + Note: + - The method requires running `find_euclidean_kins` first. + """ + + # assert self.outcome_var, "Outcome comparison requires an outcome variable" + assert hasattr(self, "euclidean_kins"), "Run `find_euclidean_kins` first" + + self.data.get_features_long([var]) + plot_data = self.data.long[var] + my_plot_data = plot_data[plot_data["GeoFIPS"] == self.fips].copy() + + if fips_top_custom is None: + fips_top = self.euclidean_kins["GeoFIPS"].iloc[1 : (self.top + 1)].values + else: + fips_top = fips_top_custom + + others_plot_data = plot_data[plot_data["GeoFIPS"].isin(fips_top)] + + value_column_name = my_plot_data.columns[-1] + fig = go.Figure() + fig.add_trace( + go.Scatter( + x=my_plot_data["Year"], + y=my_plot_data[value_column_name], + mode="lines", + name=my_plot_data["GeoName"].iloc[0], + line=dict(color="darkred", width=3), + text=my_plot_data["GeoName"].iloc[0], + textposition="top right", + ) + ) + + pastel_colors = ["#FFC0CB", "#A9A9A9", "#87CEFA", "#FFD700", "#98FB98"][ + : self.top + ] + + for i, fips in enumerate(fips_top): + subset = others_plot_data[others_plot_data["GeoFIPS"] == fips] + line_color = pastel_colors[i % len(pastel_colors)] + fig.add_trace( + go.Scatter( + x=subset["Year"] + self.lag, + y=subset[value_column_name], + mode="lines", + name=subset["GeoName"].iloc[0], + line_color=line_color, + text=subset["GeoName"].iloc[0], + textposition="top right", + ) + ) + + if self.lag > 0: + fig.update_layout( + shapes=[ + dict( + type="line", + x0=2021, + x1=2021, + y0=0, + y1=1, + xref="x", + yref="paper", + line=dict(color="darkgray", width=2), + ) + ] + ) + + fig.add_annotation( + text=f"their year {2021 - self.lag}", + x=2021.0, + y=1.05, + xref="x", + yref="paper", + showarrow=False, + font=dict(color="darkgray"), + ) + + top = self.top + lag = self.lag + title_1 = title = f"Top {self.top} locations matching your search" + title_2 = ( + f"Top {self.top} locations matching your search (lag of {self.lag} years)" + ) + + if not self.feature_groups: + if self.lag == 0: + title = title_1 + else: + title = title_2 + else: + if self.lag == 0: + title = f"Top {top} locations matching your search" + else: + title = f"Top {top} locations matching your search (lag of {lag} years)" + + fig.update_layout( + title=title, + xaxis_title="Year", + yaxis_title=f"{var}", + legend=dict(title="GeoName"), + template="simple_white", + ) + + return fig + + def plot_kins(self): + """ + Creates the time series plot of the outcome variable for the current location and its Euclidean kin locations. + """ + + fig = self.plot_kins_other_var(self.outcome_var) + return fig + + def show_kins_plot(self): + """ + Plot the time series of the outcome variable for the current location and its Euclidean kin locations. + """ + + fig = self.plot_kins() + fig.show() + + +# TODO_Nikodem add population clustering and warning if a population is much different, +# especially if small + + +class MSAFipsQuery(FipsQuery): + # super().__init__( + # fips, + # outcome_var, + # feature_groups_with_weights, + # lag, + # top, + # time_decay, + # outcome_comparison_period, + # outcome_percentile_range, + # ) + def __init__( + self, + fips, + outcome_var=None, + feature_groups_with_weights=None, + lag=0, + top=5, + time_decay=1.08, + outcome_comparison_period=None, + outcome_percentile_range=None, + ): + # self.data = MSADataGrabber() + # self.all_available_features = list_available_features(level="msa") + # self.gdp_var = "gdp_ma" + # print("MSAFipsQuery __init__ data:", self.data) + + if feature_groups_with_weights is None and outcome_var: + feature_groups_with_weights = {outcome_var: 4} + + if outcome_var: + outcome_var_dict = { + outcome_var: feature_groups_with_weights.pop(outcome_var) + } + outcome_var_dict.update(feature_groups_with_weights) + feature_groups_with_weights = outcome_var_dict + + assert not ( + lag > 0 and outcome_var is None + ), "Lag will be idle with no outcome variable" + + assert not ( + lag > 0 and outcome_comparison_period is not None + ), "outcome_comparison_period is only used when lag = 0" + + assert not ( + outcome_var is None and outcome_comparison_period is not None + ), "outcome_comparison_period requires an outcome variable" + + assert not ( + outcome_var is None and outcome_percentile_range is not None + ), "outcome_percentile_range requires an outcome variable" + + self.all_available_features = list_available_features("msa") + + feature_groups = list(feature_groups_with_weights.keys()) + + assert feature_groups, "You need to specify at least one feature group" + + assert all( + isinstance(value, int) and -4 <= value <= 4 + for value in feature_groups_with_weights.values() + ), "Feature weights need to be integers between -4 and 4" + + self.feature_groups_with_weights = feature_groups_with_weights + self.feature_groups = feature_groups + self.data = MSADataGrabber() + self.repo_root = self.data.repo_root + self.fips = fips + self.lag = lag + self.top = top + self.gdp_var = "gdp_ma" + + # it's fine if they're None (by default) + self.outcome_var = outcome_var + self.outcome_comparison_period = outcome_comparison_period + + self.time_decay = time_decay + + if self.gdp_var not in self.feature_groups: + self.all_features = [self.gdp_var] + feature_groups + else: + self.all_features = feature_groups + + self.data.get_features_std_wide(self.all_features) + self.data.get_features_wide(self.all_features) + + assert ( + fips in self.data.std_wide[self.gdp_var]["GeoFIPS"].values + ), "FIPS not found in the data set." + self.name = self.data.std_wide[self.gdp_var]["GeoName"][ + self.data.std_wide[self.gdp_var]["GeoFIPS"] == self.fips + ].values[0] + + assert ( + self.lag >= 0 and self.lag < 6 and isinstance(self.lag, int) + ), "lag must be an iteger between 0 and 5" + assert ( + self.top > 0 + and isinstance(self.top, int) + and self.top + < 100 # TODO Make sure the number makes sense once we add all datasets we need + ), "top must be a positive integer smaller than the number of locations in the dataset" + + if outcome_var: + assert check_if_tensed( + self.data.std_wide[self.outcome_var] + ), "Outcome needs to be a time series." + + self.outcome_with_percentiles = self.data.std_wide[self.outcome_var].copy() + most_recent_outcome = self.data.wide[self.outcome_var].iloc[:, -1].values + self.outcome_with_percentiles["percentile"] = ( + most_recent_outcome < most_recent_outcome[:, np.newaxis] + ).sum(axis=1) / most_recent_outcome.shape[0] + self.outcome_with_percentiles["percentile"] = round( + self.outcome_with_percentiles["percentile"] * 100, 2 + ) + self.outcome_percentile_range = outcome_percentile_range diff --git a/build/cities/utils/__init__.py b/build/cities/utils/__init__.py new file mode 100644 index 00000000..f19c781f --- /dev/null +++ b/build/cities/utils/__init__.py @@ -0,0 +1,2 @@ +# from .cleaning_utils import find_repo_root +# from .data_grabber import DataGrabber diff --git a/build/cities/utils/clean_gdp.py b/build/cities/utils/clean_gdp.py new file mode 100644 index 00000000..543d35c6 --- /dev/null +++ b/build/cities/utils/clean_gdp.py @@ -0,0 +1,80 @@ +import numpy as np +import pandas as pd + +from cities.utils.cleaning_utils import standardize_and_scale +from cities.utils.data_grabber import find_repo_root + +root = find_repo_root() + + +def clean_gdp(): + gdp = pd.read_csv(f"{root}/data/raw/CAGDP1_2001_2021.csv", encoding="ISO-8859-1") + + gdp = gdp.loc[:9533] # drop notes at the bottom + + gdp["GeoFIPS"] = gdp["GeoFIPS"].fillna("").astype(str) + gdp["GeoFIPS"] = gdp["GeoFIPS"].str.strip(' "').astype(int) + + # remove large regions + gdp = gdp[gdp["GeoFIPS"] % 1000 != 0] + + # focus on chain-type GDP + mask = gdp["Description"].str.startswith("Chain") + gdp = gdp[mask] + + # drop Region number, Tablename, LineCode, IndustryClassification columns (the last one is empty anyway) + gdp = gdp.drop(gdp.columns[2:8], axis=1) + + # 2012 makes no sense, it's 100 throughout + gdp = gdp.drop("2012", axis=1) + + gdp.replace("(NA)", np.nan, inplace=True) + gdp.replace("(NM)", np.nan, inplace=True) + + # nan_rows = gdp[gdp.isna().any(axis=1)] # if inspection is needed + + gdp.dropna(axis=0, inplace=True) + + for column in gdp.columns[2:]: + gdp[column] = gdp[column].astype(float) + + assert gdp["GeoName"].is_unique + + # subsetting GeoFIPS to values in exclusions.csv + + exclusions_df = pd.read_csv(f"{root}/data/raw/exclusions.csv") + gdp = gdp[~gdp["GeoFIPS"].isin(exclusions_df["exclusions"])] + + assert len(gdp) == len(gdp["GeoFIPS"].unique()) + assert len(gdp) > 2800, "The number of records is lower than 2800" + + patState = r", [A-Z]{2}(\*{1,2})?$" + GeoNameError = "Wrong Geoname value!" + assert gdp["GeoName"].str.contains(patState, regex=True).all(), GeoNameError + assert sum(gdp["GeoName"].str.count(", ")) == gdp.shape[0], GeoNameError + + for column in gdp.columns[2:]: + assert (gdp[column] > 0).all(), f"Negative values in {column}" + assert gdp[column].isna().sum() == 0, f"Missing values in {column}" + assert gdp[column].isnull().sum() == 0, f"Null values in {column}" + assert (gdp[column] < 3000).all(), f"Values suspiciously large in {column}" + + # TODO_Nikodem investigate strange large values + + gdp_wide = gdp.copy() + gdp_long = pd.melt( + gdp.copy(), id_vars=["GeoFIPS", "GeoName"], var_name="Year", value_name="Value" + ) + + gdp_std_wide = standardize_and_scale(gdp) + gdp_std_long = pd.melt( + gdp_std_wide.copy(), + id_vars=["GeoFIPS", "GeoName"], + var_name="Year", + value_name="Value", + ) + + gdp_wide.to_csv(f"{root}/data/processed/gdp_wide.csv", index=False) + gdp_long.to_csv(f"{root}/data/processed/gdp_long.csv", index=False) + gdp_std_wide.to_csv(f"{root}/data/processed/gdp_std_wide.csv", index=False) + gdp_std_long.to_csv(f"{root}/data/processed/gdp_std_long.csv", index=False) diff --git a/build/cities/utils/clean_variable.py b/build/cities/utils/clean_variable.py new file mode 100644 index 00000000..75d63b59 --- /dev/null +++ b/build/cities/utils/clean_variable.py @@ -0,0 +1,208 @@ +import numpy as np +import pandas as pd + +from cities.utils.clean_gdp import clean_gdp +from cities.utils.cleaning_utils import standardize_and_scale +from cities.utils.data_grabber import DataGrabber, find_repo_root + + +class VariableCleaner: + def __init__( + self, + variable_name: str, + path_to_raw_csv: str, + year_or_category: str = "Year", # Year or Category + ): + self.variable_name = variable_name + self.path_to_raw_csv = path_to_raw_csv + self.year_or_category = year_or_category + self.root = find_repo_root() + self.data_grabber = DataGrabber() + self.folder = "processed" + self.gdp = None + self.variable_df = None + + def clean_variable(self): + self.load_raw_csv() + self.drop_nans() + self.load_gdp_data() + self.check_exclusions() + self.restrict_common_fips() + self.save_csv_files(self.folder) + + def load_raw_csv(self): + self.variable_df = pd.read_csv(self.path_to_raw_csv) + self.variable_df["GeoFIPS"] = self.variable_df["GeoFIPS"].astype(int) + + def drop_nans(self): + self.variable_df = self.variable_df.dropna() + + def load_gdp_data(self): + self.data_grabber.get_features_wide(["gdp"]) + self.gdp = self.data_grabber.wide["gdp"] + + def add_new_exclusions(self, common_fips): + new_exclusions = np.setdiff1d( + self.gdp["GeoFIPS"].unique(), self.variable_df["GeoFIPS"].unique() + ) + print("Adding new exclusions to exclusions.csv: " + str(new_exclusions)) + exclusions = pd.read_csv((f"{self.root}/data/raw/exclusions.csv")) + new_rows = pd.DataFrame( + { + "dataset": [self.variable_name] * len(new_exclusions), + "exclusions": new_exclusions, + } + ) + exclusions = pd.concat([exclusions, new_rows], ignore_index=True) + exclusions = exclusions.drop_duplicates() + exclusions = exclusions.sort_values(by=["dataset", "exclusions"]).reset_index( + drop=True + ) + exclusions.to_csv((f"{self.root}/data/raw/exclusions.csv"), index=False) + print("Rerunning gdp cleaning with new exclusions") + + def check_exclusions(self): + common_fips = np.intersect1d( + self.gdp["GeoFIPS"].unique(), self.variable_df["GeoFIPS"].unique() + ) + if ( + len( + np.setdiff1d( + self.gdp["GeoFIPS"].unique(), self.variable_df["GeoFIPS"].unique() + ) + ) + > 0 + ): + self.add_new_exclusions(common_fips) + clean_gdp() + self.clean_variable() + + def restrict_common_fips(self): + common_fips = np.intersect1d( + self.gdp["GeoFIPS"].unique(), self.variable_df["GeoFIPS"].unique() + ) + self.variable_df = self.variable_df[ + self.variable_df["GeoFIPS"].isin(common_fips) + ] + self.variable_df = self.variable_df.merge( + self.gdp[["GeoFIPS", "GeoName"]], on=["GeoFIPS", "GeoName"], how="left" + ) + self.variable_df = self.variable_df.sort_values(by=["GeoFIPS", "GeoName"]) + for column in self.variable_df.columns: + if column not in ["GeoFIPS", "GeoName"]: + self.variable_df[column] = self.variable_df[column].astype(float) + + def save_csv_files(self, folder): + # it would be great to make sure that a db is wide, if not make it wide + variable_db_wide = self.variable_df.copy() + variable_db_long = pd.melt( + self.variable_df, + id_vars=["GeoFIPS", "GeoName"], + var_name=self.year_or_category, + value_name="Value", + ) + variable_db_std_wide = standardize_and_scale(self.variable_df) + variable_db_std_long = pd.melt( + variable_db_std_wide.copy(), + id_vars=["GeoFIPS", "GeoName"], + var_name=self.year_or_category, + value_name="Value", + ) + + variable_db_wide.to_csv( + (f"{self.root}/data/{folder}/" + self.variable_name + "_wide.csv"), + index=False, + ) + variable_db_long.to_csv( + (f"{self.root}/data/{folder}/" + self.variable_name + "_long.csv"), + index=False, + ) + variable_db_std_wide.to_csv( + (f"{self.root}/data/{folder}/" + self.variable_name + "_std_wide.csv"), + index=False, + ) + variable_db_std_long.to_csv( + (f"{self.root}/data/{folder}/" + self.variable_name + "_std_long.csv"), + index=False, + ) + + +class VariableCleanerMSA( + VariableCleaner +): # this class inherits functionalites of VariableCleaner, but works at the MSA level + def __init__( + self, variable_name: str, path_to_raw_csv: str, year_or_category: str = "Year" + ): + super().__init__(variable_name, path_to_raw_csv, year_or_category) + self.folder = "MSA_level" + self.metro_areas = None + + def clean_variable(self): + self.load_raw_csv() + self.drop_nans() + self.process_data() + # TODO self.check_exclusions('MA') functionality needs to be implemented in the future + # TODO but only if data missigness turns out to be a serious problem + # for now, process_data runs a check and reports missingness + # but we need to be more careful about MSA missingnes handling + # as there are much fewer MSAs than counties + self.save_csv_files(self.folder) + + def load_metro_areas(self): + self.metro_areas = pd.read_csv(f"{self.root}/data/raw/metrolist.csv") + + def process_data(self): + self.load_metro_areas() + assert ( + self.metro_areas["GeoFIPS"].nunique() + == self.variable_df["GeoFIPS"].nunique() + ) + assert ( + self.metro_areas["GeoName"].nunique() + == self.variable_df["GeoName"].nunique() + ) + self.variable_df["GeoFIPS"] = self.variable_df["GeoFIPS"].astype(np.int64) + + +def weighted_mean(group, column): + values = group[column] + weights = group["Total population"] + + not_nan_indices = ~np.isnan(values) + + if np.any(not_nan_indices) and np.sum(weights[not_nan_indices]) != 0: + weighted_values = values[not_nan_indices] * weights[not_nan_indices] + return np.sum(weighted_values) / np.sum(weights[not_nan_indices]) + else: + return np.nan + + +def communities_tracts_to_counties( + data, list_variables +) -> pd.DataFrame: # using the weighted mean function for total population + all_results = pd.DataFrame() + + for variable in list_variables: + weighted_avg = ( + data.groupby("GeoFIPS").apply(weighted_mean, column=variable).reset_index() + ) + weighted_avg.columns = ["GeoFIPS", variable] + + nan_counties = ( + data.groupby("GeoFIPS") + .apply(lambda x: all(np.isnan(x[variable]))) + .reset_index() + ) + nan_counties.columns = ["GeoFIPS", "all_nan"] + + result_df = pd.merge(weighted_avg, nan_counties, on="GeoFIPS") + result_df.loc[result_df["all_nan"], variable] = np.nan + + result_df = result_df.drop(columns=["all_nan"]) + + if "GeoFIPS" not in all_results.columns: + all_results = result_df.copy() + else: + all_results = pd.merge(all_results, result_df, on="GeoFIPS", how="left") + + return all_results diff --git a/build/cities/utils/cleaning_scripts/clean_age_composition.py b/build/cities/utils/cleaning_scripts/clean_age_composition.py new file mode 100644 index 00000000..acb63d07 --- /dev/null +++ b/build/cities/utils/cleaning_scripts/clean_age_composition.py @@ -0,0 +1,30 @@ +import pandas as pd + +from cities.utils.clean_variable import VariableCleaner +from cities.utils.data_grabber import DataGrabber, find_repo_root + +root = find_repo_root() + +data = DataGrabber() +data.get_features_wide(["gdp"]) +gdp = data.wide["gdp"] + + +def clean_age_first(): + age = pd.read_csv(f"{root}/data/raw/age.csv") + + age.iloc[:, 2:] = age.iloc[:, 2:].div(age["total_pop"], axis=0) * 100 + age.drop("total_pop", axis=1, inplace=True) + + age.to_csv(f"{root}/data/raw/age_percentages.csv", index=False) + + +def clean_age_composition(): + clean_age_first() + + cleaner = VariableCleaner( + variable_name="age_composition", + path_to_raw_csv=f"{root}/data/raw/age_percentages.csv", + year_or_category="Category", + ) + cleaner.clean_variable() diff --git a/build/cities/utils/cleaning_scripts/clean_burdens.py b/build/cities/utils/cleaning_scripts/clean_burdens.py new file mode 100644 index 00000000..cb2be9ad --- /dev/null +++ b/build/cities/utils/cleaning_scripts/clean_burdens.py @@ -0,0 +1,57 @@ +import numpy as np +import pandas as pd + +from cities.utils.clean_variable import VariableCleaner, communities_tracts_to_counties +from cities.utils.data_grabber import DataGrabber, find_repo_root + +root = find_repo_root() + +data = DataGrabber() +data.get_features_wide(["gdp"]) +gdp = data.wide["gdp"] + + +def clean_burdens_first(): + burdens = pd.read_csv(f"{root}/data/raw/communities_raw.csv") + + list_variables = ["Housing burden (percent)", "Energy burden"] + burdens = communities_tracts_to_counties(burdens, list_variables) + + burdens["GeoFIPS"] = burdens["GeoFIPS"].astype(np.int64) + + common_fips = np.intersect1d(burdens["GeoFIPS"].unique(), gdp["GeoFIPS"].unique()) + burdens = burdens[burdens["GeoFIPS"].isin(common_fips)] + burdens = burdens.merge(gdp[["GeoFIPS", "GeoName"]], on="GeoFIPS", how="left") + + burdens = burdens[ + ["GeoFIPS", "GeoName", "Housing burden (percent)", "Energy burden"] + ] + + burdens.columns = ["GeoFIPS", "GeoName", "burdens_housing", "burdens_energy"] + + columns_to_trans = burdens.columns[-2:] + burdens[columns_to_trans] = burdens[columns_to_trans].astype("float64") + + burdens_housing = burdens[["GeoFIPS", "GeoName", "burdens_housing"]] + burdens_energy = burdens[["GeoFIPS", "GeoName", "burdens_energy"]] + + burdens_housing.to_csv(f"{root}/data/raw/burdens_housing_raw.csv", index=False) + burdens_energy.to_csv(f"{root}/data/raw/burdens_energy_raw.csv", index=False) + + +def clean_burdens(): + clean_burdens_first() + + cleaner_housing = VariableCleaner( + variable_name="burdens_housing", + path_to_raw_csv=f"{root}/data/raw/burdens_housing_raw.csv", + year_or_category="Category", + ) + cleaner_housing.clean_variable() + + cleaner_energy = VariableCleaner( + variable_name="burdens_energy", + path_to_raw_csv=f"{root}/data/raw/burdens_energy_raw.csv", + year_or_category="Category", + ) + cleaner_energy.clean_variable() diff --git a/build/cities/utils/cleaning_scripts/clean_ethnic_composition.py b/build/cities/utils/cleaning_scripts/clean_ethnic_composition.py new file mode 100644 index 00000000..b18ef031 --- /dev/null +++ b/build/cities/utils/cleaning_scripts/clean_ethnic_composition.py @@ -0,0 +1,138 @@ +import numpy as np +import pandas as pd + +from cities.utils.cleaning_utils import standardize_and_scale +from cities.utils.data_grabber import DataGrabber, find_repo_root + +root = find_repo_root() + + +def clean_ethnic_composition(): + data = DataGrabber() + data.get_features_wide(["gdp"]) + gdp = data.wide["gdp"] + + ethnic_composition = pd.read_csv(f"{root}/data/raw/ACSDP5Y2021_DP05_Race.csv") + + ethnic_composition = ethnic_composition.iloc[1:] + ethnic_composition["GEO_ID"].isna() == 0 + + ethnic_composition["GEO_ID"] = ethnic_composition["GEO_ID"].str.split("US").str[1] + ethnic_composition["GEO_ID"] = ethnic_composition["GEO_ID"].astype("int64") + ethnic_composition = ethnic_composition.rename(columns={"GEO_ID": "GeoFIPS"}) + + ethnic_composition = ethnic_composition[ + ["GeoFIPS"] + [col for col in ethnic_composition.columns if col.endswith("E")] + ] + ethnic_composition = ethnic_composition.drop(columns=["NAME"]) + + common_fips = np.intersect1d( + gdp["GeoFIPS"].unique(), ethnic_composition["GeoFIPS"].unique() + ) + len(common_fips) + + ethnic_composition = ethnic_composition[ + ethnic_composition["GeoFIPS"].isin(common_fips) + ] + + ethnic_composition = ethnic_composition.merge( + gdp[["GeoFIPS", "GeoName"]], on="GeoFIPS", how="left" + ) + + ethnic_composition = ethnic_composition[ + [ + "GeoFIPS", + "GeoName", + "DP05_0070E", + "DP05_0072E", + "DP05_0073E", + "DP05_0074E", + "DP05_0075E", + "DP05_0077E", + "DP05_0078E", + "DP05_0079E", + "DP05_0080E", + "DP05_0081E", + "DP05_0082E", + "DP05_0083E", + ] + ] + + ethnic_composition.columns = [ + "GeoFIPS", + "GeoName", + "total_pop", + "mexican", + "puerto_rican", + "cuban", + "other_hispanic_latino", + "white", + "black_african_american", + "american_indian_alaska_native", + "asian", + "native_hawaiian_other_pacific_islander", + "other_race", + "two_or_more_sum", + ] + ethnic_composition = ethnic_composition.sort_values(by=["GeoFIPS", "GeoName"]) + + ethnic_composition.iloc[:, 2:] = ethnic_composition.iloc[:, 2:].apply( + pd.to_numeric, errors="coerce" + ) + ethnic_composition[ethnic_composition.columns[2:]] = ethnic_composition[ + ethnic_composition.columns[2:] + ].astype(float) + + ethnic_composition["other_race_races"] = ( + ethnic_composition["other_race"] + ethnic_composition["two_or_more_sum"] + ) + ethnic_composition = ethnic_composition.drop( + ["other_race", "two_or_more_sum"], axis=1 + ) + + ethnic_composition["totalALT"] = ethnic_composition.iloc[:, 3:].sum(axis=1) + assert (ethnic_composition["totalALT"] == ethnic_composition["total_pop"]).all() + ethnic_composition = ethnic_composition.drop("totalALT", axis=1) + + # copy with nominal values + ethnic_composition.to_csv( + f"{root}/data/raw/ethnic_composition_nominal.csv", index=False + ) + + row_sums = ethnic_composition.iloc[:, 2:].sum(axis=1) + ethnic_composition.iloc[:, 3:] = ethnic_composition.iloc[:, 3:].div( + row_sums, axis=0 + ) + + ethnic_composition = ethnic_composition.drop(["total_pop"], axis=1) + + ethnic_composition_wide = ethnic_composition.copy() + + ethnic_composition_long = pd.melt( + ethnic_composition, + id_vars=["GeoFIPS", "GeoName"], + var_name="Category", + value_name="Value", + ) + + ethnic_composition_std_wide = standardize_and_scale(ethnic_composition) + + ethnic_composition_std_long = pd.melt( + ethnic_composition_std_wide.copy(), + id_vars=["GeoFIPS", "GeoName"], + var_name="Category", + value_name="Value", + ) + + ethnic_composition_wide.to_csv( + f"{root}/data/processed/ethnic_composition_wide.csv", index=False + ) + ethnic_composition_long.to_csv( + f"{root}/data/processed/ethnic_composition_long.csv", index=False + ) + ethnic_composition_std_wide.to_csv( + f"{root}/data/processed/ethnic_composition_std_wide.csv", index=False + ) + ethnic_composition_std_long.to_csv( + f"{root}/data/processed/ethnic_composition_std_long.csv", index=False + ) diff --git a/build/cities/utils/cleaning_scripts/clean_ethnic_composition_ma.py b/build/cities/utils/cleaning_scripts/clean_ethnic_composition_ma.py new file mode 100644 index 00000000..acc69717 --- /dev/null +++ b/build/cities/utils/cleaning_scripts/clean_ethnic_composition_ma.py @@ -0,0 +1,75 @@ +import numpy as np +import pandas as pd + +from cities.utils.clean_variable import VariableCleanerMSA +from cities.utils.data_grabber import find_repo_root + +root = find_repo_root() + + +def clean_ethnic_initially(): + ethnic_composition = pd.read_csv(f"{root}/data/raw/ethnic_composition_cbsa.csv") + metro_areas = pd.read_csv(f"{root}/data/raw/metrolist.csv") + + ethnic_composition["CBSA"] = ethnic_composition["CBSA"].astype(np.int64) + ethnic_composition = ethnic_composition[ + ethnic_composition["CBSA"].isin(metro_areas["GeoFIPS"]) + ] + + ethnic_composition = pd.merge( + ethnic_composition, + metro_areas[["GeoFIPS", "GeoName"]], + left_on="CBSA", + right_on="GeoFIPS", + how="inner", + ) + ethnic_composition = ethnic_composition.drop_duplicates(subset=["CBSA"]) + + ethnic_composition.drop(columns="CBSA", inplace=True) + + cols_to_save = ethnic_composition.shape[1] - 2 + ethnic_composition_ma = ethnic_composition[ + ["GeoFIPS", "GeoName"] + list(ethnic_composition.columns[0:cols_to_save]) + ] + + ethnic_composition_ma.iloc[:, 2:] = ethnic_composition_ma.iloc[:, 2:].apply( + pd.to_numeric, errors="coerce" + ) + ethnic_composition_ma[ethnic_composition_ma.columns[2:]] = ethnic_composition_ma[ + ethnic_composition_ma.columns[2:] + ].astype(float) + + ethnic_composition_ma["other_race_races"] = ( + ethnic_composition_ma["other_race"] + ethnic_composition_ma["two_or_more_sum"] + ) + ethnic_composition_ma = ethnic_composition_ma.drop( + ["other_race", "two_or_more_sum"], axis=1 + ) + + ethnic_composition_ma["totalALT"] = ethnic_composition_ma.iloc[:, 3:].sum(axis=1) + assert ( + ethnic_composition_ma["totalALT"] == ethnic_composition_ma["total_pop"] + ).all() + ethnic_composition_ma = ethnic_composition_ma.drop("totalALT", axis=1) + + row_sums = ethnic_composition_ma.iloc[:, 2:].sum(axis=1) + ethnic_composition_ma.iloc[:, 3:] = ethnic_composition_ma.iloc[:, 3:].div( + row_sums, axis=0 + ) + + ethnic_composition_ma = ethnic_composition_ma.drop(["total_pop"], axis=1) + + ethnic_composition_ma.to_csv( + f"{root}/data/raw/ethnic_composition_ma.csv", index=False + ) + + +def clean_ethnic_composition_ma(): + clean_ethnic_initially() + + cleaner = VariableCleanerMSA( + variable_name="ethnic_composition_ma", + path_to_raw_csv=f"{root}/data/raw/ethnic_composition_ma.csv", + year_or_category="Category", + ) + cleaner.clean_variable() diff --git a/build/cities/utils/cleaning_scripts/clean_gdp_ma.py b/build/cities/utils/cleaning_scripts/clean_gdp_ma.py new file mode 100644 index 00000000..f14b6712 --- /dev/null +++ b/build/cities/utils/cleaning_scripts/clean_gdp_ma.py @@ -0,0 +1,11 @@ +from cities.utils.clean_variable import VariableCleanerMSA +from cities.utils.data_grabber import find_repo_root + +root = find_repo_root() + + +def clean_gdp_ma(): + cleaner = VariableCleanerMSA( + variable_name="gdp_ma", path_to_raw_csv=f"{root}/data/raw/gdp_ma.csv" + ) + cleaner.clean_variable() diff --git a/build/cities/utils/cleaning_scripts/clean_hazard.py b/build/cities/utils/cleaning_scripts/clean_hazard.py new file mode 100644 index 00000000..8efbb4cb --- /dev/null +++ b/build/cities/utils/cleaning_scripts/clean_hazard.py @@ -0,0 +1,87 @@ +import numpy as np +import pandas as pd + +from cities.utils.clean_variable import VariableCleaner, communities_tracts_to_counties +from cities.utils.data_grabber import DataGrabber, find_repo_root + +root = find_repo_root() + +data = DataGrabber() +data.get_features_wide(["gdp"]) +gdp = data.wide["gdp"] + + +variables_hazard = [ + "expected_agricultural_loss_rate", + "expected_building_loss_rate", + "expected_population_loss_rate", + "diesel_matter_exposure", + "proximity_to_hazardous_waste_sites", + "proximity_to_risk_management_plan_facilities", +] + + +def clean_hazard_first(): + hazard = pd.read_csv(f"{root}/data/raw/communities_raw.csv") + + list_variables = [ + "Expected agricultural loss rate (Natural Hazards Risk Index)", + "Expected building loss rate (Natural Hazards Risk Index)", + "Expected population loss rate (Natural Hazards Risk Index)", + "Diesel particulate matter exposure", + "Proximity to hazardous waste sites", + "Proximity to Risk Management Plan (RMP) facilities", + ] + + hazard = communities_tracts_to_counties(hazard, list_variables) + + hazard.dropna(inplace=True) + + hazard["GeoFIPS"] = hazard["GeoFIPS"].astype(np.int64) + + common_fips = np.intersect1d(hazard["GeoFIPS"].unique(), gdp["GeoFIPS"].unique()) + hazard = hazard[hazard["GeoFIPS"].isin(common_fips)] + hazard = hazard.merge(gdp[["GeoFIPS", "GeoName"]], on="GeoFIPS", how="left") + + hazard = hazard[ + [ + "GeoFIPS", + "GeoName", + "Expected agricultural loss rate (Natural Hazards Risk Index)", + "Expected building loss rate (Natural Hazards Risk Index)", + "Expected population loss rate (Natural Hazards Risk Index)", + "Diesel particulate matter exposure", + "Proximity to hazardous waste sites", + "Proximity to Risk Management Plan (RMP) facilities", + ] + ] + + hazard.columns = [ + "GeoFIPS", + "GeoName", + "expected_agricultural_loss_rate", + "expected_building_loss_rate", + "expected_population_loss_rate", + "diesel_matter_exposure", + "proximity_to_hazardous_waste_sites", + "proximity_to_risk_management_plan_facilities", + ] + + columns_to_trans = hazard.columns[-6:] + hazard[columns_to_trans] = hazard[columns_to_trans].astype("float64") + + for variable in variables_hazard: + hazard_variable = hazard[["GeoFIPS", "GeoName", variable]] + hazard_variable.to_csv(f"{root}/data/raw/{variable}.csv", index=False) + + +def clean_hazard(): + clean_hazard_first() + + for variable in variables_hazard: + cleaner = VariableCleaner( + variable_name=variable, + path_to_raw_csv=f"{root}/data/raw/{variable}.csv", + year_or_category="Category", + ) + cleaner.clean_variable() diff --git a/build/cities/utils/cleaning_scripts/clean_health.py b/build/cities/utils/cleaning_scripts/clean_health.py new file mode 100644 index 00000000..7b7def54 --- /dev/null +++ b/build/cities/utils/cleaning_scripts/clean_health.py @@ -0,0 +1,74 @@ +import numpy as np +import pandas as pd + +from cities.utils.clean_variable import VariableCleaner, communities_tracts_to_counties +from cities.utils.data_grabber import DataGrabber, find_repo_root + +root = find_repo_root() + +data = DataGrabber() +data.get_features_wide(["gdp"]) +gdp = data.wide["gdp"] + + +def clean_health_first(): + health = pd.read_csv(f"{root}/data/raw/communities_raw.csv") + + list_variables = [ + "Life expectancy (years)", + "Current asthma among adults aged greater than or equal to 18 years", + "Diagnosed diabetes among adults aged greater than or equal to 18 years", + "Coronary heart disease among adults aged greater than or equal to 18 years", + ] + + health = communities_tracts_to_counties(health, list_variables) + + health.dropna(inplace=True) + + health["GeoFIPS"] = health["GeoFIPS"].astype(np.int64) + + common_fips = np.intersect1d(health["GeoFIPS"].unique(), gdp["GeoFIPS"].unique()) + health = health[health["GeoFIPS"].isin(common_fips)] + health = health.merge(gdp[["GeoFIPS", "GeoName"]], on="GeoFIPS", how="left") + + health = health[ + [ + "GeoFIPS", + "GeoName", + "Life expectancy (years)", + "Current asthma among adults aged greater than or equal to 18 years", + "Diagnosed diabetes among adults aged greater than or equal to 18 years", + "Coronary heart disease among adults aged greater than or equal to 18 years", + ] + ] + + health.columns = [ + "GeoFIPS", + "GeoName", + "LifeExpectancy", + "Asthma", + "Diabetes", + "HeartDisease", + ] + + columns_to_round = health.columns[-3:] + health[columns_to_round] = health[columns_to_round].round(0).astype("float64") + health["LifeExpectancy"] = health["LifeExpectancy"].round(2).astype("float64") + + val_list = ["Asthma", "Diabetes", "HeartDisease"] + + for val in val_list: # dealing with weird format of percentages + health[val] = health[val] / 100 + + health.to_csv(f"{root}/data/raw/health_raw.csv", index=False) + + +def clean_health(): + clean_health_first() + + cleaner = VariableCleaner( + variable_name="health", + path_to_raw_csv=f"{root}/data/raw/health_raw.csv", + year_or_category="Category", + ) + cleaner.clean_variable() diff --git a/build/cities/utils/cleaning_scripts/clean_homeownership.py b/build/cities/utils/cleaning_scripts/clean_homeownership.py new file mode 100644 index 00000000..832836db --- /dev/null +++ b/build/cities/utils/cleaning_scripts/clean_homeownership.py @@ -0,0 +1,20 @@ +from cities.utils.clean_variable import VariableCleaner +from cities.utils.data_grabber import find_repo_root + +root = find_repo_root() + + +def clean_homeownership(): + variables = [ + "median_owner_occupied_home_value", + "median_rent", + "homeownership_rate", + ] + + for variable in variables: + cleaner = VariableCleaner( + variable_name=variable, + path_to_raw_csv=f"{root}/data/raw/{variable}.csv", + year_or_category="Category", + ) + cleaner.clean_variable() diff --git a/build/cities/utils/cleaning_scripts/clean_income_distribution.py b/build/cities/utils/cleaning_scripts/clean_income_distribution.py new file mode 100644 index 00000000..6525078a --- /dev/null +++ b/build/cities/utils/cleaning_scripts/clean_income_distribution.py @@ -0,0 +1,13 @@ +from cities.utils.clean_variable import VariableCleaner +from cities.utils.data_grabber import find_repo_root + +root = find_repo_root() + + +def clean_income_distribution(): + cleaner = VariableCleaner( + variable_name="income_distribution", + path_to_raw_csv=f"{root}/data/raw/income_distribution.csv", + year_or_category="Category", + ) + cleaner.clean_variable() diff --git a/build/cities/utils/cleaning_scripts/clean_industry.py b/build/cities/utils/cleaning_scripts/clean_industry.py new file mode 100644 index 00000000..41571fb2 --- /dev/null +++ b/build/cities/utils/cleaning_scripts/clean_industry.py @@ -0,0 +1,118 @@ +from pathlib import Path + +import numpy as np +import pandas as pd + +from cities.utils.clean_variable import VariableCleaner +from cities.utils.cleaning_utils import standardize_and_scale +from cities.utils.data_grabber import DataGrabber, find_repo_root + +root = find_repo_root() + +path = Path(__file__).parent.absolute() + + +def clean_industry_step_one(): + data = DataGrabber() + data.get_features_wide(["gdp"]) + gdp = data.wide["gdp"] + + industry = pd.read_csv(f"{root}/data/raw/ACSDP5Y2021_DP03_industry.csv") + + industry["GEO_ID"] = industry["GEO_ID"].str.split("US").str[1] + industry["GEO_ID"] = industry["GEO_ID"].astype("int64") + industry = industry.rename(columns={"GEO_ID": "GeoFIPS"}) + + common_fips = np.intersect1d(gdp["GeoFIPS"].unique(), industry["GeoFIPS"].unique()) + + industry = industry[industry["GeoFIPS"].isin(common_fips)] + + industry = industry.merge(gdp[["GeoFIPS", "GeoName"]], on="GeoFIPS", how="left") + + industry = industry[ + [ + "GeoFIPS", + "GeoName", + "DP03_0004E", + "DP03_0033E", + "DP03_0034E", + "DP03_0035E", + "DP03_0036E", + "DP03_0037E", + "DP03_0038E", + "DP03_0039E", + "DP03_0040E", + "DP03_0041E", + "DP03_0042E", + "DP03_0043E", + "DP03_0044E", + "DP03_0045E", + ] + ] + + column_name_mapping = { + "DP03_0004E": "employed_sum", + "DP03_0033E": "agri_forestry_mining", + "DP03_0034E": "construction", + "DP03_0035E": "manufacturing", + "DP03_0036E": "wholesale_trade", + "DP03_0037E": "retail_trade", + "DP03_0038E": "transport_utilities", + "DP03_0039E": "information", + "DP03_0040E": "finance_real_estate", + "DP03_0041E": "prof_sci_mgmt_admin", + "DP03_0042E": "education_health", + "DP03_0043E": "arts_entertainment", + "DP03_0044E": "other_services", + "DP03_0045E": "public_admin", + } + + industry.rename(columns=column_name_mapping, inplace=True) + + industry = industry.sort_values(by=["GeoFIPS", "GeoName"]) + + industry.to_csv(f"{root}/data/raw/industry_absolute.csv", index=False) + + row_sums = industry.iloc[:, 3:].sum(axis=1) + + industry.iloc[:, 3:] = industry.iloc[:, 3:].div(row_sums, axis=0) + industry = industry.drop(["employed_sum"], axis=1) + + industry.to_csv(f"{root}/data/raw/industry_percent.csv", index=False) + + industry_wide = industry.copy() + + industry_long = pd.melt( + industry, + id_vars=["GeoFIPS", "GeoName"], + var_name="Category", + value_name="Value", + ) + + industry_std_wide = standardize_and_scale(industry) + + industry_std_long = pd.melt( + industry_std_wide.copy(), + id_vars=["GeoFIPS", "GeoName"], + var_name="Category", + value_name="Value", + ) + + industry_wide.to_csv(f"{root}/data/processed/industry_wide.csv", index=False) + industry_long.to_csv(f"{root}/data/processed/industry_long.csv", index=False) + industry_std_wide.to_csv( + f"{root}/data/processed/industry_std_wide.csv", index=False + ) + industry_std_long.to_csv( + f"{root}/data/processed/industry_std_long.csv", index=False + ) + + +def clean_industry(): + clean_industry_step_one() + + cleaner = VariableCleaner( + variable_name="industry", + path_to_raw_csv=f"{root}/data/raw/industry_percent.csv", + ) + cleaner.clean_variable() diff --git a/build/cities/utils/cleaning_scripts/clean_industry_ma.py b/build/cities/utils/cleaning_scripts/clean_industry_ma.py new file mode 100644 index 00000000..f95a4c92 --- /dev/null +++ b/build/cities/utils/cleaning_scripts/clean_industry_ma.py @@ -0,0 +1,13 @@ +from cities.utils.clean_variable import VariableCleanerMSA +from cities.utils.data_grabber import find_repo_root + +root = find_repo_root() + + +def clean_industry_ma(): + cleaner = VariableCleanerMSA( + variable_name="industry_ma", + path_to_raw_csv=f"{root}/data/raw/industry_ma.csv", + year_or_category="Category", + ) + cleaner.clean_variable() diff --git a/build/cities/utils/cleaning_scripts/clean_industry_ts.py b/build/cities/utils/cleaning_scripts/clean_industry_ts.py new file mode 100644 index 00000000..b16daee7 --- /dev/null +++ b/build/cities/utils/cleaning_scripts/clean_industry_ts.py @@ -0,0 +1,124 @@ +import numpy as np +import pandas as pd + +from cities.utils.cleaning_utils import standardize_and_scale +from cities.utils.data_grabber import DataGrabber, find_repo_root + +root = find_repo_root() + + +def clean_industry_ts(): + data = DataGrabber() + data.get_features_wide(["gdp"]) + gdp = data.wide["gdp"] + + industry_ts = pd.read_csv(f"{root}/data/raw/industry_time_series_people.csv") + + industry_ts["GEO_ID"] = industry_ts["GEO_ID"].str.split("US").str[1] + industry_ts["GEO_ID"] = industry_ts["GEO_ID"].astype("int64") + industry_ts = industry_ts.rename(columns={"GEO_ID": "GeoFIPS"}) + + common_fips = np.intersect1d( + gdp["GeoFIPS"].unique(), industry_ts["GeoFIPS"].unique() + ) + + industry_ts = industry_ts[industry_ts["GeoFIPS"].isin(common_fips)] + + years = industry_ts["Year"].unique() + + for year in years: + year_df = industry_ts[industry_ts["Year"] == year] + missing_fips = set(common_fips) - set(year_df["GeoFIPS"]) + + if missing_fips: + missing_data = { + "Year": [year] * len(missing_fips), + "GeoFIPS": list(missing_fips), + } + + # Fill all columns from the fourth column (index 3) onward with 0 + for col in industry_ts.columns[2:]: + missing_data[col] = 0 + + missing_df = pd.DataFrame(missing_data) + industry_ts = pd.concat([industry_ts, missing_df], ignore_index=True) + + industry_ts = industry_ts.merge( + gdp[["GeoFIPS", "GeoName"]], on="GeoFIPS", how="left" + ) + + industry_ts = industry_ts[ + [ + "GeoFIPS", + "GeoName", + "Year", + "agriculture_total", + "mining_total", + "construction_total", + "manufacturing_total", + "wholesale_trade_total", + "retail_trade_total", + "transportation_warehousing_total", + "utilities_total", + "information_total", + "finance_insurance_total", + "real_estate_total", + "professional_services_total", + "management_enterprises_total", + "admin_support_services_total", + "educational_services_total", + "healthcare_social_services_total", + "arts_recreation_total", + "accommodation_food_services_total", + "other_services_total", + "public_administration_total", + ] + ] + + industry_ts = industry_ts.sort_values(by=["GeoFIPS", "GeoName", "Year"]) + + industry_ts.fillna(0, inplace=True) + + columns_to_save = industry_ts.columns[industry_ts.columns.get_loc("Year") + 1 :] + + for column in columns_to_save: + selected_columns = ["GeoFIPS", "GeoName", "Year", column] + subsetindustry_ts = industry_ts[selected_columns] + + subsetindustry_ts.rename(columns={column: "Value"}, inplace=True) + + subsetindustry_ts_long = subsetindustry_ts.copy() + + file_name_long = f"industry_{column}_long.csv" + subsetindustry_ts_long.to_csv( + f"{root}/data/processed/{file_name_long}", index=False + ) + + subsetindustry_ts_std_long = standardize_and_scale(subsetindustry_ts) + + file_name_std = f"industry_{column}_std_long.csv" + subsetindustry_ts_std_long.to_csv( + f"{root}/data/processed/{file_name_std}", index=False + ) + + subsetindustry_ts_wide = subsetindustry_ts.pivot_table( + index=["GeoFIPS", "GeoName"], columns="Year", values="Value" + ) + subsetindustry_ts_wide.reset_index(inplace=True) + subsetindustry_ts_wide.columns.name = None + + file_name_wide = f"industry_{column}_wide.csv" + subsetindustry_ts_wide.to_csv( + f"{root}/data/processed/{file_name_wide}", index=False + ) + + subsetindustry_ts_std_wide = subsetindustry_ts_std_long.pivot_table( + index=["GeoFIPS", "GeoName"], columns="Year", values="Value" + ) + subsetindustry_ts_std_wide.reset_index(inplace=True) + subsetindustry_ts_std_wide.columns.name = None + + file_name_std_wide = f"industry_{column}_std_wide.csv" + subsetindustry_ts_std_wide.to_csv( + f"{root}/data/processed/{file_name_std_wide}", index=False + ) diff --git a/build/cities/utils/cleaning_scripts/clean_population.py b/build/cities/utils/cleaning_scripts/clean_population.py new file mode 100644 index 00000000..3c4d0ead --- /dev/null +++ b/build/cities/utils/cleaning_scripts/clean_population.py @@ -0,0 +1,84 @@ +import numpy as np +import pandas as pd + +from cities.utils.cleaning_utils import standardize_and_scale +from cities.utils.data_grabber import DataGrabber, find_repo_root + +root = find_repo_root() + + +def clean_population(): + data = DataGrabber() + data.get_features_wide(["gdp"]) + gdp = data.wide["gdp"] + + cainc30 = pd.read_csv( + f"{root}/data/raw/CAINC30_1969_2021.csv", encoding="ISO-8859-1" + ) + + population = cainc30[cainc30["Description"] == " Population (persons) 3/"].copy() + + population["GeoFIPS"] = population["GeoFIPS"].fillna("").astype(str) + population["GeoFIPS"] = population["GeoFIPS"].str.strip(' "').astype(int) + + population = population[population["GeoFIPS"] % 1000 != 0] + + common_fips = np.intersect1d( + population["GeoFIPS"].unique(), gdp["GeoFIPS"].unique() + ) + assert len(common_fips) == len(gdp["GeoFIPS"].unique()) + + population = population[population["GeoFIPS"].isin(common_fips)] + assert population.shape[0] == gdp.shape[0] + + order = gdp["GeoFIPS"].tolist() + population = population.set_index("GeoFIPS").reindex(order).reset_index() + + # align with gdp + assert population["GeoFIPS"].tolist() == gdp["GeoFIPS"].tolist() + assert population["GeoName"].is_unique + + population = population.drop(population.columns[2:8], axis=1) + assert population.shape[0] == gdp.shape[0] + + # 243 NAs prior to 1993 + # na_counts = (population == '(NA)').sum().sum() + # print(na_counts) + + population.replace("(NA)", np.nan, inplace=True) + population.replace("(NM)", np.nan, inplace=True) + + # removed years prior to 1993, missigness, long time ago + population = population.drop(population.columns[2:26], axis=1) + + assert population.isna().sum().sum() == 0 + assert population.shape[0] == gdp.shape[0] + + for column in population.columns[2:]: + population[column] = population[column].astype(float) + + assert population.shape[0] == gdp.shape[0] + + population_long = pd.melt( + population.copy(), + id_vars=["GeoFIPS", "GeoName"], + var_name="Year", + value_name="Value", + ) + + population_std_wide = standardize_and_scale(population) + population_std_long = pd.melt( + population_std_wide.copy(), + id_vars=["GeoFIPS", "GeoName"], + var_name="Year", + value_name="Value", + ) + + population.to_csv(f"{root}/data/processed/population_wide.csv", index=False) + population_long.to_csv(f"{root}/data/processed/population_long.csv", index=False) + population_std_wide.to_csv( + f"{root}/data/processed/population_std_wide.csv", index=False + ) + population_std_long.to_csv( + f"{root}/data/processed/population_std_long.csv", index=False + ) diff --git a/build/cities/utils/cleaning_scripts/clean_population_density.py b/build/cities/utils/cleaning_scripts/clean_population_density.py new file mode 100644 index 00000000..ce429f8a --- /dev/null +++ b/build/cities/utils/cleaning_scripts/clean_population_density.py @@ -0,0 +1,12 @@ +from cities.utils.clean_variable import VariableCleaner +from cities.utils.data_grabber import find_repo_root + +root = find_repo_root() + + +def clean_population_density(): + cleaner = VariableCleaner( + variable_name="population_density", + path_to_raw_csv=f"{root}/data/raw/population_density.csv", + ) + cleaner.clean_variable() diff --git a/build/cities/utils/cleaning_scripts/clean_population_ma.py b/build/cities/utils/cleaning_scripts/clean_population_ma.py new file mode 100644 index 00000000..21d9ee3c --- /dev/null +++ b/build/cities/utils/cleaning_scripts/clean_population_ma.py @@ -0,0 +1,13 @@ +from cities.utils.clean_variable import VariableCleanerMSA +from cities.utils.data_grabber import find_repo_root + +root = find_repo_root() + + +def clean_population_ma(): + cleaner = VariableCleanerMSA( + variable_name="population_ma", + path_to_raw_csv=f"{root}/data/raw/population_ma.csv", + year_or_category="Year", + ) + cleaner.clean_variable() diff --git a/build/cities/utils/cleaning_scripts/clean_spending_HHS.py b/build/cities/utils/cleaning_scripts/clean_spending_HHS.py new file mode 100644 index 00000000..6db55e06 --- /dev/null +++ b/build/cities/utils/cleaning_scripts/clean_spending_HHS.py @@ -0,0 +1,142 @@ +import numpy as np +import pandas as pd + +from cities.utils.cleaning_utils import standardize_and_scale +from cities.utils.data_grabber import DataGrabber, find_repo_root + +root = find_repo_root() + + +def clean_spending_HHS(): + data = DataGrabber() + data.get_features_wide(["gdp"]) + gdp = data.wide + gdp = gdp.get("gdp") + + spending_HHS = pd.read_csv(f"{root}/data/raw/spending_HHS.csv") + + transportUnwanted = spending_HHS[ + ( + pd.isna(spending_HHS["total_obligated_amount"]) + | (spending_HHS["total_obligated_amount"] == 1) + | (spending_HHS["total_obligated_amount"] == 0) + ) + ] + + exclude_mask = spending_HHS["total_obligated_amount"].isin( + transportUnwanted["total_obligated_amount"] + ) + spending_HHS = spending_HHS[~exclude_mask] # 95 observations dleted + + assert spending_HHS.isna().sum().sum() == 0, "Na values detected" + + # loading names and repearing fips of value 3 and shorter + + names_HHS = pd.read_csv(f"{root}/data/raw/spending_HHS_names.csv") + + spending_only_fips = np.setdiff1d(spending_HHS["GeoFIPS"], gdp["GeoFIPS"]) + + fips4_to_repair = [fip for fip in spending_only_fips if (fip < 10000 and fip > 999)] + short4_fips = spending_HHS[spending_HHS["GeoFIPS"].isin(fips4_to_repair)] + + full_geofipsLIST = [fip for fip in spending_only_fips if fip > 9999] + full_geofips = spending_HHS[spending_HHS["GeoFIPS"].isin(full_geofipsLIST)] + + cleaningLIST = [full_geofips, short4_fips] # no 3digit FIPS + + # replacing damaged FIPS + + for badFIPS in cleaningLIST: + geofips_to_geonamealt = dict(zip(names_HHS["GeoFIPS"], names_HHS["GeoNameALT"])) + + badFIPS["GeoNameALT"] = badFIPS["GeoFIPS"].map(geofips_to_geonamealt) + badFIPS = badFIPS.rename(columns={"GeoFIPS": "damagedFIPS"}) + + badFIPSmapping_dict = dict(zip(gdp["GeoName"], gdp["GeoFIPS"])) + + badFIPS["repairedFIPS"] = badFIPS["GeoNameALT"].apply( + lambda x: badFIPSmapping_dict.get(x) + ) + repaired_geofips = badFIPS[badFIPS["repairedFIPS"].notna()] + + repair_ratio = repaired_geofips.shape[0] / badFIPS.shape[0] + print(f"Ratio of repaired FIPS: {round(repair_ratio, 2)}") + + # assert repair_ratio > 0.9, f'Less than 0.9 of FIPS were successfully repaired!' + + spending_HHS["GeoFIPS"] = spending_HHS[ + "GeoFIPS" + ].replace( # no FIPS were repaired actually + dict(zip(repaired_geofips["damagedFIPS"], repaired_geofips["repairedFIPS"])) + ) + + common_fips = np.intersect1d( + gdp["GeoFIPS"].unique(), spending_HHS["GeoFIPS"].unique() + ) + + all_FIPS_spending_HHS = spending_HHS.copy() + + spending_HHS = spending_HHS[ + spending_HHS["GeoFIPS"].isin(common_fips) + ] # 99 FIPS deleted + assert ( + spending_HHS.shape[0] / all_FIPS_spending_HHS.shape[0] > 0.9 + ), "Less than 0.9 of FIPS are common!" + + # grouping duplicate fips for years + # (they appeared because we have repaired some of them and now they match with number that is already present) + + spending_HHS = ( + spending_HHS.groupby(["GeoFIPS", "year"])["total_obligated_amount"] + .sum() + .reset_index() + ) + spending_HHS.reset_index(drop=True, inplace=True) + + # adding GeoNames + spending_HHS = spending_HHS.merge( + gdp[["GeoFIPS", "GeoName"]], on="GeoFIPS", how="left" + )[["GeoFIPS", "GeoName", "year", "total_obligated_amount"]] + + unique_gdp = gdp[["GeoFIPS", "GeoName"]].drop_duplicates( + subset=["GeoFIPS", "GeoName"], keep="first" + ) + exclude_geofips = set(spending_HHS["GeoFIPS"]) + unique_gdp = unique_gdp[~unique_gdp["GeoFIPS"].isin(exclude_geofips)] + + unique_gdp["year"] = np.repeat(2018, unique_gdp.shape[0]) + unique_gdp["total_obligated_amount"] = np.repeat(0, unique_gdp.shape[0]) + spending_HHS = pd.concat([spending_HHS, unique_gdp], ignore_index=True) + spending_HHS = spending_HHS.sort_values(by=["GeoFIPS", "GeoName", "year"]) + + assert spending_HHS["GeoFIPS"].nunique() == spending_HHS["GeoName"].nunique() + assert spending_HHS["GeoFIPS"].nunique() == gdp["GeoFIPS"].nunique() + + # Assuming you have a DataFrame named 'your_dataframe' + spending_HHS = spending_HHS.rename(columns={"year": "Year"}) + + # standardizing and saving + spending_HHS_long = spending_HHS.copy() + + spending_HHS_wide = spending_HHS.pivot_table( + index=["GeoFIPS", "GeoName"], columns="Year", values="total_obligated_amount" + ) + spending_HHS_wide.reset_index(inplace=True) + spending_HHS_wide.columns.name = None + spending_HHS_wide = spending_HHS_wide.fillna(0) + + spending_HHS_std_long = standardize_and_scale(spending_HHS) + spending_HHS_std_wide = standardize_and_scale(spending_HHS_wide) + + spending_HHS_wide.to_csv( + f"{root}/data/processed/spending_HHS_wide.csv", index=False + ) + spending_HHS_long.to_csv( + f"{root}/data/processed/spending_HHS_long.csv", index=False + ) + spending_HHS_std_wide.to_csv( + f"{root}/data/processed/spending_HHS_std_wide.csv", index=False + ) + spending_HHS_std_long.to_csv( + f"{root}/data/processed/spending_HHS_std_long.csv", index=False + ) diff --git a/build/cities/utils/cleaning_scripts/clean_spending_commerce.py b/build/cities/utils/cleaning_scripts/clean_spending_commerce.py new file mode 100644 index 00000000..2463bffa --- /dev/null +++ b/build/cities/utils/cleaning_scripts/clean_spending_commerce.py @@ -0,0 +1,147 @@ +import numpy as np +import pandas as pd + +from cities.utils.cleaning_utils import standardize_and_scale +from cities.utils.data_grabber import DataGrabber, find_repo_root + +root = find_repo_root() + + +def clean_spending_commerce(): + data = DataGrabber() + data.get_features_wide(["gdp"]) + gdp = data.wide + gdp = gdp.get("gdp") + + spending_commerce = pd.read_csv(f"{root}/data/raw/spending_commerce.csv") + + transportUnwanted = spending_commerce[ + ( + pd.isna(spending_commerce["total_obligated_amount"]) + | (spending_commerce["total_obligated_amount"] == 1) + | (spending_commerce["total_obligated_amount"] == 0) + ) + ] + + exclude_mask = spending_commerce["total_obligated_amount"].isin( + transportUnwanted["total_obligated_amount"] + ) + spending_commerce = spending_commerce[~exclude_mask] # 24 values lost + + assert spending_commerce.isna().sum().sum() == 0, "Na values detected" + + # loading names and repearing fips of value 3 and shorter + + names_commerce = pd.read_csv(f"{root}/data/raw/spending_commerce_names.csv") + + spending_only_fips = np.setdiff1d(spending_commerce["GeoFIPS"], gdp["GeoFIPS"]) + + fips4_to_repair = [fip for fip in spending_only_fips if (fip < 10000 and fip > 999)] + short4_fips = spending_commerce[spending_commerce["GeoFIPS"].isin(fips4_to_repair)] + + full_geofipsLIST = [fip for fip in spending_only_fips if fip > 9999] + full_geofips = spending_commerce[ + spending_commerce["GeoFIPS"].isin(full_geofipsLIST) + ] + + cleaningLIST = [full_geofips, short4_fips] # no small fips + + # replacing damaged FIPS + + for badFIPS in cleaningLIST: + geofips_to_geonamealt = dict( + zip(names_commerce["GeoFIPS"], names_commerce["GeoNameALT"]) + ) + + badFIPS["GeoNameALT"] = badFIPS["GeoFIPS"].map(geofips_to_geonamealt) + badFIPS = badFIPS.rename(columns={"GeoFIPS": "damagedFIPS"}) + + badFIPSmapping_dict = dict(zip(gdp["GeoName"], gdp["GeoFIPS"])) + + badFIPS["repairedFIPS"] = badFIPS["GeoNameALT"].apply( + lambda x: badFIPSmapping_dict.get(x) + ) + repaired_geofips = badFIPS[badFIPS["repairedFIPS"].notna()] + + repair_ratio = repaired_geofips.shape[0] / badFIPS.shape[0] + print(f"Ratio of repaired FIPS: {round(repair_ratio, 2)}") + + # assert repair_ratio > 0.9, f'Less than 0.9 of FIPS were successfully repaired!' + + spending_commerce["GeoFIPS"] = spending_commerce["GeoFIPS"].replace( + dict(zip(repaired_geofips["damagedFIPS"], repaired_geofips["repairedFIPS"])) + ) + + # deleting short FIPS codes + + common_fips = np.intersect1d( + gdp["GeoFIPS"].unique(), spending_commerce["GeoFIPS"].unique() + ) + + all_FIPS_spending_commerce = spending_commerce.copy() + + spending_commerce = spending_commerce[ + spending_commerce["GeoFIPS"].isin(common_fips) + ] # 67 FIPS deleted + assert ( + spending_commerce.shape[0] / all_FIPS_spending_commerce.shape[0] > 0.9 + ), "Less than 0.9 of FIPS are common!" + + # grouping duplicate fips for years + # (they appeared because we have repaired some of them and now they match with number that is already present) + + spending_commerce = ( + spending_commerce.groupby(["GeoFIPS", "year"])["total_obligated_amount"] + .sum() + .reset_index() + ) + spending_commerce.reset_index(drop=True, inplace=True) + + # adding GeoNames + spending_commerce = spending_commerce.merge( + gdp[["GeoFIPS", "GeoName"]], on="GeoFIPS", how="left" + )[["GeoFIPS", "GeoName", "year", "total_obligated_amount"]] + + unique_gdp = gdp[["GeoFIPS", "GeoName"]].drop_duplicates( + subset=["GeoFIPS", "GeoName"], keep="first" + ) + exclude_geofips = set(spending_commerce["GeoFIPS"]) + unique_gdp = unique_gdp[~unique_gdp["GeoFIPS"].isin(exclude_geofips)] + + unique_gdp["year"] = np.repeat(2018, unique_gdp.shape[0]) + unique_gdp["total_obligated_amount"] = np.repeat(0, unique_gdp.shape[0]) + spending_commerce = pd.concat([spending_commerce, unique_gdp], ignore_index=True) + spending_commerce = spending_commerce.sort_values(by=["GeoFIPS", "GeoName", "year"]) + + assert ( + spending_commerce["GeoFIPS"].nunique() == spending_commerce["GeoName"].nunique() + ) + assert spending_commerce["GeoFIPS"].nunique() == gdp["GeoFIPS"].nunique() + + spending_commerce = spending_commerce.rename(columns={"year": "Year"}) + + # standardizing and saving + spending_commerce_long = spending_commerce.copy() + + spending_commerce_wide = spending_commerce.pivot_table( + index=["GeoFIPS", "GeoName"], columns="Year", values="total_obligated_amount" + ) + spending_commerce_wide.reset_index(inplace=True) + spending_commerce_wide.columns.name = None + spending_commerce_wide = spending_commerce_wide.fillna(0) + + spending_commerce_std_long = standardize_and_scale(spending_commerce) + spending_commerce_std_wide = standardize_and_scale(spending_commerce_wide) + + spending_commerce_wide.to_csv( + f"{root}/data/processed/spending_commerce_wide.csv", index=False + ) + spending_commerce_long.to_csv( + f"{root}/data/processed/spending_commerce_long.csv", index=False + ) + spending_commerce_std_wide.to_csv( + f"{root}/data/processed/spending_commerce_std_wide.csv", index=False + ) + spending_commerce_std_long.to_csv( + f"{root}/data/processed/spending_commerce_std_long.csv", index=False + ) diff --git a/build/cities/utils/cleaning_scripts/clean_spending_transportation.py b/build/cities/utils/cleaning_scripts/clean_spending_transportation.py new file mode 100644 index 00000000..0ff49927 --- /dev/null +++ b/build/cities/utils/cleaning_scripts/clean_spending_transportation.py @@ -0,0 +1,183 @@ +import numpy as np +import pandas as pd + +from cities.utils.cleaning_utils import standardize_and_scale +from cities.utils.data_grabber import DataGrabber, find_repo_root + +root = find_repo_root() + + +def clean_spending_transportation(): + data = DataGrabber() + data.get_features_wide(["gdp"]) + gdp = data.wide + gdp = gdp.get("gdp") + + spending_transportation = pd.read_csv( + f"{root}/data/raw/spending_transportation.csv" + ) + + transportUnwanted = spending_transportation[ + ( + pd.isna(spending_transportation["total_obligated_amount"]) + | (spending_transportation["total_obligated_amount"] == 1) + | (spending_transportation["total_obligated_amount"] == 0) + ) + ] + + exclude_mask = spending_transportation["total_obligated_amount"].isin( + transportUnwanted["total_obligated_amount"] + ) + spending_transportation = spending_transportation[ + ~exclude_mask + ] # 66 values removed + + assert spending_transportation.isna().sum().sum() == 0, "Na values detected" + + # loading names and repearing fips of value 3 and shorter + + names_transportation = pd.read_csv( + f"{root}/data/raw/spending_transportation_names.csv" + ) + + short_geofips = spending_transportation[ + spending_transportation["GeoFIPS"].astype(str).str.len().between(1, 3) + ] + + spending_only_fips = np.setdiff1d( + spending_transportation["GeoFIPS"], gdp["GeoFIPS"] + ) + + fips4_to_repeair = [ + fip for fip in spending_only_fips if (fip < 10000 and fip > 999) + ] + short4_fips = spending_transportation[ + spending_transportation["GeoFIPS"].isin(fips4_to_repeair) + ] + + full_geofipsLIST = [fip for fip in spending_only_fips if fip > 9999] + full_geofips = spending_transportation[ + spending_transportation["GeoFIPS"].isin(full_geofipsLIST) + ] + + cleaningLIST = [full_geofips, short4_fips, short_geofips] + + for badFIPS in cleaningLIST: + geofips_to_geonamealt = dict( + zip(names_transportation["GeoFIPS"], names_transportation["GeoNameALT"]) + ) + + badFIPS["GeoNameALT"] = badFIPS["GeoFIPS"].map(geofips_to_geonamealt) + badFIPS = badFIPS.rename(columns={"GeoFIPS": "damagedFIPS"}) + + badFIPSmapping_dict = dict(zip(gdp["GeoName"], gdp["GeoFIPS"])) + + badFIPS["repairedFIPS"] = badFIPS["GeoNameALT"].apply( + lambda x: badFIPSmapping_dict.get(x) + ) + repaired_geofips = badFIPS[badFIPS["repairedFIPS"].notna()] + + repair_ratio = repaired_geofips.shape[0] / badFIPS.shape[0] + print(f"Ratio of repaired FIPS: {round(repair_ratio, 2)}") + + # assert repair_ratio > 0.9, f'Less than 0.9 of FIPS were successfully repaired!' + + spending_transportation["GeoFIPS"] = spending_transportation["GeoFIPS"].replace( + dict(zip(repaired_geofips["damagedFIPS"], repaired_geofips["repairedFIPS"])) + ) + + # deleting short FIPS codes + count_short_geofips = spending_transportation[ + spending_transportation["GeoFIPS"] <= 999 + ]["GeoFIPS"].count() + assert ( + count_short_geofips / spending_transportation.shape[0] < 0.05 + ), "More than 0.05 of FIPS are short and will be deleted!" + + spending_transportation = spending_transportation[ + spending_transportation["GeoFIPS"] > 999 + ] + + common_fips = np.intersect1d( + gdp["GeoFIPS"].unique(), spending_transportation["GeoFIPS"].unique() + ) + + all_FIPS_spending_transportation = spending_transportation.copy() + + spending_transportation = spending_transportation[ + spending_transportation["GeoFIPS"].isin(common_fips) + ] # 0.96 of FIPS are common + assert ( + spending_transportation.shape[0] / all_FIPS_spending_transportation.shape[0] + > 0.9 + ), "Less than 0.9 of FIPS are common!" + + # grouping duplicate fips for years + # (they appeared because we have repaired some of them and now they match with number that is already present) + + spending_transportation = ( + spending_transportation.groupby(["GeoFIPS", "year"])["total_obligated_amount"] + .sum() + .reset_index() + ) + spending_transportation.reset_index(drop=True, inplace=True) + + # adding GeoNames + spending_transportation = spending_transportation.merge( + gdp[["GeoFIPS", "GeoName"]], on="GeoFIPS", how="left" + )[["GeoFIPS", "GeoName", "year", "total_obligated_amount"]] + + # adding missing FIPS with 0 values in total_obligated_amount column, and 2018 year (as a dummy variable) + + unique_gdp = gdp[["GeoFIPS", "GeoName"]].drop_duplicates( + subset=["GeoFIPS", "GeoName"], keep="first" + ) + exclude_geofips = set(spending_transportation["GeoFIPS"]) + unique_gdp = unique_gdp[~unique_gdp["GeoFIPS"].isin(exclude_geofips)] + + unique_gdp["year"] = np.repeat(2018, unique_gdp.shape[0]) + unique_gdp["total_obligated_amount"] = np.repeat(0, unique_gdp.shape[0]) + spending_transportation = pd.concat( + [spending_transportation, unique_gdp], ignore_index=True + ) + spending_transportation = spending_transportation.sort_values( + by=["GeoFIPS", "GeoName", "year"] + ) + + assert ( + spending_transportation["GeoFIPS"].nunique() + == spending_transportation["GeoName"].nunique() + ) + assert spending_transportation["GeoFIPS"].nunique() == gdp["GeoFIPS"].nunique() + + spending_transportation = spending_transportation.rename(columns={"year": "Year"}) + + # standardizing and saving + spending_transportation_long = spending_transportation.copy() + + spending_transportation_wide = spending_transportation.pivot_table( + index=["GeoFIPS", "GeoName"], columns="Year", values="total_obligated_amount" + ) + spending_transportation_wide.reset_index(inplace=True) + spending_transportation_wide.columns.name = None + spending_transportation_wide = spending_transportation_wide.fillna(0) + + spending_transportation_std_long = standardize_and_scale( + spending_transportation_long + ) + spending_transportation_std_wide = standardize_and_scale( + spending_transportation_wide + ) + + spending_transportation_wide.to_csv( + f"{root}/data/processed/spending_transportation_wide.csv", index=False + ) + spending_transportation_long.to_csv( + f"{root}/data/processed/spending_transportation_long.csv", index=False + ) + spending_transportation_std_wide.to_csv( + f"{root}/data/processed/spending_transportation_std_wide.csv", index=False + ) + spending_transportation_std_long.to_csv( + f"{root}/data/processed/spending_transportation_std_long.csv", index=False + ) diff --git a/build/cities/utils/cleaning_scripts/clean_transport.py b/build/cities/utils/cleaning_scripts/clean_transport.py new file mode 100644 index 00000000..df789ecb --- /dev/null +++ b/build/cities/utils/cleaning_scripts/clean_transport.py @@ -0,0 +1,93 @@ +import numpy as np +import pandas as pd + +from cities.utils.cleaning_utils import standardize_and_scale +from cities.utils.data_grabber import DataGrabber, find_repo_root + +root = find_repo_root() + + +def clean_transport(): + data = DataGrabber() + data.get_features_wide(["gdp"]) + gdp = data.wide + gdp = gdp.get("gdp") + + # grabbing gdp for comparison + + transport = pd.read_csv(f"{root}/data/raw/smartLocationSmall.csv") + + # choosing transport variables + transport = transport[["GeoFIPS", "D3A", "WeightAvgNatWalkInd"]] + + # list of GeoFips with Na values + transportUnwanted = transport[ + ( + pd.isna(transport["WeightAvgNatWalkInd"]) + | (transport["WeightAvgNatWalkInd"] == 1) + ) + | (transport["D3A"] == 0) + | (transport["D3A"] == 1) + ] + + exclude_mask = transport["GeoFIPS"].isin(transportUnwanted["GeoFIPS"]) + transport = transport[~exclude_mask] + + # the step above deleted 10 records with NAs, + # no loss on a dataset because they were not common with gdp anyway + + assert transport.isna().sum().sum() == 0, "Na values detected" + assert transport["GeoFIPS"].is_unique + + # subsetting to common FIPS numbers + + common_fips = np.intersect1d(gdp["GeoFIPS"].unique(), transport["GeoFIPS"].unique()) + transport = transport[transport["GeoFIPS"].isin(common_fips)] + + assert len(common_fips) == len(transport["GeoFIPS"].unique()) + assert len(transport) > 2800, "The number of records is lower than 2800" + + # adding geoname column + transport = transport.merge(gdp[["GeoFIPS", "GeoName"]], on="GeoFIPS", how="left")[ + ["GeoFIPS", "GeoName", "D3A", "WeightAvgNatWalkInd"] + ] + + # renaming D3A to roadDenisty + transport.rename(columns={"D3A": "roadDensity"}, inplace=True) + + patState = r", [A-Z]{2}(\*{1,2})?$" + GeoNameError = "Wrong GeoName value!" + assert transport["GeoName"].str.contains(patState, regex=True).all(), GeoNameError + assert sum(transport["GeoName"].str.count(", ")) == transport.shape[0], GeoNameError + + # changing values to floats + + for column in transport.columns[2:]: + transport[column] = transport[column].astype(float) + + # Standardizing, formatting, saving + + transport_wide = transport.copy() + transport_std_wide = standardize_and_scale(transport) + + transport_long = pd.melt( + transport, + id_vars=["GeoFIPS", "GeoName"], + var_name="Category", + value_name="Value", + ) + transport_std_long = pd.melt( + transport_std_wide.copy(), + id_vars=["GeoFIPS", "GeoName"], + var_name="Category", + value_name="Value", + ) + + transport_wide.to_csv(f"{root}/data/processed/transport_wide.csv", index=False) + transport_long.to_csv(f"{root}/data/processed/transport_long.csv", index=False) + transport_std_wide.to_csv( + f"{root}/data/processed/transport_std_wide.csv", index=False + ) + transport_std_long.to_csv( + f"{root}/data/processed/transport_std_long.csv", index=False + ) diff --git a/build/cities/utils/cleaning_scripts/clean_unemployment.py b/build/cities/utils/cleaning_scripts/clean_unemployment.py new file mode 100644 index 00000000..4e25369c --- /dev/null +++ b/build/cities/utils/cleaning_scripts/clean_unemployment.py @@ -0,0 +1,12 @@ +from cities.utils.clean_variable import VariableCleaner +from cities.utils.data_grabber import find_repo_root + +root = find_repo_root() + + +def clean_unemployment(): + cleaner = VariableCleaner( + variable_name="unemployment_rate", + path_to_raw_csv=f"{root}/data/raw/unemployment_rate_wide_withNA.csv", + ) + cleaner.clean_variable() diff --git a/build/cities/utils/cleaning_scripts/clean_urbanicity_ma.py b/build/cities/utils/cleaning_scripts/clean_urbanicity_ma.py new file mode 100644 index 00000000..710c8533 --- /dev/null +++ b/build/cities/utils/cleaning_scripts/clean_urbanicity_ma.py @@ -0,0 +1,118 @@ +import numpy as np +import pandas as pd + +from cities.utils.clean_variable import VariableCleanerMSA +from cities.utils.data_grabber import find_repo_root + +root = find_repo_root() + + +def clean_urbanicity_initially(): + population_urban = pd.read_csv( + f"{root}/data/raw/DECENNIALDHC2020.P2-2023-12-25T165149.csv" + ) + + population_urban.set_index("Label (Grouping)", inplace=True) + transposed_df = population_urban.transpose() + transposed_df.reset_index(inplace=True) + df_population_urban = transposed_df.copy() + + filtered_df = pd.DataFrame( + df_population_urban[df_population_urban["index"].str.endswith("Metro Area")] + ) + + filtered_df = filtered_df.rename(columns={"index": "MetroName"}) + + filtered_df.columns = filtered_df.columns.str.replace("Total:", "total_pop") + filtered_df.columns = filtered_df.columns.str.replace("Urban", "urban_pop") + filtered_df.columns = filtered_df.columns.str.replace("Rural", "rural_pop") + filtered_df = filtered_df.iloc[:, :-1].reset_index(drop=True) + + population_urban = filtered_df.copy() + + housing_urban = pd.read_csv( + f"{root}/data/raw/DECENNIALDHC2020.H2-2023-12-25T174403.csv" + ) + + housing_urban.set_index("Label (Grouping)", inplace=True) + transposed_df = housing_urban.transpose() + transposed_df.reset_index(inplace=True) + housing_urban = transposed_df.copy() + + filtered_df = pd.DataFrame( + housing_urban[housing_urban["index"].str.endswith("Metro Area")] + ) + + filtered_df = filtered_df.rename(columns={"index": "MetroName"}) + + filtered_df.columns = filtered_df.columns.str.replace("Total:", "total_housing") + filtered_df.columns = filtered_df.columns.str.replace("Urban", "urban_housing") + filtered_df.columns = filtered_df.columns.str.replace("Rural", "rural_housing") + filtered_df = filtered_df.iloc[:, :-1].reset_index(drop=True) + housing_urban = filtered_df.copy() + + metrolist = pd.read_csv(f"{root}/data/raw/metrolist.csv") + + merged_df = housing_urban.merge(population_urban, on="MetroName") + + merged_df["MetroName"] = merged_df["MetroName"].str.replace("Metro Area", "(MA)") + + df1_subset = metrolist[["GeoFIPS", "GeoName"]].drop_duplicates() + + merged_df = pd.merge( + merged_df, df1_subset, left_on=["MetroName"], right_on=["GeoName"], how="left" + ) + + merged_df = merged_df.drop(columns=["GeoName"]) + merged_df.dropna(inplace=True) + + merged_df.columns = merged_df.columns.str.strip() + ordered_columns = [ + "GeoFIPS", + "MetroName", + "total_housing", + "urban_housing", + "rural_housing", + "total_pop", + "urban_pop", + "rural_pop", + ] + ordered_df = merged_df[ordered_columns] + + ordered_df = ordered_df.rename(columns={"MetroName": "GeoName"}) + + numeric_columns = [ + "total_housing", + "urban_housing", + "rural_housing", + "total_pop", + "urban_pop", + "rural_pop", + ] + ordered_df[numeric_columns] = ( + ordered_df[numeric_columns].replace({",": ""}, regex=True).astype(float) + ) + + ordered_df["GeoFIPS"] = ordered_df["GeoFIPS"].astype(np.int64) + + ordered_df["rural_pop_prct"] = ordered_df["rural_pop"] / ordered_df["total_pop"] + ordered_df["rural_housing_prct"] = ( + ordered_df["rural_housing"] / ordered_df["total_housing"] + ) + + ordered_df.drop(["total_pop", "total_housing"], axis=1, inplace=True) + + ordered_df.reset_index(drop=True, inplace=True) + + ordered_df.to_csv(f"{root}/data/raw/urbanicity_ma.csv", index=False) + + +def clean_urbanicity_ma(): + clean_urbanicity_initially() + + cleaner = VariableCleanerMSA( + variable_name="urbanicity_ma", + path_to_raw_csv=f"{root}/data/raw/urbanicity_ma.csv", + year_or_category="Category", + ) + cleaner.clean_variable() diff --git a/build/cities/utils/cleaning_scripts/clean_urbanization.py b/build/cities/utils/cleaning_scripts/clean_urbanization.py new file mode 100644 index 00000000..db199e2b --- /dev/null +++ b/build/cities/utils/cleaning_scripts/clean_urbanization.py @@ -0,0 +1,78 @@ +import numpy as np +import pandas as pd + +from cities.utils.cleaning_utils import standardize_and_scale +from cities.utils.data_grabber import DataGrabber, find_repo_root + +root = find_repo_root() + + +def clean_urbanization(): + data = DataGrabber() + data.get_features_wide(["gdp"]) + gdp = data.wide["gdp"] + + dtype_mapping = {"STATE": str, "COUNTY": str} + urbanization = pd.read_csv( + f"{root}/data/raw/2020_UA_COUNTY.csv", dtype=dtype_mapping + ) + + urbanization["GeoFIPS"] = urbanization["STATE"].astype(str) + urbanization[ + "COUNTY" + ].astype(str) + urbanization["GeoFIPS"] = urbanization["GeoFIPS"].astype(int) + + common_fips = np.intersect1d( + gdp["GeoFIPS"].unique(), urbanization["GeoFIPS"].unique() + ) + + urbanization = urbanization[urbanization["GeoFIPS"].isin(common_fips)] + + urbanization = urbanization.merge( + gdp[["GeoFIPS", "GeoName"]], on="GeoFIPS", how="left" + ) + + urbanization = urbanization[ + [ + "GeoFIPS", + "GeoName", + "POPDEN_RUR", + "POPDEN_URB", + "HOUDEN_COU", + "HOUDEN_RUR", + "ALAND_PCT_RUR", + ] + ] + + urbanization = urbanization.sort_values(by=["GeoFIPS", "GeoName"]) + + urbanization_wide = urbanization.copy() + + urbanization_long = pd.melt( + urbanization, + id_vars=["GeoFIPS", "GeoName"], + var_name="Category", + value_name="Value", + ) + + urbanization_std_wide = standardize_and_scale(urbanization) + + urbanization_std_long = pd.melt( + urbanization_std_wide.copy(), + id_vars=["GeoFIPS", "GeoName"], + var_name="Category", + value_name="Value", + ) + + urbanization_wide.to_csv( + f"{root}/data/processed/urbanization_wide.csv", index=False + ) + urbanization_long.to_csv( + f"{root}/data/processed/urbanization_long.csv", index=False + ) + urbanization_std_wide.to_csv( + f"{root}/data/processed/urbanization_std_wide.csv", index=False + ) + urbanization_std_long.to_csv( + f"{root}/data/processed/urbanization_std_long.csv", index=False + ) diff --git a/build/cities/utils/cleaning_scripts/cleaning_pipeline.py b/build/cities/utils/cleaning_scripts/cleaning_pipeline.py new file mode 100644 index 00000000..542836de --- /dev/null +++ b/build/cities/utils/cleaning_scripts/cleaning_pipeline.py @@ -0,0 +1,74 @@ +from cities.utils.clean_age_composition import clean_age_composition +from cities.utils.clean_burdens import clean_burdens +from cities.utils.clean_ethnic_composition import clean_ethnic_composition +from cities.utils.clean_ethnic_composition_ma import clean_ethnic_composition_ma +from cities.utils.clean_gdp import clean_gdp +from cities.utils.clean_gdp_ma import clean_gdp_ma +from cities.utils.clean_hazard import clean_hazard +from cities.utils.clean_homeownership import clean_homeownership +from cities.utils.clean_income_distribution import clean_income_distribution +from cities.utils.clean_industry import clean_industry +from cities.utils.clean_industry_ma import clean_industry_ma +from cities.utils.clean_industry_ts import clean_industry_ts +from cities.utils.clean_population import clean_population +from cities.utils.clean_population_density import clean_population_density +from cities.utils.clean_population_ma import clean_population_ma +from cities.utils.clean_spending_commerce import clean_spending_commerce +from cities.utils.clean_spending_HHS import clean_spending_HHS +from cities.utils.clean_spending_transportation import clean_spending_transportation +from cities.utils.clean_transport import clean_transport +from cities.utils.clean_unemployment import clean_unemployment +from cities.utils.clean_urbanicity_ma import clean_urbanicity_ma +from cities.utils.clean_urbanization import clean_urbanization +from cities.utils.cleaning_poverty import clean_poverty + +# from cities.utils.clean_health import clean_health + + +# clean_health() lost of another 15-ish fips + +clean_population_density() + +clean_homeownership() + +clean_income_distribution() + +clean_hazard() + +clean_burdens() + +clean_age_composition() + +clean_gdp_ma() + +clean_industry_ma() + +clean_urbanicity_ma() + +clean_ethnic_composition_ma() + +clean_population_ma() + +clean_poverty() + +clean_unemployment() + +clean_gdp() + +clean_population() + +clean_transport() + +clean_spending_transportation() + +clean_spending_commerce() + +clean_spending_HHS() + +clean_ethnic_composition() + +clean_industry() + +clean_urbanization() + +clean_industry_ts() diff --git a/build/cities/utils/cleaning_scripts/cleaning_poverty.py b/build/cities/utils/cleaning_scripts/cleaning_poverty.py new file mode 100644 index 00000000..83d9d7e2 --- /dev/null +++ b/build/cities/utils/cleaning_scripts/cleaning_poverty.py @@ -0,0 +1,23 @@ +from cities.utils.clean_variable import VariableCleaner +from cities.utils.data_grabber import find_repo_root + +root = find_repo_root() + + +poverty_variables = [ + "povertyAll", + "povertyAllprct", + "povertyUnder18", + "povertyUnder18prct", + "medianHouseholdIncome", +] + + +def clean_poverty(): + for variable_name in poverty_variables: + cleaner = VariableCleaner( + variable_name, + path_to_raw_csv=f"{root}/data/raw/{variable_name}_wide.csv", + year_or_category="Year", + ) + cleaner.clean_variable() diff --git a/build/cities/utils/cleaning_utils.py b/build/cities/utils/cleaning_utils.py new file mode 100644 index 00000000..fa15818d --- /dev/null +++ b/build/cities/utils/cleaning_utils.py @@ -0,0 +1,83 @@ +from typing import List, Union + +import numpy as np +import pandas as pd +from sklearn.preprocessing import StandardScaler + +from cities.utils.data_grabber import DataGrabber + + +def sigmoid(x, scale=1 / 3): + range_0_1 = 1 / (1 + np.exp(-x * scale)) + range_minus1_1 = 2 * range_0_1 - 1 + return range_minus1_1 + + +def standardize_and_scale(data: pd.DataFrame) -> pd.DataFrame: + """ + Standardizes and scales float columns in a DataFrame to [-1,1], copying other columns. Returns a new DataFrame. + """ + standard_scaler = StandardScaler() # Standardize to mean 0, std 1 + + # Copy all columns first + new_data = data.copy() + + # Select float columns + float_cols = data.select_dtypes(include=["float64"]) + + # Standardize float columns to mean 0, std 1 + standardized_floats = standard_scaler.fit_transform(float_cols) + + # Apply sigmoid transformation, [-3std, 3std] to [-1, 1] + new_data[float_cols.columns] = sigmoid(standardized_floats, scale=1 / 3) + + return new_data + + +def revert_standardize_and_scale_scaler( + transformed_values: Union[np.ndarray, List, pd.Series, float], + year: int, + variable_name: str, +) -> List: + if not isinstance(transformed_values, np.ndarray): + transformed_values = np.array(transformed_values) + + def inverse_sigmoid(y, scale=1 / 3): + return -np.log((2 / (y + 1)) - 1) / scale + + # needed to avoid lint issues + dg: DataGrabber + + # normally this will be deployed in a context in which dg already exists + # and we want to avoid wasting time by reloading the data + try: + original_column = dg.wide[variable_name][str(year)].values + except NameError: + dg = DataGrabber() + dg.get_features_wide([variable_name]) + original_column = dg.wide[variable_name][str(year)].values.reshape(-1, 1) + + # dg = DataGrabber() + # dg.get_features_wide([variable_name]) + + # original_column = dg.wide[variable_name][str(year)].values.reshape(-1, 1) + scaler = StandardScaler() + scaler.fit(original_column) + + inverted_values_sigmoid = inverse_sigmoid(transformed_values) + inverted_values = scaler.inverse_transform( + inverted_values_sigmoid.reshape(-1, 1) + ).flatten() + + return inverted_values + + +def revert_prediction_df(df: pd.DataFrame, variable_name: str) -> pd.DataFrame: + df_copy = df.copy() + + for i in range(len(df)): + df_copy.iloc[i, 1:] = revert_standardize_and_scale_scaler( + df.iloc[i, 1:].tolist(), df.iloc[i, 0], variable_name + ) + + return df_copy diff --git a/build/cities/utils/data_grabber.py b/build/cities/utils/data_grabber.py new file mode 100644 index 00000000..ba6ee5e6 --- /dev/null +++ b/build/cities/utils/data_grabber.py @@ -0,0 +1,119 @@ +import os +import re +import sys +from pathlib import Path +from typing import List + +import pandas as pd + + +def find_repo_root() -> Path: + return Path(__file__).parent.parent.parent + + +def check_if_tensed(df): + years_to_check = ["2015", "2018", "2019", "2020"] + check = df.columns[2:].isin(years_to_check).any().any() + return check + + +class DataGrabber: + def __init__(self): + self.repo_root = find_repo_root() + self.data_path = os.path.join(self.repo_root, "data/processed") + self.wide = {} + self.std_wide = {} + self.long = {} + self.std_long = {} + + def get_features_wide(self, features: List[str]) -> None: + for feature in features: + file_path = os.path.join(self.data_path, f"{feature}_wide.csv") + self.wide[feature] = pd.read_csv(file_path) + + def get_features_std_wide(self, features: List[str]) -> None: + for feature in features: + file_path = os.path.join(self.data_path, f"{feature}_std_wide.csv") + self.std_wide[feature] = pd.read_csv(file_path) + + def get_features_long(self, features: List[str]) -> None: + for feature in features: + file_path = os.path.join(self.data_path, f"{feature}_long.csv") + self.long[feature] = pd.read_csv(file_path) + + def get_features_std_long(self, features: List[str]) -> None: + for feature in features: + file_path = os.path.join(self.data_path, f"{feature}_std_long.csv") + self.std_long[feature] = pd.read_csv(file_path) + + +class MSADataGrabber(DataGrabber): + def __init__(self): + super().__init__() + self.repo_root = find_repo_root() + self.data_path = os.path.join(self.repo_root, "data/MSA_level") + sys.path.insert(0, self.data_path) + + +def list_available_features(level="county"): + root = find_repo_root() + + if level == "county": + folder_path = f"{root}/data/processed" + elif level == "msa": + folder_path = f"{root}/data/MSA_level" + else: + raise ValueError("Invalid level. Please choose 'county' or 'msa'.") + + file_names = [f for f in os.listdir(folder_path) if f != ".gitkeep"] + processed_file_names = [] + + for file_name in file_names: + # Use regular expressions to find the patterns and split accordingly + matches = re.split(r"_wide|_long|_std", file_name) + if matches: + processed_file_names.append(matches[0]) + + feature_names = list(set(processed_file_names)) + + return sorted(feature_names) + + +def list_tensed_features(level="county"): + if level == "county": + data = DataGrabber() + all_features = list_available_features(level="county") + + elif level == "msa": + data = MSADataGrabber() + all_features = list_available_features(level="msa") + + else: + raise ValueError("Invalid level. Please choose 'county' or 'msa'.") + + data.get_features_wide(all_features) + + tensed_features = [] + for feature in all_features: + if check_if_tensed(data.wide[feature]): + tensed_features.append(feature) + + return sorted(tensed_features) + + +# TODO this only will pick up spending-based interventions +# needs to be modified/expanded when we add other types of interventions +def list_interventions(): + interventions = [ + feature for feature in list_tensed_features() if feature.startswith("spending_") + ] + return sorted(interventions) + + +def list_outcomes(): + outcomes = [ + feature + for feature in list_tensed_features() + if feature not in list_interventions() + ] + return sorted(outcomes) diff --git a/build/cities/utils/data_loader.py b/build/cities/utils/data_loader.py new file mode 100644 index 00000000..db3a13e3 --- /dev/null +++ b/build/cities/utils/data_loader.py @@ -0,0 +1,89 @@ +import os +from typing import Dict, List + +import pandas as pd +import sqlalchemy +import torch +from torch.utils.data import Dataset + + +class ZoningDataset(Dataset): + def __init__( + self, + categorical, + continuous, + standardization_dictionary=None, + ): + self.categorical = categorical + self.continuous = continuous + + self.standardization_dictionary = standardization_dictionary + + if self.categorical: + self.categorical_levels = dict() + for name in self.categorical.keys(): + self.categorical_levels[name] = torch.unique(categorical[name]) + + N_categorical = len(categorical.keys()) + N_continuous = len(continuous.keys()) + + if N_categorical > 0: + self.n = len(next(iter(categorical.values()))) + elif N_continuous > 0: + self.n = len(next(iter(continuous.values()))) + + def __len__(self): + return self.n + + def __getitem__(self, idx): + cat_data = {key: val[idx] for key, val in self.categorical.items()} + cont_data = {key: val[idx] for key, val in self.continuous.items()} + return { + "categorical": cat_data, + "continuous": cont_data, + } + + +def select_from_data(data, kwarg_names: Dict[str, List[str]]): + _data = {} + _data["outcome"] = data["continuous"][kwarg_names["outcome"]] + _data["categorical"] = { + key: val + for key, val in data["categorical"].items() + if key in kwarg_names["categorical"] + } + _data["continuous"] = { + key: val + for key, val in data["continuous"].items() + if key in kwarg_names["continuous"] + } + + return _data + + +def db_connection(): + DB_USERNAME = os.getenv("DB_USERNAME") + HOST = os.getenv("HOST") + DATABASE = os.getenv("DATABASE") + PASSWORD = os.getenv("PASSWORD") + DB_SEARCH_PATH = os.getenv("DB_SEARCH_PATH") + + return sqlalchemy.create_engine( + f"postgresql://{DB_USERNAME}:{PASSWORD}@{HOST}/{DATABASE}", + connect_args={"options": f"-csearch-path={DB_SEARCH_PATH}"}, + ).connect() + + +def select_from_sql(sql, conn, kwargs, params=None): + df = pd.read_sql(sql, conn, params=params) + return { + "outcome": df[kwargs["outcome"]], + "categorical": { + key: torch.tensor(df[key].values, dtype=torch.int64) + for key in kwargs["categorical"] + }, + "continuous": { + key: torch.tensor(df[key], dtype=torch.float32) + for key in kwargs["continuous"] + }, + } diff --git a/build/cities/utils/percentiles.py b/build/cities/utils/percentiles.py new file mode 100644 index 00000000..c4837a53 --- /dev/null +++ b/build/cities/utils/percentiles.py @@ -0,0 +1,64 @@ +import os + +import dill as dill +import numpy as np + +from cities.utils.data_grabber import DataGrabber, find_repo_root, list_interventions + + +def export_sorted_interventions(): + root = find_repo_root() + + interventions = list_interventions() + dg = DataGrabber() + + dg.get_features_std_wide(interventions) + + interventions_sorted = {} + for intervention in interventions: + intervention_frame = dg.std_wide[intervention].copy().iloc[:, 2:] + intervention_frame = intervention_frame.apply( + lambda col: col.sort_values().values + ) + assert ( + all(np.diff(intervention_frame[col]) >= 0) + for col in intervention_frame.columns + ), "A column is not increasing." + interventions_sorted[intervention] = intervention_frame + + with open( + os.path.join(root, "data/sorted_interventions", "interventions_sorted.pkl"), + "wb", + ) as f: + dill.dump(interventions_sorted, f) + + +def transformed_intervention_from_percentile(intervention, year, percentile): + root = find_repo_root() + + with open( + os.path.join(root, "data/sorted_interventions", "interventions_sorted.pkl"), + "rb", + ) as f: + interventions_sorted = dill.load(f) + intervention_frame = interventions_sorted[intervention] + + if str(year) not in intervention_frame.columns: + raise ValueError("Year not in intervention frame.") + + sorted_var = intervention_frame[str(year)] + n = len(sorted_var) + index = percentile * (n - 1) / 100 + + lower_index = int(index) + upper_index = lower_index + 1 + + if lower_index == n - 1: + return sorted_var[lower_index] + + interpolation_factor = index - lower_index + interpolated_value = (1 - interpolation_factor) * sorted_var[ + lower_index + ] + interpolation_factor * sorted_var[upper_index] + + return interpolated_value diff --git a/build/cities/utils/similarity_utils.py b/build/cities/utils/similarity_utils.py new file mode 100644 index 00000000..1db37327 --- /dev/null +++ b/build/cities/utils/similarity_utils.py @@ -0,0 +1,172 @@ +from typing import Dict + +import numpy as np +import pandas as pd +from plotly import graph_objs as go + +from cities.utils.data_grabber import check_if_tensed + + +def slice_with_lag(df: pd.DataFrame, fips: int, lag: int) -> Dict[str, np.ndarray]: + """ + Takes a pandas dataframe, a location FIPS and a lag (years), + returns a dictionary with two numpy arrays: + - my_array: the array of features for the location with the given FIPS + - other_arrays: the array of features for all other locations + if lag>0, drops first lag columns from my_array and last lag columns from other_arrays. + Meant to be used prior to calculating similarity. + """ + original_length = df.shape[0] + original_array_width = df.shape[1] - 2 + + # assert error if lag > original array width + assert ( + lag <= original_array_width + ), "Lag is greater than the number of years in the dataframe" + assert lag >= 0, "Lag must be a positive integer" + + # this assumes input df has two columns of metadata, then the rest are features + # obey this convention with other datasets! + + my_row = df.loc[df["GeoFIPS"] == fips].copy() + my_id = my_row[["GeoFIPS", "GeoName"]] + my_values = my_row.iloc[:, 2 + lag :] + + my_df = pd.concat([my_id, my_values], axis=1) + + my_df = pd.DataFrame( + {**my_id.to_dict(orient="list"), **my_values.to_dict(orient="list")} + ) + + assert fips in df["GeoFIPS"].values, "FIPS not found in the dataframe" + other_df = df[df["GeoFIPS"] != fips].copy() + + my_array = np.array(my_values) + + if lag > 0: + other_df = df[df["GeoFIPS"] != fips].iloc[:, :-lag] + + assert fips not in other_df["GeoFIPS"].values, "FIPS found in the other dataframe" + other_arrays = np.array(other_df.iloc[:, 2:]) + + assert other_arrays.shape[0] + 1 == original_length, "Dataset sizes don't match" + assert other_arrays.shape[1] == my_array.shape[1], "Lengths don't match" + + return { + "my_array": my_array, + "other_arrays": other_arrays, + "my_df": my_df, + "other_df": other_df, + } + + +def generalized_euclidean_distance(u, v, weights): + featurewise_squared_contributions = ( + abs(weights) + * ((weights >= 0) * abs(u - v) + (weights < 0) * (-abs(u - v) + 2)) ** 2 + ) + + featurewise_contributions = featurewise_squared_contributions ** (1 / 2) + + distance = sum(featurewise_squared_contributions) ** (1 / 2) + return { + "distance": distance, + "featurewise_contributions": featurewise_contributions, + } + + +def divide_exponentially(group_weight, number_of_features, rate): + """ + Returns a list of `number_of_features` weights that sum to `group_weight` and are distributed + exponentially. Intended for time series feature groups. + If `rate` is 1, all weights are equal. If `rate` is greater than 1, weights + prefer more recent events. + """ + result = [] + denominator = sum([rate**j for j in range(number_of_features)]) + for i in range(number_of_features): + value = group_weight * (rate**i) / denominator + result.append(value) + return result + + +def compute_weight_array(query_object, rate=1.08): + assert ( + sum( + abs(value) + for key, value in query_object.feature_groups_with_weights.items() + ) + != 0 + ), "At least one weight has to be other than 0" + + max_other_scores = sum( + abs(value) + for key, value in query_object.feature_groups_with_weights.items() + if key != query_object.outcome_var + ) + + if ( + query_object.outcome_var + and query_object.feature_groups_with_weights[query_object.outcome_var] != 0 + ): + weight_outcome_joint = max_other_scores if max_other_scores > 0 else 1 + query_object.feature_groups_with_weights[query_object.outcome_var] = ( + weight_outcome_joint + * query_object.feature_groups_with_weights[query_object.outcome_var] + ) + + tensed_status = {} + columns = {} + column_counts = {} + weight_lists = {} + all_columns = [] + for feature in query_object.feature_groups: + tensed_status[feature] = check_if_tensed(query_object.data.std_wide[feature]) + + if feature == query_object.outcome_var: + columns[feature] = query_object.restricted_outcome_df.columns[2:] + else: + columns[feature] = query_object.data.std_wide[feature].columns[2:] + + # TODO remove if all tests passed before merging + # column_counts[feature] = len(query_object.data.std_wide[feature].columns) - 2 + + column_counts[feature] = len(columns[feature]) + + if feature == query_object.outcome_var and query_object.lag > 0: + column_counts[feature] -= query_object.lag + + all_columns.extend([f"{column}_{feature}" for column in columns[feature]]) + + # TODO: remove if tests passed + # column_tags.extend([feature] * column_counts[feature]) + if tensed_status[feature]: + weight_lists[feature] = divide_exponentially( + query_object.feature_groups_with_weights[feature], + column_counts[feature], + rate, + ) + else: + weight_lists[feature] = [ + query_object.feature_groups_with_weights[feature] + / column_counts[feature] + ] * column_counts[feature] + + query_object.all_columns = all_columns[query_object.lag :] + query_object.all_weights = np.concatenate(list(weight_lists.values())) + + +def plot_weights(query_object): + fig = go.Figure() + + fig.add_trace(go.Bar(x=query_object.all_columns, y=query_object.all_weights)) + + fig.update_layout( + xaxis_title="columns", + yaxis_title="weights", + title="Weights of columns", + template="plotly_white", + ) + + query_object.weigth_plot = fig + query_object.weigth_plot.show() diff --git a/build/cities/utils/years_available_pipeline.py b/build/cities/utils/years_available_pipeline.py new file mode 100644 index 00000000..37ea85fe --- /dev/null +++ b/build/cities/utils/years_available_pipeline.py @@ -0,0 +1,31 @@ +import os + +import dill + +from cities.modeling.modeling_utils import prep_wide_data_for_inference +from cities.utils.data_grabber import find_repo_root, list_interventions, list_outcomes + +root = find_repo_root() +interventions = list_interventions() +outcomes = list_outcomes() + + +for intervention in interventions: + for outcome in outcomes: + # intervention = "spending_HHS" + # outcome = "gdp" + data = prep_wide_data_for_inference( + outcome_dataset=outcome, + intervention_dataset=intervention, + forward_shift=3, # shift doesn't matter here, as long as data exists + ) + data_slim = {key: data[key] for key in ["years_available", "outcome_years"]} + + assert len(data_slim["years_available"]) > 2 + file_path = os.path.join( + root, "data/years_available", f"{intervention}_{outcome}.pkl" + ) + print(file_path) + if not os.path.exists(file_path): + with open(file_path, "wb") as f: + dill.dump(data_slim, f) diff --git a/build/main.py b/build/main.py new file mode 100644 index 00000000..fbfcea0b --- /dev/null +++ b/build/main.py @@ -0,0 +1,235 @@ +import os + +from typing import Annotated + +from dotenv import load_dotenv +from fastapi import FastAPI, Depends, Query +from fastapi.middleware.gzip import GZipMiddleware +import uvicorn + +import psycopg2 +from psycopg2.pool import ThreadedConnectionPool + +load_dotenv() + +ENV = os.getenv("ENV") +USERNAME = os.getenv("DB_USERNAME") +PASSWORD = os.getenv("PASSWORD") +HOST = os.getenv("HOST") +DATABASE = os.getenv("DATABASE") +DB_SEARCH_PATH = os.getenv("DB_SEARCH_PATH") +INSTANCE_CONNECTION_NAME = os.getenv("INSTANCE_CONNECTION_NAME") + +app = FastAPI() + +if ENV == "dev": + from fastapi.middleware.cors import CORSMiddleware + + origins = [ + "http://localhost", + "http://localhost:5000", + ] + app.add_middleware(CORSMiddleware, allow_origins=origins, allow_credentials=True) + +app.add_middleware(GZipMiddleware, minimum_size=1000, compresslevel=5) + + +if ENV == "dev": + host = HOST +else: + host = f"/cloudsql/{INSTANCE_CONNECTION_NAME}" + +pool = ThreadedConnectionPool( + 1, + 10, + user=USERNAME, + password=PASSWORD, + host=HOST, + database=DATABASE, + options=f"-csearch_path={DB_SEARCH_PATH}", +) + + +def get_db() -> psycopg2.extensions.connection: + db = pool.getconn() + try: + yield db + finally: + pool.putconn(db) + + +predictor = None + + +def get_predictor(db: psycopg2.extensions.connection = Depends(get_db)): + from cities.deployment.tracts_minneapolis.predict import TractsModelPredictor + + global predictor + if predictor is None: + predictor = TractsModelPredictor(db) + return predictor + + +Limit = Annotated[float, Query(ge=0, le=1)] +Radius = Annotated[float, Query(ge=0)] +Year = Annotated[int, Query(ge=2000, le=2030)] + + +@app.middleware("http") +async def add_cache_control_header(request, call_next): + response = await call_next(request) + response.headers["Cache-Control"] = "public, max-age=300" + return response + + +if ENV == "dev": + + @app.middleware("http") + async def add_acess_control_header(request, call_next): + response = await call_next(request) + response.headers["Access-Control-Allow-Origin"] = "*" + return response + + +@app.get("/demographics") +async def read_demographics( + category: Annotated[str, Query(max_length=100)], db=Depends(get_db) +): + with db.cursor() as cur: + cur.execute( + """ + select tract_id, "2011", "2012", "2013", "2014", "2015", "2016", "2017", "2018", "2019", "2020", "2021", "2022" + from api__demographics where description = %s + """, + (category,), + ) + return [[desc[0] for desc in cur.description]] + cur.fetchall() + + +@app.get("/census-tracts") +async def read_census_tracts(year: Year, db=Depends(get_db)): + with db.cursor() as cur: + cur.execute("select * from api__census_tracts where year_ = %s", (year,)) + row = cur.fetchone() + + return row[1] if row is not None else None + + +@app.get("/high-frequency-transit-lines") +async def read_high_frequency_transit_lines(year: Year, db=Depends(get_db)): + with db.cursor() as cur: + cur.execute( + """ + select line_geom_json + from api__high_frequency_transit_lines + where '%s-01-01'::date <@ valid + """, + (year,), + ) + row = cur.fetchone() + + return row[0] if row is not None else None + + +@app.get("/high-frequency-transit-stops") +async def read_high_frequency_transit_stops(year: Year, db=Depends(get_db)): + with db.cursor() as cur: + cur.execute( + """ + select stop_geom_json + from api__high_frequency_transit_lines + where '%s-01-01'::date <@ valid + """, + (year,), + ) + row = cur.fetchone() + + return row[0] if row is not None else None + + +@app.get("/yellow-zone") +async def read_yellow_zone( + year: Year, line_radius: Radius, stop_radius: Radius, db=Depends(get_db) +): + with db.cursor() as cur: + cur.execute( + """ + select + st_asgeojson(st_transform(st_union(st_buffer(line_geom, %s, 'quad_segs=4'), st_buffer(stop_geom, %s, 'quad_segs=4')), 4269))::json + from api__high_frequency_transit_lines + where '%s-01-01'::date <@ valid + """, + (line_radius, stop_radius, year), + ) + row = cur.fetchone() + + if row is None: + return None + + return { + "type": "FeatureCollection", + "features": [ + {"type": "Feature", "properties": {"id": "0"}, "geometry": row[0]} + ], + } + + +@app.get("/blue-zone") +async def read_blue_zone(year: Year, radius: Radius, db=Depends(get_db)): + with db.cursor() as cur: + cur.execute( + """ + select st_asgeojson(st_transform(st_buffer(line_geom, %s, 'quad_segs=4'), 4269))::json + from api__high_frequency_transit_lines + where '%s-01-01'::date <@ valid + """, + (radius, year), + ) + row = cur.fetchone() + + if row is None: + return None + + return { + "type": "FeatureCollection", + "features": [ + {"type": "Feature", "properties": {"id": "0"}, "geometry": row[0]} + ], + } + + +@app.get("/predict") +async def read_predict( + blue_zone_radius: Radius, + yellow_zone_line_radius: Radius, + yellow_zone_stop_radius: Radius, + blue_zone_limit: Limit, + yellow_zone_limit: Limit, + year: Year, + db=Depends(get_db), + predictor=Depends(get_predictor), +): + result = predictor.predict_cumulative( + db, + intervention=( + { + "radius_blue": blue_zone_radius, + "limit_blue": blue_zone_limit, + "radius_yellow_line": yellow_zone_line_radius, + "radius_yellow_stop": yellow_zone_stop_radius, + "limit_yellow": yellow_zone_limit, + "reform_year": year, + } + ), + ) + return { + "census_tracts": [str(t) for t in result["census_tracts"]], + "housing_units_factual": [t.item() for t in result["housing_units_factual"]], + "housing_units_counterfactual": [ + t.tolist() for t in result["housing_units_counterfactual"] + ], + } + + +if __name__ == "__main__": + uvicorn.run(app, host="0.0.0.0", port=int(os.getenv("PORT", 8000))) diff --git a/build/postgrest.conf b/build/postgrest.conf new file mode 100644 index 00000000..ddb71965 --- /dev/null +++ b/build/postgrest.conf @@ -0,0 +1,107 @@ +## Admin server used for checks. It's disabled by default unless a port is specified. +# admin-server-port = 3001 + +## The database role to use when no client authentication is provided +db-anon-role = "web_anon" + +## Notification channel for reloading the schema cache +db-channel = "pgrst" + +## Enable or disable the notification channel +db-channel-enabled = true + +## Enable in-database configuration +db-config = true + +## Function for in-database configuration +## db-pre-config = "postgrest.pre_config" + +## Extra schemas to add to the search_path of every request +db-extra-search-path = "public" + +## Limit rows in response +# db-max-rows = 1000 + +## Allow getting the EXPLAIN plan through the `Accept: application/vnd.pgrst.plan` header +# db-plan-enabled = false + +## Number of open connections in the pool +db-pool = 10 + +## Time in seconds to wait to acquire a slot from the connection pool +# db-pool-acquisition-timeout = 10 + +## Time in seconds after which to recycle pool connections +# db-pool-max-lifetime = 1800 + +## Time in seconds after which to recycle unused pool connections +# db-pool-max-idletime = 30 + +## Allow automatic database connection retrying +# db-pool-automatic-recovery = true + +## Stored proc to exec immediately after auth +# db-pre-request = "stored_proc_name" + +## Enable or disable prepared statements. disabling is only necessary when behind a connection pooler. +## When disabled, statements will be parametrized but won't be prepared. +db-prepared-statements = true + +## The name of which database schema to expose to REST clients +db-schemas = "api" + +## How to terminate database transactions +## Possible values are: +## commit (default) +## Transaction is always committed, this can not be overriden +## commit-allow-override +## Transaction is committed, but can be overriden with Prefer tx=rollback header +## rollback +## Transaction is always rolled back, this can not be overriden +## rollback-allow-override +## Transaction is rolled back, but can be overriden with Prefer tx=commit header +db-tx-end = "commit" + +## The standard connection URI format, documented at +## https://www.postgresql.org/docs/current/libpq-connect.html#LIBPQ-CONNSTRING +db-uri = "postgresql://postgres@34.123.100.76:5432/cities" + +# jwt-aud = "your_audience_claim" + +## Jspath to the role claim key +jwt-role-claim-key = ".role" + +## Choose a secret, JSON Web Key (or set) to enable JWT auth +## (use "@filename" to load from separate file) +# jwt-secret = "secret_with_at_least_32_characters" +jwt-secret-is-base64 = false + +## Enables and set JWT Cache max lifetime, disables caching with 0 +# jwt-cache-max-lifetime = 0 + +## Logging level, the admitted values are: crit, error, warn, info and debug. +log-level = "error" + +## Determine if the OpenAPI output should follow or ignore role privileges or be disabled entirely. +## Admitted values: follow-privileges, ignore-privileges, disabled +openapi-mode = "follow-privileges" + +## Base url for the OpenAPI output +openapi-server-proxy-uri = "" + +## Configurable CORS origins +# server-cors-allowed-origins = "" + +server-host = "!4" +server-port = 3001 + +## Allow getting the request-response timing information through the `Server-Timing` header +server-timing-enabled = true + +## Unix socket location +## if specified it takes precedence over server-port +# server-unix-socket = "/tmp/pgrst.sock" + +## Unix socket file mode +## When none is provided, 660 is applied by default +# server-unix-socket-mode = "660" diff --git a/build/requirements.txt b/build/requirements.txt new file mode 100644 index 00000000..15840bbf --- /dev/null +++ b/build/requirements.txt @@ -0,0 +1,184 @@ +# +# This file is autogenerated by pip-compile with Python 3.12 +# by the following command: +# +# pip-compile --extra=api --output-file=api/requirements.txt +# +annotated-types==0.7.0 + # via pydantic +anyio==4.4.0 + # via + # httpx + # starlette + # watchfiles +certifi==2024.8.30 + # via + # httpcore + # httpx +chirho @ git+https://github.com/BasisResearch/chirho.git + # via cities (setup.py) +click==8.1.7 + # via + # typer + # uvicorn +contourpy==1.3.0 + # via matplotlib +cycler==0.12.1 + # via matplotlib +dill==0.3.8 + # via cities (setup.py) +dnspython==2.6.1 + # via email-validator +email-validator==2.2.0 + # via fastapi +fastapi[standard]==0.114.0 + # via cities (setup.py) +fastapi-cli[standard]==0.0.5 + # via fastapi +filelock==3.16.0 + # via torch +fonttools==4.53.1 + # via matplotlib +fsspec==2024.9.0 + # via torch +h11==0.14.0 + # via + # httpcore + # uvicorn +httpcore==1.0.5 + # via httpx +httptools==0.6.1 + # via uvicorn +httpx==0.27.2 + # via fastapi +idna==3.8 + # via + # anyio + # email-validator + # httpx +jinja2==3.1.4 + # via + # fastapi + # torch +joblib==1.4.2 + # via scikit-learn +kiwisolver==1.4.7 + # via matplotlib +markdown-it-py==3.0.0 + # via rich +markupsafe==2.1.5 + # via jinja2 +matplotlib==3.9.2 + # via cities (setup.py) +mdurl==0.1.2 + # via markdown-it-py +mpmath==1.3.0 + # via sympy +networkx==3.3 + # via torch +numpy==2.1.1 + # via + # cities (setup.py) + # contourpy + # matplotlib + # opt-einsum + # pandas + # pyro-ppl + # scikit-learn + # scipy +opt-einsum==3.3.0 + # via pyro-ppl +packaging==24.1 + # via + # matplotlib + # plotly +pandas==2.2.2 + # via cities (setup.py) +pillow==10.4.0 + # via matplotlib +plotly==5.24.0 + # via cities (setup.py) +psycopg2==2.9.9 + # via cities (setup.py) +pydantic==2.9.1 + # via fastapi +pydantic-core==2.23.3 + # via pydantic +pygments==2.18.0 + # via rich +pyparsing==3.1.4 + # via matplotlib +pyro-api==0.1.2 + # via pyro-ppl +pyro-ppl==1.8.6 + # via + # chirho + # cities (setup.py) +python-dateutil==2.9.0.post0 + # via + # matplotlib + # pandas +python-dotenv==1.0.1 + # via uvicorn +python-multipart==0.0.9 + # via fastapi +pytz==2024.1 + # via pandas +pyyaml==6.0.2 + # via uvicorn +rich==13.8.0 + # via typer +scikit-learn==1.5.1 + # via cities (setup.py) +scipy==1.14.1 + # via scikit-learn +shellingham==1.5.4 + # via typer +six==1.16.0 + # via python-dateutil +sniffio==1.3.1 + # via + # anyio + # httpx +sqlalchemy==2.0.34 + # via cities (setup.py) +starlette==0.38.5 + # via fastapi +sympy==1.13.2 + # via torch +tenacity==9.0.0 + # via plotly +threadpoolctl==3.5.0 + # via scikit-learn +#torch==2.4.1 +torch @ https://download.pytorch.org/whl/cpu-cxx11-abi/torch-2.4.1%2Bcpu.cxx11.abi-cp312-cp312-linux_x86_64.whl + # via + # cities (setup.py) + # pyro-ppl +tqdm==4.66.5 + # via pyro-ppl +typer==0.12.5 + # via fastapi-cli +typing-extensions==4.12.2 + # via + # fastapi + # pydantic + # pydantic-core + # sqlalchemy + # torch + # typer +tzdata==2024.1 + # via pandas +uvicorn[standard]==0.30.6 + # via + # fastapi + # fastapi-cli +uvloop==0.20.0 + # via uvicorn +watchfiles==0.24.0 + # via uvicorn +websockets==13.0.1 + # via uvicorn + +# The following packages are considered to be unsafe in a requirements file: +# setuptools diff --git a/build/schema.sql b/build/schema.sql new file mode 100644 index 00000000..2285c2b7 --- /dev/null +++ b/build/schema.sql @@ -0,0 +1,67 @@ +begin; +drop schema if exists api cascade; + +create schema api; + +create view api.demographics as ( + select * from api__demographics +); + +create view api.census_tracts as ( + select * from api__census_tracts +); + +create function api.high_frequency_transit_lines() returns setof dev.api__high_frequency_transit_lines as $$ + select * from dev.api__high_frequency_transit_lines +$$ language sql; + +create function api.high_frequency_transit_lines( + blue_zone_radius double precision, + yellow_zone_line_radius double precision, + yellow_zone_stop_radius double precision +) returns table ( + valid daterange, + geom geometry(LineString, 4269), + blue_zone_geom geometry(LineString, 4269), + yellow_zone_geom geometry(Geometry, 4269) +) as $$ + with + lines as (select * from dev.stg_high_frequency_transit_lines_union), + stops as (select * from dev.high_frequency_transit_stops), + lines_and_stops as ( + select + lines.valid * stops.valid as valid, + lines.geom as line_geom, + stops.geom as stop_geom + from lines inner join stops on lines.valid && stops.valid + ) + select + valid, + st_transform(line_geom, 4269) as geom, + st_transform(st_buffer(line_geom, blue_zone_radius), 4269) as blue_zone_geom, + st_transform(st_union(st_buffer(line_geom, yellow_zone_line_radius), st_buffer(stop_geom, yellow_zone_stop_radius)), 4269) as yellow_zone_geom + from lines_and_stops +$$ language sql; + +do $$ +begin +create role web_anon nologin; +exception when duplicate_object then raise notice '%, skipping', sqlerrm using errcode = sqlstate; +end +$$; + +grant all on schema public to web_anon; +grant all on schema dev to web_anon; +grant select on table public.spatial_ref_sys TO web_anon; +grant usage on schema api to web_anon; +grant all on all tables in schema api to web_anon; +grant all on all functions in schema api to web_anon; +grant all on schema api to web_anon; +GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA dev TO web_anon; +GRANT ALL PRIVILEGES ON ALL functions IN SCHEMA dev TO web_anon; +GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA api TO web_anon; +GRANT ALL PRIVILEGES ON ALL functions IN SCHEMA api TO web_anon; +GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA public TO web_anon; +GRANT ALL PRIVILEGES ON ALL functions IN SCHEMA public TO web_anon; +grant web_anon to postgres; +commit; diff --git a/cities/deployment/tracts_minneapolis/tracts_model_guide.pkl b/cities/deployment/tracts_minneapolis/tracts_model_guide.pkl new file mode 100644 index 00000000..b99e3a1d Binary files /dev/null and b/cities/deployment/tracts_minneapolis/tracts_model_guide.pkl differ diff --git a/cities/deployment/tracts_minneapolis/tracts_model_params.pth b/cities/deployment/tracts_minneapolis/tracts_model_params.pth new file mode 100644 index 00000000..07942006 Binary files /dev/null and b/cities/deployment/tracts_minneapolis/tracts_model_params.pth differ diff --git a/cities/utils/data_grabber.py b/cities/utils/data_grabber.py index bdd48780..3cb3736b 100644 --- a/cities/utils/data_grabber.py +++ b/cities/utils/data_grabber.py @@ -294,15 +294,15 @@ def get_features_std_long(self, features: List[str]) -> None: self._get_features(features, "std_long") -DataGrabber = DataGrabberDB - +# DataGrabber = DataGrabberDB +# DataGrabber = DataGrabberCSV -def MSADataGrabberFactory(): - return DataGrabberDB(level="msa") +# def MSADataGrabberFactory(): +# return DataGrabberDB(level="msa") -MSADataGrabber = MSADataGrabberFactory +# MSADataGrabber = MSADataGrabberFactory # this reverts to csvs -# DataGrabber = DataGrabberCSV -# MSADataGrabber = MSADataGrabberCSV +DataGrabber = DataGrabberCSV +MSADataGrabber = MSADataGrabberCSV diff --git a/data/minneapolis/.pgpass b/data/minneapolis/.pgpass new file mode 100644 index 00000000..ec7b3921 --- /dev/null +++ b/data/minneapolis/.pgpass @@ -0,0 +1 @@ +34.123.100.76:5432:cities:postgres:VA.TlSR#Z%mu**Q9 \ No newline at end of file diff --git a/data/minneapolis/sourced/demographic/ar-two-ts-one-predictor.ipynb b/data/minneapolis/sourced/demographic/ar-two-ts-one-predictor.ipynb new file mode 100644 index 00000000..0d6c2cb9 --- /dev/null +++ b/data/minneapolis/sourced/demographic/ar-two-ts-one-predictor.ipynb @@ -0,0 +1,836 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "import os\n", + "from typing import Dict, List\n", + "import math\n", + "import torch\n", + "import pyro\n", + "import pyro.distributions as dist\n", + "from ts_plots import plot_ts\n", + "import pyro.optim as optim\n", + "import pyro.infer as infer\n", + "import seaborn as sns \n", + "import matplotlib.pyplot as plt\n", + "import pyro\n", + "import torch\n", + "from chirho.indexed.ops import IndexSet, gather, indices_of\n", + "from pyro.infer.autoguide import (AutoMultivariateNormal, init_to_mean, AutoNormal,\n", + " AutoLowRankMultivariateNormal, AutoGaussian,)\n", + "import copy\n", + "\n", + "# import condition from chirho\n", + "from chirho.observational.handlers import condition\n", + "\n", + "\n", + "from torch.utils.data import DataLoader\n", + "\n", + "\n", + "\n", + "smoke_test = 'CI' in os.environ\n", + "\n", + "n_samples = 10 if smoke_test else 1000\n", + "n_steps = 10 if smoke_test else 500\n", + "n_series = 2 if smoke_test else 8 #TODO upgarde to 5" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [], + "source": [ + "census_tracts_data_path = \"pg_census_tracts_dataset.pt\"\n", + "\n", + "def select_from_data(data, kwarg_names: Dict[str, List[str]]):\n", + " _data = {}\n", + " _data[\"outcome\"] = data[\"continuous\"][kwarg_names[\"outcome\"]]\n", + " _data[\"categorical\"] = {\n", + " key: val\n", + " for key, val in data[\"categorical\"].items()\n", + " if key in kwarg_names[\"categorical\"]\n", + " }\n", + " _data[\"continuous\"] = {\n", + " key: val\n", + " for key, val in data[\"continuous\"].items()\n", + " if key in kwarg_names[\"continuous\"]\n", + " }\n", + "\n", + " return _data\n", + "\n", + "ct_dataset_read = torch.load(census_tracts_data_path, weights_only=False)\n", + "ct_loader = DataLoader(ct_dataset_read, batch_size=len(ct_dataset_read), shuffle=True)\n", + "data = next(iter(ct_loader))\n", + "\n", + "kwargs = {\n", + " \"categorical\": [\"year\", \"census_tract\", 'university_index', 'downtown_index'],\n", + " \"continuous\": {\n", + " \"housing_units\",\n", + " \"housing_units_original\"\n", + " \"total_value\",\n", + " \"median_value\",\n", + " \"mean_limit_original\",\n", + " \"median_distance\",\n", + " \"income\",\n", + " 'limit',\n", + " \"segregation_original\",\n", + " \"white_original\",\n", + " \"parcel_sqm\",\n", + " 'downtown_overlap', \n", + " 'university_overlap',\n", + " },\n", + " \"outcome\": \"housing_units\",\n", + "}\n", + "\n", + "subset = select_from_data(data, kwargs)" + ] + }, + { + "cell_type": "code", + "execution_count": 38, + "metadata": {}, + "outputs": [], + "source": [ + "outcome_obs = copy.deepcopy(subset['outcome'])\n", + "\n", + "series_idx = copy.deepcopy(subset['categorical']['census_tract'])\n", + "time_idx = copy.deepcopy(subset['categorical']['year'])\n", + "\n", + "\n", + "unique_series = torch.unique(series_idx)\n", + "unique_times = torch.unique(time_idx)\n", + "\n", + "num_series = unique_series.size(0)\n", + "time_steps = unique_times.size(0)\n", + "\n", + "reshaped_outcome = torch.empty((num_series, time_steps), dtype=outcome_obs.dtype)\n", + "reshaped_outcome[...,:] = torch.nan \n", + "\n", + "def reshape_into_time_series(variable, series_idx, time_idx):\n", + " \n", + " # raise value eror if they are not of the same shape\n", + " if variable.shape[0] != series_idx.shape[0] or variable.shape[0] != time_idx.shape[0]:\n", + " raise ValueError(\"The shapes of variable, series_idx, and time_idx must match.\")\n", + " \n", + " unique_series = torch.unique(series_idx)\n", + " unique_times = torch.unique(time_idx)\n", + "\n", + " num_series = unique_series.size(0)\n", + " time_steps = unique_times.size(0)\n", + "\n", + " reshaped_variable= torch.empty((num_series, time_steps), dtype=variable.dtype)\n", + " reshaped_variable[...,:] = torch.nan\n", + "\n", + " for i, series in enumerate(unique_series):\n", + " for j, time in enumerate(unique_times):\n", + " mask = (series_idx == series) & (time_idx == time)\n", + " index = torch.where(mask)[0]\n", + " if index.numel() > 0:\n", + " reshaped_variable[i, j] = variable[index]\n", + " \n", + " for i, series_id in enumerate(unique_series):\n", + " sorted_times, sorted_indices = torch.sort(time_idx[series_idx == series_id])\n", + " sorted_outcomes = outcome_obs[series_idx == series_id][sorted_indices]\n", + " assert torch.all(reshaped_variable[i,:] == sorted_outcomes)\n", + "\n", + " return { \"reshaped_variable\": reshaped_variable, \"unique_series\": unique_series, \"unique_times\": unique_times }\n", + "\n", + "reshaped_outcome_obs = reshape_into_time_series(outcome_obs, series_idx, time_idx) \n", + "outcome_obs_ts = reshaped_outcome_obs[\"reshaped_variable\"]\n" + ] + }, + { + "cell_type": "code", + "execution_count": 33, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "tensor([27053000101, 27053000102, 27053000300, 27053000601, 27053000603,\n", + " 27053001100, 27053001700, 27053002200, 27053002400, 27053002700,\n", + " 27053003200, 27053003300, 27053003800, 27053005901, 27053005902,\n", + " 27053006800, 27053007700, 27053007801, 27053008100, 27053008200,\n", + " 27053008300, 27053008400, 27053008500, 27053009500, 27053009600,\n", + " 27053010600, 27053010700, 27053011000, 27053011703, 27053011800,\n", + " 27053011998, 27053012001, 27053012003, 27053100200, 27053100400,\n", + " 27053100500, 27053100700, 27053100800, 27053100900, 27053101200,\n", + " 27053101300, 27053101600, 27053101800, 27053101900, 27053102000,\n", + " 27053102100, 27053102300, 27053102500, 27053102600, 27053102800,\n", + " 27053102900, 27053103000, 27053103100, 27053103400, 27053103600,\n", + " 27053103700, 27053103900, 27053104000, 27053104100, 27053104400,\n", + " 27053104800, 27053104900, 27053105100, 27053105201, 27053105204,\n", + " 27053105400, 27053105500, 27053105600, 27053105700, 27053106000,\n", + " 27053106200, 27053106400, 27053106500, 27053106600, 27053106700,\n", + " 27053106900, 27053107000, 27053107400, 27053107500, 27053107600,\n", + " 27053108000, 27053108600, 27053108700, 27053108800, 27053108900,\n", + " 27053109000, 27053109100, 27053109200, 27053109300, 27053109400,\n", + " 27053109700, 27053109800, 27053109900, 27053110000, 27053110100,\n", + " 27053110200, 27053110400, 27053110500, 27053110800, 27053110900,\n", + " 27053111100, 27053111200, 27053111300, 27053111400, 27053111500,\n", + " 27053111600, 27053125600, 27053125700, 27053125800, 27053125900,\n", + " 27053126000, 27053126100, 27053126200])\n", + "torch.Size([1130])\n" + ] + } + ], + "source": [ + "print(unique_series)\n", + "print(series_position.shape)" + ] + }, + { + "cell_type": "code", + "execution_count": 30, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "tensor([-0.3007, -0.3340, -0.3229, -0.3007, -0.3340, -0.3007, -0.3229, -0.3451,\n", + " -0.3007, -0.3340])\n" + ] + }, + { + "data": { + "text/plain": [ + "tensor([27053102800, 27053105600, 27053102000, ..., 27053108600,\n", + " 27053100200, 27053100700])" + ] + }, + "execution_count": 30, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "print(outcome_obs[series_idx == 27053102800])\n", + "\n", + "series_idx" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "torch.Size([8, 1])\n", + "predictor tensor([[ 1.0000, 1.0000, 1.0000, 1.0000, 1.0000, 1.0000, 1.0000, 1.0000,\n", + " 1.0000, 1.0000, 1.0000, 1.0000, 1.0000, 1.0000, 1.0000, 1.0000,\n", + " 1.0000, 1.0000, 1.0000, 1.0000, 1.0000, 1.0000, 1.0000, 1.0000,\n", + " 1.0000, -2.0000, -2.0000, -2.0000, -2.0000, -2.0000, -2.0000, -2.0000,\n", + " -2.0000, -2.0000, -2.0000, -2.0000, -2.0000, -2.0000, -2.0000, -2.0000,\n", + " -2.0000, -2.0000, -2.0000, -2.0000, -2.0000, -2.0000, -2.0000, -2.0000,\n", + " -2.0000, -2.0000],\n", + " [ 1.1000, 1.1000, 1.1000, 1.1000, 1.1000, 1.1000, 1.1000, 1.1000,\n", + " 1.1000, 1.1000, 1.1000, 1.1000, 1.1000, 1.1000, 1.1000, 1.1000,\n", + " 1.1000, 1.1000, 1.1000, 1.1000, 1.1000, 1.1000, 1.1000, 1.1000,\n", + " 1.1000, -1.8000, -1.8000, -1.8000, -1.8000, -1.8000, -1.8000, -1.8000,\n", + " -1.8000, -1.8000, -1.8000, -1.8000, -1.8000, -1.8000, -1.8000, -1.8000,\n", + " -1.8000, -1.8000, -1.8000, -1.8000, -1.8000, -1.8000, -1.8000, -1.8000,\n", + " -1.8000, -1.8000],\n", + " [ 1.2000, 1.2000, 1.2000, 1.2000, 1.2000, 1.2000, 1.2000, 1.2000,\n", + " 1.2000, 1.2000, 1.2000, 1.2000, 1.2000, 1.2000, 1.2000, 1.2000,\n", + " 1.2000, 1.2000, 1.2000, 1.2000, 1.2000, 1.2000, 1.2000, 1.2000,\n", + " 1.2000, -1.6000, -1.6000, -1.6000, -1.6000, -1.6000, -1.6000, -1.6000,\n", + " -1.6000, -1.6000, -1.6000, -1.6000, -1.6000, -1.6000, -1.6000, -1.6000,\n", + " -1.6000, -1.6000, -1.6000, -1.6000, -1.6000, -1.6000, -1.6000, -1.6000,\n", + " -1.6000, -1.6000],\n", + " [ 1.3000, 1.3000, 1.3000, 1.3000, 1.3000, 1.3000, 1.3000, 1.3000,\n", + " 1.3000, 1.3000, 1.3000, 1.3000, 1.3000, 1.3000, 1.3000, 1.3000,\n", + " 1.3000, 1.3000, 1.3000, 1.3000, 1.3000, 1.3000, 1.3000, 1.3000,\n", + " 1.3000, -1.4000, -1.4000, -1.4000, -1.4000, -1.4000, -1.4000, -1.4000,\n", + " -1.4000, -1.4000, -1.4000, -1.4000, -1.4000, -1.4000, -1.4000, -1.4000,\n", + " -1.4000, -1.4000, -1.4000, -1.4000, -1.4000, -1.4000, -1.4000, -1.4000,\n", + " -1.4000, -1.4000],\n", + " [ 3.4000, 3.4000, 3.4000, 3.4000, 3.4000, 3.4000, 3.4000, 3.4000,\n", + " 3.4000, 3.4000, 3.4000, 3.4000, 3.4000, 3.4000, 3.4000, 3.4000,\n", + " 3.4000, 3.4000, 3.4000, 3.4000, 3.4000, 3.4000, 3.4000, 3.4000,\n", + " 3.4000, 4.8000, 4.8000, 4.8000, 4.8000, 4.8000, 4.8000, 4.8000,\n", + " 4.8000, 4.8000, 4.8000, 4.8000, 4.8000, 4.8000, 4.8000, 4.8000,\n", + " 4.8000, 4.8000, 4.8000, 4.8000, 4.8000, 4.8000, 4.8000, 4.8000,\n", + " 4.8000, 4.8000],\n", + " [ 3.5000, 3.5000, 3.5000, 3.5000, 3.5000, 3.5000, 3.5000, 3.5000,\n", + " 3.5000, 3.5000, 3.5000, 3.5000, 3.5000, 3.5000, 3.5000, 3.5000,\n", + " 3.5000, 3.5000, 3.5000, 3.5000, 3.5000, 3.5000, 3.5000, 3.5000,\n", + " 3.5000, 5.0000, 5.0000, 5.0000, 5.0000, 5.0000, 5.0000, 5.0000,\n", + " 5.0000, 5.0000, 5.0000, 5.0000, 5.0000, 5.0000, 5.0000, 5.0000,\n", + " 5.0000, 5.0000, 5.0000, 5.0000, 5.0000, 5.0000, 5.0000, 5.0000,\n", + " 5.0000, 5.0000],\n", + " [ 3.6000, 3.6000, 3.6000, 3.6000, 3.6000, 3.6000, 3.6000, 3.6000,\n", + " 3.6000, 3.6000, 3.6000, 3.6000, 3.6000, 3.6000, 3.6000, 3.6000,\n", + " 3.6000, 3.6000, 3.6000, 3.6000, 3.6000, 3.6000, 3.6000, 3.6000,\n", + " 3.6000, 5.2000, 5.2000, 5.2000, 5.2000, 5.2000, 5.2000, 5.2000,\n", + " 5.2000, 5.2000, 5.2000, 5.2000, 5.2000, 5.2000, 5.2000, 5.2000,\n", + " 5.2000, 5.2000, 5.2000, 5.2000, 5.2000, 5.2000, 5.2000, 5.2000,\n", + " 5.2000, 5.2000],\n", + " [ 3.7000, 3.7000, 3.7000, 3.7000, 3.7000, 3.7000, 3.7000, 3.7000,\n", + " 3.7000, 3.7000, 3.7000, 3.7000, 3.7000, 3.7000, 3.7000, 3.7000,\n", + " 3.7000, 3.7000, 3.7000, 3.7000, 3.7000, 3.7000, 3.7000, 3.7000,\n", + " 3.7000, 5.4000, 5.4000, 5.4000, 5.4000, 5.4000, 5.4000, 5.4000,\n", + " 5.4000, 5.4000, 5.4000, 5.4000, 5.4000, 5.4000, 5.4000, 5.4000,\n", + " 5.4000, 5.4000, 5.4000, 5.4000, 5.4000, 5.4000, 5.4000, 5.4000,\n", + " 5.4000, 5.4000]])\n", + "init tensor([[ 1.6614],\n", + " [ 1.2669],\n", + " [ 1.0617],\n", + " [ 1.6213],\n", + " [ 0.5481],\n", + " [ 0.8339],\n", + " [-0.5228],\n", + " [ 1.3817]]) torch.Size([8, 1])\n", + "ytrue tensor([0., 0., 0., 0., 0., 0., 0., 0.]) torch.Size([8])\n", + "init tensor([[ 1.6614],\n", + " [ 1.2669],\n", + " [ 1.0617],\n", + " [ 1.6213],\n", + " [ 0.5481],\n", + " [ 0.8339],\n", + " [-0.5228],\n", + " [ 1.3817]]) torch.Size([8, 1])\n", + "sampling tensor([1.1645, 1.0568, 1.0247, 1.2985, 1.9192, 2.0835, 1.5909, 2.4027]) tensor([0.9590, 0.9442, 0.8462, 1.2869, 1.8801, 1.8904, 1.6754, 2.4561]) 0.2\n", + "sampling tensor([0.8836, 0.9277, 0.9385, 1.1648, 2.4521, 2.5062, 2.4702, 2.8325]) tensor([0.7994, 0.8255, 0.6240, 1.1401, 3.1695, 2.1399, 2.7899, 2.5771]) 0.2\n", + "sampling tensor([0.8197, 0.8802, 0.8496, 1.1060, 2.9678, 2.6060, 2.9160, 2.8808]) tensor([0.8848, 0.7844, 1.1254, 1.6118, 3.0499, 2.4084, 2.7343, 2.9893]) 0.2\n", + "sampling tensor([0.8539, 0.8638, 1.0502, 1.2947, 2.9200, 2.7133, 2.8937, 3.0457]) tensor([0.8760, 0.4120, 1.1715, 1.2670, 3.0862, 2.6638, 2.7331, 3.0930]) 0.2\n", + "sampling tensor([0.8504, 0.7148, 1.0686, 1.1568, 2.9345, 2.8155, 2.8933, 3.0872]) tensor([0.9075, 0.8527, 0.9420, 1.3327, 2.7976, 2.9062, 2.9515, 2.9209]) 0.2\n", + "sampling tensor([0.8630, 0.8911, 0.9768, 1.1831, 2.8191, 2.9125, 2.9806, 3.0183]) tensor([0.7525, 1.0182, 0.8974, 1.0517, 2.4905, 3.1085, 2.9722, 2.8542]) 0.2\n", + "sampling tensor([0.8010, 0.9573, 0.9590, 1.0707, 2.6962, 2.9934, 2.9889, 2.9917]) tensor([0.8637, 0.7302, 1.0344, 1.0142, 2.1829, 2.7073, 3.0891, 3.1004]) 0.2\n", + "sampling tensor([0.8455, 0.8421, 1.0138, 1.0557, 2.5731, 2.8329, 3.0356, 3.0902]) tensor([0.7643, 1.0689, 0.7915, 1.1257, 2.4191, 2.8035, 3.1611, 3.3089]) 0.2\n", + "sampling tensor([0.8057, 0.9776, 0.9166, 1.1003, 2.6676, 2.8714, 3.0644, 3.1735]) tensor([0.8245, 1.2252, 0.6474, 1.2027, 2.5290, 2.8380, 2.8644, 2.8440]) 0.2\n", + "sampling tensor([0.8298, 1.0401, 0.8590, 1.1311, 2.7116, 2.8852, 2.9458, 2.9876]) tensor([0.9918, 1.0512, 1.0858, 1.0245, 2.8434, 2.5659, 2.8704, 2.3672]) 0.2\n", + "sampling tensor([0.8967, 0.9705, 1.0343, 1.0598, 2.8374, 2.7764, 2.9482, 2.7969]) tensor([0.8768, 0.8262, 1.2885, 1.0594, 2.6183, 2.8967, 3.0878, 2.6368]) 0.2\n", + "sampling tensor([0.8507, 0.8805, 1.1154, 1.0738, 2.7473, 2.9087, 3.0351, 2.9047]) tensor([1.1584, 1.1739, 1.4344, 0.7682, 2.9505, 2.8683, 2.7778, 3.0693]) 0.2\n", + "sampling tensor([0.9633, 1.0196, 1.1738, 0.9573, 2.8802, 2.8973, 2.9111, 3.0777]) tensor([0.8413, 0.7604, 0.9851, 1.0909, 3.1127, 2.8327, 3.2868, 2.9644]) 0.2\n", + "sampling tensor([0.8365, 0.8542, 0.9940, 1.0864, 2.9451, 2.8831, 3.1147, 3.0358]) tensor([0.9169, 0.8311, 1.0574, 1.1989, 3.1183, 2.8125, 3.1844, 3.2632]) 0.2\n", + "sampling tensor([0.8667, 0.8824, 1.0230, 1.1296, 2.9473, 2.8750, 3.0737, 3.1553]) tensor([0.8000, 0.5880, 1.1689, 1.1033, 2.8200, 3.0836, 3.1718, 3.3616]) 0.2\n", + "sampling tensor([0.8200, 0.7852, 1.0676, 1.0913, 2.8280, 2.9834, 3.0687, 3.1947]) tensor([0.7002, 1.1055, 0.8529, 0.8479, 2.9574, 2.9752, 3.0332, 3.0946]) 0.2\n", + "sampling tensor([0.7801, 0.9922, 0.9411, 0.9891, 2.8830, 2.9401, 3.0133, 3.0879]) tensor([0.9535, 0.9376, 0.8490, 0.9693, 2.9775, 3.1411, 2.9559, 2.8555]) 0.2\n", + "sampling tensor([0.8814, 0.9250, 0.9396, 1.0377, 2.8910, 3.0064, 2.9823, 2.9922]) tensor([0.8869, 1.0381, 0.9373, 1.1719, 2.7924, 3.3074, 2.5171, 3.3156]) 0.2\n", + "sampling tensor([0.8548, 0.9652, 0.9749, 1.1187, 2.8170, 3.0730, 2.8068, 3.1762]) tensor([0.6742, 1.0000, 0.9904, 0.9320, 2.8353, 3.3518, 2.6693, 3.0751]) 0.2\n", + "sampling tensor([0.7697, 0.9500, 0.9961, 1.0228, 2.8341, 3.0907, 2.8677, 3.0800]) tensor([0.8082, 1.0932, 0.8338, 0.7305, 2.8807, 3.1286, 2.8236, 3.1098]) 0.2\n", + "sampling tensor([0.8233, 0.9873, 0.9335, 0.9422, 2.8523, 3.0014, 2.9295, 3.0939]) tensor([0.8253, 0.9624, 1.2274, 0.8632, 2.7502, 3.2247, 2.8109, 3.2757]) 0.2\n", + "sampling tensor([0.8301, 0.9350, 1.0910, 0.9953, 2.8001, 3.0399, 2.9244, 3.1603]) tensor([0.6143, 0.7999, 1.3726, 0.6261, 2.6870, 2.8580, 2.8266, 3.0368]) 0.2\n", + "sampling tensor([0.7457, 0.8700, 1.1491, 0.9005, 2.7748, 2.8932, 2.9306, 3.0647]) tensor([0.8224, 0.9470, 1.3068, 1.1277, 2.7519, 2.8896, 2.9404, 3.1502]) 0.2\n", + "sampling tensor([0.8290, 0.9288, 1.1227, 1.1011, 2.8007, 2.9058, 2.9762, 3.1101]) tensor([0.6490, 1.0351, 1.2034, 1.3915, 2.3171, 2.6677, 3.1155, 3.3360]) 0.2\n", + "sampling tensor([-0.7404, -0.4860, -0.3186, -0.1434, 3.3268, 3.5671, 3.8462, 4.0344]) tensor([-0.6961, -0.4971, -0.0775, 0.2463, 3.3115, 3.3958, 3.6888, 3.8712]) 0.2\n", + "sampling tensor([-1.2784, -1.0989, -0.8310, -0.6015, 3.7246, 3.8583, 4.0755, 4.2485]) tensor([-1.1690, -1.3330, -0.9250, -0.9269, 3.7021, 4.1779, 3.9066, 4.0387]) 0.2\n", + "sampling tensor([-1.4676, -1.4332, -1.1700, -1.0708, 3.8808, 4.1712, 4.1626, 4.3155]) tensor([-1.2799, -1.3256, -0.8626, -1.2096, 3.9243, 4.1113, 4.0877, 4.6889]) 0.2\n", + "sampling tensor([-1.5120, -1.4303, -1.1450, -1.1838, 3.9697, 4.1445, 4.2351, 4.5756]) tensor([-1.3311, -1.4066, -0.7662, -1.2684, 4.1184, 4.1596, 4.4624, 4.1900]) 0.2\n", + "sampling tensor([-1.5324, -1.4627, -1.1065, -1.2074, 4.0473, 4.1639, 4.3850, 4.3760]) tensor([-1.6437, -1.4913, -0.5709, -1.0727, 4.1306, 3.9616, 4.4953, 4.5742]) 0.2\n", + "sampling tensor([-1.6575, -1.4965, -1.0283, -1.1291, 4.0522, 4.0847, 4.3981, 4.5297]) tensor([-1.8631, -1.6930, -1.4019, -1.0118, 3.9594, 3.8904, 4.1861, 4.6715]) 0.2\n", + "sampling tensor([-1.7452, -1.5772, -1.3608, -1.1047, 3.9838, 4.0561, 4.2744, 4.5686]) tensor([-1.7631, -1.7439, -1.2705, -1.2866, 3.9983, 4.2274, 4.0546, 4.6271]) 0.2\n", + "sampling tensor([-1.7053, -1.5976, -1.3082, -1.2146, 3.9993, 4.1910, 4.2219, 4.5508]) tensor([-1.5366, -1.5879, -1.0659, -1.5067, 4.3592, 4.2945, 3.9881, 4.7027]) 0.2\n", + "sampling tensor([-1.6146, -1.5351, -1.2264, -1.3027, 4.1437, 4.2178, 4.1953, 4.5811]) tensor([-1.9884, -1.4237, -1.1947, -1.4989, 3.9685, 4.1652, 4.1970, 4.5946]) 0.2\n", + "sampling tensor([-1.7954, -1.4695, -1.2779, -1.2996, 3.9874, 4.1661, 4.2788, 4.5379]) tensor([-1.8362, -1.5743, -1.3397, -1.2107, 3.7901, 3.8011, 4.3986, 4.7661]) 0.2\n", + "sampling tensor([-1.7345, -1.5297, -1.3359, -1.1843, 3.9161, 4.0204, 4.3594, 4.6065]) tensor([-1.7281, -1.4548, -1.3361, -0.9866, 4.1320, 3.7112, 4.3819, 4.2332]) 0.2\n", + "sampling tensor([-1.6912, -1.4819, -1.3344, -1.0946, 4.0528, 3.9845, 4.3528, 4.3933]) tensor([-1.9101, -1.4205, -1.0189, -1.2292, 4.3946, 4.0302, 4.4955, 4.1212]) 0.2\n", + "sampling tensor([-1.7641, -1.4682, -1.2076, -1.1917, 4.1578, 4.1121, 4.3982, 4.3485]) tensor([-1.6857, -1.4738, -1.0328, -1.6376, 3.9828, 3.6963, 4.5198, 4.2196]) 0.2\n", + "sampling tensor([-1.6743, -1.4895, -1.2131, -1.3550, 3.9931, 3.9785, 4.4079, 4.3878]) tensor([-1.7335, -1.5964, -0.8609, -1.5713, 3.7540, 4.0331, 4.0207, 4.1290]) 0.2\n", + "sampling tensor([-1.6934, -1.5386, -1.1444, -1.3285, 3.9016, 4.1132, 4.2083, 4.3516]) tensor([-1.7766, -1.5831, -1.1011, -1.2238, 4.0234, 4.2672, 4.3486, 4.3273]) 0.2\n", + "sampling tensor([-1.7106, -1.5333, -1.2404, -1.1895, 4.0094, 4.2069, 4.3395, 4.4309]) tensor([-2.0009, -1.9794, -1.5991, -1.3017, 3.8831, 4.2267, 4.2345, 4.2356]) 0.2\n", + "sampling tensor([-1.8004, -1.6917, -1.4397, -1.2207, 3.9532, 4.1907, 4.2938, 4.3942]) tensor([-1.5994, -1.4702, -1.3363, -1.2015, 3.9650, 3.9079, 4.2204, 4.7107]) 0.2\n", + "sampling tensor([-1.6397, -1.4881, -1.3345, -1.1806, 3.9860, 4.0632, 4.2882, 4.5843]) tensor([-1.7306, -1.1702, -1.0202, -1.2503, 4.0385, 3.9392, 4.1451, 4.6010]) 0.2\n", + "sampling tensor([-1.6923, -1.3681, -1.2081, -1.2001, 4.0154, 4.0757, 4.2580, 4.5404]) tensor([-1.6326, -0.9675, -1.0959, -1.5258, 3.7411, 3.8427, 4.0080, 4.6235]) 0.2\n", + "sampling tensor([-1.6531, -1.2870, -1.2384, -1.3103, 3.8964, 4.0371, 4.2032, 4.5494]) tensor([-1.5052, -1.4606, -1.1210, -1.3427, 3.6279, 4.1991, 4.4115, 4.6487]) 0.2\n", + "sampling tensor([-1.6021, -1.4842, -1.2484, -1.2371, 3.8512, 4.1796, 4.3646, 4.5595]) tensor([-1.2590, -1.7062, -1.1769, -1.3045, 3.8121, 4.5182, 4.1822, 4.5201]) 0.2\n", + "sampling tensor([-1.5036, -1.5825, -1.2708, -1.2218, 3.9249, 4.3073, 4.2729, 4.5080]) tensor([-1.3670, -1.4537, -1.5777, -1.1912, 3.8517, 4.3122, 4.2566, 4.8096]) 0.2\n", + "sampling tensor([-1.5468, -1.4815, -1.4311, -1.1765, 3.9407, 4.2249, 4.3026, 4.6238]) tensor([-1.3126, -1.3427, -1.2613, -1.1219, 4.0166, 4.2344, 4.5727, 4.6434]) 0.2\n", + "sampling tensor([-1.5250, -1.4371, -1.3045, -1.1488, 4.0066, 4.1938, 4.4291, 4.5574]) tensor([-1.8126, -1.0757, -1.5558, -0.8167, 3.8255, 4.0765, 4.6362, 4.6970]) 0.2\n", + "sampling tensor([-1.7250, -1.3303, -1.4223, -1.0267, 3.9302, 4.1306, 4.4545, 4.5788]) tensor([-1.4974, -1.4293, -1.4973, -0.9230, 3.7944, 4.4144, 4.6211, 4.2113]) 0.2\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "/tmp/ipykernel_259967/3164560226.py:57: UserWarning: FigureCanvasAgg is non-interactive, and thus cannot be shown\n", + " fig.show()\n" + ] + }, + { + "data": { + "image/png": "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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "# true ar1 process\n", + "T = 50\n", + "n_series = n_series\n", + "\n", + "true_phi = .4\n", + "true_sigma = .2\n", + "\n", + "true_contribution = 0.5\n", + "\n", + " # 2D tensor of shape (n_series, 1) with random values\n", + " #set seed\n", + "torch.manual_seed(1)\n", + "\n", + "with pyro.plate(\"series\", n_series, dim = -2):\n", + " init = pyro.sample(\"init\", dist.Normal(1, 1))\n", + " \n", + "mid = T//2\n", + "\n", + "predictor = torch.zeros((n_series,T))\n", + "for i in range(n_series//2):\n", + " predictor[i,:mid] = 1. + i/10\n", + " predictor[i, mid:] = -2. + 2*i/10\n", + "\n", + "for i in range(n_series//2, n_series):\n", + " predictor[i,:mid] = 3. + i/10\n", + " predictor[i, mid:] = 4. + 2*i/10\n", + "\n", + "\n", + "print(\"predictor\", predictor)\n", + "\n", + "print(\"init\", init, init.shape)\n", + "y_true = torch.zeros((n_series,T))\n", + "y_exp_true = torch.zeros( (n_series,T))\n", + "y_prev_true = torch.zeros((n_series,T))\n", + "\n", + "\n", + "y_exp_true[:,0] = true_contribution * predictor[:,0]\n", + "print(\"ytrue\", y_true[:,0], y_true[:,0].shape)\n", + "print(\"init\", init, init.shape)\n", + "y_true[:,0] = init.squeeze()\n", + "\n", + "\n", + "for t in range(1, T):\n", + " \n", + " y_prev_true[:,t] = y_true[:,t-1]\n", + " y_exp_true[:,t] = true_phi * y_prev_true[...,:,t] + true_contribution * predictor[...,:,t] \n", + " \n", + " y_true[:,t] = pyro.sample(f\"y_{t}\", dist.Normal(y_exp_true[:,t], true_sigma))\n", + " print(\"sampling\", y_exp_true[:,t], y_true[:,t], true_sigma)\n", + " \n", + "\n", + "fig, ax= plot_ts(y_true, title=f\"{n_series} true AR(1) processes\", xlabel=\"t\", ylabel=\"y\",)\n", + "fig.show()\n" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "tensor([[ 1.6614],\n", + " [ 1.2669],\n", + " [ 1.0617],\n", + " [ 1.6213],\n", + " [ 0.5481],\n", + " [ 0.8339],\n", + " [-0.5228],\n", + " [ 1.3817]])\n" + ] + } + ], + "source": [ + "class AR1model(pyro.nn.PyroModule):\n", + " def __init__(self):\n", + " super().__init__()\n", + "\n", + " def forward(self, outcome_obs = None, predictor_obs = None,\n", + " initial_obs = None, T = None, no_series = n_series):\n", + "\n", + " if outcome_obs is not None:\n", + " T = outcome_obs.shape[-1]\n", + "\n", + "\n", + " phi = pyro.sample(\"phi\", dist.Normal(1., 0.4)) \n", + " sigma = pyro.sample(\"sigma\", dist.Uniform(0.001, 1.0))\n", + " \n", + "\n", + " contribution = pyro.sample(\"contribution\", dist.Normal(0.02, 1.))\n", + "\n", + " series_plate = pyro.plate(\"series\", no_series, dim = -2)\n", + "\n", + " time_plate = pyro.plate(\"time\", T, dim=-1)\n", + "\n", + " with series_plate:\n", + " \n", + " with time_plate:\n", + " predictor = pyro.sample( \"predictor\", dist.Normal(0.0, 1.0), obs=predictor_obs)\n", + "\n", + " \n", + " y_ts = {}\n", + " y_exp = {}\n", + " y_prev = {}\n", + "\n", + " \n", + " y_prev[0] = torch.zeros_like(predictor[...,:,0].unsqueeze(-1))\n", + "\n", + "\n", + " with series_plate:\n", + "\n", + " y_exp[0] = contribution * predictor[...,:,0].unsqueeze(-1)\n", + " \n", + " y_ts[0]= pyro.sample(\"y_0\", dist.Normal(y_exp[0], sigma), obs=initial_obs)\n", + "\n", + "\n", + " for t in range(1, T):\n", + " \n", + " with series_plate:\n", + " y_prev[t] = y_ts[t-1]\n", + " pred_slice = predictor[...,:,t].unsqueeze(-1)\n", + " y_exp[t] = pyro.deterministic(f\"y_exp_{t}\", phi * y_prev[t] + contribution * pred_slice)\n", + " \n", + " y_ts[t] = pyro.sample(f\"y_{t}\", dist.Normal(y_exp[t], sigma), \n", + " obs=outcome_obs[:,t].unsqueeze(-1) if outcome_obs is not None else None)\n", + " \n", + " y_ts_stacked = pyro.deterministic(\"y_stacked\", torch.cat(list(y_ts.values()), dim=1))\n", + " \n", + " return y_ts, y_ts_stacked\n", + "\n", + "ar1_model = AR1model()\n", + "\n", + "print(init)\n", + "\n", + "with condition(data = {\"phi\": true_phi, \"sigma\": true_sigma, \"contribution\": true_contribution}):\n", + " with pyro.poutine.trace() as tr:\n", + " _, y_intermediate = ar1_model(outcome_obs=None, initial_obs=init, \n", + " predictor_obs=predictor, T=T, no_series=n_series)" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "odict_keys(['phi', 'sigma', 'contribution', 'series', 'time', 'init', 'predictor', 'y_0', 'y_exp_1', 'y_1', 'y_exp_2', 'y_2', 'y_exp_3', 'y_3', 'y_exp_4', 'y_4', 'y_exp_5', 'y_5', 'y_exp_6', 'y_6', 'y_exp_7', 'y_7', 'y_exp_8', 'y_8', 'y_exp_9', 'y_9', 'y_exp_10', 'y_10', 'y_exp_11', 'y_11', 'y_exp_12', 'y_12', 'y_exp_13', 'y_13', 'y_exp_14', 'y_14', 'y_exp_15', 'y_15', 'y_exp_16', 'y_16', 'y_exp_17', 'y_17', 'y_exp_18', 'y_18', 'y_exp_19', 'y_19', 'y_exp_20', 'y_20', 'y_exp_21', 'y_21', 'y_exp_22', 'y_22', 'y_exp_23', 'y_23', 'y_exp_24', 'y_24', 'y_exp_25', 'y_25', 'y_exp_26', 'y_26', 'y_exp_27', 'y_27', 'y_exp_28', 'y_28', 'y_exp_29', 'y_29', 'y_exp_30', 'y_30', 'y_exp_31', 'y_31', 'y_exp_32', 'y_32', 'y_exp_33', 'y_33', 'y_exp_34', 'y_34', 'y_exp_35', 'y_35', 'y_exp_36', 'y_36', 'y_exp_37', 'y_37', 'y_exp_38', 'y_38', 'y_exp_39', 'y_39', 'y_exp_40', 'y_40', 'y_exp_41', 'y_41', 'y_exp_42', 'y_42', 'y_exp_43', 'y_43', 'y_exp_44', 'y_44', 'y_exp_45', 'y_45', 'y_exp_46', 'y_46', 'y_exp_47', 'y_47', 'y_exp_48', 'y_48', 'y_exp_49', 'y_49', 'y_prev_stacked', 'y_exp_stacked', 'y_stacked'])\n", + "tensor([0.5000, 0.5500, 0.6000, 0.6500, 1.7000, 1.7500, 1.8000, 1.8500]) tensor([0.5000, 0.5500, 0.6000, 0.6500, 1.7000, 1.7500, 1.8000, 1.8500])\n", + "tensor([1.1645, 1.0568, 1.0247, 1.2985, 1.9192, 2.0835, 1.5909, 2.4027]) tensor([1.1645, 1.0568, 1.0247, 1.2985, 1.9192, 2.0835, 1.5909, 2.4027])\n", + "tensor([0.8836, 0.9277, 0.9385, 1.1648, 2.4521, 2.5062, 2.4702, 2.8325]) tensor([1.0502, 0.9273, 1.0581, 1.3108, 2.4210, 2.6779, 2.2307, 2.8185])\n", + "tensor([0.8197, 0.8802, 0.8496, 1.1060, 2.9678, 2.6060, 2.9160, 2.8808]) tensor([1.0123, 0.8076, 0.9897, 1.4341, 2.6439, 2.8260, 2.7146, 3.0477])\n", + "tensor([0.8539, 0.8638, 1.0502, 1.2947, 2.9200, 2.7133, 2.8937, 3.0457]) tensor([0.8916, 0.9109, 0.9697, 1.2109, 2.7454, 2.7820, 2.7742, 3.0364])\n", + "tensor([0.8504, 0.7148, 1.0686, 1.1568, 2.9345, 2.8155, 2.8933, 3.0872]) tensor([0.8743, 0.9516, 1.1500, 1.0170, 2.7246, 2.7563, 2.7727, 3.0428])\n", + "tensor([0.8630, 0.8911, 0.9768, 1.1831, 2.8191, 2.9125, 2.9806, 3.0183]) tensor([0.9627, 1.0049, 1.0865, 1.0314, 2.8402, 2.6880, 2.9638, 3.0245])\n", + "tensor([0.8010, 0.9573, 0.9590, 1.0707, 2.6962, 2.9934, 2.9889, 2.9917]) tensor([0.8729, 0.8960, 1.0738, 1.0944, 2.8961, 2.8426, 3.0439, 3.1306])\n", + "tensor([0.8455, 0.8421, 1.0138, 1.0557, 2.5731, 2.8329, 3.0356, 3.0902]) tensor([0.8652, 0.9206, 1.0096, 1.2486, 2.9276, 2.9358, 2.9242, 3.1912])\n", + "tensor([0.8057, 0.9776, 0.9166, 1.1003, 2.6676, 2.8714, 3.0644, 3.1735]) tensor([0.8726, 1.1580, 0.9862, 1.1014, 2.8368, 2.8784, 2.9254, 3.0789])\n", + "tensor([0.8298, 1.0401, 0.8590, 1.1311, 2.7116, 2.8852, 2.9458, 2.9876]) tensor([0.8158, 1.0143, 1.0263, 1.0887, 2.8517, 2.8923, 2.9601, 3.2067])\n", + "tensor([0.8967, 0.9705, 1.0343, 1.0598, 2.8374, 2.7764, 2.9482, 2.7969]) tensor([0.8760, 0.9548, 1.0525, 1.0189, 2.9125, 3.0329, 3.0194, 3.1012])\n", + "tensor([0.8507, 0.8805, 1.1154, 1.0738, 2.7473, 2.9087, 3.0351, 2.9047]) tensor([0.8096, 0.8901, 1.0790, 0.9685, 2.7349, 3.0110, 3.0408, 3.1209])\n", + "tensor([0.9633, 1.0196, 1.1738, 0.9573, 2.8802, 2.8973, 2.9111, 3.0777]) tensor([0.8745, 1.0499, 0.9375, 1.1455, 2.6899, 3.0113, 2.9424, 3.1455])\n", + "tensor([0.8365, 0.8542, 0.9940, 1.0864, 2.9451, 2.8831, 3.1147, 3.0358]) tensor([0.8359, 0.9203, 0.8611, 1.0428, 2.8268, 3.0387, 3.0766, 2.9582])\n", + "tensor([0.8667, 0.8824, 1.0230, 1.1296, 2.9473, 2.8750, 3.0737, 3.1553]) tensor([0.8258, 0.9340, 0.9788, 1.0379, 2.7741, 2.9866, 3.1595, 3.0339])\n", + "tensor([0.8200, 0.7852, 1.0676, 1.0913, 2.8280, 2.9834, 3.0687, 3.1947]) tensor([0.7733, 0.8297, 1.0582, 1.1030, 2.9505, 2.8937, 3.0980, 2.9975])\n", + "tensor([0.7801, 0.9922, 0.9411, 0.9891, 2.8830, 2.9401, 3.0133, 3.0879]) tensor([0.8556, 0.8375, 1.0603, 1.0193, 2.9080, 2.8303, 2.9387, 2.9179])\n", + "tensor([0.8814, 0.9250, 0.9396, 1.0377, 2.8910, 3.0064, 2.9823, 2.9922]) tensor([0.9416, 1.0208, 1.0046, 1.0556, 2.8464, 3.0221, 3.0801, 3.0434])\n", + "tensor([0.8548, 0.9652, 0.9749, 1.1187, 2.8170, 3.0730, 2.8068, 3.1762]) tensor([0.7694, 0.9122, 1.1662, 0.9579, 2.8433, 2.9017, 3.0328, 2.9312])\n", + "tensor([0.7697, 0.9500, 0.9961, 1.0228, 2.8341, 3.0907, 2.8677, 3.0800]) tensor([0.8695, 0.8874, 1.1264, 1.0153, 2.8599, 2.9131, 2.9261, 2.8543])\n", + "tensor([0.8233, 0.9873, 0.9335, 0.9422, 2.8523, 3.0014, 2.9295, 3.0939]) tensor([1.0712, 0.9299, 1.0466, 1.0515, 2.8432, 2.9389, 2.9508, 3.1740])\n", + "tensor([0.8301, 0.9350, 1.0910, 0.9953, 2.8001, 3.0399, 2.9244, 3.1603]) tensor([0.9582, 0.9080, 1.1097, 0.9560, 2.8583, 3.0293, 3.0668, 3.1522])\n", + "tensor([0.7457, 0.8700, 1.1491, 0.9005, 2.7748, 2.8932, 2.9306, 3.0647]) tensor([0.8080, 0.8076, 1.1719, 1.1376, 2.7944, 2.8864, 3.0133, 2.9750])\n", + "tensor([0.8290, 0.9288, 1.1227, 1.1011, 2.8007, 2.9058, 2.9762, 3.1101]) tensor([0.6574, 0.9978, 1.0282, 0.9728, 2.8105, 2.8191, 2.9675, 3.0369])\n", + "tensor([-0.7404, -0.4860, -0.3186, -0.1434, 3.3268, 3.5671, 3.8462, 4.0344]) tensor([-0.7375, -0.5097, -0.3774, -0.2913, 3.4742, 3.5643, 3.8861, 3.9855])\n", + "tensor([-1.2784, -1.0989, -0.8310, -0.6015, 3.7246, 3.8583, 4.0755, 4.2485]) tensor([-1.3301, -1.1797, -1.0378, -0.8174, 3.8348, 3.8820, 4.1075, 4.2840])\n", + "tensor([-1.4676, -1.4332, -1.1700, -1.0708, 3.8808, 4.1712, 4.1626, 4.3155]) tensor([-1.7230, -1.3804, -1.1281, -1.0717, 3.9592, 4.1742, 4.2534, 4.3393])\n", + "tensor([-1.5120, -1.4303, -1.1450, -1.1838, 3.9697, 4.1445, 4.2351, 4.5756]) tensor([-1.7691, -1.5664, -1.3102, -1.1311, 3.9939, 4.1693, 4.1149, 4.4613])\n", + "tensor([-1.5324, -1.4627, -1.1065, -1.2074, 4.0473, 4.1639, 4.3850, 4.3760]) tensor([-1.8056, -1.3707, -1.1896, -1.0990, 3.8874, 4.1342, 4.1281, 4.4463])\n", + "tensor([-1.6575, -1.4965, -1.0283, -1.1291, 4.0522, 4.0847, 4.3981, 4.5297]) tensor([-1.6782, -1.5440, -1.2719, -1.2843, 4.1154, 4.2316, 4.2942, 4.5359])\n", + "tensor([-1.7452, -1.5772, -1.3608, -1.1047, 3.9838, 4.0561, 4.2744, 4.5686]) tensor([-1.5704, -1.5229, -1.1246, -1.3332, 3.9616, 4.0951, 4.3739, 4.6010])\n", + "tensor([-1.7053, -1.5976, -1.3082, -1.2146, 3.9993, 4.1910, 4.2219, 4.5508]) tensor([-1.5132, -1.4700, -1.1067, -1.1595, 4.0973, 4.1015, 4.3584, 4.5211])\n", + "tensor([-1.6146, -1.5351, -1.2264, -1.3027, 4.1437, 4.2178, 4.1953, 4.5811]) tensor([-1.5861, -1.3731, -1.2480, -1.0940, 4.0933, 4.1043, 4.3262, 4.3598])\n", + "tensor([-1.7954, -1.4695, -1.2779, -1.2996, 3.9874, 4.1661, 4.2788, 4.5379]) tensor([-1.6687, -1.2991, -1.2302, -1.1314, 4.1098, 4.2381, 4.4349, 4.4850])\n", + "tensor([-1.7345, -1.5297, -1.3359, -1.1843, 3.9161, 4.0204, 4.3594, 4.6065]) tensor([-1.7697, -1.5314, -1.3945, -1.1723, 4.0106, 4.2833, 4.3849, 4.3810])\n", + "tensor([-1.6912, -1.4819, -1.3344, -1.0946, 4.0528, 3.9845, 4.3528, 4.3933]) tensor([-1.6579, -1.6825, -1.3609, -1.1451, 3.8681, 4.1977, 4.2091, 4.2931])\n", + "tensor([-1.7641, -1.4682, -1.2076, -1.1917, 4.1578, 4.1121, 4.3982, 4.3485]) tensor([-1.6826, -1.6192, -1.2888, -1.2383, 3.9444, 4.0677, 4.2555, 4.5724])\n", + "tensor([-1.6743, -1.4895, -1.2131, -1.3550, 3.9931, 3.9785, 4.4079, 4.3878]) tensor([-1.6393, -1.5431, -1.4845, -1.0267, 4.0036, 4.0963, 4.2806, 4.5675])\n", + "tensor([-1.6934, -1.5386, -1.1444, -1.3285, 3.9016, 4.1132, 4.2083, 4.3516]) tensor([-1.6855, -1.5984, -1.4361, -1.0818, 3.9685, 4.1836, 4.3519, 4.6738])\n", + "tensor([-1.7106, -1.5333, -1.2404, -1.1895, 4.0094, 4.2069, 4.3395, 4.4309]) tensor([-1.7210, -1.6293, -1.3275, -1.1264, 4.0605, 4.1694, 4.1924, 4.4684])\n", + "tensor([-1.8004, -1.6917, -1.4397, -1.2207, 3.9532, 4.1907, 4.2938, 4.3942]) tensor([-1.7798, -1.6624, -1.2498, -1.2893, 3.8786, 4.1006, 4.2881, 4.4843])\n", + "tensor([-1.6397, -1.4881, -1.3345, -1.1806, 3.9860, 4.0632, 4.2882, 4.5843]) tensor([-1.7135, -1.6286, -1.2257, -1.2059, 3.9408, 4.1294, 4.3063, 4.6547])\n", + "tensor([-1.6923, -1.3681, -1.2081, -1.2001, 4.0154, 4.0757, 4.2580, 4.5404]) tensor([-1.5569, -1.4990, -1.3459, -1.2117, 3.9104, 4.1156, 4.3978, 4.6076])\n", + "tensor([-1.6531, -1.2870, -1.2384, -1.3103, 3.8964, 4.0371, 4.2032, 4.5494]) tensor([-1.5990, -1.3875, -1.3124, -1.1304, 3.9873, 4.1873, 4.3362, 4.4175])\n", + "tensor([-1.6021, -1.4842, -1.2484, -1.2371, 3.8512, 4.1796, 4.3646, 4.5595]) tensor([-1.7088, -1.2711, -1.3150, -1.2897, 4.0126, 4.0010, 4.3126, 4.4318])\n", + "tensor([-1.5036, -1.5825, -1.2708, -1.2218, 3.9249, 4.3073, 4.2729, 4.5080]) tensor([-1.6650, -1.2157, -1.3652, -1.3055, 4.0069, 4.2310, 4.4414, 4.5414])\n", + "tensor([-1.5468, -1.4815, -1.4311, -1.1765, 3.9407, 4.2249, 4.3026, 4.6238]) tensor([-1.6460, -1.3221, -1.5031, -1.2773, 3.8542, 4.1358, 4.3750, 4.5518])\n", + "tensor([-1.5250, -1.4371, -1.3045, -1.1488, 4.0066, 4.1938, 4.4291, 4.5574]) tensor([-1.6855, -1.3387, -1.5088, -1.3580, 4.0307, 4.1735, 4.3126, 4.4787])\n", + "tensor([-1.7250, -1.3303, -1.4223, -1.0267, 3.9302, 4.1306, 4.4545, 4.5788]) tensor([-1.5945, -1.3868, -1.3389, -1.2973, 3.9685, 4.2125, 4.3691, 4.4954])\n" + ] + }, + { + "data": { + "image/png": "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z6E6li9fzqeffsqLL77IV199RZ8+ffj999/TBEmAkydPcunSpTStNQcOHABIt96SSG7TmBqRPHD+/Pk0r318fKhXrx6Afap16i8FR6Y651RqS45x3ZTduLg4Zs2ale7coKCgDGvq1q0bGzZssP9t/noXL160j9+5++67SUlJSTNd3GKxMGXKFIfrrVWrFnXr1uWbb77hm2++ITw8nJYtW6a5343jgEJDQylbtmy6qeyuVKVKlXTjYT7++ON0LTWOfq+y0rNnT0wmE4MHD+avv/666Vo6NwoNDaV169bMnDkzXegCOHv2bJqaHn/8cRo3bsz48eP59NNP2bZtG+PHj093XUpKCjNnzrS/vnr1KjNnzqR06dI0atTIqRpFckotNSIusGzZMvbv35/ueNOmTYmMjOTxxx8nNjaWNm3aUL58ef7++2+mTJlCgwYN7NO2GzRogK+vLxMnTiQuLo6AgAD7OjKudtddd9lbjp566ikSExP55JNPCA0NTfcLr1GjRkyfPp033niDqlWrEhoaSps2bXjhhRdYvHgx99xzD3379qVRo0ZcunSJXbt2sWDBAo4ePUqpUqXo3LkzzZo1Y+TIkRw9epSoqCi+//57hwYjX6979+6MHj2awMBAHnvsMXx8/v07WUJCAuXLl+ehhx6ifv36FC1alFWrVrF582beffddl3zPMvL444/z9NNP8+CDD9KuXTv++OMPVqxYQalSpdKc5+j3KiulS5emQ4cOfPvttxQrVoxOnTo5Xe+0adNo3rw5devW5YknniAyMpLTp0+zYcMG/vnnH/744w8ABg8ezPnz51m1ahW+vr506NCBxx9/nDfeeIMuXbpQv359+z3Lli3LxIkTOXr0KNWrV+ebb75hx44dfPzxx2kGsYvkCfdOvhLxbFlN6ea66coLFiww7rrrLiM0NNTw9/c3KlSoYDz11FNGTExMmvt98sknRmRkpOHr65tmendmU7q//fbbDOvZvHlzmuNjxowxAOPs2bP2Y4sXLzbq1atnBAYGGpUqVTImTpxo/Oc//zEA48iRI/bzTp06ZXTq1MkIDg42gDR1JCQkGKNGjTKqVq1q+Pv7G6VKlTKaNm1qvPPOO2mm854/f9549NFHjZCQEMNsNhuPPvqosX37doemdKc6ePCg/fu6bt26NO8lJycbL7zwglG/fn0jODjYCAoKMurX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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "print(tr.trace.nodes.keys())\n", + "\n", + "assert tr.trace.nodes['phi']['value']== true_phi\n", + "assert tr.trace.nodes['sigma']['value']== true_sigma\n", + "assert tr.trace.nodes['contribution']['value']== true_contribution\n", + "assert torch.equal(tr.trace.nodes['predictor']['value'], predictor) \n", + "\n", + "\n", + "max_graph = 1.2 * torch.max(y_exp_true)\n", + "min_graph = 1.2 * torch.min(y_exp_true)\n", + "plt.scatter( y_exp_true.flatten(), tr.trace.nodes[\"y_exp_stacked\"]['value'].flatten())\n", + "plt.plot([min_graph, max_graph], [min_graph, max_graph], linestyle='--', color='red')\n", + "\n", + "plt.xlabel(\"True y_exp\")\n", + "plt.ylabel(\"Estimated y_exp\")\n", + "plt.title(\"Estimated vs True y_exp\")\n", + "plt.show()\n", + "\n", + "assert torch.allclose(y_intermediate, y_true, atol= true_sigma * 8)" + ] + }, + { + "cell_type": "code", + "execution_count": 21, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "torch.Size([8, 50]) torch.Size([8, 50]) torch.Size([8, 1])\n", + "[iteration 0001] loss: 2812.8303\n", + "[iteration 0100] loss: 2630.1743\n", + "[iteration 0200] loss: 2557.0708\n", + "[iteration 0300] loss: 2576.9009\n", + "[iteration 0400] loss: 2599.6711\n", + "[iteration 0500] loss: 2560.7441\n", + "[iteration 0600] loss: 2564.7576\n", + "[iteration 0700] loss: 2572.7246\n", + "[iteration 0800] loss: 2556.7070\n", + "[iteration 0900] loss: 2558.2761\n", + "[iteration 1000] loss: 2556.4187\n", + "[iteration 1100] loss: 2561.4504\n", + "[iteration 1200] loss: 2557.6111\n", + "[iteration 1300] loss: 2557.6667\n", + "[iteration 1400] loss: 2571.2625\n", + "[iteration 1500] loss: 2557.4009\n", + "[iteration 1600] loss: 2560.4299\n", + "[iteration 1700] loss: 2555.8784\n", + "[iteration 1800] loss: 2559.1411\n", + "[iteration 1900] loss: 2556.8948\n", + "[iteration 2000] loss: 2571.1294\n" + ] + }, + { + "data": { + "image/png": "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dhhgzMBBvERERNbBAENERESywwBjBg7iJSIisg4GGCIiIpIdBhgiIiKSHQYYM3AQLxERkXUwwBAREZHsMMCYgYN4iYiIrIMBhoiIiGSHAcYMHANDRERkHQwwREREJDsMMGbYnqDGhax8a1eDiIio1WGAMdNr6+KsXQUiIqJWhwHGTDkFpdauAhERUavDAENERESywwBDREREssMAQ0RERLLDAENERESywwBDREREssMAQ0RERLLDAENERESywwBjJt6RmoiIqOkxwBAREZHsMMCYiXekJiIianoMMGbiJSQiIqKmxwBDREREssMAYyZeQiIiImp6DDBm4iUkIiKipscAQ0RERLLDAGMmXkIiIiJqegwwZuIlJCIioqbHAENERESywwBDREREssMAQ0RERLLDAENERESywwBDREREssMAQ0RERLLDAENERESywwBDREREssMAQ0RERLLDAENERESywwBDREREssMAQ0RERLLDAENERESywwBDREREssMAQ0RERLLDAENERESywwBDREREssMAQ0RERLLDAENERESywwBDREREssMAQ0RERLLDAENERESyY1KAWblyJfr37w+VSgWVSoWgoCDs2LEDAJCTk4PXX38dAQEBcHJygp+fH9544w3k5eXp7CMtLQ2hoaFo06YN3N3dMX/+fJSXl+uUiYqKwqBBg6BUKuHv7481a9aY10oiIiJqUexNKezj44MlS5agZ8+eEEJg7dq1GD9+PE6ePAkhBDIyMvDRRx8hMDAQV65cwcyZM5GRkYGffvoJAFBRUYHQ0FB4enri6NGjyMzMxNSpU+Hg4IB///vfAIDU1FSEhoZi5syZWL9+Pfbu3YtXXnkFXl5eCAkJsfz/ABEREcmOjRBCmLMDNzc3LFu2DNOnT6/13I8//ogXXngBBQUFsLe3x44dOzBu3DhkZGTAw8MDAPDVV19hwYIFuH79OhQKBRYsWICIiAgkJiZK+5k0aRJyc3Oxc+dOo+ul0Wjg4uKCvLw8qFQqc5pYS9eFEdLXLk4OOPXBaIvun4iIqLUy9vzd4DEwFRUV2LhxIwoKChAUFFRnmao3t7ev7OiJjo5Gv379pPACACEhIdBoNEhKSpLKBAcH6+wnJCQE0dHRButTUlICjUaj8yAiIqKWyeQAk5CQgHbt2kGpVGLmzJnYunUrAgMDa5W7ceMG/vGP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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "def run_svi_inference(\n", + " model,\n", + " n_steps=500,\n", + " verbose=True,\n", + " lr=0.03,\n", + " vi_family=AutoMultivariateNormal,\n", + " guide=None,\n", + " **model_kwargs,\n", + "):\n", + " losses = []\n", + " if guide is None:\n", + " guide = vi_family(model, init_loc_fn=init_to_mean)\n", + " elbo = pyro.infer.Trace_ELBO()(model, guide)\n", + " # initialize parameters\n", + " elbo(**model_kwargs)\n", + " adam = torch.optim.Adam(elbo.parameters(), lr=lr)\n", + " # Do gradient steps\n", + " for step in range(1, n_steps + 1):\n", + " adam.zero_grad()\n", + " loss = elbo(**model_kwargs)\n", + " loss.backward()\n", + " losses.append(loss.item())\n", + " adam.step()\n", + " if (step % 100 == 0) or (step == 1) & verbose:\n", + " print(\"[iteration %04d] loss: %.4f\" % (step, loss))\n", + "\n", + " plt.plot(losses)\n", + "\n", + " return guide\n", + "\n", + "pyro.clear_param_store()\n", + "\n", + "print(y_true.shape, predictor.shape, init.shape)\n", + "guide = run_svi_inference(ar1_model, n_steps=2000, lr=0.03, \n", + " vi_family= AutoMultivariateNormal,\n", + " outcome_obs = y_intermediate, predictor_obs = predictor, \n", + " initial_obs = init, no_series = n_series)\n" + ] + }, + { + "cell_type": "code", + "execution_count": 23, + "metadata": {}, + "outputs": [], + "source": [ + "predictive = pyro.infer.Predictive(ar1_model, guide=guide, num_samples = n_samples)\n", + "samples = predictive(initial_obs=init, predictor_obs = predictor, T = T)" + ] + }, + { + "cell_type": "code", + "execution_count": 24, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAjMAAAGzCAYAAADaCpaHAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjkuMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8hTgPZAAAACXBIWXMAAA9hAAAPYQGoP6dpAAA2+klEQVR4nO3deXgUZaL+/Ttbd0LIQgLZIEBAkU1BQTGC4jhRREdB8SCKiuiASvAMMOqIyiZqBBUYkEUcBTyjB5cRxm0YEVxeFVA2XxVkkbCTsCaBQPbn9wcnPTYJS+hOnlT4fq6rL0h1dfWdLujcebqeqgBjjBEAAIBDBdoOAAAA4AvKDAAAcDTKDAAAcDTKDAAAcDTKDAAAcDTKDAAAcDTKDAAAcDTKDAAAcDTKDAAAcDTKDOAAc+fOVUBAgLZu3Wotw7333qvmzZt7LQsICNDYsWOr/bm/+OILBQQE6IsvvvAsu/rqq9W+fftqf25J2rp1qwICAjR37twaeb6ztWjRInXs2FGhoaEKCAhQTk6Oz9sMCAjQ0KFDT7tebfg3inMXZQZ1Uvkba/ktNDRUrVq10tChQ5Wdne335zt69KjGjh3r9cMWlXvrrbc0ZcoU2zEqVZuznc6BAwfUt29fhYWFafr06fqf//kfhYeH244F1Ihg2wGA6vT0008rJSVFBQUF+vrrrzVz5kx98skn+umnn1SvXj2/Pc/Ro0c1btw4ScdHDPzt7rvvVr9+/eR2u/2+bV8cO3ZMwcFVext566239NNPP2nYsGFn/JirrrpKx44dk8vlqmLCqjlZtmbNmunYsWMKCQmp1uf3xffff6/Dhw9r/PjxSktLq/Hnr63/RnFuoMygTuvZs6c6d+4sSfrjH/+o2NhYTZo0Sf/85z91xx13WE53evn5+QoPD1dQUJCCgoL8tt2jR4/6pcyFhob6Ic3JFRQUyOVyKTAwsNqf61TKR/dqs71790qSoqOjrTy/v/+NAlXBx0w4p1xzzTWSpMzMTElSSUmJxo8fr5YtW8rtdqt58+Z64oknVFhY6PW4lStXqkePHmrYsKHCwsKUkpKi++67T9Lx4ykaNWokSRo3bpzno63fHkvyyy+/6LbbblNMTIxCQ0PVuXNnffDBB17PUf7R2JdffqkhQ4YoLi5OTZo08brvxOMRZsyYoXbt2sntdispKUnp6ekVjpMoP7Zk1apVuuqqq1SvXj098cQTp3ydFi5cqPbt2ys0NFTt27fXggULKl3vxO/z8OHDGjZsmJo3by632624uDhde+21Wr16tSfLxx9/rG3btnlep/LjcMqPi5k/f76eeuopNW7cWPXq1VNeXl6lx8yUW7Vqla644grPfpk1a1alr+uJr92J2zxVtpMdM7N06VJdeeWVCg8PV3R0tHr16qX169d7rTN27FgFBARo8+bNuvfeexUdHa2oqCgNHDhQR48ePflO+I13331XnTp1UlhYmBo2bKi77rpLu3bt8tx/9dVXa8CAAZKkSy+9VAEBAbr33ntPur3yTL/88ov69u2ryMhIxcbG6k9/+pMKCgoqfUz5vwm326127dpp0aJFXvdzzAxsYmQG55Rff/1VkhQbGyvp+GjNvHnzdNttt+nPf/6zVqxYoYyMDK1fv97zA3zv3r267rrr1KhRIz3++OOKjo7W1q1b9f7770uSGjVqpJkzZ+qhhx7SLbfcoltvvVWSdNFFF0mSfv75Z3Xt2lWNGzfW448/rvDwcL3zzjvq3bu3/vGPf+iWW27xyjhkyBA1atRIo0ePVn5+/km/l7Fjx2rcuHFKS0vTQw89pA0bNmjmzJn6/vvv9c0333h9JHLgwAH17NlT/fr101133aX4+PiTbvfTTz9Vnz591LZtW2VkZOjAgQMaOHCgp1idyoMPPqj33ntPQ4cOVdu2bXXgwAF9/fXXWr9+vS655BI9+eSTys3N1c6dOzV58mRJUv369b22MX78eLlcLj3yyCMqLCw85UdLhw4d0g033KC+ffvqjjvu0DvvvKOHHnpILpfLUzbP1Jlk+63PPvtMPXv2VIsWLTR27FgdO3ZM06ZNU9euXbV69eoKB0v37dtXKSkpysjI0OrVq/W3v/1NcXFxmjBhwilzzZ07VwMHDtSll16qjIwMZWdn669//au++eYbrVmzRtHR0XryySd1wQUXaPbs2Z6PVlu2bHna77lv375q3ry5MjIytHz5ck2dOlWHDh3SG2+84bXe119/rffff19DhgxRRESEpk6dqj59+mj79u2e/0uAVQaog+bMmWMkmc8++8zs27fP7Nixw8yfP9/ExsaasLAws3PnTrN27Vojyfzxj3/0euwjjzxiJJmlS5caY4xZsGCBkWS+//77kz7fvn37jCQzZsyYCvf9/ve/NxdeeKEp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//33e6ZmR0VF+e16VSEhIZowYYIGDhyo7t2764477vBMzW7evLmGDx/u0/YzMzN188036/rrr9eyZcv097//XXfeeac6dOjgl/xAjbE6lwqoJmc6TbW4uNiMGzfOpKSkmJCQEJOcnGxGjhzpNY169erV5o477jBNmzY1brfbxMXFmT/84Q9m5cqVXtv69ttvTadOnYzL5aowZfnXX38199xzj0lISDAhISGmcePG5g9/+IN57733zijzyaa9vvzyy6Z169YmJCTExMfHm4ceesgcOnTIa53u3bubdu3aneYV8/aPf/zDtGnTxrjdbtO2bVvz/vvvmwEDBpxyanZhYaF59NFHTYcOHUxERIQJDw83HTp0MDNmzPB6zJEjR8ydd95poqOjvaZ7l0+VfvfddyvkOdnU7Hbt2pmVK1ea1NRUExoaapo1a2ZefvnlCo//9ddfTVpamnG73SY+Pt488cQTZvHixRW2ebJslU3NNsaYzz77zHTt2tWEhYWZyMhIc9NNN5l169Z5rVM+DXrfvn1ey6sylfntt982F198sXG73SYmJsb079/f7Ny5s9LtVWVq9rp168xtt91mIiIiTIMGDczQoUO9poAbc3wfVzbdvlmzZmbAgAFn9f0A/hZgDEdwAcC5pPyEi/v27VPDhg1txwF8xjEzAADA0SgzAADA0SgzAADA0ThmBgAAOBojMwAAwNEoMwAAwNEcedK8srIy7d69WxEREX49NToAAKg+xhgdPnxYSUlJCgz033iKI8vM7t27lZycbDsGAAA4Czt27FCTJk38tj1HlpnyC/Pt2LFDkZGRltMAtcPatVL37tKXX0r/d+moWm3vXumdd6S+faW4ONtpANSEvLw8JScnn9UFdk/FkWWm/KOlyMhIygzwf+rX/8+fTvhvERkpPfGE7RQAbPD3ISJV/sDqq6++0k033aSkpCQFBARo4cKFXvcbYzR69GglJiYqLCxMaWlpFS4zf/DgQfXv31+RkZGKjo7W/ffff8oL2AGoew4dkt599/ifAOCLKpeZ/Px8dejQocKl48tNnDhRU6dO1axZs7RixQqFh4erR48eKigo8KzTv39//fzzz1q8eLE++ugjffXVVxo8ePDZfxcAHCcz8/hHTJmZtpMAcLoqf8zUs2dP9ezZs9L7jDGaMmWKnnrqKfXq1UuS9MYbbyg+Pl4LFy5U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dP1vvvnGBAUFmYkTJ5p169aZp556yoSEhJgff/yxhpPXPVXdF3feeaeZPn26WbNmjVm/fr259957TVRUlNm5c2cNJ697qrovymVmZprGjRubK6+80vTq1atmwp4Dqro/CgsLTefOnc0NN9xgvv76a5OZmWm++OILs3bt2hpOXvdUdV+8+eabxu12mzfffNNkZmaaf//73yYxMdEMHz68hpPXPZ988ol58sknzfvvv28kmQULFpxy/S1btph69eqZESNGmHXr1plp06aZoKAgs2jRoio9b60sM5dddplJT0/3fF1aWmqSkpJMRkZGpev37dvX3HjjjV7LunTpYh544IFqzXkuqOq+OFFJSYmJiIgw8+bNq66I54yz2RclJSXmiiuuMH/729/MgAEDKDN+VNX9MXPmTNOiRQtTVFRUUxHPGVXdF+np6eaaa67xWjZixAjTtWvXas15rjmTMvPYY4+Zdu3aeS27/fbbTY8ePar0XLXuY6aioiKtWrVKaWlpnmWBgYFKS0vTsmXLKn3MsmXLvNaXpB49epx0fZyZs9kXJzp69KiKi4v9foXUc83Z7ounn35acXFxuv/++2si5jnjbPbHBx98oNTUVKWnpys+Pl7t27fXc889p9LS0pqKXSedzb644oortGrVKs9HUVu2bNEnn3yiG264oUYy4z/89fPb2uUMTmb//v0qLS2tcFmD+Ph4/fLLL5U+Jisrq9L1s7Kyqi3nueBs9sWJ/vKXvygpKanCP1ZUzdnsi6+//lqvvfaa1q5dWwMJzy1nsz+2bNmipUuXqn///vrkk0+0efNmDRkyRMXFxRozZkxNxK6TzmZf3Hnnndq/f7+6desmY4xKSkr04IMP6oknnqiJyPiNk/38zsvL07FjxxQWFnZG26l1IzOoO55//nnNnz9fCxYsUGhoqO0455TDhw/r7rvv1quvvqqGDRvajgNJZWVliouL0+zZs9WpUyfdfvvtevLJJzVr1izb0c45X3zxhZ577jnNmDFDq1ev1vvvv6+PP/5Y48ePtx0NZ6nWjcw0bNhQQUFBys7O9lqenZ2thISESh+TkJBQpfVxZs5mX5R78cUX9fzzz+uzzz7TRRddVJ0xzwlV3Re//vqrtm7dqptuusmzrKysTJIUHBysDRs2qGXLltUbug47m/8biYmJCgkJUVBQkGdZmzZtlJWVpaKiIrlcrmrNXFedzb4YNWqU7r77bv3xj3+UJF144YXKz8/X4MGD9eSTTyowkN/za8rJfn5HRkae8aiMVAtHZlwulzp16qQlS5Z4lpWVlWnJkiVKTU2t9DGpqale60vS4sWLT7o+zszZ7AtJmjhxosaPH69Fixapc+fONRG1zqvqvmjdurV+/PFHrV271nO7+eab9bvf/U5r165VcnJyTcavc87m/0bXrl21efNmT6mUpI0bNyoxMZEi44Oz2RdHjx6tUFjKS6bh2ss1ym8/v6t2bHLNmD9/vnG73Wbu3Llm3bp1ZvDgwSY6OtpkZWUZY4y5++67zeOPP+5Z/5tvvjHBwcHmxRdfNOvXrzdjxoxharafVHVfPP/888blcpn33nvP7Nmzx3M7fPiwrW+hzqjqvjgRs5n8q6r7Y/v27SYiIsIMHTrUbNiwwXz00UcmLi7OPPPMM7a+hTqjqvtizJgxJiIiwvzv//6v2bJli/n0009Ny5YtTd++fW19C3XG4cOHzZo1a8yaNWuMJDNp0iSzZs0as23bNmOMMY8//ri5++67PeuXT81+9NFHzfr168306dPrztRsY4yZNm2aadq0qXG5XOayyy4zy5cv99zXvXt3M2DAAK/133nnHdOqVSvjcrlMu3btzMcff1zDieuuquyLZs2aGUkVbmPGjKn54HVQVf9f/BZlxv+quj++/fZb06VLF+N2u02LFi3Ms88+a0pKSmo4dd1UlX1RXFxsxo4da1q2bGlCQ0NNcnKyGTJkiDl06FDNB69jPv/880p/BpS//gMGDDDdu3ev8JiOHTsal8tlWrRoYebMmVPl5w0whjE1AADgXLXumBkAAICqoMwAAABHo8wAAABHo8wAAABHo8wAAABHo8wAAABHo8wAAABHo8wAAABHo8wAAABHo8wAAABHo8wAAABH+3/nMzh9tEPG/AAAAABJRU5ErkJggg==", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAioAAAGzCAYAAAABsTylAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjkuMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8hTgPZAAAACXBIWXMAAA9hAAAPYQGoP6dpAAA98UlEQVR4nO3deXQUZaL+8Sdbd0JCEgJkgwABgbCKgkAERZkoF4EBYQZ3A+IGwXshLiMugLhEmVEYNYA4DOAdGRRHcEcBhfmhgALiRUH2HdKsScjW2d7fHx56bBKWDoEqk+/nnDqa6uqqJ12BPLxdb7WfMcYIAADAhvytDgAAAHAmFBUAAGBbFBUAAGBbFBUAAGBbFBUAAGBbFBUAAGBbFBUAAGBbFBUAAGBbFBUAAGBbFBWgms2ZM0d+fn7avXu3ZRmGDRumZs2aea3z8/PTxIkTL/qxly9fLj8/Py1fvtyz7rrrrlP79u0v+rElaffu3fLz89OcOXMuyfGqavHixerUqZOCg4Pl5+en7OzsKu+rsvMN1BQUFVju1C/2U0twcLBatWql0aNHy+VyVfvxCgoKNHHiRK9fpKjcvHnzNHXqVKtjVMrO2c7l2LFjGjp0qEJCQpSZman//d//VWhoqNWxAFsKtDoAcMqkSZOUmJiooqIirVy5UtOnT9enn36qH3/8UXXq1Km24xQUFOiZZ56R9Mu/9KvbXXfdpVtvvVVOp7Pa930hCgsLFRjo2x/5efPm6ccff9SYMWPO+znXXnutCgsL5XA4fEzomzNla9q0qQoLCxUUFHRRj38hvvvuO508eVLPPvusUlJSLnh/b775psrLy6shGWA/FBXYRt++fdWlSxdJ0r333qv69evrlVde0QcffKDbbrvN4nTnlp+fr9DQUAUEBCggIKDa9ltQUFAtRS04OLga0pxZUVGRHA6H/P39L/qxzubUqJydHT58WJIUGRlZLfuzcykDLhRv/cC2evfuLUnatWuXJKm0tFTPPvusWrRoIafTqWbNmumJJ56Q2+32et7atWvVp08fNWjQQCEhIUpMTNQ999wj6ZfrFxo2bChJeuaZZzxvN/362o2ff/5Zf/jDHxQVFaXg4GB16dJFH374odcxTr1dtWLFCo0aNUrR0dFq3Lix12OnX6Mybdo0tWvXTk6nU/Hx8UpLS6twXcKpaznWrVuna6+9VnXq1NETTzxx1tdp0aJFat++vYKDg9W+fXstXLiw0u1O/z5PnjypMWPGqFmzZnI6nYqOjtYNN9yg9evXe7J88skn2rNnj+d1OnUdxKnrUObPn6+nnnpKjRo1Up06dZSbm1vpNSqnrFu3TldffbXnvMyYMaPS1/X01+70fZ4t25muUfnyyy91zTXXKDQ0VJGRkRo4cKA2b97stc3EiRPl5+en7du3a9iwYYqMjFRERISGDx+ugoKCM5+EX1mwYIE6d+6skJAQNWjQQHfeeacOHDjgefy6665TamqqJOmqq66Sn5+fhg0bdsb9nes8SZVfo3Ls2DHdddddCg8PV2RkpFJTU/XDDz9UeG2GDRumsLAw7d27V/3791dYWJgaNWqkzMxMSdLGjRvVu3dvhYaGqmnTppo3b57XcY4fP65HHnlEHTp0UFhYmMLDw9W3b1/98MMP5/V6AefCiApsa8eOHZKk+vXrS/pllGXu3Ln6wx/+oIcfflhr1qxRRkaGNm/e7PnlfPjwYd14441q2LChHn/8cUVGRmr37t16//33JUkNGzbU9OnTNXLkSN18880aPHiwJKljx46SpJ9++kk9evRQo0aN9Pjjjys0NFTvvvuuBg0apH/961+6+eabvTKOGjVKDRs21Pjx45Wfn3/G72XixIl65plnlJKSopEjR2rLli2aPn26vvvuO3399dde/yI+duyY+vbtq1tvvVV33nmnYmJizrjfL774QkOGDFHbtm2VkZGhY8eOafjw4Z7SdDYPPvig3nvvPY0ePVpt27bVsWPHtHLlSm3evFlXXnmlnnzySeXk5Gj//v2aMmWKJCksLMxrH88++6wcDoceeeQRud3us77dc+LECd10000aOnSobrvtNr377rsaOXKkHA6Hp0ier/PJ9mtLly5V37591bx5c02cOFGFhYV67bXX1KNHD61fv77CL/mhQ4cqMTFRGRkZWr9+vf72t78pOjpaL7300llzzZkzR8OHD9dVV12ljIwMuVwu/fWvf9XXX3+t77//XpGRkXryySfVunVrzZw50/N2Z4sWLc64z3Odp8qUl5drwIAB+vbbbzVy5EglJSXpgw8+8BSk05WVlalv37669tprNXnyZL399tsaPXq0QkND9eSTT+qOO+7Q4MGDNWPGDN19991KTk5WYmKiJGnnzp1atGiR/vjHPyoxMVEul0tvvPGGevXqpU2bNik+Pv6srxlwTgaw2OzZs40ks3TpUnPkyBGzb98+M3/+fFO/fn0TEhJi9u/fbzZs2GAkmXvvvdfruY888oiRZL788ktjjDELFy40ksx33313xuMdOXLESDITJkyo8Njvfvc706FDB1NUVORZV15ebq6++mrTsmXLCpl79uxpSktLK/1+du3aZYwx5vDhw8bhcJgbb7zRlJWVebZ7/fXXjSTz97//3bOuV69eRpKZMWPGuV84Y0ynTp1MXFycyc7O9qz74osvjCTTtGlTr21P/54jIiJMWlraWfffr1+/CvsxxpivvvrKSDLNmzc3BQUFlT721VdfVfi+Xn75Zc86t9ttOnXqZKKjo01xcbExpuJrd7Z9ninbrl27jCQze/Zsz7pTxzl27Jhn3Q8//GD8/f3N3Xff7Vk3YcIEI8ncc889Xvu8+eabTf369Ssc69eKi4tNdHS0ad++vSksLPSs//jjj40kM378eM+6U9/n2X5OTzmf85Samur1WvzrX/8ykszUqVM968rKykzv3r0rvDapqalGknnhhRc8606cOGFCQkKMn5+fmT9/vmf9zz//XOHnqKioyOvn2phfzoHT6TSTJk065/cHnAtv/cA2UlJS1LBhQyUkJOjWW29VWFiYFi5cqEaNGunTTz+VJKWnp3s95+GHH5YkffLJJ5L+857/xx9/rJKSEp+Of/z4cX355ZcaOnSoTp48qaNHj+ro0aM6duyY+vTpo23btnkN4UvSfffdd87rUZYuXari4mKNGTNG/v7/+SN33333KTw83JP9FKfTqeHDh58z76FDh7RhwwalpqYqIiLCs/6GG25Q27Ztz/n8yMhIrVmzRgcPHjzntmeSmpqqkJCQ89o2MDBQDzzwgOdrh8OhBx54QIcPH9a6deuqnOFcTr1Ow4YNU1RUlGd9x44ddcMNN3h+tn7twQcf9Pr6mmuu0bFjx5Sbm3vG46xdu1aHDx/WqFGjvK6R6devn5KSkiqc5/NVlfO0ePFiBQUF6b777vOs8/f3V1pa2hmfc++993ods3Xr1goNDdXQoUM961u3bq3IyEjt3LnTs87pdHp+rsvKynTs2DGFhYWpdevWXm9PAVVFUYFtZGZmasmSJfrqq6+0adMm7dy5U3369JEk7dmzR/7+/rrsssu8nhMbG6vIyEjt2bNHktSrVy8NGTJEzzzzjBo0aKCBAwdq9uzZFa5jqcz27dtljNHTTz+thg0bei0TJkyQ9J+LIE85Nfx9NqeytW7d2mu9w+FQ8+bNPY+f0qhRo/OaMXPqeS1btqzw2OnHqszkyZP1448/KiEhQV27dtXEiRO9fgGdj/P5/k+Jj4+vMAW3VatWknRR7zlzptdfktq0aaOjR49WeNuuSZMmXl/Xq1dP0i9vX1XlOElJSRXO8/mqynnas2eP4uLiKlyEffqfn1OCg4M9126dEhERocaNG8vPz6/C+l+/DuXl5ZoyZYpatmwpp9OpBg0aqGHDhvq///s/5eTk+PKtApWiqMA2unbtqpSUFF133XVq06aN1+jDKaf/pVnZ4++9955WrVql0aNH68CBA7rnnnvUuXNn5eXlnfW5p6Z3PvLII1qyZEmly+l/0Z/vaIIvLsY+KzN06FDt3LlTr732muLj4/XnP/9Z7dq102effXbe+6jurGc6v2VlZdV6nHM50yiZMeaS5pCq5zydy5m+3/N5HV544QWlp6fr2muv1T/+8Q99/vnnWrJkidq1a8eUaVQLigp+E5o2bary8nJt27bNa73L5VJ2draaNm3qtb579+56/vnntXbtWr399tv66aefNH/+fEln/mXYvHlzSb9M9UxJSal0qVu3bpWyS9KWLVu81hcXF2vXrl0Vsvu639Nfk8qOdSZxcXEaNWqUFi1apF27dql+/fp6/vnnPY+fqxj64uDBgxVGLrZu3SpJnotZT41cnD4bqrLRiPPNdqbXX/plhleDBg2q5WZrZzvOli1bqnyepXOfp8qyHDp0qMJMpe3bt1c5w5m89957uv766zVr1izdeuutuvHGG5WSknJBd9oFfo2igt+Em266SZIq3In0lVdekfTLdQDSL0Pzp/+rt1OnTpLkefvn1HD46X+RRkdH67rrrtMbb7yhQ4cOVchw5MiRKmVPSUmRw+HQq6++6pVt1qxZysnJ8WT3VVxcnDp16qS5c+d6DbEvWbJEmzZtOutzy8rKKgzLR0dHKz4+3uttstDQ0Gobvi8tLdUbb7zh+bq4uFhvvPGGGjZsqM6dO0uSZ/bLv//9b6+sM2fOrLC/883269fp1+f8xx9/1BdffOH52bpQXbp0UXR0tGbMmOH1Gn722WfavHlzlc7z+Z6n0/Xp00clJSV68803PevKy8s9U46rU0BAQIU/cwsWLKhwPRdQVUxPxm/C5ZdfrtTUVM2cOVPZ2dnq1auXvv32W82dO1eDBg3S9ddfL0maO3eupk2bpptvvlktWrTQyZMn9eabbyo8PNzzCykkJERt27bVO++8o1atWikqKkrt27dX+/btlZmZqZ49e6pDhw6677771Lx5c7lcLq1atUr79++v0r0hGjZsqHHjxumZZ57Rf/3Xf+n3v/+9tmzZomnTpumqq67SnXfeWeXXJSMjQ/369VPPnj11zz336Pjx43rttdfUrl27s77VdfLkSTVu3Fh/+MMfdPnllyssLExLly7Vd999p5dfftmzXefOnfXOO+8oPT1dV111lcLCwjRgwIAqZY2Pj9dLL72k3bt3q1WrVnrnnXe0YcMGzZw50zM9u127durevbvGjRun48ePKyoqSvPnz1dpaWmF/fmS7c9//rP69u2r5ORkjRgxwjM9OSIioto+/ygoKEgvvfSShg8frl69eum2227zTE9u1qyZxo4d6/M+z/c8nW7QoEHq2rWrHn74YW3fvl1JSUn68MMPdfz4cUnVO1LWv39/TZo0ScOHD9fVV1+tjRs36u233/aMUAIXzMopR4Ax5z9Vs6SkxDzzzDMmMTHRBAUFmYSEBDNu3DivqcTr1683t912m2nSpIlxOp0mOjra9O/f36xdu9ZrX998843p3LmzcTgcFaZb7tixw9x9990mNjbWBAUFmUaNGpn+/fub995777wyn2mK7euvv26SkpJMUFCQiYmJMSNHjjQnTpzw2qZXr16mXbt253jFvP3rX/8ybdq0MU6n07Rt29a8//77FaarGuM9PdntdptHH33UXH755aZu3bomNDTUXH755WbatGlez8nLyzO33367iYyM9JryfGq68IIFCyrkOdP05Hbt2pm1a9ea5ORkExwcbJo2bWpef/31Cs/fsWOHSUlJMU6n08TExJgnnnjCLFmypMI+z5StsunJxhizdOlS06NHDxMSEmLCw8PNgAEDzKZNm7y2OTU9+ciRI17rz3ROK/POO++YK664wjidThMVFWXuuOMOs3///kr3d66f+fM9T5Wd7yNHjpjbb7/d1K1b10RERJhhw4aZr7/+2kjymnKcmppqQkNDKxz7TD+LTZs2Nf369fN8XVRUZB5++GETFxdnQkJCTI8ePcyqVatMr169TK9evc76/QHnw88YC64O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wEyePNls2rTJPPXUUyYoKMhs3LjxEieveXw9F7fffrvJzMw033//vdm8ebMZNmyYiYiIMPv377/EyWsmX8/HKbt27TKNGjUy11xzjRk4cOClCVvD+Xou3G636dKli7npppvMypUrza5du8zy5cvNhg0bLnHymsfXc/H2228bp9Np3n77bbNr1y7z+eefm7i4ODN27NhLnLzm+fTTT82TTz5p3n//fSPJLFy48Kzb79y509SpU8ekp6ebTZs2mddee80EBASYxYsX+3TcS15UunbtatLS0jxfl5WVmfj4eJORkVHp9kOHDjX9+vXzWtetWzfzwAMPXNSctYGv5+J0paWlpm7dumbu3LkXK2KtUpXzUVpaaq6++mrzt7/9zaSmplJUqomv52L69OmmefPmpri4+FJFrDV8PRdpaWmmd+/eXuvS09NNjx49LmrO2uZ8ispjjz1m2rVr57XulltuMX369PHpWJf0rZ/i4mKtW7dOKSkpnnX+/v5KSUnRqlWrKn3OqlWrvLaXpD59+pxxe5yfqpyL0xUUFKikpKTaPymzNqrq+Zg0aZKio6M1YsSISxGzVqjKufjwww+VnJystLQ0xcTEqH379nrhhRdUVlZ2qWLXSFU5F1dffbXWrVvneXto586d+vTTT3XTTTddksz4j+r6/X1RbqF/JkePHlVZWVmFW+nHxMTo559/rvQ5WVlZlW6flZV10XLWBlU5F6f705/+pPj4+Ao/iPBdVc7HypUrNWvWLG3YsOESJKw9qnIudu7cqS+//FJ33HGHPv30U23fvl2jRo1SSUmJJkyYcCli10hVORe33367jh49qp49e8oYo9LSUj344IN64oknLkVk/MqZfn/n5uaqsLBQISEh57UfZv2gSl588UXNnz9fCxcuVHBwsNVxap2TJ0/qrrvu0ptvvqkGDRpYHafWKy8vV3R0tGbOnKnOnTvrlltu0ZNPPqkZM2ZYHa3WWb58uV544QVNmzZN69ev1/vvv69PPvlEzz77rNXRUEWXdESlQYMGCggIkMvl8lrvcrkUGxtb6XNiY2N92h7npyrn4pS//OUvevHFF7V06VJ17NjxYsasNXw9Hzt27NDu3bs1YMAAz7ry8nJJUmBgoLZs2aIWLVpc3NA1VFX+bMTFxSkoKEgBAQGedW3atFFWVpaKi4vlcDguauaaqirn4umnn9Zdd92le++9V5LUoUMH5efn6/7779eTTz4pf3/+fX6pnOn3d3h4+HmPpkiXeETF4XCoc+fOWrZsmWddeXm5li1bpuTk5Eqfk5yc7LW9JC1ZsuSM2+P8VOVcSNLkyZP17LPPavHixerSpculiFor+Ho+kpKStHHjRm3YsMGz/P73v9f111+vDRs2KCEh4VLGr1Gq8mejR48e2r59u6csStLWrVsVFxdHSbkAVTkXBQUFFcrIqQJp+AzeS6rafn/7dp3vhZs/f75xOp1mzpw5ZtOmTeb+++83kZGRJisryxhjzF133WUef/xxz/Zff/21CQwMNH/5y1/M5s2bzYQJE5ieXE18PRcvvviicTgc5r333jOHDh3yLCdPnrTqW6hRfD0fp2PWT/Xx9Vzs3bvX1K1b14wePdps2bLFfPzxxyY6Oto899xzVn0LNYav52LChAmmbt265p///KfZuXOn+eKLL0yLFi3M0KFDrfoWaoyTJ0+a77//3nz//fdGknnllVfM999/b/bs2WOMMebxxx83d911l2f7U9OTH330UbN582aTmZn525iebIwxr732mmnSpIlxOByma9euZvXq1Z7HevXqZVJTU722f/fdd02rVq2Mw+Ew7dq1M5988sklTlxz+XIumjZtaiRVWCZMmHDpg9dQvv7Z+DWKSvXy9Vx88803plu3bsbpdJrmzZub559/3pSWll7i1DWTL+eipKTETJw40bRo0cIEBwebhIQEM2rUKHPixIlLH7yG+eqrryr9HXDq9U9NTTW9evWq8JxOnToZh8NhmjdvbmbPnu3zcf2MYSwMAADYE1cVAQAA26KoAAAA26KoAAAA26KoAAAA26KoAAAA26KoAAAA26KoAAAA26KoAAAA26KoAAAA26KoAAAA26KoAAAA2/r/dxONtU6ZeoIAAAAASUVORK5CYII=", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAioAAAGzCAYAAAABsTylAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjkuMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8hTgPZAAAACXBIWXMAAA9hAAAPYQGoP6dpAAA1bElEQVR4nO3deXhU5eH+/3smyUz2hEBWCBCoyqaiIIqgWI1SXFEs7gIuKMT2g1QtuLG4IFSRqiBiLdL+VBQq1q3IouhHBZTNrwgFgbCTsGYhezLP7w8u5mNIIkxm4BwO79d1zaU5c+bMPfOQ5M4z55lxGWOMAAAAbMhtdQAAAICGUFQAAIBtUVQAAIBtUVQAAIBtUVQAAIBtUVQAAIBtUVQAAIBtUVQAAIBtUVQAAIBtUVRwSnnzzTflcrm0efNmyzIMHDhQrVu3rrXN5XJp9OjRx/2+Fy1aJJfLpUWLFvm3XXLJJerUqdNxv29J2rx5s1wul958880Tcn+NNXfuXHXu3FmRkZFyuVwqKCiwOlLQGHucrCgq+FWHf7EfvkRGRur000/XAw88oPz8/JDfX2lpqUaPHl3rhynq9/bbb2vSpElWx6iXnbMdzb59+9S/f39FRUVp8uTJ+uc//6mYmBirY9Vi5+fXztlwcnLxWT/4NW+++aYGDRqksWPHKisrS+Xl5fr666/1z3/+U61atdLq1asVHR0dsvvbu3evkpOTNWrUqOMyw1BTU6Oqqip5vV65XK6QH/9YDBw4UIsWLao1q1NeXq7w8HCFh4cf83GuvvpqrV69OqDZIZ/Pp8rKSnk8Hrndh/5OueSSS7R3716tXr36mI/T2GzGGFVUVCgiIkJhYWEhu79Qmjt3rvr06aP58+crOzvb6jj1YuxxKjn2n4o4pfXp00ddu3aVJN1zzz1q2rSpJk6cqH//+9+65ZZbLE53dCUlJYqJiVFYWFhIf0iWlpaGpKhFRkaGIE3DysvL/b+gjvd9/ZrDs3J2tnv3bklSYmKitUFChLHHyY6XftAol156qSQpNzdXklRdXa2nnnpKbdu2ldfrVevWrfXoo4+qoqKi1u2WLVum3r17q1mzZoqKilJWVpbuuusuSYdew05OTpYkjRkzxv9y0y9nVv773//qxhtvVFJSkiIjI9W1a1d9+OGHte7j8MtVX375pYYOHaqUlBS1aNGi1nVH/rU3ZcoUdezYUV6vVxkZGcrJyalzXsLh1/OXL1+uiy++WNHR0Xr00Ud/9Xn64IMP1KlTJ0VGRqpTp06aM2dOvfsd+TiLi4s1bNgwtW7dWl6vVykpKbr88su1YsUKf5ZPPvlEW7Zs8T9Ph897OXwuwsyZM/X444+refPmio6OVlFRUb3nKRy2fPlyXXjhhf5xmTp1ar3P65HP3ZHH/LVsDZ2n8Pnnn+uiiy5STEyMEhMTdd1112nt2rW19hk9erRcLpc2bNiggQMHKjExUQkJCRo0aJBKS0sbHoRfmDVrlrp06aKoqCg1a9ZMt99+u3bs2OG//pJLLtGAAQMkSeedd55cLpcGDhz4q8fcsWOH7r77bmVkZMjr9SorK0tDhgxRZWWlf59Nmzbp97//vZKSkhQdHa0LLrhAn3zySb3P43vvvadnnnlGLVq0UGRkpC677DJt2LChVkbGPvCxx8mLGRU0ysaNGyVJTZs2lXRolmXGjBm68cYb9ac//UlLly7VuHHjtHbtWv8v5927d+uKK65QcnKyRowYocTERG3evFnvv/++JCk5OVmvvvqqhgwZouuvv1433HCDJOmss86SJP3000/q0aOHmjdvrhEjRigmJkbvvfee+vbtq3/961+6/vrra2UcOnSokpOT9eSTT6qkpKTBxzJ69GiNGTNG2dnZGjJkiNatW6dXX31V33//vb755htFRET49923b5/69Omjm2++WbfffrtSU1MbPO68efPUr18/dejQQePGjdO+ffs0aNAgf2n6Nffff79mz56tBx54QB06dNC+ffv09ddfa+3atTr33HP12GOPqbCwUNu3b9eLL74oSYqNja11jKeeekoej0cPPfSQKioq5PF4Gry/AwcO6Morr1T//v11yy236L333tOQIUPk8Xj8RfJYHUu2X1qwYIH69OmjNm3aaPTo0SorK9PLL7+sHj16aMWKFXVOPO7fv7+ysrI0btw4rVixQn/729+UkpKi8ePH/2quwy9jnnfeeRo3bpzy8/P117/+Vd98841WrlypxMREPfbYYzrjjDM0bdo0/8udbdu2bfCYO3fuVLdu3VRQUKDBgwerXbt22rFjh2bPnq3S0lJ5PB7l5+frwgsvVGlpqf74xz+qadOmmjFjhq699lrNnj27zr/b5557Tm63Ww899JAKCws1YcIE3XbbbVq6dOkxP7+MPRzFAL9i+vTpRpJZsGCB2bNnj9m2bZuZOXOmadq0qYmKijLbt283q1atMpLMPffcU+u2Dz30kJFkPv/8c2OMMXPmzDGSzPfff9/g/e3Zs8dIMqNGjapz3WWXXWbOPPNMU15e7t/m8/nMhRdeaE477bQ6mXv27Gmqq6vrfTy5ubnGGGN2795tPB6PueKKK0xNTY1/v1deecVIMn//+9/923r16mUkmalTpx79iTPGdO7c2aSnp5uCggL/tnnz5hlJplWrVrX2PfIxJyQkmJycnF89/lVXXVXnOMYY88UXXxhJpk2bNqa0tLTe67744os6j+uFF17wb6uoqDCdO3c2KSkpprKy0hhT97n7tWM2lC03N9dIMtOnT/dvO3w/+/bt82/74YcfjNvtNnfeead/26hRo4wkc9ddd9U65vXXX2+aNm1a575+qbKy0qSkpJhOnTqZsrIy//aPP/7YSDJPPvmkf9vhx/lr/04Pu/POO43b7a53X5/PZ4wxZtiwYUaS+d///V//dcXFxSYrK8u0bt3a/+/u8PPYvn17U1FR4d/3r3/9q5FkfvzxR/82xv6QYxl7nPx46QfHJDs7W8nJycrMzNTNN9+s2NhYzZkzR82bN9enn34qSRo+fHit2/zpT3+SJP8U9+HX/D/++GNVVVUFdP/79+/X559/rv79+6u4uFh79+7V3r17tW/fPvXu3Vs///xzrSl8Sbr33nuPej7KggULVFlZqWHDhvlPMDx82/j4+DrT816vV4MGDTpq3l27dmnVqlUaMGCAEhIS/Nsvv/xydejQ4ai3T0xM1NKlS7Vz586j7tuQAQMGKCoq6pj2DQ8P13333ef/2uPx6L777tPu3bu1fPnyRmc4msPP08CBA5WUlOTfftZZZ+nyyy/3/9v6pfvvv7/W1xdddJH27dunoqKiBu9n2bJl2r17t4YOHVrrPImrrrpK7dq1qzPOx8Ln8+mDDz7QNddc4z9/65cOn6z96aefqlu3burZs6f/utjYWA0ePFibN2/WmjVrat1u0KBBtWZALrroIkmHXj46Vow9nISigmMyefJkzZ8/X1988YXWrFmjTZs2qXfv3pKkLVu2yO126ze/+U2t26SlpSkxMVFbtmyRJPXq1Uv9+vXTmDFj1KxZM1133XWaPn16nfNY6rNhwwYZY/TEE08oOTm51mXUqFGS/u8kyMOysrKOetzD2c4444xa2z0ej9q0aeO//rDmzZv/6jT6kcc97bTT6lx35H3VZ8KECVq9erUyMzPVrVs3jR49OqBfVNKxPf7DMjIy6izBPf300yXpuL7nTEPPvyS1b99ee/furfOyXcuWLWt93aRJE0mHXsJozP20a9euzjgfiz179qioqOio70OyZcuWBh/fL7Md1pjHdyTGHk7COSo4Jt26dav3r8ZfOtpyX5fLpdmzZ2vJkiX66KOP9Nlnn+muu+7SCy+8oCVLlvzqa9k+n0+S9NBDD/kL0pGOLErH+hdlII7HMevTv39/XXTRRZozZ47mzZunv/zlLxo/frzef/999enT55iOEeqsDY1vTU1NSO/naBqaJTMOeaeFUDw+xh5OwowKgtaqVSv5fD79/PPPtbbn5+eroKBArVq1qrX9ggsu0DPPPKNly5bprbfe0k8//aSZM2dKavgHYps2bSRJERERys7OrvcSFxfXqOyStG7dulrbKysrlZubWyd7oMc98jmp774akp6erqFDh+qDDz5Qbm6umjZtqmeeecZ/fSjfB2bnzp11/npdv369JPlPaDz81+uRq6Hqm4041mwNPf/SoRVezZo1C8mbrf3a/axbt65R45ycnKz4+PijvgdJq1atGnx8v8wWCMYepxKKCoJ25ZVXSlKdd6OcOHGipEPnAUiHpmeP/Munc+fOkuR/+efwe5Ic+QMxJSVFl1xyiV577TXt2rWrToY9e/Y0Knt2drY8Ho9eeumlWtneeOMNFRYW+rMHKj09XZ07d9aMGTNUWFjo3z5//vw65yQcqaamptZtpEOPPyMjo9bLZDExMXX2a6zq6mq99tpr/q8rKyv12muvKTk5WV26dJEk/+qXr776qlbWadOm1TnesWb75fP0yzFfvXq15s2b5/+3FayuXbsqJSVFU6dOrfUc/uc//9HatWsbNc5ut1t9+/bVRx99pGXLltW5/vC/pyuvvFLfffedFi9e7L+upKRE06ZNU+vWrY/pnKUjMfY4lfDSD4J29tlna8CAAZo2bZoKCgrUq1cvfffdd5oxY4b69u2r3/72t5KkGTNmaMqUKbr++uvVtm1bFRcX6/XXX1d8fLz/h1JUVJQ6dOigd999V6effrqSkpLUqVMnderUSZMnT1bPnj115pln6t5771WbNm2Un5+vxYsXa/v27frhhx8Czp6cnKyRI0dqzJgx+t3vfqdrr71W69at05QpU3Teeefp9ttvb/TzMm7cOF111VXq2bOn7rrrLu3fv18vv/yyOnbsqIMHDzZ4u+LiYrVo0UI33nijzj77bMXGxmrBggX6/vvv9cILL/j369Kli959910NHz5c5513nmJjY3XNNdc0KmtGRobGjx+vzZs36/TTT9e7776rVatWadq0af7l2R07dtQFF1ygkSNHav/+/UpKStLMmTNVXV1d53iBZPvLX/6iPn36qHv37rr77rv9S1QTEhJC9u7EERERGj9+vAYNGqRevXrplltu8S9Pbt26tR588MFGHffZZ5/VvHnz1KtXLw0ePFjt27fXrl27NGvWLH399ddKTEzUiBEj9M4776hPnz764x//qKSkJM2YMUO5ubn617/+Vesk7mPF2OOUYuGKI5wEjnWpZlVVlRkzZozJysoyERERJjMz04wcObLWUuIVK1aYW265xbRs2dJ4vV6TkpJirr76arNs2bJax/r2229Nly5djMfjqbNsd+PGjebOO+80aWlpJiIiwjRv3txcffXVZvbs2ceUuaFllq+88opp166diYiIMKmpqWbIkCHmwIEDtfbp1auX6dix41Gesdr+9a9/mfbt2xuv12s6dOhg3n//fTNgwIBfXZ5cUVFhHn74YXP22WebuLg4ExMTY84++2wzZcqUWrc5ePCgufXWW01iYmKtJc+Hl4zOmjWrTp6Glqh27NjRLFu2zHTv3t1ERkaaVq1amVdeeaXO7Tdu3Giys7ON1+s1qamp5tFHHzXz58+vc8yGstW3RNUYYxYsWGB69OhhoqKiTHx8vLnmmmvMmjVrau1zeInqnj17am1vaEzr8+6775pzzjnHeL1ek5SUZG677Tazffv2eo93LMuTjTFmy5Yt5s477zTJycnG6/WaNm3amJycnFpLjDdu3GhuvPFGk5iYaCIjI023bt3Mxx9/XOs4DY1bfc8ZY39IIGOPkxef9QMAAGyLc1QAAIBtUVQAAIBtUVQAAIBtUVQAAIBtUVQAAIBtUVQAAIBt2e4N33w+n3bu3Km4uLiQvk00AAA4fowxKi4uVkZGRqPeyLAhtisqO3fuVGZmptUxAABAI2zbtk0tWrQI2fFsV1QOf7Dctm3bFB8fb3Ea4ORzcPdBrXlvjTr076DYlIY/kdoKeavyNL3XdA36cpDS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breys7O1ePHiem+zePHiWvtLUu/evRvcH8emMWNxpNLSUlVVVYX8kzJPRY0dj7FjxyolJUV33333iYh5SmjMWHz44Yfq3r27cnJylJqaqk6dOunZZ59VTU3NiYrtSI0ZiwsvvFDLly/3vzy0adMmffrpp7ryyitPSGb8n1D9/j4ub6HfkL1796qmpqbOW+mnpqbqv//9b723ycvLq3f/vLy845bzVNCYsTjSn//8Z2VkZNT5h4jANWY8vv76a73xxhtatWrVCUh46mjMWGzatEmff/65brvtNn366afasGGDhg4dqqqqKo0aNepExHakxozFrbfeqr1796pnz54yxqi6ulr333+/Hn300RMRGb/Q0O/voqIilZWVKSoq6piOw6ofNMpzzz2nmTNnas6cOYqMjLQ6zimnuLhYd9xxh15//XU1a9bM6jinPJ/Pp5SUFE2bNk1dunTRTTfdpMcee0xTp061OtopZ9GiRXr22Wc1ZcoUrVixQu+//74++eQTPfXUU1ZHQyOd0BmVZs2aKSwsTPn5+bW25+fnKy0trd7bpKWlBbQ/jk1jxuKw559/Xs8995wWLFigs84663jGPGUEOh4bN27U5s2bdc011/i3+Xw+SVJ4eLjWrVuntm3bHt/QDtWY74309HRFREQoLCzMv619+/bKy8tTZWWlPB7Pcc3sVI0ZiyeeeEJ33HGH7rnnHknSmWeeqZKSEg0ePFiPPfaY3G7+Pj9RGvr9HR8ff8yzKdIJnlHxeDzq0qWLFi5c6N/m8/m0cOFCde/evd7bdO/evdb+kjR//vwG98exacxYSNKECRP01FNPae7cuerateuJiHpKCHQ82rVrpx9//FGrVq3yX6699lr99re/1apVq5SZmXki4ztKY743evTooQ0bNvjLoiStX79e6enplJQgNGYsSktL65SRwwXS8Bm8J1TIfn8Hdp5v8GbOnGm8Xq958803zZo1a8zgwYNNYmKiycvLM8YYc8cdd5gRI0b49//mm29MeHi4ef75583atWvNqFGjWJ4cIoGOxXPPPWc8Ho+ZPXu22bVrl/9SXFxs1UNwlEDH40is+gmdQMdi69atJi4uzjzwwANm3bp15uOPPzYpKSnm6aeftuohOEagYzFq1CgTFxdn3nnnHbNp0yYzb94807ZtW9O/f3+rHoJjFBcXm5UrV5qVK1caSWbixIlm5cqVZsuWLcYYY0aMGGHuuOMO//6Hlyc//PDDZu3atWby5Mknx/JkY4x5+eWXTcuWLY3H4zHdunUzS5Ys8V/Xq1cvM2DAgFr7v/fee+b00083Ho/HdOzY0XzyyScnOLFzBTIWrVq1MpLqXEaNGnXigztUoN8bv0RRCa1Ax+Lbb781559/vvF6vaZNmzbmmWeeMdXV1Sc4tTMFMhZVVVVm9OjRpm3btiYyMtJkZmaaoUOHmgMHDpz44A7zxRdf1Ps74PDzP2DAANOrV686t+ncubPxeDymTZs2Zvr06QHfr8sY5sIAAIA9cVYRAACwLYoKAACwLYoKAACwLYoKAACwLYoKAACwLYoKAACwLYoKAACwLYoKAACwLYoKAACwLYoKAACwLYoKAACwrf8fy1wlWIY1OH4AAAAASUVORK5CYII=", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "phi, sigma, contribution = samples[\"phi\"].flatten(), samples[\"sigma\"].flatten(), samples[\"contribution\"].flatten()\n", + "phi, sigma = samples[\"phi\"].flatten(), samples[\"sigma\"].flatten()#, samples[\"contribution\"].flatten()\n", + "phi_color = 'blue'\n", + "sigma_color = 'green'\n", + "contribution_color = 'purple'\n", + "\n", + "sites = [phi, sigma, contribution]\n", + "names = ['phi', 'sigma', 'contribution']\n", + "colors = [phi_color, sigma_color, contribution_color]\n", + "\n", + "for i in range(len(sites)):\n", + " plt.hist(sites[i].numpy(), bins=30, alpha=0.5)\n", + " plt.axvline(sites[i].mean().item(), color=colors[i], linestyle='dashed', linewidth=1, label=f'mean {names[i]}')\n", + " plt.axvline(eval(f'true_{names[i]}'), color=colors[i], linewidth=1, label=f'true {names[i]}')\n", + " plt.title(f\"Posterior distribution of {names[i]}\")\n", + " plt.xlim(0, 1)\n", + " plt.show()" + ] + }, + { + "cell_type": "code", + "execution_count": 25, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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WloaX3zxBX/605/44Q9/iN1u79E9CSGE2OtwrK81TaOmpoYpU6b06rg2Ul/v1Vl9/U2RSIRXXnmFY4455rBPLCgG2RD37AsxbH3wwQeaXq/X9Hq9NnfuXO22227T3n//fS0cDrfb75prrtFycnLaDavSNE27+OKLtaSkJM3v92uapml33XWXBmiXXHJJh2s999xzGqCVlJT0+rxJSUna97///T7da38Ng1+7dq0GaPfdd59WV1enVVZWau+9955WVFSk2e12bdWqVe32Ly0t1QDNYrFodrs98fj000+7vc6SJUs0oEePfT/TzkyZMkX71re+1WH75s2bNUB78sknuz1+2rRp2vjx4zsMIxw5cqQGaK+++mq7/e+77z7NarW2K+Ptt9/e7TWEEEJ07XCqr9v87W9/0wDtL3/5ywEdL/V1XHf19b7efPNNDdCeeOKJbq8hRH+TnnUhunDqqaeyfPlyHnjgAd5//32WL1/OQw89REZGBs888wxnnXUWmqbx2muvceGFF6JpGvX19Ynj58+fzz/+8Y9EQpM2119//X6v3ZvzJicns2LFCiorK8nNze3fD6GXNmzYAMAdd9zBHXfckdg+b948Pv/8c2bMmNFu/4KCgm57K7pSVFTU4+yv+xvqHwgEMJvNHbZbLJbE+9258cYbueGGG7jmmmu47bbbUFWVX/3qV1RVVXV6fGFhISeccALnnXceaWlpvP322/z6178mOzubm266qUf3JIQQYq/Drb7etm0b3//+95k7dy5XXHHFAZ1D6uv919f7eumllzAajVx44YX7uw0h+tdQtRIIcTAJhULaypUrtUWLFmkWi0UzGo3a5s2btZqamv22FP/rX//SNG1vS/2ePXs6nP+bLfW9Oe/LL7+sWSwWTafTaXPmzNHuuusurbi4uFf3118967fccosGaG+//bb24Ycfai+88II2ZcoUzel0art27erTuQdKX1vqNU3TfvGLX2hGozHxu5k9e7Z2++23a4D2+uuvJ/b7+9//rlmtVq2srKzd8VdeeaVms9k69MoIIYTonUO9vq6qqtJGjx6t5efnaxUVFQf8OUl93X19vS+Px6PZbDbtjDPO6OstCNFr0rMuRA+YTCbmzJnDnDlzGD9+PFdddRX//Oc/+d///V8Avvvd73bZuj19+vR2rzubL/VNqqr2+LwXXnghxx9/PK+/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IX//938/qfN+4xvf4J//+Z/5r//6L4qLiwmHwzzyyCM8++yzfOELX+D+++8f8bhIJMJFF13ENddcw7333nsqX23C3ve+9/Hoo49y1113MX/+fB566CE2b97M888/z/nnnz/msdu2beO8886jurqaO+64A8Mw+P73v09fXx9vvPEGCxcuHLb/008/zbXXXsuqVau49dZbcbvdHD58GMMw+MY3vjGVX1MIIU5Lp3t9fbyWlhYWLlyIpmnU1dWxa9euSZ9L6uvR6+uNGzdy+PDhYccrpfjEJz5BXV0du3fvnpLvJ8QJlBBiRNdcc40qLi5W/f39J7zX2dmZkc8IBoMZOU+mJJNJtWLFCrVw4cJJn+MDH/iAcjgcKplMpl+LxWKqrKxM1dfXj3hMPB5X73znO9X73/9+ZRjGpD97MjZt2qQA9c1vfjP9WiQSUXPnzlUbNmw46fHXXHONys/PVz09PenX2tralNvtVjfeeOOwfQcGBlRpaam64YYblK7rmfsSQghxBjuT6utbb71VXXLJJerCCy9US5cuPaVzSX09en09kpdfflkB6r777pvcFxBiEmQYvBCjOHz4MEuXLsXr9Z7wXklJybDnra2t3HbbbZSWlmK321m6dCkPPPDAsH2+8pWvoGkae/bs4f3vfz/5+fnpVuCHHnoITdM4evTohM8bCAS46667qKurw263U1JSwuWXX862bdsm/J3NZjPV1dX4fL4JHztkx44dLF26FLPZnH7NZrNRUVHBwMDACfsbhsGHPvQhNE3jpz/96bT3VDz66KOYzeZhIwkcDge33347GzdupLm5eczjX375ZS677DIKCwvTr5WXl3PhhRfyxz/+cVjynV/96ld0dnZy3333YTKZCIVCGIaR+S8lhBBnkDOlvn7ppZd49NFH+c53vjOu/U9G6uvR6+uR/OpXv0LTNN7//vef2hcRYgIsM10AIbJVbW0tGzduZNeuXWPOC+vs7OScc85B0zQ+9alPUVxczF/+8hduv/12/H4/d91117D9b7nlFubPn8///b//FzXGLJTxnvcTn/gEjz76KJ/61KdYsmQJvb29vPLKK+zdu5fVq1ef9HuGQiEikQgDAwP84Q9/4C9/+Qu33nrruK7R28Xjcfbv38+HPvShYa+3tbWxZ88eLrzwwhOOueOOO2hvb+epp57CYhnfP0mJRGLEG4mRFBQUYDKN3i755ptvsmDBAnJzc4e9vm7dOgC2b99OdXX1qMfHYjGcTucJr7tcLuLxOLt27eKcc84B4NlnnyU3N5fW1lauv/56Dhw4QE5ODh/60If49re/jcPhGNd3EkIIccyZUF/rus6nP/1p/u7v/o6zzjpr3NdmNFJfHzNSff12iUSC3/72t5x77rlnfGJBMc1mumtfiGz19NNPK7PZrMxms9qwYYP6/Oc/r5566ikVj8eH7Xf77ber8vLyYcOqlFLqve99r8rLy1PhcFgppdS9996rAPW+973vhM968MEHFaAaGhomfN68vDx15513Tvp73nHHHQpQgDKZTOrmm29WfX19kzrXm2++qQD17//+76q7u1u1tbWpv/71r2rFihUqJydHbd68edj+R48eVYByOBwqJycnvb300ktjfs7zzz+fLvPJtuOv6UiWLl2qLrnkkhNe3717twLUD37wgzGPP+uss9SCBQtOGEZYU1OjAPXoo4+mX1++fLlyuVzK5XKpT3/60+qxxx5Tn/70pxWg3vve9475OUIIIUZ2JtTX/+///T+Vl5enurq6lFLqlIfBS32dMlp9/XZPPvmkAtT3v//9MT9DiEyTnnUhRnH55ZezceNG7r//fp566ik2btzIN77xDYqLi/nxj3/Mddddh1KKxx57jPe85z0opejp6Ukff+WVV/Kb3/wmndBkyCc+8YmTfvZEzuv1etm0aRNtbW1UVFRM+Hvedddd3HzzzbS1tfHb3/4WXddPmgV2NDt37gTgS1/6El/60pfSr1900UW88sorrFy5ctj+tbW1Y/ZWjGbFihXjzv5aVlY25vuRSAS73X7C60O93JFIZMzjP/nJT/IP//AP3H777Xz+85/HMAz+4z/+g/b29hOODwaDhMNhPvGJT6Szv994443E43F++MMf8m//9m/Mnz9/XN9LCCFEyuleX/f29vLlL3+ZL33pSxQXF4/7uLFIfT12ff12v/rVr7BarbznPe852dcQIrNmqpVAiNkkFoupN954Q91zzz3K4XAoq9Wqdu/erTo7O0/aUvy73/1OKXWspb6pqemE87+9pX4i53344YeVw+FQJpNJrV27Vt17773q8OHDk/6ul19+uVq7du2kEsd89rOfVYD605/+pJ555hn1i1/8Qi1dulR5PB515MiRSZdpKp1qS71SSn3xi19UVqs1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r2Tz5s0z3SwhhBBCnEX6bCGmnwTrQogZk81mmTt3Li+//DLBYJBPf/rT3HHHHUSj0ZlumhBCCCHOIH22ENNPU0qpmW6EEJe673//+9x3332cPHmSuXPnznRzZlRdXR2//OUvWb9+/Uw3RQghhDiH9NlvkD5biKklM+tCjGLv3r3cfffdzJkzB6fTSX19PTfddBP/+q//OtNNm7Tnn38eTdOGvW3ZsmXC7/vUU08NeS+bzcbChQv5/Oc/TzqdHvW1R48epb+/n4ULF0748ycilUrx2c9+lrq6OlwuF1dccQXPPPPMmF9/9OhR7rnnHhoaGnC73SxdupS/+7u/Ix6PT+g4IYQQ43cx99mDduzYwZ133klZWRlut5uVK1fyta99bcLvdyn22du3b+fWW2/F7/fj8/m4+eab2bVr15Bjtm3bxic+8QlWrFiBx+OhqamJ97znPRw5cqTIP40Qo5OZdSFG8Oqrr3L99dfT1NTEhz/8YWpqamhpaWHLli0cP36cY8eOFe2zDMMgk8ngcDjQNK1o7zua559/nuuvv54//dM/ZePGjUO+d+utt1JRUTGh9/3Sl77EZz/7Wf7lX/6FyspK4vE4jz32GM8++yyf+9zneOihh4Z9XSKR4LrrruP222/nwQcfnNBnT9T73vc+Hn/8cT796U+zaNEivv/977Nt2zaee+453vSmN4362paWFlavXk0gEODjH/84ZWVlbN68me9///vceeed/PznPx/XcUIIIcbvYu+zAZ5++mnuuOMOLrvsMt773vfi9Xo5fvw4pmnypS99aULvean12Tt27ODqq6+msbGRj33sY5imyTe+8Q36+/t57bXXWLJkCQB33303r7zyCu9+97tZvXo1nZ2dfP3rXycajbJlyxZWrlw5HT+qEKCEEMO6/fbbVWVlpRoYGDjne11dXUX5jGg0WpT3mYjnnntOAeqxxx4r6vvee++9yul0qmw2W3gulUqpmpoaNW/evGFfk06n1Vvf+lb1/ve/X5mmWdT2nM/WrVsVoL785S8XnkskEmrBggVq06ZN5339F7/4RQWoffv2DXn+Qx/6kAJUf3//uI4TQggxfhd7nx0KhVR1dbV65zvfqQzDKNr7Xmp99u23365KS0tVb29v4bn29nbl9XrVu971rsJzr7zyikqlUkNee+TIEeVwONS9995bhJ9EiLGRZfBC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VwAsXrx4yLGhUIjbbruNYDDISy+9NK7VEEIUgwTrQozTYPK1jo4OKisr8fl8GIZR1EBrvO9bW1vLn/zJn/Anf/IndHd3s27dOr74xS9OKFg/ceIETqcTr9c77tfu2bOnkORl0LJly9iwYQM/+clPitbxD9bTHYuTJ08yd+7cEb+/du1annvuOcLh8JDBia1btxa+P5quri5KS0vPeT6TyQAUsuyP9TghhBDFc7H02evXr+eZZ56hra2tUAsccsngBtswXpdinz3ozOz+kEvg19DQwNKlSwvPJZNJ7rjjDo4cOcKzzz7L8uXLx/TeQhSTlG4TYgTPPffcsHuzfvOb3wCwZMkSLBYLd911Fz/5yU/Yt2/fOcf29PRM6LPH+r6GYZyTYbWqqoq6ujpSqdSonzFc23bv3s0vfvELbr755lGzsQ6ns7OT7u7uYbPw3nLLLZw8ebJo5U4G97+N5Xa+/W933303hmHw7W9/u/BcKpXie9/7HldcccWQrLLxeJxDhw4N2Y+4ePFidu7cyZEjR4a87//8z/+g63phNmWsxwkhhBi/i73Pfs973gPAd77znSHP/8d//AdWq5XrrrtuXG2+VPvs4fzoRz9i27ZtfPrTny5c+xiGwXvf+142b97MY489xqZNmyZxBoSYOJlZF2IEn/zkJ4nH47zzne9k6dKlpNNpXn31VX70ox8xd+5c7rvvPgAefvhhnnvuOa644gr+8A//kOXLl9Pf38+OHTt49tlnx7z062xjed9IJEJDQwN33303a9aswev18uyzz7Jt2zb+z//5P6O+/3vf+15cLhdXXXUVVVVVHDhwgG9/+9u43W4efvjhIcdqmsa1117L888/P+L77d69G4BVq1ad872bb76ZL37xi/z6179m2bJl4z8ZZyktLS3arMgVV1zBu9/9bh544AG6u7tZuHAhP/jBDzh16tQ5F0WvvfYa119/PQ8++CCf//znAfjf//t/8+STT3LNNdfwiU98gvLycn71q1/x5JNP8r/+1/8qLJkb63FCCCHG72Lvsy+77DI+8pGP8N3vfpdsNlvokx977DEeeOCBIX2I9Nk5w/XZL774In/3d3/HzTffTHl5OVu2bOF73/set956K5/61KcKr/3zP/9zfvGLX3DHHXfQ39/Pf/3Xfw157w984ANF+XmEOK+Z3jQvxGz15JNPqo985CNq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iIiIxlOcNEqtOiuW5bglRERE08dgfZJc6RrrcmFDjltCREREY4nH46gQPQCAmiVrc9waIiKi6WOwPglCCBQn2wEA3qrlOW4NERFRfnj55Zdx6623orKyEpIk4cknn8x1k9DVchxmSUNMWLB0MRPCEhHR/MVgfRL6IklUS10AgPI6ButEREQAEIlEsH79enz/+9/PdVMy+pqPAgDa5AqYzeYct4aIiGj68q50Wz7q6B3AagwAACwlvEpPREQEADfddBNuuummSe+fSCSQSCQyj4PBYNbblOg6DgDos1aDPTYREc1nHFmfBH/7KciSQAR2wFGY6+YQERHNS9u2bYPX683campmIWlr32kAQNxdn/1jExERzSEG65MQ6z4JAOg1VwIsAUNERDQt999/PwKBQObW0tKS9fdwhJsAANaypVk/NhER0VziNPhJ0PuaAABhR3VuG0JERDSPWa1WWK3WWX2PwbJt3uoVs/o+REREs40j65NgCTUBAHRffU7bQURERGNLJGIo17sBAKV1q3PcGiIioplhsD4JrmgbAEAuYo11IiKifNXZdAyKJBARNhSWcTYcERHNb5wGPwnFSSNYd5QxrywREdGgcDiMkydPZh43NjZi//79KCwsRG1t7Zy3Z6DlKOoAdJgqsUTmeAQREc1vDNYnkEilUCm6AAkoqFqW6+YQERHljd27d+Paa6/NPP7c5z4HALj77rvx0EMPzXl74umybUH7LGSZJyIimmMM1ifQ096MaikFVcjwlnMaPBER0aBrrrkGQohcNyND6j8FAEh42V8TEdH8xzliExhoM67Sd8slkEyWHLeGiIiIxuIInwEAKMVctkZERPMfg/UJxLuNq/R9lsoct4SIiIjGU5TOMeOuXJ7jlhAREc0cp8FPwFu7Bjs67oRUtCjXTSEiIqJxnGl4P9r6T2LJorW5bgoREdGMSSKfFptlQTAYhNfrRSAQgMfjyXVziIiIaAzss4mIiMbGafBEREREREREeYbBOhEREREREVGeYbBORERERERElGcYrBMRERERERHlGQbrRERERERERHmGwToRERERERFRnmGwTkRERERERJRnTLluQLYNlo0PBoM5bgkREdHcc7vdkCQp182YFPbZRER0vppMf73ggvVQKAQAqKmpyXFLiIiI5l4gEIDH48l1MyaFfTYREZ2vJtNfS2LwsvYCoes62tvbszqyEAwGUVNTg5aWlnnzBShf8VxmD89l9vBcZg/PZfZM91zOp5H1bPfZ/P3LHp7L7OG5zB6ey+zhucye2eyvF9zIuizLqK6unpVjezwe/jJnCc9l9vBcZg/PZfbwXGbPQj6Xs9VnL+RzNtd4LrOH5zJ7eC6zh+cye2bjXDLBHBEREREREVGeYbBORERERERElGcYrE+C1WrFAw88AKvVmuumzHs8l9nDc5k9PJfZw3OZPTyXU8dzlj08l9nDc5k9PJfZw3OZPbN5LhdcgjkiIiIiIiKi+Y4j60RERERERER5hsE6ERERERERUZ5hsE5ERERERESUZxisExEREREREeUZButEREREREREeYbB+gS+//3vo76+HjabDZs2bcIbb7yR6yblvZdffhm33norKisrIUkSnnzyyWHPCyHw93//96ioqIDdbseWLVtw4sSJ3DQ2z23btg0bN26E2+1GaWkpbr/9dhw7dmzYPvF4HFu3bkVRURFcLhfe8573oKurK0ctzl8//OEPsW7dOng8Hng8HmzevBlPP/105nmex+l78MEHIUkS7rvvvsw2ns/J+cpXvgJJkobdVqxYkXme53Fq2GdPHfvs7GB/nT3sr2cP++vpy1V/zWB9HI899hg+97nP4YEHHsDevXuxfv163Hjjjeju7s510/JaJBLB+vXr8f3vf3/U57/5zW/iu9/9Lv7jP/4DO3fuhNPpxI033oh4PD7HLc1/L730ErZu3YodO3bgueeeQyqVwg033IBIJJLZ56/+6q/wm9/8Bo8//jheeukltLe3493vfncOW52fqqur8eCDD2LPnj3YvXs3rrvuOrzzne/EoUOHAPA8TteuXbvwox/9COvWrRu2nedz8lavXo2Ojo7M7dVXX808x/M4eeyzp4d9dnawv84e9tezg/31zOWkvxY0pksuuURs3bo181jTNFFZWSm2bduWw1bNLwDEE088kXms67ooLy8X3/rWtzLb/H6/sFqt4pFHHslBC+eX7u5uAUC89NJLQgjj3JnNZvH4449n9jly5IgAILZv356rZs4bBQUF4ic/+QnP4zSFQiGxdOlS8dxzz4mrr75a3HvvvUII/l5OxQMPPCDWr18/6nM8j1PDPnvm2GdnD/vr7GJ/PTPsr2cuV/01R9bHkEwmsWfPHmzZsiWzTZZlbNmyBdu3b89hy+a3xsZGdHZ2DjuvXq8XmzZt4nmdhEAgAAAoLCwEAOzZswepVGrY+VyxYgVqa2t5PsehaRoeffRRRCIRbN68medxmrZu3Ypbbrll2HkD+Hs5VSdOnEBlZSUWLVqEu+66C83NzQB4HqeCffbsYJ89feyvs4P9dXawv86OXPTXphm9egHr7e2FpmkoKysbtr2srAxHjx7NUavmv87OTgAY9bwOPkej03Ud9913Hy6//HKsWbMGgHE+LRYLfD7fsH15Pkf31ltvYfPmzYjH43C5XHjiiSewatUq7N+/n+dxih599FHs3bsXu3btGvEcfy8nb9OmTXjooYewfPlydHR04Ktf/SquvPJKHDx4kOdxCthnzw722dPD/nrm2F9nD/vr7MhVf81gnWie2Lp1Kw4ePDhsfQxNzfLly7F//34EAgH84he/wN13342XXnop182ad1paWnDvvffiueeeg81my3Vz5rWbbrop8/O6deuwadMm1NXV4ec//znsdnsOW0ZE08X+eubYX2cH++vsyVV/zWnwYyguLoaiKCOy+HV1daG8vDxHrZr/Bs8dz+vU3HPPPfjtb3+LF154AdXV1Znt5eXlSCaT8Pv9w/bn+RydxWLBkiVLcNFFF2Hbtm1Yv349vvOd7/A8TtGePXvQ3d2NDRs2wGQywWQy4aWXXsJ3v/tdmEwmlJWV8XxOk8/nw7Jly3Dy5En+Xk4B++zZwT576thfZwf76+xgfz175qq/ZrA+BovFgosuugh//OMfM9t0Xccf//hHbN68OYctm98aGhpQXl4+7LwGg0Hs3LmT53UUQgjcc889eOKJJ/CnP/0JDQ0Nw56/6KKLYDabh53PY8eOobm5medzEnRdRyKR4Hmcouuvvx5vvfUW9u/fn7ldfPHFuOuuuzI/83xOTzgcxqlTp1BRUcHfyylgnz072GdPHvvr2cX+enrYX8+eOeuvZ5SeboF79NFHhdVqFQ899JA4fPiw+PM//3Ph8/lEZ2dnrpuW10KhkNi3b5/Yt2+fACD+5V/+Rezbt0+cOXNGCCHEgw8+KHw+n3jqqafEm2++Kd75zneKhoYGEYvFctzy/PMXf/EXwuv1ihdffFF0dHRkbtFoNLPPpz/9aVFbWyv+9Kc/id27d4vNmzeLzZs357DV+elLX/qSeOmll0RjY6N48803xZe+9CUhSZL4wx/+IITgeZypodllheD5nKz/9//+n3jxxRdFY2OjeO2118SWLVtEcXGx6O7uFkLwPE4F++zpYZ+dHeyvs4f99exifz09ueqvGaxP4N///d9FbW2tsFgs4pJLLhE7duzIdZPy3gsvvCAAjLjdfffdQgijFMyXv/xlUVZWJqxWq7j++uvFsWPHctvoPDXaeQQgfvazn2X2icVi4jOf+YwoKCgQDodDvOtd7xIdHR25a3Se+vjHPy7q6uqExWIRJSUl4vrrr890/ELwPM7UuZ0/z+fkvP/97xcVFRXCYrGIqqoq8f73v1+cPHky8zzP49Swz5469tnZwf46e9hfzy7219OTq/5aEkKImY3NExEREREREVE2cc06ERERERERUZ5hsE5ERERERESUZxisExEREREREeUZButEREREREREeYbBOhEREREREVGeYbBORERERERElGcYrBMRERERERHlGQbrRERERERERHmGwToRERERERFRnmGwTkRERERERJRnGKwTERERERER5RkG60RERERERER5hsE6ERERERERUZ5hsE5ERERERESUZxisExEREREREeUZButEREREREREeYbBOhEREREREVGeYbBORERERERElGcYrBNRziQSCXz84x9HbW0tPB4PLr30Umzfvj3XzSIiIqIh2F8T5QaDdSLKGVVVUV9fj1dffRV+vx/33Xcfbr31VoTD4Vw3jYiIiNLYXxPlhiSEELluBNH57qGHHsLHPvYxNDY2or6+PtfNyanKykr85je/wUUXXZTrphAREQ3D/vos9tdEs48j60TjeOutt3DHHXegrq4ONpsNVVVVeNvb3oZ///d/z3XTZuyjH/0oJEka89bW1jat4z777LPDjmM2m7FkyRJ85StfQTKZHPe1J06cQH9/P5YsWTKt956uRCKBL37xi6isrITdbsemTZvw3HPPTfr1e/bswdvf/nZ4PB643W7ccMMN2L9//4j9XnzxxTHP944dO7L4iYiIzi8Lub8GjP7xAx/4AKqrq+FwOLBixQp87WtfQzQanfYx2V+P3V8fOnQI733ve7Fo0SI4HA4UFxfjqquuwm9+85ssfhqiiXFknWgMr7/+Oq699lrU1tbi7rvvRnl5OVpaWrBjxw6cOnUKJ0+ezNp7aZqGVCoFq9UKSZKydtzxbN++HadOnRq2TQiBT3/606ivr8ehQ4emddxvfvOb+OIXv4h/+Zd/QUlJCaLRKB5//HE8//zz+NKXvoRt27aN+rpYLIZrrrkGN998Mx544IFpvfd03XnnnfjFL36B++67D0uXLsVDDz2EXbt24YUXXsAVV1wx7mv37t2Lyy+/HDU1NfjUpz4FXdfxgx/8AP39/XjjjTewfPnyzL4vvvgirr32WvzlX/4lNm7cOOw4b3/721FcXDwrn4+IaCFb6P11S0sL1q1bB6/Xi09/+tMoLCzE9u3b8dBDD+G2227DU089Na3jsr8eu7/+/e9/j+9+97vYvHkzKisrEY1G8ctf/hKvvPIKfvSjH+HP//zPZ/ujEhkEEY3q5ptvFiUlJWJgYGDEc11dXVl5j3A4nJXjZMsrr7wiAIhvfOMb0z7GXXfdJWw2m1BVNbMtkUiI8vJy0dDQMOprksmkuOWWW8QHP/hBoev6tN97Onbu3CkAiG9961uZbbFYTCxevFhs3rx5wtfffPPNoqCgQPT29ma2tbe3C5fLJd797ncP2/eFF14QAMTjjz+evQ9ARHSeW+j99Te+8Q0BQBw8eHDY9o985CMCgOjv75/Wcdlfj91fj0ZVVbF+/XqxfPny6X0AomngNHiiMZw6dQqrV6+Gz+cb8Vxpaemwx21tbfj4xz+OsrIyWK1WrF69Gv/1X/81bJ+vfOUrkCQJhw8fxgc/+EEUFBRkrgI/9NBDkCQJTU1NUz5uKBTCfffdh/r6elitVpSWluJtb3sb9u7dO+XP/PDDD0OSJHzwgx+c8msHHThwAKtXr4aiKJltFosFlZWVCAQCI/bXdR0f/vCHIUkS/vu//3vORioG/eIXv4CiKMOukttsNnziE5/A9u3b0dLSMu7rX3nlFWzZsgVFRUWZbRUVFbj66qvx29/+dszkO6FQCKqqZudDEBGdxxZ6fx0MBgEAZWVlw7ZXVFRAlmVYLJZxXz8W9teT668HKYqCmpoa+P3+GX0Ooqkw5boBRPmqrq4O27dvx8GDB7FmzZox9+vq6sKll14KSZJwzz33oKSkBE8//TQ+8YlPIBgM4r777hu2/3vf+14sXboU//iP/wgxziqUyR7305/+NH7xi1/gnnvuwapVq9DX14dXX30VR44cwYYNGyb9eVOpFH7+85/jsssum3bSnGQyiWPHjuHDH/7wsO3t7e04fPgwrr766hGv+dSnPoWOjg48++yzMJkm9ycplUqN+kViNIWFhZDlsa9L7tu3D8uWLYPH4xm2/ZJLLgEA7N+/HzU1NWO+PpFIwG63j9jucDiQTCZx8OBBXHrppcOe+9jHPoZwOAxFUXDllVfiW9/6Fi6++OJJfR4iIhpuoffX11xzDf7pn/4Jn/jEJ/DVr34VRUVFeP311/HDH/4Qf/mXfwmn0zml8wWwvx5qvP46EokgFoshEAjg17/+NZ5++mm8//3vn9TnIcqKXA/tE+WrP/zhD0JRFKEoiti8ebP467/+a/Hss8+KZDI5bL9PfOIToqKiYti0KiGE+MAHPiC8Xq+IRqNCCCEeeOABAUDceeedI97rZz/7mQAgGhsbp3xcr9crtm7dOuPP+5vf/EYAED/4wQ+mfYx9+/YJAOLrX/+66OnpEe3t7eKZZ54R69evF06nU+zatWvY/k1NTQKAsNlswul0Zm4vv/zyuO8zOJ18Mreh53Q0q1evFtddd92I7YcOHRIAxH/8x3+M+/q1a9eKZcuWjZhGWFtbKwCIX/ziF5ntr732mnjPe94jfvrTn4qnnnpKbNu2TRQVFQmbzSb27t077vsQEdHozof++utf/7qw2+3D+re//du/ndaxhGB/PWis/nrQpz71qUz7ZFkWd9xxx7SXHRBNB0fWicbwtre9Ddu3b8e2bdvw7LPPYvv27fjmN7+JkpIS/OQnP8Ftt90GIQR++ctf4n3vex+EEOjt7c28/sYbb8Sjjz6aSWgy6NOf/vSE7z2V4/p8PuzcuRPt7e2orKyc9ud9+OGHYTab8b73vW/ax3jzzTcBAF/+8pfx5S9/ObP9mmuuwauvvooLLrhg2P51dXXjjlaMZf369ZPO/lpeXj7u87FYDFardcR2m82WeX48n/nMZ/AXf/EX+MQnPoG//uu/hq7r+Id/+Ad0dHSMeP1ll12Gyy67LPP4tttuwx133IF169bh/vvvxzPPPDOpz0RERGedD/11fX09rrrqKrznPe9BUVERfve73+Ef//EfUV5ejnvuuWdKxwLYX0/UXw+67777cMcdd6C9vR0///nPoWnahJnyibIqV1cJiOaTRCIh3njjDXH//fcLm80mzGazOHTokOjq6prwSvGvfvUrIcTZK/XNzc0jjn/ulfqpHPexxx4TNptNyLIsNm7cKB544AFx6tSpKX2+UCgkHA6HeMc73jGj8/S5z31OABC/+93vxHPPPSf+93//V6xevVq43W5x+vTpGR17tsz0Sr0QQvzN3/yNMJvNmX+biy++WPzt3/6tACCeeOKJCV//gQ98QFgslmFX+4mIaOoWYn/9yCOPCLvdLlpaWoZt/+hHPyocDseIEf3JYH89vf76bW97m9i4ceOcJ9ej8xdH1okmwWKxYOPGjdi4cSOWLVuGj33sY3j88cfxqU99CgDwoQ99CHffffeor123bt2wx6OtlzqXruuTPu773vc+XHnllXjiiSfwhz/8Ad/61rfwT//0T/jVr36Fm266aVKf78knn0Q0GsVdd901qf3H8uabb6Kurg4333xzZtuGDRuwatUq/OAHP8C3vvWtGR1/UDKZRH9//6T2LSkpGZY851wVFRWj1pQfvNI+mdGPb3zjG/j85z+PQ4cOwev1Yu3atfibv/kbAMCyZcsmfH1NTQ2SySQikciItXhERDR5C7G//sEPfoALL7wQ1dXVw7bfdttteOihh7Bv3z5s2bJlwrYOxf56ev31HXfcgU996lM4fvz4sFJvRLOFwTrRFA0mAuvo6EBJSQncbjc0TZtyRzmeqR63oqICn/nMZ/CZz3wG3d3d2LBhA77xjW9MOlj/v//7P7hcLtx2220zavebb76ZSfQyaOXKlbj44ovxy1/+Mmud/2BN3clobGwcN2HeBRdcgBdeeAHBYHBYoLxz587M85MxNFswADz//POorq7GihUrJnzt6dOnYbPZ4HK5JvVeREQ0sYXSX3d1daGgoGDE9lQqBQDTqizC/np6/fXgVPnJJs0jmimWbiMawwsvvDDq+qzf//73AIDly5dDURS85z3vwS9/+UscPHhwxL49PT3Teu/JHlfTtBEdRmlpKSorK5FIJCb1Xj09PXj++efxrne9Cw6HY1rtBYDOzk50d3ePmon3xhtvRGNjI44cOTLt4w81uAZuMreJ1sDdcccd0DQNP/7xjzPbEokEfvazn2HTpk3DMstGo1EcPXp02JrE0Tz22GPYtWsX7rvvvmGZbUf7fThw4AB+/etf44Ybbhg3Cy4REY1uoffXy5Ytw759+3D8+PFh2x955BHIsjxiRsBE2F+fNVZ/3d3dPWLfVCqF//mf/4HdbseqVasmewqIZoQj60Rj+OxnP4toNIp3vetdWLFiBZLJJF5//XU89thjqK+vx8c+9jEAwIMPPogXXngBmzZtwic/+UmsWrUK/f392Lt3L55//vlJT/8612SOGwqFUF1djTvuuAPr16+Hy+XC888/j127duHb3/72pN7nscceg6qq406BlyQJV199NV588cUx9zlw4AAAYO3atSOeu+GGG/CNb3wDv/vd77By5cpJtWs8BQUFWRsZ2bRpE9773vfi/vvvR3d3N5YsWYL//u//RlNTE376058O2/eNN97AtddeiwceeABf+cpXAAAvv/wyvva1r+GGG25AUVERduzYgZ/97Gd4+9vfjnvvvXfY69///vfDbrfjsssuQ2lpKQ4fPowf//jHcDgcePDBB7PyeYiIzjcLvb/+whe+gKeffhpXXnkl7rnnHhQVFeG3v/0tnn76afzZn/3ZsOnf7K8NM+2vP/WpTyEYDOKqq65CVVUVOjs78X//9384evQovv3tb3MmHM2dXC+aJ8pXTz/9tPj4xz8uVqxYIVwul7BYLGLJkiXis5/9rOjq6hq2b1dXl9i6dauoqakRZrNZlJeXi+uvv178+Mc/zuwzmLCmp6dnxHuNVgpmMsdNJBLiC1/4gli/fr1wu93C6XSK9evXT6n82qWXXipKS0vHTG4WCoUEAPGBD3xg3ON885vfFADEgQMHRjyXTCaF2+0W11577aTbNZdisZj4/Oc/L8rLy4XVahUbN24UzzzzzIj9BkvQPPDAA5ltJ0+eFDfccIMoLi4WVqtVrFixQmzbtk0kEokRr//Od74jLrnkElFYWChMJpOoqKgQH/rQh8SJEydm8+MRES1o50N/vXPnTnHTTTeJ8vJyYTabxbJly8Q3vvENkUqlMvuwvz5rpv31I488IrZs2SLKysqEyWQSBQUFYsuWLeKpp56azY9HNIIkxDTqMBDReeP3v/893vGOd+DAgQOjXoUnIiKi3GN/TbTwcIEkEY3rhRdewAc+8AF2/ERERHmM/TXRwsORdSIiIiIiIqI8w5F1IiIiIiIiojzDYJ2IiIiIiIgozzBYJyIiIiIiIsozDNaJiIiIiIiI8syCC9aFEAgGg2DePCIiovzGPpuIiGhseResf+UrX4EkScNuK1asmPTrQ6EQvF4vQqHQLLaSiIiIZop9NhER0dhMuW7AaFavXo3nn38+89hkystmEhEREREREc2KvIyCTSYTysvLc90MIiIiIiIiopzIu2nwAHDixAlUVlZi0aJF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Lxw5X89doc7XEqxP4T//8z957LHH+OIXv8g777zDhg0buPvuu/H7/YUeWlGLRCJs2LCBr3/96xO+/nd/93f80z/9E9/4xjd48803cblc3H333cTj8UUeafHbs2cP27dvZ+/evezatYtUKsVdd91FJBLJbfPf//t/58c//jFPP/00e/bsoaenh1//9V8v4KiLU0NDA1/+8pfZv38/b7/9Nh/+8Ie59957OXLkCCDHca727dvHN7/5TdavXz/ueTmeM7d27Vp6e3tzt9deey33mhzHmZNz9tzIOTs/5HydP3K+Xhhyvp6/gpyvDTGp6667zti+fXvusaZpRl1dnbFz584CjmppAYxnnnkm91jXdaOmpsb4yle+kntudHTUsNlsxn/8x38UYIRLi9/vNwBjz549hmFkjp3FYjGefvrp3DbHjh0zAOONN94o1DCXjNLSUuNf//Vf5TjOUSgUMlpbW41du3YZt9xyi/HII48YhiF/L2fji1/8orFhw4YJX5PjODtyzp4/OWfnj5yv80vO1/Mj5+v5K9T5WmbWJ5FMJtm/fz933HFH7jlVVbnjjjt44403Cjiype3s2bP09fWNO64+n4/rr79ejusMBAIBAMrKygDYv38/qVRq3PFcvXo1TU1NcjynoGkaTz31FJFIhPb2djmOc7R9+3Y+9rGPjTtuIH8vZ+vkyZPU1dWxfPlyPvWpT9HR0QHIcZwNOWcvDDlnz52cr/NDztf5Iefr/CjE+do8r3dfwQYHB9E0jerq6nHPV1dXc/z48QKNaunr6+sDmPC4jr0mJqbrOo8++ig33ngj69atAzLH02q1UlJSMm5bOZ4TO3ToEO3t7cTjcdxuN8888wxr1qzh4MGDchxn6amnnuKdd95h3759l70mfy9n7vrrr+eJJ56gra2N3t5evvSlL3HTTTdx+PBhOY6zIOfshSHn7LmR8/X8yfk6f+R8nR+FOl9LsC7EErF9+3YOHz48bn2MmJ22tjYOHjxIIBDg+9//Pg8++CB79uwp9LCWnM7OTh555BF27dqF3W4v9HCWtG3btuV+Xr9+Pddffz3Nzc38n//zf3A4HAUcmRBiruR8PX9yvs4POV/nT6HO15IGP4mKigpMJtNlVfz6+/upqakp0KiWvrFjJ8d1dh5++GGef/55fv7zn9PQ0JB7vqamhmQyyejo6Ljt5XhOzGq1snLlSjZv3szOnTvZsGEDX/va1+Q4ztL+/fvx+/1cc801mM1mzGYze/bs4Z/+6Z8wm81UV1fL8ZyjkpISVq1axalTp+Tv5SzIOXthyDl79uR8nR9yvs4POV8vnMU6X0uwPgmr1crmzZt5+eWXc8/pus7LL79Me3t7AUe2tC1btoyamppxxzUYDPLmm2/KcZ2AYRg8/PDDPPPMM7zyyissW7Zs3OubN2/GYrGMO54nTpygo6NDjucM6LpOIpGQ4zhLt99+O4cOHeLgwYO527XXXsunPvWp3M9yPOcmHA5z+vRpamtr5e/lLMg5e2HIOXvm5Hy9sOR8PTdyvl44i3a+nld5uivcU089ZdhsNuOJJ54wjh49avze7/2eUVJSYvT19RV6aEUtFAoZBw4cMA4cOGAAxj/8wz8YBw4cMM6fP28YhmF8+ctfNkpKSoznnnvOeO+994x7773XWLZsmRGLxQo88uLzuc99zvD5fMbu3buN3t7e3C0ajea2+f3f/32jqanJeOWVV4y3337baG9vN9rb2ws46uL0p3/6p8aePXuMs2fPGu+9957xp3/6p4aiKMZLL71kGIYcx/m6uLqsYcjxnKnPf/7zxu7du42zZ88av/zlL4077rjDqKioMPx+v2EYchxnQ87ZcyPn7PyQ83X+yPl6Ycn5em4Kdb6WYH0a//t//2+jqanJsFqtxnXXXWfs3bu30EMqej//+c8N4LLbgw8+aBhGphXMX/zFXxjV1dWGzWYzbr/9duPEiROFHXSRmug4AsZ3vvOd3DaxWMz4gz/4A6O0tNRwOp3Gr/3arxm9vb2FG3SR+p3f+R2jubnZsFqtRmVlpXH77bfnTvyGIcdxvi49+cvxnJlPfOITRm1trWG1Wo36+nrjE5/4hHHq1Knc63IcZ0fO2bMn5+z8kPN1/sj5emHJ+XpuCnW+VgzDMOY3Ny+EEEIIIYQQQoh8kjXrQgghhBBCCCFEkZFgXQghhBBCCCGEKDISrAshhBBCCCGEEEVGgnUhhBBCCCGEEKLISLAuhBBCCCGEEEIUGQnWhRBCCCGEEEKIIiPBuhBCCCGEEEIIUWQkWBdCCCGEEEIIIYqMBOtCCCGEEEIIIUSRkWBdCCGEEEIIIYQoMhKsCyGEEEIIIYQQReb/B0+n+HOVzfzOAAAAAElFTkSuQmCC", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "\n", + "n_rows = math.ceil(n_series / 2)\n", + "\n", + "fig, axs = plt.subplots(n_rows, 2, figsize=(10, n_rows * 3))\n", + "\n", + "for series in range(n_series):\n", + "\n", + " ax = axs[series // 2, series % 2] if n_rows > 1 else axs[series % 2]\n", + " \n", + " ax.plot(y_true[series, :].detach().numpy(), label=\"true\")\n", + " mean_pred = samples['y_stacked'][...,series,:].mean(dim = -4).squeeze()\n", + " low_pred = samples['y_stacked'][...,series,:].quantile(0.05, dim=-4).squeeze()\n", + " high_pred = samples['y_stacked'][...,series,:].quantile(0.95, dim=-4).squeeze()\n", + "\n", + " overall_mean = y_true[series,:].mean()\n", + " null_residuals = y_true[series,:] - overall_mean\n", + " model_residuals = y_true[series,:] - mean_pred\n", + " # r^2 \n", + " r2 = 1 - (model_residuals.var() / null_residuals.var())\n", + "\n", + "\n", + " ax.plot(mean_pred.detach().numpy(), label=\"mean prediction\")\n", + "\n", + " ax.fill_between(range(T), low_pred.detach().numpy(),\n", + " high_pred.detach().numpy(), alpha=0.5, label=\"95% credible interval\")\n", + "\n", + "\n", + " ax.set_title(f\"Series {series + 1}, $R^2$ = {r2:.2f}\")\n", + "\n", + " if series == 0:\n", + " ax.legend()\n", + " \n", + "sns.despine()\n", + "plt.tight_layout()\n", + "plt.show() \n" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "polis-dev", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.10.13" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/docs/experimental_notebooks/.Rhistory b/docs/experimental_notebooks/.Rhistory new file mode 100644 index 00000000..e86675ec --- /dev/null +++ b/docs/experimental_notebooks/.Rhistory @@ -0,0 +1,87 @@ +require(dagitty) +# with zones +zones_dag <- dagitty('dag { +year [pos="0,2"] +month [pos="1,2"] +limit_con [pos="2,1"] +parcel_area [pos="2,0"] +ward_id [pos="3.5,0.2"] +zone_id [pos = "1, 0"] +neighborhood_id [pos = "4, 0"] +housing_units [pos = "5,1"] +past_reform [pos ="0, .5"] +past_reform_by_zone [pos = "0,1"] +year -> housing_units +month -> housing_units +limit_con -> housing_units +parcel_area -> housing_units +ward_id -> housing_units +zone_id -> housing_units +neighborhood_id -> housing_units +neighborhood_id -> parcel_area +zone_id -> past_reform_by_zone +zone_id -> parcel_area +past_reform -> past_reform_by_zone +past_reform_by_zone -> limit_con +}') +plot(zones_dag) +paths(zones_dag,"limit_con","housing_units") +adjustmentSets(zones_dag,"limit_con","housing_units",type = "all") +impliedConditionalIndependencies(zones_dag) +#--------------------------------------------------------------------------------------- +# with distances +zones_dag <- dagitty('dag { +year [pos="0,2"] +month [pos="1,2"] +limit_con [pos="2,1"] +parcel_area [pos="2,0"] +ward_id [pos="3.5,0.2"] +zone_id [pos = "1, 0"] +neighborhood_id [pos = "4, 0"] +housing_units [pos = "5,1"] +past_reform [pos ="0, .5"] +past_reform_by_zone [pos = "0,1"] +year -> housing_units +month -> housing_units +limit_con -> housing_units +parcel_area -> housing_units +ward_id -> housing_units +zone_id -> housing_units +neighborhood_id -> housing_units +neighborhood_id -> parcel_area +zone_id -> past_reform_by_zone +zone_id -> parcel_area +past_reform -> past_reform_by_zone +past_reform_by_zone -> limit_con +}') +plot(zones_dag) +paths(zones_dag,"limit_con","housing_units") +adjustmentSets(zones_dag,"limit_con","housing_units",type = "all") +impliedConditionalIndependencies(zones_dag) +require(dagitty) +# with zones +tracts_dag <- dagitty('dag { +year [pos="0,2"] +distance [pos = "0,0"] +total_value [pos = "1,0"] +median_value [pos = "1.2,0.3"] +limit [pos="1,1"] +units [pos = "2,1"] +distance -> limit +distance -> total_value +distance -> median_value +distance -> units +year -> limit +year -> total_value +year -> median_value +year -> units +total_value -> units +median_value -> units +limit -> total_value +limit -> median_value +limit -> units +}') +plot(tracts_dag) +paths(tracts_dag,"limit","units") +adjustmentSets(tracts_dag,"limit","units", type = "all") +impliedConditionalIndependencies(tracts_dag) diff --git a/docs/experimental_notebooks/.Rproj.user/735F60EC/pcs/files-pane.pper b/docs/experimental_notebooks/.Rproj.user/735F60EC/pcs/files-pane.pper new file mode 100644 index 00000000..257a7704 --- /dev/null +++ b/docs/experimental_notebooks/.Rproj.user/735F60EC/pcs/files-pane.pper @@ -0,0 +1,9 @@ +{ + "sortOrder": [ + { + "columnIndex": 2, + "ascending": true + } + ], + "path": "~/s78projects/cities/docs/experimental_notebooks/zoning" +} \ No newline at end of file diff --git a/docs/experimental_notebooks/.Rproj.user/735F60EC/pcs/source-pane.pper b/docs/experimental_notebooks/.Rproj.user/735F60EC/pcs/source-pane.pper new file mode 100644 index 00000000..b074a4fe --- /dev/null +++ b/docs/experimental_notebooks/.Rproj.user/735F60EC/pcs/source-pane.pper @@ -0,0 +1,3 @@ +{ + "activeTab": 1 +} \ No newline at end of file diff --git a/docs/experimental_notebooks/.Rproj.user/735F60EC/pcs/windowlayoutstate.pper b/docs/experimental_notebooks/.Rproj.user/735F60EC/pcs/windowlayoutstate.pper new file mode 100644 index 00000000..5563078a --- /dev/null +++ b/docs/experimental_notebooks/.Rproj.user/735F60EC/pcs/windowlayoutstate.pper @@ -0,0 +1,14 @@ +{ + "left": { + "splitterpos": 463, + "topwindowstate": "NORMAL", + "panelheight": 1120, + "windowheight": 1158 + }, + "right": { + "splitterpos": 694, + "topwindowstate": "NORMAL", + "panelheight": 1120, + "windowheight": 1158 + } +} \ No newline at end of file diff --git a/docs/experimental_notebooks/.Rproj.user/735F60EC/pcs/workbench-pane.pper b/docs/experimental_notebooks/.Rproj.user/735F60EC/pcs/workbench-pane.pper new file mode 100644 index 00000000..d3c76342 --- /dev/null +++ b/docs/experimental_notebooks/.Rproj.user/735F60EC/pcs/workbench-pane.pper @@ -0,0 +1,5 @@ +{ + "TabSet1": 0, + "TabSet2": 1, + "TabZoom": {} +} \ No newline at end of file diff --git a/docs/experimental_notebooks/.Rproj.user/735F60EC/rmd-outputs b/docs/experimental_notebooks/.Rproj.user/735F60EC/rmd-outputs new file mode 100644 index 00000000..3f2ff2d6 --- /dev/null +++ b/docs/experimental_notebooks/.Rproj.user/735F60EC/rmd-outputs @@ -0,0 +1,5 @@ + + + + + diff --git a/docs/experimental_notebooks/.Rproj.user/735F60EC/saved_source_markers b/docs/experimental_notebooks/.Rproj.user/735F60EC/saved_source_markers new file mode 100644 index 00000000..2b1bef11 --- /dev/null +++ b/docs/experimental_notebooks/.Rproj.user/735F60EC/saved_source_markers @@ -0,0 +1 @@ +{"active_set":"","sets":[]} \ No newline at end of file diff --git a/docs/experimental_notebooks/.Rproj.user/735F60EC/sources/per/t/4EAFCA4F b/docs/experimental_notebooks/.Rproj.user/735F60EC/sources/per/t/4EAFCA4F new file mode 100644 index 00000000..fc4c1eb3 --- /dev/null +++ b/docs/experimental_notebooks/.Rproj.user/735F60EC/sources/per/t/4EAFCA4F @@ -0,0 +1,26 @@ +{ + "id": "4EAFCA4F", + "path": "~/s78projects/cities/docs/experimental_notebooks/zoning/tracts_dags.R", + "project_path": "zoning/tracts_dags.R", + "type": "r_source", + "hash": "2157559845", + "contents": "", + "dirty": true, + "created": 1724161369201.0, + "source_on_save": false, + "relative_order": 2, + "properties": { + "source_window_id": "", + "Source": "Source", + "cursorPosition": "21,24", + "scrollLine": "4" + }, + "folds": "", + "lastKnownWriteTime": 1724161086, + "encoding": "UTF-8", + "collab_server": "", + "source_window": "", + "last_content_update": 1724161086, + "read_only": false, + "read_only_alternatives": [] +} \ No newline at end of file diff --git a/docs/experimental_notebooks/.Rproj.user/735F60EC/sources/per/t/4EAFCA4F-contents b/docs/experimental_notebooks/.Rproj.user/735F60EC/sources/per/t/4EAFCA4F-contents new file mode 100644 index 00000000..56daab70 --- /dev/null +++ b/docs/experimental_notebooks/.Rproj.user/735F60EC/sources/per/t/4EAFCA4F-contents @@ -0,0 +1,37 @@ +require(dagitty) + +# with zones +tracts_dag <- dagitty('dag { + year [pos="0,2"] + distance [pos = "0,0"] + total_value [pos = "1,0"] + median_value [pos = "1.2,0.3"] + limit [pos="1,1"] + units [pos = "2,1"] + + distance -> limit + distance -> total_value + distance -> median_value + distance -> units + + year -> limit + year -> total_value + year -> median_value + year -> units + + total_value -> units + median_value -> units + + + limit -> total_value + limit -> median_value + limit -> units + + }') + + + +plot(tracts_dag) +paths(tracts_dag,"limit","units") +adjustmentSets(tracts_dag,"limit","units", type = "all") +impliedConditionalIndependencies(tracts_dag) diff --git a/docs/experimental_notebooks/.Rproj.user/735F60EC/sources/per/t/FFB1EEE4 b/docs/experimental_notebooks/.Rproj.user/735F60EC/sources/per/t/FFB1EEE4 new file mode 100644 index 00000000..1ab31a63 --- /dev/null +++ b/docs/experimental_notebooks/.Rproj.user/735F60EC/sources/per/t/FFB1EEE4 @@ -0,0 +1,26 @@ +{ + "id": "FFB1EEE4", + "path": "~/s78projects/cities/docs/experimental_notebooks/zoning/zoning_dags.R", + "project_path": "zoning/zoning_dags.R", + "type": "r_source", + "hash": "150867923", + "contents": "", + "dirty": false, + "created": 1724161317981.0, + "source_on_save": false, + "relative_order": 1, + "properties": { + "source_window_id": "", + "Source": "Source", + "cursorPosition": "2,2", + "scrollLine": "0" + }, + "folds": "", + "lastKnownWriteTime": 1724161086, + "encoding": "UTF-8", + "collab_server": "", + "source_window": "", + "last_content_update": 1724161086, + "read_only": false, + "read_only_alternatives": [] +} \ No newline at end of file diff --git a/docs/experimental_notebooks/.Rproj.user/735F60EC/sources/per/t/FFB1EEE4-contents b/docs/experimental_notebooks/.Rproj.user/735F60EC/sources/per/t/FFB1EEE4-contents new file mode 100644 index 00000000..eef85bf9 --- /dev/null +++ b/docs/experimental_notebooks/.Rproj.user/735F60EC/sources/per/t/FFB1EEE4-contents @@ -0,0 +1,79 @@ +require(dagitty) + +# with zones +zones_dag <- dagitty('dag { + year [pos="0,2"] + month [pos="1,2"] + limit_con [pos="2,1"] + parcel_area [pos="2,0"] + ward_id [pos="3.5,0.2"] + zone_id [pos = "1, 0"] + neighborhood_id [pos = "4, 0"] + housing_units [pos = "5,1"] + past_reform [pos ="0, .5"] + past_reform_by_zone [pos = "0,1"] + + + year -> housing_units + month -> housing_units + limit_con -> housing_units + parcel_area -> housing_units + ward_id -> housing_units + zone_id -> housing_units + neighborhood_id -> housing_units + + neighborhood_id -> parcel_area + zone_id -> past_reform_by_zone + zone_id -> parcel_area + past_reform -> past_reform_by_zone + past_reform_by_zone -> limit_con + +}') + + + +plot(zones_dag) +paths(zones_dag,"limit_con","housing_units") +adjustmentSets(zones_dag,"limit_con","housing_units",type = "all") +impliedConditionalIndependencies(zones_dag) + + + + +#--------------------------------------------------------------------------------------- +# with distances +zones_dag <- dagitty('dag { + year [pos="0,2"] + month [pos="1,2"] + limit_con [pos="2,1"] + parcel_area [pos="2,0"] + ward_id [pos="3.5,0.2"] + zone_id [pos = "1, 0"] + neighborhood_id [pos = "4, 0"] + housing_units [pos = "5,1"] + past_reform [pos ="0, .5"] + past_reform_by_zone [pos = "0,1"] + + + year -> housing_units + month -> housing_units + limit_con -> housing_units + parcel_area -> housing_units + ward_id -> housing_units + zone_id -> housing_units + neighborhood_id -> housing_units + + neighborhood_id -> parcel_area + zone_id -> past_reform_by_zone + zone_id -> parcel_area + past_reform -> past_reform_by_zone + past_reform_by_zone -> limit_con + +}') + + + +plot(zones_dag) +paths(zones_dag,"limit_con","housing_units") +adjustmentSets(zones_dag,"limit_con","housing_units",type = "all") +impliedConditionalIndependencies(zones_dag) diff --git a/docs/experimental_notebooks/.Rproj.user/735F60EC/sources/prop/4057158B b/docs/experimental_notebooks/.Rproj.user/735F60EC/sources/prop/4057158B new file mode 100644 index 00000000..e1be0f7d --- /dev/null +++ b/docs/experimental_notebooks/.Rproj.user/735F60EC/sources/prop/4057158B @@ -0,0 +1,7 @@ +{ + "tempName": "Untitled1", + "source_window_id": "", + "Source": "Source", + "cursorPosition": "33,40", + "scrollLine": "18" +} \ No newline at end of file diff --git a/docs/experimental_notebooks/.Rproj.user/735F60EC/sources/prop/AE428842 b/docs/experimental_notebooks/.Rproj.user/735F60EC/sources/prop/AE428842 new file mode 100644 index 00000000..c01e52d7 --- /dev/null +++ b/docs/experimental_notebooks/.Rproj.user/735F60EC/sources/prop/AE428842 @@ -0,0 +1,6 @@ +{ + "source_window_id": "", + "Source": "Source", + "cursorPosition": "95,0", + "scrollLine": "0" +} \ No newline at end of file diff --git a/docs/experimental_notebooks/.Rproj.user/735F60EC/sources/prop/B2BF0B6B b/docs/experimental_notebooks/.Rproj.user/735F60EC/sources/prop/B2BF0B6B new file mode 100644 index 00000000..b67e905d --- /dev/null +++ b/docs/experimental_notebooks/.Rproj.user/735F60EC/sources/prop/B2BF0B6B @@ -0,0 +1,6 @@ +{ + "source_window_id": "", + "Source": "Source", + "cursorPosition": "2,2", + "scrollLine": "0" +} \ No newline at end of file diff --git a/docs/experimental_notebooks/.Rproj.user/735F60EC/sources/prop/CEE077AB b/docs/experimental_notebooks/.Rproj.user/735F60EC/sources/prop/CEE077AB new file mode 100644 index 00000000..ece09bb4 --- /dev/null +++ b/docs/experimental_notebooks/.Rproj.user/735F60EC/sources/prop/CEE077AB @@ -0,0 +1,7 @@ +{ + "tempName": "Untitled1", + "source_window_id": "", + "Source": "Source", + "cursorPosition": "57,4", + "scrollLine": "56" +} \ No newline at end of file diff --git a/docs/experimental_notebooks/.Rproj.user/735F60EC/sources/prop/D2FE184D b/docs/experimental_notebooks/.Rproj.user/735F60EC/sources/prop/D2FE184D new file mode 100644 index 00000000..4102d7f5 --- /dev/null +++ b/docs/experimental_notebooks/.Rproj.user/735F60EC/sources/prop/D2FE184D @@ -0,0 +1,6 @@ +{ + "source_window_id": "", + "Source": "Source", + "cursorPosition": "21,24", + "scrollLine": "4" +} \ No newline at end of file diff --git a/docs/experimental_notebooks/.Rproj.user/735F60EC/sources/prop/INDEX b/docs/experimental_notebooks/.Rproj.user/735F60EC/sources/prop/INDEX new file mode 100644 index 00000000..f24983a6 --- /dev/null +++ b/docs/experimental_notebooks/.Rproj.user/735F60EC/sources/prop/INDEX @@ -0,0 +1,2 @@ +~%2Fs78projects%2Fcities%2Fdocs%2Fexperimental_notebooks%2Fzoning%2Ftracts_dags.R="D2FE184D" +~%2Fs78projects%2Fcities%2Fdocs%2Fexperimental_notebooks%2Fzoning%2Fzoning_dags.R="B2BF0B6B" diff --git a/docs/experimental_notebooks/.Rproj.user/735F60EC/sources/session-fb0f82db/644C3C4D b/docs/experimental_notebooks/.Rproj.user/735F60EC/sources/session-fb0f82db/644C3C4D new file mode 100644 index 00000000..45bda793 --- /dev/null +++ b/docs/experimental_notebooks/.Rproj.user/735F60EC/sources/session-fb0f82db/644C3C4D @@ -0,0 +1,27 @@ +{ + "id": "644C3C4D", + "path": "~/s78projects/cities/docs/experimental_notebooks/zoning/tracts_population_dag.R", + "project_path": "zoning/tracts_population_dag.R", + "type": "r_source", + "hash": "0", + "contents": "", + "dirty": false, + "created": 1727800740083.0, + "source_on_save": false, + "relative_order": 2, + "properties": { + "tempName": "Untitled1", + "source_window_id": "", + "Source": "Source", + "cursorPosition": "33,40", + "scrollLine": "18" + }, + "folds": "", + "lastKnownWriteTime": 1728657199, + "encoding": "UTF-8", + "collab_server": "", + "source_window": "", + "last_content_update": 1728657199368, + "read_only": false, + "read_only_alternatives": [] +} \ No newline at end of file diff --git a/docs/experimental_notebooks/.Rproj.user/735F60EC/sources/session-fb0f82db/644C3C4D-contents b/docs/experimental_notebooks/.Rproj.user/735F60EC/sources/session-fb0f82db/644C3C4D-contents new file mode 100644 index 00000000..0b5a1dcc --- /dev/null +++ b/docs/experimental_notebooks/.Rproj.user/735F60EC/sources/session-fb0f82db/644C3C4D-contents @@ -0,0 +1,108 @@ +require(dagitty) + +if (rstudioapi::isAvailable()) { + # Set working directory to the script's location + setwd(dirname(rstudioapi::getActiveDocumentContext()$path)) +} + +print(getwd()) + +# with zones +tracts_dag <- dagitty('dag { + year [pos="0,2"] + distance [pos = "0,0"] + university_overlap [pos = "0,.8"] + downtown_overlap [pos = "0, 1.2"] + + total_population [pos = "0.1, .2"] + + square_meters [pos = "0.2,.4"] + limit [pos = "0.2, 1.6"] + + white [pos = "0.4,1.8"] + segregation [pos = "0.6,0.2"] + + income [pos = "0.7, .8"] + + median_value [pos = "0.9,1.4"] + housing_units [pos = "1.,.6"] + + + distance -> total_population + year -> total_population + university_overlap -> total_popoulation + downtown_overlap -> total_population + + distance -> square_meters + year -> square_meters + + distance -> limit + year -> limit + + distance -> white + square_meters -> white + limit -> white + + distance -> segregation + year -> segregation + limit -> segregation + square_meters -> segregation + white -> segregation + + distance -> income + white -> income + segregation -> income + square_meters -> income + limit -> income + year -> income + + distance -> median_value + income -> median_value + white -> median_value + segregation -> median_value + square_meters -> median_value + limit -> median_value + year -> median_value + + + university_overlap -> housing_units + downtown_overlap -> housing_units + median_value -> housing_units + distance -> housing_units + income -> housing_units + white -> housing_units + limit -> housing_units + segregation -> housing_units + square_meters -> housing_units + year -> housing_units + + + + + }') + +plot(tracts_dag) + + +png("tracts_dag_plot_high_density.png", + width = 2000, + height = 1600, + res = 300 +) +plot(tracts_dag) +dev.off() + +pdf("tracts_dag_plot.pdf", + width = 10, + height = 8, + pointsize = 18, + paper = "special", + useDingbats = FALSE, + compress = FALSE) +plot(tracts_dag) +dev.off() + +plot(tracts_dag) +paths(tracts_dag,"limit","housing_units") +adjustmentSets(tracts_dag,"limit","housing_units", type = "all") +impliedConditionalIndependencies(tracts_dag) diff --git a/docs/experimental_notebooks/.Rproj.user/735F60EC/sources/session-fb0f82db/A2603F02 b/docs/experimental_notebooks/.Rproj.user/735F60EC/sources/session-fb0f82db/A2603F02 new file mode 100644 index 00000000..784022b7 --- /dev/null +++ b/docs/experimental_notebooks/.Rproj.user/735F60EC/sources/session-fb0f82db/A2603F02 @@ -0,0 +1,26 @@ +{ + "id": "A2603F02", + "path": "~/s78projects/cities/docs/experimental_notebooks/zoning/tracts_dags.R", + "project_path": "zoning/tracts_dags.R", + "type": "r_source", + "hash": "0", + "contents": "", + "dirty": false, + "created": 1727800733002.0, + "source_on_save": false, + "relative_order": 1, + "properties": { + "source_window_id": "", + "Source": "Source", + "cursorPosition": "95,0", + "scrollLine": "0" + }, + "folds": "", + "lastKnownWriteTime": 1727798984, + "encoding": "UTF-8", + "collab_server": "", + "source_window": "", + "last_content_update": 1727798984, + "read_only": false, + "read_only_alternatives": [] +} \ No newline at end of file diff --git a/docs/experimental_notebooks/.Rproj.user/735F60EC/sources/session-fb0f82db/A2603F02-contents b/docs/experimental_notebooks/.Rproj.user/735F60EC/sources/session-fb0f82db/A2603F02-contents new file mode 100644 index 00000000..104e3944 --- /dev/null +++ b/docs/experimental_notebooks/.Rproj.user/735F60EC/sources/session-fb0f82db/A2603F02-contents @@ -0,0 +1,95 @@ +require(dagitty) + +if (rstudioapi::isAvailable()) { + # Set working directory to the script's location + setwd(dirname(rstudioapi::getActiveDocumentContext()$path)) +} + +print(getwd()) + +# with zones +tracts_dag <- dagitty('dag { + year [pos="0,2"] + distance [pos = "0,0"] + + square_meters [pos = "0.2,.4"] + limit [pos = "0.2, 1.6"] + + white [pos = "0.4,1.8"] + segregation [pos = "0.6,0.2"] + + income [pos = "0.7, .8"] + + median_value [pos = "0.9,1.4"] + housing_units [pos = "1.,.6"] + + distance -> square_meters + year -> square_meters + + distance -> limit + year -> limit + + distance -> white + square_meters -> white + limit -> white + + distance -> segregation + year -> segregation + limit -> segregation + square_meters -> segregation + white -> segregation + + distance -> income + white -> income + segregation -> income + square_meters -> income + limit -> income + year -> income + + distance -> median_value + income -> median_value + white -> median_value + segregation -> median_value + square_meters -> median_value + limit -> median_value + year -> median_value + + median_value -> housing_units + distance -> housing_units + income -> housing_units + white -> housing_units + limit -> housing_units + segregation -> housing_units + square_meters -> housing_units + year -> housing_units + + + + + }') + +plot(tracts_dag) + + +png("tracts_dag_plot_high_density.png", + width = 2000, + height = 1600, + res = 300 +) +plot(tracts_dag) +dev.off() + +pdf("tracts_dag_plot.pdf", + width = 10, + height = 8, + pointsize = 18, + paper = "special", + useDingbats = FALSE, + compress = FALSE) +plot(tracts_dag) +dev.off() + +plot(tracts_dag) +paths(tracts_dag,"limit","housing_units") +adjustmentSets(tracts_dag,"limit","housing_units", type = "all") +impliedConditionalIndependencies(tracts_dag) diff --git a/docs/experimental_notebooks/.Rproj.user/735F60EC/sources/session-fb0f82db/lock_file b/docs/experimental_notebooks/.Rproj.user/735F60EC/sources/session-fb0f82db/lock_file new file mode 100644 index 00000000..e69de29b diff --git a/docs/experimental_notebooks/.Rproj.user/shared/notebooks/patch-chunk-names b/docs/experimental_notebooks/.Rproj.user/shared/notebooks/patch-chunk-names new file mode 100644 index 00000000..e69de29b diff --git a/docs/experimental_notebooks/.Rproj.user/shared/notebooks/paths b/docs/experimental_notebooks/.Rproj.user/shared/notebooks/paths new file mode 100644 index 00000000..6c1f37fe --- /dev/null +++ b/docs/experimental_notebooks/.Rproj.user/shared/notebooks/paths @@ -0,0 +1,2 @@ +/home/rafal/s78projects/cities/docs/experimental_notebooks/zoning/tracts_interactions_dag.R="37338FC3" +/home/rafal/s78projects/cities/docs/experimental_notebooks/zoning/tracts_population_dag.R="69D3F49D" diff --git a/docs/experimental_notebooks/zoning/.RData b/docs/experimental_notebooks/zoning/.RData new file mode 100644 index 00000000..dab7dc96 Binary files /dev/null and b/docs/experimental_notebooks/zoning/.RData differ diff --git a/docs/experimental_notebooks/zoning/.Rhistory b/docs/experimental_notebooks/zoning/.Rhistory new file mode 100644 index 00000000..3c6261fb --- /dev/null +++ b/docs/experimental_notebooks/zoning/.Rhistory @@ -0,0 +1,403 @@ +require(dagitty) +# with zones +tracts_dag <- dagitty('dag { +year [pos="0,2"] +distance [pos = "0,0"] +white [pos = ".2,1"] +segregation [pos = ".6,1"] +income [pos = ".9,.8"] +median_value [pos = "1.2,0.2"] +limit [pos=".7,1.8"] +units [pos = "1.5,.8"] +sqm [pos = ".2,.4"] +distance -> sqm +year -> sqm +year -> limit +distance -> limit +distance -> white +year -> white +sqm -> white +limit -> white +sqm -> segregation +distance -> segregation +white -> segregation +year -> segregation +limit -> segregation +sqm -> income +distance -> income +white -> income +segregation -> income +year -> income +limit -> income +sqm -> median_value +distance -> median_value +limit -> median_value +income -> median_value +white -> median_value +segregation -> median_value +year -> median_value +sqm -> units +median_value -> units +distance -> units +income -> units +white -> units +limit -> units +segregation -> units +year -> units +}') +plot(tracts_dag) +paths(tracts_dag,"limit","units") +adjustmentSets(tracts_dag,"limit","units", type = "all") +impliedConditionalIndependencies(tracts_dag) +require(dagitty) +if (rstudioapi::isAvailable()) { +# Set working directory to the script's location +setwd(dirname(rstudioapi::getActiveDocumentContext()$path)) +} +print(getwd()) +# with zones +tracts_dag <- dagitty('dag { +year [pos="0,2"] +distance [pos = "0,0"] +sqm [pos = "0.2,.4"] +limit [pos = "0.2, 1.6"] +white [pos = "0.4,1.8"] +segregation [pos = "0.6,0.2"] +income [pos = "0.7, .8"] +median_value [pos = "0.9,1.4"] +housing_units [pos = "1.,.6"] +distance -> sqm +year -> sqm +distance -> limit +year -> limit +distance -> white +sqm -> white +limit -> white +distance -> segregation +year -> segregation +limit -> segregation +sqm -> segregation +white -> segregation +distance -> income +white -> income +segregation -> income +sqm -> income +limit -> income +year -> income +distance -> median_value +income -> median_value +white -> median_value +segregation -> median_value +sqm -> median_value +limit -> median_value +year -> median_value +median_value -> housing_units +distance -> housing_units +income -> housing_units +white -> housing_units +limit -> housing_units +segregation -> housing_units +sqm -> housing_units +year -> housing_units +}') +plot(tracts_dag) +png("tracts_dag_plot_high_density.png", +width = 2000, +height = 1600, +res = 300 +) +plot(tracts_dag) +dev.off() +pdf("tracts_dag_plot.pdf", +width = 10, +height = 8, +pointsize = 18, +paper = "special", +useDingbats = FALSE, +compress = FALSE) +plot(tracts_dag) +dev.off() +plot(tracts_dag) +paths(tracts_dag,"limit","units") +require(dagitty) +if (rstudioapi::isAvailable()) { +# Set working directory to the script's location +setwd(dirname(rstudioapi::getActiveDocumentContext()$path)) +} +print(getwd()) +# with zones +tracts_dag <- dagitty('dag { +year [pos="0,2"] +distance [pos = "0,0"] +square_meters [pos = "0.2,.4"] +limit [pos = "0.2, 1.6"] +white [pos = "0.4,1.8"] +segregation [pos = "0.6,0.2"] +income [pos = "0.7, .8"] +median_value [pos = "0.9,1.4"] +housing_units [pos = "1.,.6"] +distance -> sqm +year -> sqm +distance -> limit +year -> limit +distance -> white +square_meters -> white +limit -> white +distance -> segregation +year -> segregation +limit -> segregation +square_meters -> segregation +white -> segregation +distance -> income +white -> income +segregation -> income +square_meters -> income +limit -> income +year -> income +distance -> median_value +income -> median_value +white -> median_value +segregation -> median_value +square_meters -> median_value +limit -> median_value +year -> median_value +median_value -> housing_units +distance -> housing_units +income -> housing_units +white -> housing_units +limit -> housing_units +segregation -> housing_units +square_meters -> housing_units +year -> housing_units +}') +plot(tracts_dag) +png("tracts_dag_plot_high_density.png", +width = 2000, +height = 1600, +res = 300 +) +plot(tracts_dag) +dev.off() +pdf("tracts_dag_plot.pdf", +width = 10, +height = 8, +pointsize = 18, +paper = "special", +useDingbats = FALSE, +compress = FALSE) +plot(tracts_dag) +dev.off() +plot(tracts_dag) +paths(tracts_dag,"limit","units") +require(dagitty) +if (rstudioapi::isAvailable()) { +# Set working directory to the script's location +setwd(dirname(rstudioapi::getActiveDocumentContext()$path)) +} +print(getwd()) +# with zones +tracts_dag <- dagitty('dag { +year [pos="0,2"] +distance [pos = "0,0"] +square_meters [pos = "0.2,.4"] +limit [pos = "0.2, 1.6"] +white [pos = "0.4,1.8"] +segregation [pos = "0.6,0.2"] +income [pos = "0.7, .8"] +median_value [pos = "0.9,1.4"] +housing_units [pos = "1.,.6"] +distance -> square_meters +year -> square_meters +distance -> limit +year -> limit +distance -> white +square_meters -> white +limit -> white +distance -> segregation +year -> segregation +limit -> segregation +square_meters -> segregation +white -> segregation +distance -> income +white -> income +segregation -> income +square_meters -> income +limit -> income +year -> income +distance -> median_value +income -> median_value +white -> median_value +segregation -> median_value +square_meters -> median_value +limit -> median_value +year -> median_value +median_value -> housing_units +distance -> housing_units +income -> housing_units +white -> housing_units +limit -> housing_units +segregation -> housing_units +square_meters -> housing_units +year -> housing_units +}') +plot(tracts_dag) +png("tracts_dag_plot_high_density.png", +width = 2000, +height = 1600, +res = 300 +) +plot(tracts_dag) +dev.off() +pdf("tracts_dag_plot.pdf", +width = 10, +height = 8, +pointsize = 18, +paper = "special", +useDingbats = FALSE, +compress = FALSE) +plot(tracts_dag) +dev.off() +plot(tracts_dag) +paths(tracts_dag,"limit","units") +require(dagitty) +if (rstudioapi::isAvailable()) { +# Set working directory to the script's location +setwd(dirname(rstudioapi::getActiveDocumentContext()$path)) +} +print(getwd()) +# with zones +tracts_dag <- dagitty('dag { +year [pos="0,2"] +distance [pos = "0,0"] +square_meters [pos = "0.2,.4"] +limit [pos = "0.2, 1.6"] +white [pos = "0.4,1.8"] +segregation [pos = "0.6,0.2"] +income [pos = "0.7, .8"] +median_value [pos = "0.9,1.4"] +housing_units [pos = "1.,.6"] +distance -> square_meters +year -> square_meters +distance -> limit +year -> limit +distance -> white +square_meters -> white +limit -> white +distance -> segregation +year -> segregation +limit -> segregation +square_meters -> segregation +white -> segregation +distance -> income +white -> income +segregation -> income +square_meters -> income +limit -> income +year -> income +distance -> median_value +income -> median_value +white -> median_value +segregation -> median_value +square_meters -> median_value +limit -> median_value +year -> median_value +median_value -> housing_units +distance -> housing_units +income -> housing_units +white -> housing_units +limit -> housing_units +segregation -> housing_units +square_meters -> housing_units +year -> housing_units +}') +plot(tracts_dag) +png("tracts_dag_plot_high_density.png", +width = 2000, +height = 1600, +res = 300 +) +plot(tracts_dag) +dev.off() +pdf("tracts_dag_plot.pdf", +width = 10, +height = 8, +pointsize = 18, +paper = "special", +useDingbats = FALSE, +compress = FALSE) +plot(tracts_dag) +dev.off() +plot(tracts_dag) +paths(tracts_dag,"limit","units") +require(dagitty) +if (rstudioapi::isAvailable()) { +# Set working directory to the script's location +setwd(dirname(rstudioapi::getActiveDocumentContext()$path)) +} +print(getwd()) +# with zones +tracts_dag <- dagitty('dag { +year [pos="0,2"] +distance [pos = "0,0"] +square_meters [pos = "0.2,.4"] +limit [pos = "0.2, 1.6"] +white [pos = "0.4,1.8"] +segregation [pos = "0.6,0.2"] +income [pos = "0.7, .8"] +median_value [pos = "0.9,1.4"] +housing_units [pos = "1.,.6"] +distance -> square_meters +year -> square_meters +distance -> limit +year -> limit +distance -> white +square_meters -> white +limit -> white +distance -> segregation +year -> segregation +limit -> segregation +square_meters -> segregation +white -> segregation +distance -> income +white -> income +segregation -> income +square_meters -> income +limit -> income +year -> income +distance -> median_value +income -> median_value +white -> median_value +segregation -> median_value +square_meters -> median_value +limit -> median_value +year -> median_value +median_value -> housing_units +distance -> housing_units +income -> housing_units +white -> housing_units +limit -> housing_units +segregation -> housing_units +square_meters -> housing_units +year -> housing_units +}') +plot(tracts_dag) +png("tracts_dag_plot_high_density.png", +width = 2000, +height = 1600, +res = 300 +) +plot(tracts_dag) +dev.off() +pdf("tracts_dag_plot.pdf", +width = 10, +height = 8, +pointsize = 18, +paper = "special", +useDingbats = FALSE, +compress = FALSE) +plot(tracts_dag) +dev.off() +plot(tracts_dag) +paths(tracts_dag,"limit","housing_units") +adjustmentSets(tracts_dag,"limit","housing_units", type = "all") +impliedConditionalIndependencies(tracts_dag) diff --git a/docs/testing_notebooks/causal_insights_demo.ipynb b/docs/testing_notebooks/causal_insights_demo.ipynb index 61c1d424..a104e02f 100644 --- a/docs/testing_notebooks/causal_insights_demo.ipynb +++ b/docs/testing_notebooks/causal_insights_demo.ipynb @@ -10,8 +10,7 @@ "import random\n", "\n", "from cities.queries.causal_insight import CausalInsight\n", - "from cities.utils.data_grabber import (DataGrabber, list_interventions,\n", - " list_outcomes)\n", + "from cities.utils.data_grabber import DataGrabber, list_interventions, list_outcomes\n", "\n", "smoke_test = \"CI\" in os.environ\n", "num_samples = 10 if smoke_test else 1000" diff --git a/docs/testing_notebooks/slider.ipynb b/docs/testing_notebooks/slider.ipynb index 90691e87..db8a6f79 100644 --- a/docs/testing_notebooks/slider.ipynb +++ b/docs/testing_notebooks/slider.ipynb @@ -6,12 +6,14 @@ "metadata": {}, "outputs": [], "source": [ - "import os \n", + "import os\n", + "\n", + "import numpy as np\n", + "\n", "from cities.queries.causal_insight import CausalInsight as CausalInsight\n", "from cities.queries.causal_insight_slim import CausalInsightSlim as CausalInsightSlim\n", "from cities.utils.data_grabber import DataGrabber\n", "\n", - "import numpy as np\n", "smoke_test = \"CI\" in os.environ\n", "num_samples = 10 if smoke_test else 1000" ] @@ -53,7 +55,7 @@ "intervention = \"spending_commerce\"\n", "year = 2018\n", "\n", - "#the object instantiation doesn't change\n", + "# the object instantiation doesn't change\n", "ci = CausalInsight(\n", " outcome_dataset=outcome,\n", " intervention_dataset=intervention,\n", @@ -61,8 +63,7 @@ ")\n", "\n", "\n", - "\n", - "percent_calc = ci.slider_values_to_interventions(intervened_percent=50, year = year)\n", + "percent_calc = ci.slider_values_to_interventions(intervened_percent=50, year=year)\n", "\n", "display(percent_calc)\n", "\n", @@ -70,12 +71,15 @@ "\n", "ci.get_tau_samples()\n", "\n", - "ci.get_fips_predictions(intervened_value= percent_calc['intervened_transformed'],\n", - " fips=fips, year = year)\n", + "ci.get_fips_predictions(\n", + " intervened_value=percent_calc[\"intervened_transformed\"], fips=fips, year=year\n", + ")\n", "\n", "ci.plot_predictions(range_multiplier=1)\n", "\n", - "assert np.allclose(ci.intervened_value_original, percent_calc['intervened_original'], rtol = 0.01)\n" + "assert np.allclose(\n", + " ci.intervened_value_original, percent_calc[\"intervened_original\"], rtol=0.01\n", + ")" ] }, { @@ -2161,7 +2165,6 @@ } ], "source": [ - "\n", "ci_slim = CausalInsightSlim(\n", " outcome_dataset=outcome,\n", " intervention_dataset=intervention,\n", @@ -2170,17 +2173,21 @@ "\n", "\n", "ci_slim.get_tau_samples()\n", - "ci_slim.get_fips_predictions(intervened_value= percent_calc['intervened_transformed'],\n", - " fips=fips, year = year)\n", + "ci_slim.get_fips_predictions(\n", + " intervened_value=percent_calc[\"intervened_transformed\"], fips=fips, year=year\n", + ")\n", "\n", "ci_slim.plot_predictions(range_multiplier=1)\n", "\n", - "ci_slim.plot_predictions(range_multiplier =1, scaling = \"original\")\n", + "ci_slim.plot_predictions(range_multiplier=1, scaling=\"original\")\n", "\n", - "percent_calc_slim = ci.slider_values_to_interventions(intervened_percent=50, year = year)\n", + "percent_calc_slim = ci.slider_values_to_interventions(intervened_percent=50, year=year)\n", "\n", - "assert np.allclose(ci_slim.intervened_value_original, percent_calc_slim['intervened_original'], rtol = 0.01)\n", - " " + "assert np.allclose(\n", + " ci_slim.intervened_value_original,\n", + " percent_calc_slim[\"intervened_original\"],\n", + " rtol=0.01,\n", + ")" ] } ], diff --git a/docs/testing_notebooks/slim_insight.ipynb b/docs/testing_notebooks/slim_insight.ipynb index 0ad30bd8..0b4e6aea 100644 --- a/docs/testing_notebooks/slim_insight.ipynb +++ b/docs/testing_notebooks/slim_insight.ipynb @@ -6,12 +6,11 @@ "metadata": {}, "outputs": [], "source": [ - "import os\n", "import cProfile\n", + "import os\n", "\n", "from cities.queries.causal_insight import CausalInsight\n", - "from cities.utils.data_grabber import (DataGrabber, list_interventions,\n", - " list_outcomes)\n", + "from cities.utils.data_grabber import DataGrabber, list_interventions, list_outcomes\n", "\n", "smoke_test = \"CI\" in os.environ\n", "num_samples = 10 if smoke_test else 1000" @@ -36,8 +35,8 @@ "data = DataGrabber()\n", "data.get_features_wide([\"gdp\"])\n", "gdp = data.wide[\"gdp\"]\n", - "fips = gdp[\"GeoFIPS\"][5] #1011\n", - "fips2 = gdp[\"GeoFIPS\"][6] #1013" + "fips = gdp[\"GeoFIPS\"][5] # 1011\n", + "fips2 = gdp[\"GeoFIPS\"][6] # 1013" ] }, { @@ -4777,9 +4776,9 @@ "\n", "# confirming that the time consuming moves involve the model\n", "# gettign samples, etc.\n", - "profiler_basic.print_stats(sort='cumulative')\n", + "profiler_basic.print_stats(sort=\"cumulative\")\n", "\n", - "# note: restricting sites to tau drops time from 8s to 5s. " + "# note: restricting sites to tau drops time from 8s to 5s." ] }, { @@ -4800,11 +4799,11 @@ "# this is prep pipeline\n", "print(smoke_test)\n", "ci = CausalInsight(\n", - " outcome_dataset=outcome,\n", - " intervention_dataset=intervention2,\n", - " num_samples=num_samples,\n", - " smoke_test=smoke_test\n", - " )\n", + " outcome_dataset=outcome,\n", + " intervention_dataset=intervention2,\n", + " num_samples=num_samples,\n", + " smoke_test=smoke_test,\n", + ")\n", "ci.generate_tensed_samples()" ] }, @@ -7368,7 +7367,7 @@ } ], "source": [ - "# this is the slim execution \n", + "# this is the slim execution\n", "def slim_run():\n", " ci = CausalInsight(\n", " outcome_dataset=outcome,\n", @@ -7388,7 +7387,7 @@ "profiler_slim.disable()\n", "\n", "\n", - "profiler_slim.print_stats(sort='cumulative')" + "profiler_slim.print_stats(sort=\"cumulative\")" ] } ], diff --git a/scripts/clean.sh b/scripts/clean.sh index 6918545f..a7ec44ae 100755 --- a/scripts/clean.sh +++ b/scripts/clean.sh @@ -1,22 +1,12 @@ #!/bin/bash set -euxo pipefail -# isort suspended as conflicting with black -# nbqa isort docs/guides/ - - -# this sometimes conflicts with black but does some -# preliminary import sorting -# and is then overriden by black -isort cities/ tests/ - -black ./cities/ ./tests/ ./docs/guides/ - -black docs/guides/ +isort --profile="black" cities/ tests/ +black cities/ tests/ autoflake --remove-all-unused-imports --in-place --recursive ./cities ./tests -nbqa autoflake --nbqa-shell --remove-all-unused-imports --recursive --in-place docs/guides/ - -#nbqa black docs/guides/ +nbqa --nbqa-shell autoflake --remove-all-unused-imports --recursive --in-place docs/guides/ docs/testing_notebooks +nbqa --nbqa-shell isort --profile="black" docs/guides/ docs/testing_notebooks +black docs/guides/ docs/testing_notebooks diff --git a/scripts/clean_path.sh b/scripts/clean_path.sh new file mode 100755 index 00000000..4cbc324f --- /dev/null +++ b/scripts/clean_path.sh @@ -0,0 +1,15 @@ +#!/bin/bash +set -euxo pipefail + + +path="${1:-.}" + +isort --profile="black" "$path" +black "$path" +autoflake --remove-all-unused-imports --in-place --recursive "$path" + +if [[ -d "$path" ]]; then + nbqa --nbqa-shell autoflake --remove-all-unused-imports --recursive --in-place "$path" + nbqa --nbqa-shell isort --profile="black" "$path" + black "$path" +fi diff --git a/scripts/lint.sh b/scripts/lint.sh index 5e5b9abe..aa432ab9 100755 --- a/scripts/lint.sh +++ b/scripts/lint.sh @@ -2,11 +2,12 @@ set -euxo pipefail mypy --ignore-missing-imports cities/ -#isort --check --diff cities/ tests/ -black --check cities/ tests/ docs/guides/ -flake8 cities/ tests/ --ignore=E203,W503 --max-line-length=127 +isort --profile="black" --check --diff cities/ tests/ +black --check cities/ tests/ +flake8 cities/ tests/ --ignore=E203,W503 --max-line-length=127 -nbqa autoflake --nbqa-shell -v --recursive --check docs/guides/ -#nbqa isort --check docs/guides/ +nbqa --nbqa-shell autoflake -v --recursive --check docs/guides/ +nbqa --nbqa-shell isort --profile="black" --check docs/guides/ +black --check docs/guides/ diff --git a/tests/test_data_grabber_sql.py b/tests/test_data_grabber_sql.py index d1c9d708..6b2d2097 100644 --- a/tests/test_data_grabber_sql.py +++ b/tests/test_data_grabber_sql.py @@ -13,6 +13,14 @@ list_csvs, ) +smoke_test = "CI" in os.environ + +if smoke_test: + pytest.skip( + "Skipping all tests in this file during smoke tests", allow_module_level=True + ) + + root = find_repo_root() data_dirs = { diff --git a/tests/test_sorted_interventions.py b/tests/test_sorted_interventions.py index 40c85355..1914d801 100644 --- a/tests/test_sorted_interventions.py +++ b/tests/test_sorted_interventions.py @@ -2,10 +2,18 @@ import dill import numpy as np +import pytest from cities.utils.data_grabber import DataGrabber, find_repo_root, list_interventions from cities.utils.percentiles import transformed_intervention_from_percentile +smoke_test = "CI" in os.environ + +if smoke_test: + pytest.skip( + "Skipping all tests in this file during smoke tests", allow_module_level=True + ) + def test_sorted_interventions_present(): root = find_repo_root()