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# Author: Simon-Pierre Boucher — contact@spboucher.ai2#3"""Sentence embeddings and cosine-similarity features."""45import numpy as np67from . import config8from .references import REFERENCES, SIM_COLS91011def encode_references(model=None):12 """Encode the 20 reference descriptions. Returns (names, embeddings)."""13 if model is None:14 from sentence_transformers import SentenceTransformer15 model = SentenceTransformer(config.EMBEDDING_MODEL)16 names = list(REFERENCES.keys())17 embeddings = model.encode(list(REFERENCES.values()), normalize_embeddings=True)18 return names, embeddings192021def encode_remarks(texts, model=None, show_progress=True):22 """Encode listing descriptions with the paper's embedding model."""23 if model is None:24 from sentence_transformers import SentenceTransformer25 model = SentenceTransformer(config.EMBEDDING_MODEL)26 return model.encode(27 list(texts),28 batch_size=config.ENCODE_BATCH_SIZE,29 show_progress_bar=show_progress,30 normalize_embeddings=True,31 )323334def load_or_encode_remarks(texts, cache_path=config.EMBEDDINGS_NPY, force=False):35 """Load cached embeddings if they match the sample size, else encode.3637 Embeddings are deterministic for a given model version, so the cache is a38 pure speed-up; pass force=True to re-encode from scratch.39 """40 if not force and cache_path.exists():41 cached = np.load(cache_path)42 if len(cached) == len(texts):43 return cached, True44 embeddings = encode_remarks(texts)45 cache_path.parent.mkdir(parents=True, exist_ok=True)46 np.save(cache_path, embeddings)47 return embeddings, False484950def similarity_features(prop_embeddings, ref_embeddings):51 """Cosine similarities (dot product of normalized vectors): n x 20 matrix."""52 return prop_embeddings @ ref_embeddings.T535455def add_similarity_columns(df, sim_matrix):56 """Attach the 20 ``sim_<slug>`` columns to the DataFrame (in place)."""57 for i, col in enumerate(SIM_COLS):58 df[col] = sim_matrix[:, i]59 return df60