apartment-predictor / documentation.md
vasanthi8134's picture
Update documentation.md
96e121c verified
|
Raw
History Blame Contribute Delete
8.8 kB

A newer version of the Gradio SDK is available: 6.20.0

Upgrade

Documentation

Week 2: Apartment Predictor (Saved Regression Model + LLM Workflow)

This file documents the apartment rent prediction app that I built, tested, and deployed on Hugging Face Spaces.


1. Project Summary

The app accepts a German natural language apartment request. The user writes a sentence that includes the number of rooms, the apartment size and the town.

The LLM extracts the structured values rooms, area_m2 and town from the user text. A saved Random Forest regression model then predicts the estimated monthly rent in CHF. Finally, the LLM generates a short German explanation of the prediction and mentions that the result is only an estimate.


2. Files Used

File Purpose
app.py Final deployable app used by Hugging Face Spaces
app_student.py Student implementation with the completed TODOs
random_forest_regression.pkl Saved Random Forest regression model
bfs_municipality_and_tax_data.csv Municipality data used for prediction
requirements.txt Python dependencies for Hugging Face Spaces
README.md Hugging Face Space configuration and short app description
documentation.md Written documentation for the submission
screenshot1.png Screenshot of the first working app test
screenshot2.png Screenshot of the second working app test

3. Numeric Prediction Part

3.1 Reused Model

I used the saved model file:

random_forest_regression.pkl

The model predicts the estimated monthly apartment rent in CHF.

The model uses apartment information and municipality information for the prediction.

3.2 Input Features

The model uses these features:

  1. rooms
  2. area
  3. pop
  4. pop_dens
  5. frg_pct
  6. emp
  7. tax_income

In the user interface and in the LLM extraction step, the apartment size is called area_m2.
For the model input, I map area_m2 to the trained model feature area, because the saved model expects the feature name area.

3.3 Prediction Logic

First, the LLM extracts the number of rooms, the apartment area and the town from the German user text.

Then the app matches the extracted town to the municipality data in bfs_municipality_and_tax_data.csv.

After that, the app combines the apartment values with the municipality values and passes them to the saved Random Forest model.

The model returns a monthly rent prediction in CHF.


4. LLM Extraction Part

4.1 Goal

The goal of the first LLM step is to transform a free German apartment request into structured JSON.

The LLM extracts:

  • rooms
  • area_m2
  • town

4.2 Prompt Design

The system prompt tells the LLM to extract apartment preferences from German text.

It requires strict JSON output only, without Markdown or additional explanation.

The required JSON keys are:

  • rooms
  • area_m2
  • town

The prompt also tells the model to use null if a value is missing.

4.3 Expected Output Format

Example:

{
  "rooms": 3.5,
  "area_m2": 85,
  "town": "Winterthur"
}

4.4 Validation

The app validates the LLM response before using it.

It checks whether the response is valid JSON and whether all required keys are present.

It also checks that rooms, area and town are not missing.

The town is matched against the BFS municipality data before the prediction is made.


5. LLM Explanation Part

5.1 Goal

The second LLM step generates a short German explanation of the model prediction.

The LLM does not calculate the rent itself.

It only explains the numeric prediction returned by the Random Forest model.

5.2 Prompt Design

The explanation prompt includes the extracted apartment preferences and the predicted monthly rent.

The LLM is instructed to answer in German, mention the predicted rent in CHF and include one short uncertainty note.

The response is also required to be valid JSON with the key answer.

5.3 Expected Output Format

Example:

{
  "answer": "Die Wohnung mit 3.5 Zimmern und 85 m² in Winterthur hat eine geschätzte Monatsmiete von etwa 2117 CHF. Diese Schätzung basiert auf einem numerischen Modell und kommunalen Daten. Bitte beachten Sie, dass es leichte Abweichungen geben kann."
}

6. End-to-End Pipeline

The full pipeline works like this:

  1. The user enters a German apartment request.
  2. The LLM extracts rooms, area_m2 and town.
  3. Python validates the extracted JSON.
  4. The app matches the town to the municipality data.
  5. The app builds the model input features.
  6. The Random Forest model predicts the estimated monthly rent.
  7. The LLM generates a short German explanation.
  8. The app returns the extracted JSON, the predicted rent and the final explanation.

7. Test Cases

Test Input Extracted Output Correct? Prediction Returned? Explanation Returned? Notes
Ich suche eine 3.5-Zimmer-Wohnung mit etwa 85 m2 in Winterthur. Yes Yes Yes Extracted 3.5 rooms, 85 m² and Winterthur. Prediction and explanation were returned successfully.
Ich möchte eine 2-Zimmer-Wohnung mit ungefähr 60 m2 in Zürich mieten. Yes Yes Yes Extracted 2 rooms, 60 m² and Zürich. Prediction and explanation were returned successfully.
Ich suche eine 4.5-Zimmer-Wohnung mit 110 m2 in Bern. Yes Yes Yes This was used as an additional German test prompt to check another Swiss city.

8. Errors and Problems

Problem 1: Missing API key

At first, the app returned an error saying that the API key was missing.

The reason was that the OpenAI API key was not set as an environment variable.

I fixed this by adding the API key as a Hugging Face secret named OPENAI_API_KEY.

Problem 2: Wrong or invalid API key

On Hugging Face, the app returned an error saying that the API key was incorrect.

The reason was that the API key was copied incorrectly or an invalid key was used.

I fixed this by replacing the secret with a valid key and restarting the Space.

Problem 3: Model feature name mismatch

The model returned an error because it expected the feature name area, but the app originally passed area_m2.

The saved model was trained with the feature name area.

I fixed this by mapping the extracted value area_m2 to the model feature area.

Problem 4: Model version warning

A warning appeared because the Random Forest model was saved with a different scikit-learn version.

This warning did not stop the app. The model still loaded and returned predictions.


9. Deployment Notes

9.1 Files included

The following files were uploaded to Hugging Face Spaces:

  • app.py
  • app_student.py
  • requirements.txt
  • README.md
  • documentation.md
  • bfs_municipality_and_tax_data.csv
  • random_forest_regression.pkl
  • screenshot1.png
  • screenshot2.png

9.2 Secrets / Environment Variables

The app requires these Hugging Face secrets:

  • OPENAI_API_KEY
  • OPENAI_MODEL

The model name used was:

gpt-4.1-mini

9.3 Deployment Result

The Hugging Face Space ran successfully.

The app accepted German apartment requests, extracted structured JSON, returned a rent prediction and generated a German explanation.


10. Screenshots

Example 1

Example 1

In this example, the app extracted 3.5 rooms, 85 m² and Winterthur from the German input. It returned a monthly rent prediction and a short German explanation.

Example 2

Example 2

In this example, the app extracted 2 rooms, 60 m² and Zürich from the German input. It returned a monthly rent prediction and explained that the result is an estimate.


11. Reflection

The combination of a regression model and an LLM worked well because both parts have a clear role.

The LLM is useful for understanding natural language and extracting structured values.

The regression model is useful for making the numeric prediction.

The system is still fragile because the LLM could extract values incorrectly or the town might not match the municipality data.

I would improve the app by adding better town suggestions and more apartment features.


12. Responsible Use Note

The prediction is only an estimate and should not be used as a guaranteed rental price.

Real rental prices depend on many additional factors, such as location quality, building condition, floor, balcony, renovation status and market situation.

The LLM may also extract values incorrectly, so the extracted JSON should always be checked.

The app is useful as a learning prototype, but not as a final real estate pricing tool.