Shyanil's picture
Update app.py
1e21296 verified
from fastapi import FastAPI, HTTPException
import numpy as np
import pandas as pd
import xgboost as xgb
import joblib
from sklearn.preprocessing import OneHotEncoder, StandardScaler
from pydantic import BaseModel
from fastapi.middleware.cors import CORSMiddleware
from enum import Enum
import logging
import uvicorn
from fastapi.responses import JSONResponse
# Set up logging
logging.basicConfig(level=logging.DEBUG)
logger = logging.getLogger(__name__)
# Initialize FastAPI app
app = FastAPI()
# Enable CORS
app.add_middleware(
CORSMiddleware,
allow_origins=["*"],
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
# Define model types enum
class ModelType(str, Enum):
XGBOOST = "xgboost"
DECISION_TREE = "decision_tree"
RANDOM_FOREST = "random_forest"
LINEAR_REGRESSION = "linear"
POLYNOMIAL_REGRESSION = "polynomial"
# Define input model
class InsuranceInput(BaseModel):
age: int
sex: str
bmi: float
children: int
smoker: str
region: str
model_type: ModelType
# Load models
def load_models():
models = {}
try:
# Load XGBoost model
xgb_model = xgb.Booster()
xgb_model.load_model("best_xgboost_model.json")
models['xgboost'] = xgb_model
# Load other models
models['decision_tree'] = joblib.load("DecisionTree_model.pkl")
models['random_forest'] = joblib.load("RandomForest_model.pkl")
models['linear'] = joblib.load("LinearRegression_model.pkl")
# Load Polynomial Regression model and preprocessors
poly_model = joblib.load("insurance_Model.pkl")
models['polynomial'] = {
'model': poly_model,
'poly_transformer': joblib.load("Final_Poly_Transformer.pkl"),
'scaler': joblib.load("Final_Scaler.pkl")
}
logger.info("Models loaded successfully!")
return models
except Exception as e:
logger.error(f"Error loading models: {e}")
return None
# Initialize preprocessors
def initialize_preprocessors():
categorical_features = ['sex', 'smoker', 'region']
df = pd.DataFrame([
{'sex': 'male', 'smoker': 'yes', 'region': 'northeast'},
{'sex': 'female', 'smoker': 'no', 'region': 'southwest'},
{'sex': 'male', 'smoker': 'no', 'region': 'southeast'},
{'sex': 'female', 'smoker': 'yes', 'region': 'northwest'}
])
# ✅ Fixed `sparse_output=False` for latest scikit-learn
encoder = OneHotEncoder(drop='first', sparse_output=False)
encoder.fit(df[categorical_features])
return encoder, categorical_features
# Global variables
MODELS = load_models()
encoder, categorical_features = initialize_preprocessors()
# Prediction function
def make_prediction(model, X_user, model_type):
try:
if model_type == ModelType.POLYNOMIAL_REGRESSION:
poly_transformer = model['poly_transformer']
poly_scaler = model['scaler']
model = model['model']
X_user_poly = poly_transformer.transform(X_user)
X_user_scaled = poly_scaler.transform(X_user_poly)
return model.predict(X_user_scaled)
elif model_type == ModelType.LINEAR_REGRESSION:
# ✅ Fit scaler dynamically on `X_user`
scaler_lr = StandardScaler()
scaler_lr.fit(X_user)
X_user_scaled = scaler_lr.transform(X_user)
return model.predict(X_user_scaled)
elif model_type == ModelType.XGBOOST:
dtest = xgb.DMatrix(X_user)
return model.predict(dtest)
else:
return model.predict(X_user)
except Exception as e:
logger.error(f"Error during prediction: {e}")
raise
# Preprocessing function
def preprocess_input(user_df):
try:
encoded_columns = encoder.transform(user_df[categorical_features])
encoded_df = pd.DataFrame(
encoded_columns,
columns=encoder.get_feature_names_out(categorical_features)
)
X_user = np.concatenate([
user_df.drop(categorical_features, axis=1).values,
encoded_df.values
], axis=1)
return X_user
except Exception as e:
logger.error(f"Error during preprocessing: {e}")
raise
# Root endpoint
@app.get("/")
async def root():
return {"message": "Welcome to Insurance Premium Prediction API"}
# Prediction endpoint
@app.post("/predict")
async def predict_insurance(input_data: InsuranceInput):
try:
if not MODELS:
raise HTTPException(status_code=500, detail="Models not loaded properly")
user_input = {
'age': input_data.age,
'sex': input_data.sex.lower(),
'bmi': input_data.bmi,
'children': input_data.children,
'smoker': input_data.smoker.lower(),
'region': input_data.region.lower()
}
user_df = pd.DataFrame([user_input])
X_user = preprocess_input(user_df)
model = MODELS.get(input_data.model_type)
if not model:
raise HTTPException(status_code=400, detail=f"Invalid model type: {input_data.model_type}")
log_predicted_charge = make_prediction(model, X_user, input_data.model_type)
predicted_charge = np.expm1(log_predicted_charge)
response_data = {
"model_type": input_data.model_type,
"prediction": round(float(predicted_charge[0]), 2)
}
# Set CORS headers in response
response = JSONResponse(content=response_data)
response.headers["Access-Control-Allow-Origin"] = "*"
return response
except HTTPException as he:
raise he
except Exception as e:
logger.error(f"Unexpected error: {e}")
raise HTTPException(status_code=500, detail=str(e))
# Health check endpoint
@app.get("/health")
async def health_check():
return {"status": "healthy", "models_loaded": list(MODELS.keys()) if MODELS else []}
# Run the FastAPI app with Uvicorn
if __name__ == "__main__":
uvicorn.run(app, host="0.0.0.0", port=7860)