from fastapi import FastAPI, Request from fastapi import Depends, FastAPI, HTTPException, status from fastapi.security import HTTPBearer, HTTPAuthorizationCredentials from pydantic import BaseModel app = FastAPI() @app.get("/") def greet_json(): return {"Hello": "World!"} import numpy as np import pandas as pd from utils import compute_features import json import joblib # Define the same file path filename = 'finalized_linear_model.joblib' # Load the model from disk loaded_model = joblib.load(filename) REQUIRED_COLUMN_ORDER = [ 'num_hotel', 'num_attraction', 'num_restaurant', 'num_convenience_store', 'num_pharmacy', 'num_cafe', 'num_bookstore', 'num_school', 'num_co_working', 'num_clinic', 'num_bank', 'num_supermarket', 'num_gym', 'num_fast_food', 'num_shopping_mall', 'num_bakery', 'num_university', 'num_hospital', 'num_dentist', 'num_clothing_store', 'num_department_store', 'num_college', 'num_electronics_store', 'num_hostel', 'num_charging_station', 'num_viewpoint', 'num_jewelry_store' ] # @app.post('/predict') # def predict_score(lat, lon): def atm_score(num_atm, num_prediction_atm, k=7, pct=0.15): # num_atm = np.asarray(num_atm, dtype=float) # num_prediction_atm = np.asarray(num_prediction_atm, dtype=float) # Avoid division by zero eps = 1e-8 # num_atm = num_atm*(1 + pct) num_prediction_atm = num_prediction_atm*(1 + pct) # delta = (num_atm - num_prediction_atm) / (num_prediction_atm + eps) delta = (num_prediction_atm - num_atm) / (num_atm + eps) score = 100.0 / (1.0 + np.exp(-k * (delta))) # score = 100 * np.exp( -k*delta ** 2 /( 300*(0.085)**2)) return score class Location(BaseModel): lat: float lon: float @app.post("/predict") def predict_score(location: Location, request: Request): lat, lon = location.lat, location.lon auth_header = request.headers.get("Authorization") api_key = auth_header.split(" ")[1] if auth_header else None inputs = compute_features((lat,lon), api_key, 500) print("[INPUTS]", inputs) num_banks = inputs.pop("num_banks_in_radius", 0) input_dict = inputs.copy() input_dict_new = {} for col in REQUIRED_COLUMN_ORDER: input_dict_new[col] = input_dict[col] mu_pred = loaded_model.predict([list(input_dict_new.values())])[0] # r = 1/alpha # p = r / (r + mu_pred) # # Compute pmf and mode # k_mode = int((r - 1) * (1 - p) / p) # mode of NB # p_k = nbinom.pmf(num_banks, r, p) # p_mode = nbinom.pmf(k_mode, r, p) # # Score normalized 0–100 # score = (p_k / p_mode) * 100 # score = np.clip(score, 0, 100) # diff = (num_banks - mu_pred) / (mu_pred + 1e-6) # # score = (1 - np.tanh(diff)) # print("[TANH]", np.tanh(diff)) # diff = mu_pred2 - num_banks # score = 100 / (1 + np.exp(-alpha * diff)) # score = np.abs(1 + np.tanh(diff)) / 2 * 100 # score = (1 * np.abs(mu_pred2 + 0.1)) * 100 # score = np.sigmoid(mu_pred2 - num_banks + 0.1) * 100 # score = 100 / (1 + np.exp(num_banks - mu_pred)) score = atm_score(num_banks, mu_pred) input_dict_new.update({ "score":round(float(score), 3), "num_atm":num_banks, "num_prediction_atm":round(float(mu_pred), 3), "lat":lat, "lon":lon }) return input_dict_new # return ( # round(float(score), 3), # num_banks, # round(float(mu_pred), 3), # # round(float(log_score),3) # # "Normal Score": round(float(normal_score), 3), # # input_dict["total_amenities"], # *[v for k,v in input_dict_new.items() if k[:3] == "num"] # ) # # ======== Gradio Interface ======== # interface = gr.Interface( # fn=predict_score, # inputs=[ # gr.Number(label="Latitude"), # gr.Number(label="Longitude"), # gr.Text(label="Google Api Key") # ], # outputs=[ # gr.Number(label="Score (0 - 100)"), # gr.Number(label="Current ATMs"), # gr.Number(label="Ideal ATMs"), # # gr.Number(label="Log Score Probability"), # # gr.Number(label="Total Amenities"), # *[gr.Number(label=x) for x in REQUIRED_COLUMN_ORDER] # ], # title="Bank Location Scoring Model", # description="Enter latitude and longitude to get the predicted score, number of banks, and normalized score.", # ) # interface.launch()