SPB Git

spb/wp2_uqo Public

UQO Working Paper No. 2 — Decoding Real Estate Descriptions: text-based hedonic analysis of housing listings.

TeX 73.8% Python 26%
1.9 KB · 56 lines python
Raw Blame History
1#!/usr/bin/env python32# Author: Simon-Pierre Boucher — contact@spboucher.ai3#4"""Step 2 — Embed descriptions and compute the 20 cosine-similarity features.56Inputs : data/processed/houses.parquet7Outputs: data/processed/embeddings_maisons.npy   (17,087 x 384, cached)8         data/processed/sim_matrix_maisons.npy    (17,087 x 20)9         data/processed/hedonic_maison_results.csv (analysis dataset)1011Pass --force to re-encode the embeddings even if a valid cache exists.12"""1314import sys15from pathlib import Path1617import numpy as np18import pandas as pd1920sys.path.insert(0, str(Path(__file__).resolve().parents[1]))2122from src import config23from src.embeddings import (add_similarity_columns, encode_references,24                            load_or_encode_remarks, similarity_features)25from src.references import SIM_COLS262728def main(force=False):29    df = pd.read_parquet(config.HOUSES_PARQUET)30    print(f"{len(df):,} houses loaded")3132    print("Encoding 20 reference descriptions ...")33    _, ref_embeddings = encode_references()3435    print("Encoding listing descriptions (cache: data/processed) ...")36    prop_embeddings, from_cache = load_or_encode_remarks(37        df["remarks"], force=force38    )39    print(f"  embeddings {prop_embeddings.shape} "40          f"({'loaded from cache' if from_cache else 'freshly encoded'})")4142    sim_matrix = similarity_features(prop_embeddings, ref_embeddings)43    np.save(config.SIM_MATRIX_NPY, sim_matrix)44    add_similarity_columns(df, sim_matrix)4546    export_cols = ["id", "price", "log_price", "bedrooms", "bathrooms",47                   "half_baths", "parking", "stories", "land_size",48                   "remarks_length"] + SIM_COLS49    df[export_cols].to_csv(config.ANALYSIS_CSV, index=False)50    print(f"  -> {config.SIM_MATRIX_NPY}")51    print(f"  -> {config.ANALYSIS_CSV}")525354if __name__ == "__main__":55    main(force="--force" in sys.argv)56