SPB Git forge

spb/wp14_uqo

Public
2commits 1branches 1releases
909.0 KBsize
maindefault branch
1 h agolast push
Python 57% TeX 42.9%
6.6 KB · 125 lines python
Raw Blame History
1#!/usr/bin/env python32# -*- coding: utf-8 -*-3"""Régénère les tableaux LaTeX du papier en v5 (texte GPT + vision)."""4import numpy as np, pandas as pd, statsmodels.formula.api as smf, warnings5warnings.filterwarnings("ignore")6# construire df via le pipeline de v5_ml (jusqu'avant la CV)7exec(open("v5_ml.py").read().split("kf=KFold")[0])8amen_=list(AMEN.keys())9df["ln_price"]=np.log(df["price"])10df["ln_sqft"]=np.log(df["sqft_final"].fillna(df.groupby("ptype")["sqft_final"].transform("median")).fillna(df["sqft_final"].median()))11df["ln_lot"]=np.log(df["lot_sqft"].fillna(df["lot_sqft"].median()));df["has_lot"]=df["lot_sqft"].notna().astype(int)12df["has_age"]=df["age"].notna().astype(int)13for c in ["beds","baths","storeys","age","age2"]:14    df[c]=df[c].fillna(df.groupby("ptype")[c].transform("median")).fillna(df[c].median())15df["parking"]=df["parking"].fillna(0)16form=("ln_price ~ ln_sqft+ln_lot+has_lot+beds+baths+parking+storeys+age+age2+has_age+C(source)+C(ptype_fe)+"17      +"+".join(amen_)+"+n_images_c+virtual_tour+"+"+".join(rv)+"+"+"+".join(gv)+"+"+"+".join(vv)+"+C(city_fe)")18mA=smf.ols(form,data=df[df["has_sqft"]==1]).fit(cov_type="HC3")19mB=smf.ols(form.replace("ln_sqft+",""),data=df).fit(cov_type="HC3")20print("A R2=%.4f adj=%.4f N=%d | B R2=%.4f adj=%.4f N=%d"%(mA.rsquared,mA.rsquared_adj,mA.nobs,mB.rsquared,mB.rsquared_adj,mB.nobs))2122def star(p): return "^{***}" if p<.01 else "^{**}" if p<.05 else "^{*}" if p<.1 else ""23def cell(m,k):24    if k not in m.params.index: return "",""25    b=m.params[k];se=m.bse[k];p=m.pvalues[k];s="$-$" if b<0 else ""26    return f"{s}{abs(b):.3f}${star(p)}$",f"({se:.3f})"27disp=[("ln_sqft",r"$\ln(\text{Living area})$"),("ln_lot",r"$\ln(\text{Lot area})$"),28("beds","Bedrooms"),("baths","Bathrooms"),("parking","Parking"),("age","Age"),29("__A__","\\textit{Amenities \\& text (LLM)}"),30("central_air","Central A/C"),("transit","Public transit"),("waterfront","Waterfront"),31("g_cond","Condition (LLM, ord.)"),("g_renovated_kitchen","Reno.\\ kitchen (LLM)"),32("g_hardwood","Hardwood floor (LLM)"),("g_new_construction","New construction (LLM)"),33("g_income_property","Income property (LLM)"),34("__V__","\\textit{Vision (façade)}"),35("v_curb","Curb appeal (1--10)"),("v_reno","Renovation level (ord.)"),36("v_luxury","Luxury (visual)"),("v_garage_vis","Garage visible"),37("v_mat_brique","Brick façade"),("v_mat_pierre","Stone façade"),38("v_mat_vinyle","Vinyl façade"),("v_set_rural","Rural setting")]39L=[]40for k,lab in disp:41    if k in ("__A__","__V__"):42        L.append(f"      \\multicolumn{{3}}{{@{{}}l}}{{{lab}}} \\\\[2pt]");continue43    a1,a2=cell(mA,k);b1,b2=cell(mB,k)44    L.append(f"      {lab} & {a1} & {b1} \\\\")45    L.append(f"       & {a2} & {b2} \\\\[3pt]")46reg=r"""% Auto-generated v547\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)+r"""58      \midrule59      City FE / Type FE  & Yes & Yes \\60      Living area        & Yes & No  \\61      Observations       & """+f"{int(mA.nobs):,}".replace(",","{,}")+r""" & """+f"{int(mB.nobs):,}".replace(",","{,}")+r""" \\62      $R^2$              & """+f"{mA.rsquared:.3f}"+r""" & """+f"{mB.rsquared:.3f}"+r""" \\63      Adjusted $R^2$     & """+f"{mA.rsquared_adj:.3f}"+r""" & """+f"{mB.rsquared_adj:.3f}"+r""" \\64      \bottomrule65    \end{tabular}66    \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). HC3 standard errors in parentheses. $^{***}$, $^{**}$, $^{*}$: significance76      at 1\%, 5\%, 10\%.77    \end{tablenotes}78  \end{threeparttable}79\end{table}80"""81open("paper/tables/regression.tex","w").write(reg)82print("-> paper/tables/regression.tex (v5)")8384# ---- models.tex : deux panels (texte / +vision) avec chiffres CV ----85models=r"""% Auto-generated v586\begin{table}[htbp]87  \centering88  \begin{threeparttable}89    \caption{Predictive Performance: From OLS to Deep Learning}90    \label{tab:models}91    \begin{tabular}{@{}lcccc@{}}92      \toprule93      Estimator & $R^2_{\text{OOS}}$ & Median AE & Within $\pm$15\% & Within $\pm$25\% \\94      \midrule95      \multicolumn{5}{@{}l}{\textit{Panel A: Structural + amenity + LLM-text features}} \\[3pt]96      OLS (linear hedonic)              & 0.628 & 17.9\% & 43\% & 64\% \\97      Random Forest                     & 0.678 & 18.0\% & 43\% & 64\% \\98      Neural network (plain MLP)        & 0.711 & 16.1\% & 47\% & 69\% \\99      Neural network (robust ResNet)    & 0.741 & 15.2\% & 49\% & 70\% \\100      Gradient boosting (HistGBM)       & 0.743 & 15.4\% & 49\% & 70\% \\101      Blend (NN + GBM)                  & 0.760 & 14.7\% & 51\% & 72\% \\[4pt]102      \multicolumn{5}{@{}l}{\textit{Panel B: \ + Vision (façade) features}} \\[3pt]103      Gradient boosting (HistGBM)       & 0.770 & 14.5\% & 51\% & 71\% \\104      Neural network (robust ResNet)    & 0.747 & 14.8\% & 51\% & 71\% \\105      \textbf{Blend (NN + GBM)}         & \textbf{0.779} & \textbf{14.0\%} & \textbf{53\%} & \textbf{73\%} \\106      \bottomrule107    \end{tabular}108    \begin{tablenotes}[flushleft]109      \footnotesize110      \item \textit{Notes:} Out-of-sample performance from 5-fold cross-validation with a111      common seed (identical folds across rows). $R^2_{\text{OOS}}$ is on112      $\ln(\text{Price})$; ``Median AE'' is the median absolute percentage error in113      levels (Equation~\ref{eq:cvmetrics}). Panel~A uses structural, amenity, room-detail,114      listing-signal, and LLM text-derived features; Panel~B adds the twelve façade115      vision attributes. City, type, and source enter as one-hot indicators for the116      linear and tree models and as learned embeddings for the neural networks. The tree117      and neural models handle missing living area natively. The best model is the118      text\,+\,vision blend.119    \end{tablenotes}120  \end{threeparttable}121\end{table}122"""123open("paper/tables/models.tex","w").write(models)124print("-> paper/tables/models.tex (v5, 2 panels)")125