File size: 5,499 Bytes
6a0ab2e
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
"""
House Price Predictor - HuggingFace Space
Standalone Gradio application for Seattle/King County house price prediction
"""
import gradio as gr
import pandas as pd
import plotly.express as px
import joblib
from pathlib import Path

# Paths (files in same directory as app.py)
MODEL_PATH = Path("house_price_model.joblib")
DATA_PATH = Path("kc_house_data.csv")

class HousePricePredictor:
    def __init__(self):
        self.model = joblib.load(MODEL_PATH)

    def predict(self, bedrooms, bathrooms, sqft, age):
        X = pd.DataFrame([[bedrooms, bathrooms, sqft, age]],
                        columns=['bedrooms', 'bathrooms', 'sqft', 'age'])
        price = self.model.predict(X)[0]
        return f"${price:,.2f}"

predictor = HousePricePredictor()

def create_price_map(min_price, max_price, sample_size):
    """Create interactive map of house prices"""
    df = pd.read_csv(DATA_PATH)

    # Filter by price range
    df_filtered = df[(df['price'] >= min_price) & (df['price'] <= max_price)]

    # Limit sample size for performance
    if len(df_filtered) > sample_size:
        df_filtered = df_filtered.sample(n=sample_size, random_state=42)

    # Create the map
    fig = px.scatter_mapbox(
        df_filtered,
        lat='lat',
        lon='long',
        color='price',
        size='sqft_living',
        hover_data={
            'price': ':$,.0f',
            'bedrooms': True,
            'bathrooms': True,
            'sqft_living': ':,',
            'waterfront': True,
            'lat': ':.4f',
            'long': ':.4f'
        },
        color_continuous_scale='Viridis',
        zoom=9,
        height=500,
        title=f'Seattle/King County House Prices ({len(df_filtered):,} houses shown)'
    )

    fig.update_layout(
        mapbox_style="open-street-map",
        margin={"r":0,"t":40,"l":0,"b":0}
    )

    return fig

def predict_price(bedrooms, bathrooms, sqft, age):
    """Make a price prediction"""
    return predictor.predict(bedrooms, bathrooms, sqft, age)

# Build Gradio Interface
with gr.Blocks() as demo:
    # Custom CSS for Helvetica Neue font
    gr.HTML("""
    <style>
    * {
        font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif !important;
    }
    </style>
    """)

    gr.Markdown(
        """
        # 🏠 House Price Predictor
        ### AI-Powered Real Estate Valuation - Seattle/King County

        Trained on **21,613 real house sales** from King County, Washington (2014-2015).
        """
    )

    # Map Visualization Section
    gr.Markdown("## 🗺️ Explore House Prices on Map")

    with gr.Row():
        min_price_filter = gr.Slider(
            minimum=0,
            maximum=8000000,
            value=0,
            step=100000,
            label="Min Price ($)",
            info="Minimum price"
        )

        max_price_filter = gr.Slider(
            minimum=0,
            maximum=8000000,
            value=2000000,
            step=100000,
            label="Max Price ($)",
            info="Maximum price"
        )

        sample_slider = gr.Slider(
            minimum=100,
            maximum=2000,
            value=1000,
            step=100,
            label="Houses to Display",
            info="More = slower"
        )

        update_map_btn = gr.Button("🔄 Update Map", variant="secondary", size="sm")

    map_plot = gr.Plot(label="Interactive Price Map")

    # Load initial map
    demo.load(
        fn=lambda: create_price_map(0, 2000000, 1000),
        outputs=map_plot
    )

    # Update map on button click
    update_map_btn.click(
        fn=create_price_map,
        inputs=[min_price_filter, max_price_filter, sample_slider],
        outputs=map_plot
    )

    gr.Markdown("---")

    # Price Prediction Section
    gr.Markdown("## 🔮 Predict House Price")

    with gr.Row():
        with gr.Column():
            bedrooms = gr.Slider(1, 10, value=3, step=1, label="Bedrooms")
            bathrooms = gr.Slider(1, 10, value=2, step=1, label="Bathrooms")
            sqft = gr.Slider(500, 10000, value=2000, step=100, label="Square Feet")
            age = gr.Slider(0, 100, value=5, step=1, label="Age (years)")

            predict_btn = gr.Button("🔮 Predict Price", variant="primary", size="lg")

        with gr.Column():
            output = gr.Textbox(
                label="Predicted Price",
                placeholder="Click 'Predict Price' to see the result",
                scale=2
            )

            gr.Markdown(
                """
                ### Example Houses:
                - **Starter Home**: 2br, 1ba, 1200 sqft, 15 years
                - **Family Home**: 4br, 3ba, 2500 sqft, 10 years
                - **Luxury Home**: 5br, 4ba, 4000 sqft, 2 years
                """
            )

    gr.Examples(
        examples=[
            [2, 1, 1200, 15],  # Starter
            [3, 2, 2000, 5],   # Average
            [4, 3, 2500, 10],  # Family
            [5, 4, 4000, 2],   # Luxury
        ],
        inputs=[bedrooms, bathrooms, sqft, age],
        label="Quick Examples"
    )

    predict_btn.click(
        fn=predict_price,
        inputs=[bedrooms, bathrooms, sqft, age],
        outputs=output
    )

    gr.Markdown(
        """
        ---
        **Dataset:** 21,613 King County house sales (2014-2015)
        **Model:** Random Forest (R² Score: 0.53 on test data)
        **Architecture:** Gradio Frontend → ML Model (scikit-learn)
        """
    )

if __name__ == "__main__":
    demo.launch()