File size: 3,859 Bytes
11118c6
 
b9fb926
 
11118c6
69d9c01
11118c6
ef3f9b1
32ffec2
b9fb926
48eed47
2b94494
69d9c01
6fa1ec4
 
 
 
 
 
 
 
 
 
 
7616bd7
69d9c01
6fa1ec4
 
 
11118c6
6fa1ec4
 
32ffec2
 
1244666
 
48eed47
1244666
dda248f
48eed47
8424804
11118c6
aea93fc
8000abb
32ffec2
932fdef
aea93fc
ef3f9b1
 
48eed47
11118c6
6fa1ec4
 
11118c6
6fa1ec4
69d9c01
302e248
48eed47
32ffec2
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
ef3f9b1
 
 
 
 
32ffec2
ef3f9b1
32ffec2
ef3f9b1
32ffec2
8319fac
11118c6
 
3446916
 
 
6fa1ec4
48eed47
32ffec2
69d9c01
6fa1ec4
ef3f9b1
 
 
3446916
11118c6
 
 
 
 
 
 
8424804
11118c6
 
a6df1c4
ef3f9b1
6fa1ec4
ef3f9b1
32ffec2
ef3f9b1
6fa1ec4
ef3f9b1
 
 
 
 
 
 
 
 
 
 
11118c6
 
 
 
 
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
import gradio as gr
import torch
from torch import nn

import numpy as np
import pandas as pd

from utils2 import compute_features
from scipy.stats import nbinom

from xgboost import XGBRegressor
import json

# class NegBinomialModel(nn.Module):
#     def __init__(self, in_features):
#         super().__init__()
#         self.linear = nn.Linear(in_features, 1)
#         self.alpha = nn.Parameter(torch.tensor(0.5))

#     def forward(self, x):
#         # safer activation than exp()
#         mu = torch.exp(torch.clamp(self.linear(x), min=-5, max=5))
#         alpha = torch.clamp(self.alpha, min=1e-3, max=10)
#         return mu.squeeze(), alpha

    
# model = NegBinomialModel(12)
# model.load_state_dict(torch.load("model_weights(1).pt", map_location='cpu'))
# model.eval()

# MU_BANKS = 2.6035915713614286
# STD_BANKS = 3.0158890435512125


# with open("xgb_model(1).json", "r") as f:
#     params = json.load(f)

xgb_model = XGBRegressor()
xgb_model.load_model("xgb_model(1).json")

def predict_score(lat, lon, api_key):
    # Convert input to tensor
    # inputs = torch.tensor([[lat, lon]], dtype=torch.float32)
    inputs = compute_features((lat,lon), api_key, 500)
    print("[INPUTS]", inputs)
    num_banks = inputs.pop("num_banks_in_radius", 0)

    input_dict = inputs.copy()

    inputs = torch.tensor(list(inputs.values()), dtype=torch.float32)

    # with torch.no_grad():
    #     mu_pred, alpha = model(inputs)

    # mu_pred = mu_pred.numpy().flatten()

    mu_pred2 = xgb_model.predict(inputs.unsqueeze(0).numpy())

    # 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_pred2))

    # You can apply any post-processing here
    return (
        round(float(score), 3),
        num_banks,
        # round(float(mu_pred), 3),
        round(float(mu_pred2), 3),
        # round(float(log_score),3)
        # "Normal Score": round(float(normal_score), 3),
        # input_dict["total_amenities"],

        *[v for k,v in input_dict.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 (Negative Binomial)"),
        gr.Number(label="Ideal ATMs (XGBoost)"),
        # gr.Number(label="Log Score Probability"),

        # gr.Number(label="Total Amenities"),

        gr.Number(label="Dining and Drinking"),
        gr.Number(label="Community and Government"),
        gr.Number(label="Retail"),
        gr.Number(label="Business and Professional Services"),
        gr.Number(label="Landmarks and Outdoors"),
        gr.Number(label="Arts and Entertainment"),
        gr.Number(label="Health and Medicine"),
        gr.Number(label="Travel and Transportation"),
        gr.Number(label="Sports and Recreation"),
        gr.Number(label="Event"),
    ],
    title="Bank Location Scoring Model",
    description="Enter latitude and longitude to get the predicted score, number of banks, and normalized score.",
)