SPB Git forge

spb/wp14_uqo

Public
2commits 1branches 1releases
909.0 KBsize
maindefault branch
59 min agolast push
Python 57% TeX 42.9%
3.9 KB · 86 lines python
Raw Blame History
1#!/usr/bin/env python32# -*- coding: utf-8 -*-3"""Régénère paper/tables/regression.tex à partir de revision_extras.json4   avec SE clusterisées par municipalité (et stars associées)."""5import json67R = json.load(open("results/revision_extras.json"))89def star(p):10    return "^{***}" if p < .01 else "^{**}" if p < .05 else "^{*}" if p < .1 else ""1112def cell(model, k):13    c = R[model]["coef"].get(k)14    if not c:15        return "", ""16    b, se, p = c["b"], c["se_cl"], c["p_cl"]17    s = "$-$" if b < 0 else ""18    st = star(p)19    coef = f"{s}{abs(b):.3f}" + (f"${st}$" if st else "")20    return coef, f"({se:.3f})"2122disp = [("ln_sqft", r"$\ln(\text{Living area})$"), ("ln_lot", r"$\ln(\text{Lot area})$"),23        ("beds", "Bedrooms"), ("baths", "Bathrooms"), ("parking", "Parking"), ("age", "Age"),24        ("__A__", r"\textit{Amenities \& text (LLM)}"),25        ("central_air", "Central A/C"), ("transit", "Public transit"), ("waterfront", "Waterfront"),26        ("g_cond", "Condition (LLM, ord.)"), ("g_renovated_kitchen", r"Reno.\ kitchen (LLM)"),27        ("g_hardwood", "Hardwood floor (LLM)"), ("g_new_construction", "New construction (LLM)"),28        ("g_income_property", "Income property (LLM)"),29        ("__V__", r"\textit{Vision (façade)}"),30        ("v_curb", "Curb appeal (1--10)"), ("v_reno", "Renovation level (ord.)"),31        ("v_luxury", "Luxury (visual)"), ("v_garage_vis", "Garage visible"),32        ("v_mat_brique", "Brick façade"), ("v_mat_pierre", "Stone façade"),33        ("v_mat_vinyle", "Vinyl façade"), ("v_set_rural", "Rural setting")]3435L = []36for k, lab in disp:37    if k in ("__A__", "__V__"):38        L.append(f"      \\multicolumn{{3}}{{@{{}}l}}{{{lab}}} \\\\[2pt]")39        continue40    a1, a2 = cell("modelA", k)41    b1, b2 = cell("modelB", k)42    L.append(f"      {lab} & {a1} & {b1} \\\\")43    L.append(f"       & {a2} & {b2} \\\\[3pt]")4445nA, nB = R["modelA"]["n"], R["modelB"]["n"]46tex = r"""% Auto-generated (revision: clustered SEs)47\begin{table}[htbp]48  \centering49  \begin{threeparttable}50    \caption{Hedonic Regression Results (Text + Vision Features)}51    \label{tab:regression}52    \begin{tabular}{@{}lcc@{}}53      \toprule54      & (1) Model~A & (2) Model~B \\55      & \textit{rich} & \textit{broad} \\56      \midrule57""" + "\n".join(L) + f"""58      \\midrule59      City FE / Type FE  & Yes & Yes \\\\60      Living area        & Yes & No  \\\\61      Observations       & {nA:,} & {nB:,} \\\\62      $R^2$              & {R['modelA']['r2']:.3f} & {R['modelB']['r2']:.3f} \\\\63      Adjusted $R^2$     & {R['modelA']['adj']:.3f} & {R['modelB']['adj']:.3f} \\\\64      \\bottomrule65    \\end{{tabular}}66""".replace(f"{nA:,}", f"{nA:,}".replace(",", "{,}")).replace(f"{nB:,}", f"{nB:,}".replace(",", "{,}")) + r"""    \begin{tablenotes}[flushleft]67      \footnotesize68      \item \textit{Notes:} OLS estimates of Equation~\eqref{eq:hedonic} with the full69      feature set. Model~A includes $\ln(\text{Living area})$ (measured-area subsample);70      Model~B omits it (full sample). ``LLM'' variables are extracted from the71      description text; ``Vision'' variables from the façade photograph. Curb appeal and72      renovation level enter as scores; luxury, garage, and material/setting are73      indicators. All specifications include city and property-type fixed effects and the74      full amenity, room-detail, and listing-signal controls (only selected coefficients75      shown). Standard errors clustered by municipality (195 clusters) in parentheses.76      Heteroskedasticity-robust (HC3) standard errors are uniformly smaller and yield77      the same significance pattern for the text- and vision-derived attributes, except78      that curb appeal in Model~B is significant under HC3 but not under clustering.79      $^{***}$, $^{**}$, $^{*}$: significance at 1\%, 5\%, 10\%.80    \end{tablenotes}81  \end{threeparttable}82\end{table}83"""84open("paper/tables/regression.tex", "w").write(tex)85print("-> paper/tables/regression.tex (clustered SEs)")86