from fastapi import FastAPI, HTTPException from pydantic import BaseModel import joblib import pandas as pd import numpy as np app = FastAPI(title="Airbnb Price Prediction in Copenhagen") # Load model and preprocessing objects model_xgb = joblib.load('model_xgb.joblib') scaler = joblib.load('scaler.joblib') ohe = joblib.load('ohe.joblib') class RoomFeatures(BaseModel): neighbourhood_cleansed: str room_type: str instant_bookable: bool accommodates: int bedrooms: int beds: int minimum_nights_avg_ntm: int @app.post("/predict") async def predict_price(features: RoomFeatures): try: # Prepare categorical features cat_features = pd.DataFrame({ 'neighbourhood_cleansed': [features.neighbourhood_cleansed], 'room_type': [features.room_type] }) cat_encoded = pd.DataFrame( ohe.transform(cat_features).todense(), columns=ohe.get_feature_names_out(['neighbourhood_cleansed', 'room_type']) ) # Prepare numerical features num_features = pd.DataFrame({ 'instant_bookable': [int(features.instant_bookable)], 'accommodates': [features.accommodates], 'bedrooms': [features.bedrooms], 'beds': [features.beds], 'minimum_nights_avg_ntm': [features.minimum_nights_avg_ntm] }) num_scaled = pd.DataFrame(scaler.transform(num_features), columns=num_features.columns) # Combine features combined_features = pd.concat([num_scaled, cat_encoded], axis=1) # Make prediction predicted_price = model_xgb.predict(combined_features)[0] # Calculate price range lower_range = max(0, round(predicted_price - 350)) upper_range = round(predicted_price + 350) return { "predicted_price": round(predicted_price), "suggested_price_range": { "lower": lower_range, "upper": upper_range } } except Exception as e: raise HTTPException(status_code=400, detail=str(e)) @app.get("/") async def root(): return {"message": "Welcome to the Airbnb Price Prediction API for Copenhagen"} if __name__ == "__main__": import uvicorn uvicorn.run(app, host="0.0.0.0", port=8000)