% ============================================================================ \section{Data} \label{sec:data} % ============================================================================ \subsection{Data Sources} \label{subsec:data_sources} We assemble a cross-section of residential listings from two complementary Quebec platforms, both retrieved on 3~July~2026 with web-scraping actors. The first, \textbf{Realtor.ca}, is the national Multiple Listing Service (MLS) portal and provides broker-listed inventory (27{,}302 raw records). The second, \textbf{DuProprio}, is the dominant for-sale-by-owner (FSBO) platform in Quebec (7{,}693 raw records). Pooling the two sources broadens coverage across price segments and sale channels---brokered and FSBO listings differ systematically in seller composition and marketing \citep{hendel2009mls}---and a source indicator absorbs any systematic level difference between them. The price we observe is the \emph{asking} price; Section~\ref{subsec:limits} discusses the interpretation of hedonic coefficients estimated on list rather than transaction prices \citep{horowitz1992list,knight2002listing,han2016asking}. Each record is a structured JSON object containing a price, an address with a postal code, a property-attribute block, a free-text description, a list of features, and an array of image URLs. The two sources differ in their auxiliary fields: Realtor.ca records include room-by-room dimensions but no geographic coordinates, whereas DuProprio records include coordinates and captioned images but no room block. We construct a unique key by concatenating the source and the listing identifier. Because the data form a single-date cross-section, no time dimension is modelled and no forward-in-time holdout is possible. \subsection{Sample Construction} \label{subsec:sample} We restrict attention to \emph{houses}, defined as single-family dwellings and townhouses. On Realtor.ca this corresponds to building types \textit{House} and \textit{Row/Townhouse}; on DuProprio it corresponds to the property types \textit{Home}, \textit{Bungalow}, \textit{Semi Detached}, \textit{Intergenerational}, \textit{Country Home}, \textit{Cottage}, \textit{Villa}, and \textit{Townhouse}. Condominiums, income properties (duplex through quintuplex), vacant land, farms, commercial properties, and mobile homes are excluded. After requiring a non-missing, positive price, the pooled sample contains 19{,}273 houses. \subsection{Outlier Cleaning} \label{subsec:cleaning} Scraped prices contain parsing artifacts spanning several orders of magnitude (the raw minimum and maximum are \$899 and \$368~billion). We apply conservative, transparent bounds rather than model-based trimming: prices are retained in the \$50{,}000--\$15{,}000{,}000 range; living area in 300--20{,}000~ft$^2$; lot area in 200--5{,}000{,}000~ft$^2$; bedrooms in 0--15 and bathrooms in 0--12. When a single attribute violates its bound it is set to missing (and later imputed) rather than deleting the observation, preserving sample size. Finally, we trim the price-per-square-foot distribution at its 0.5th and 99.5th percentiles (approximately \$73--\$1{,}276/ft$^2$) among listings with a measured area, removing residual price- or area-parsing errors. The cleaned sample contains \textbf{19{,}123 houses}, of which 80.3\% originate from Realtor.ca (Table~\ref{tab:app_flow} in the Appendix summarizes the flow). \subsection{Content and Language of the Descriptions} \label{subsec:text_content} Because the language model reads the description verbatim, what the description contains matters for the interpretation of the text layer. The two platforms differ sharply. A Realtor.ca description is a free-text paragraph written by the listing broker (mean length about 540 characters); only 2.5\% of these descriptions contain any dollar amount, and fewer than 0.3\% mention the municipal assessment. A DuProprio ``description,'' as delivered by the crawler, concatenates the owner's comments with the platform's structured property sheet rendered as text: room counts, living and lot area, year of construction, exterior cladding, heating, inclusions, and---in every one of the 3{,}767 DuProprio listings in the cleaned sample---the asking price itself (``Asking Price \$499,999''), which equals the recorded list price in 3{,}761 cases; 46.6\% of DuProprio descriptions also mention the municipal assessment. The language model was therefore shown the dependent variable for 19.7\% of the sample. The extraction schema has no price field, and the prompt instructs the model to report only what the text states about the property, so leakage can operate only indirectly (a model that sees a high price may, for instance, lean towards ``like-new'' when the condition is ambiguous). We treat this as a first-order threat to the text layer and address it in Sections~\ref{subsec:robust_leakage} and~\ref{subsec:limits}: all text-layer gains are reported separately for Realtor.ca, where the text contains no price, and for DuProprio. The vision model receives only the image URL and never sees any text or price. Quebec is a bilingual listing market. Classifying each description from counts of French and English stop words (a ratio rule of 1.5, as in \citealp{boucher2026decoding}), 44.6\% of descriptions are French, 43.1\% English, and 12.3\% ``mixed''---mostly DuProprio descriptions that juxtapose an automated English translation and the French original. Within Realtor.ca, 57.0\% of descriptions are French and 41.9\% English, and the two groups are priced very differently: the median asking price of English-language Realtor.ca listings is \$749{,}000 against \$524{,}900 for French ones, a raw gap of 0.37 log points that falls to 0.21 within municipalities. English descriptions concentrate in the Montreal West Island and other affluent anglophone municipalities, so language proxies for location and for the clientele targeted by the broker. Because the LLM processes both languages with the same schema, language could also affect the extraction itself. We therefore add language indicators to the hedonic specification and re-estimate the gains from both AI layers within each language group (Section~\ref{subsec:robust_language}). \subsection{Summary Statistics} \label{subsec:summary_stats} Table~\ref{tab:summary_stats} reports descriptive statistics for the key variables. The median list price is \$599{,}900. The distribution of living area is right-skewed, motivating the logarithmic transformation adopted in Section~\ref{sec:methodology}. Living area is reported for only a minority of Realtor.ca listings; where it is missing we reconstruct it from room-level dimensions (Section~\ref{subsec:structural}), and where neither is available we rely on the area-free specification. The room count is available only for Realtor.ca listings (the DuProprio room block is absent and coded as zero rooms, with the source indicator absorbing the level). \input{tables/summary_stats} Table~\ref{tab:ai_summary} previews the machine-generated attributes described in Section~\ref{sec:methodology}: roughly a quarter of listings are described as recently renovated, the mean visual condition and curb-appeal scores are 7.4 and 7.2 on a 10-point scale, and 43\% of façades display a visual luxury cue. The text layer covers all 19{,}123 listings and the vision layer all 19{,}123 photographs, of which 95.8\% were recognized by the model as exterior shots. \input{tables/ai_summary}