|
from fastapi import FastAPI |
|
from pydantic import BaseModel |
|
import pandas as pd |
|
import pickle |
|
import uvicorn |
|
from sklearn.preprocessing import StandardScaler, QuantileTransformer |
|
import category_encoders as ce |
|
|
|
|
|
app = FastAPI(title="Product Demand Prediction API") |
|
|
|
|
|
with open("model.pkl", "rb") as f: |
|
model = pickle.load(f) |
|
|
|
|
|
categorical_cols = ['center_id', 'meal_id', 'emailer_for_promotion', 'homepage_featured', 'city_code', 'region_code', 'center_type', 'category', 'cuisine'] |
|
numeric_cols = ['week', 'base_price', 'discount', 'op_area'] |
|
|
|
|
|
encoder = ce.BinaryEncoder(drop_invariant=False, return_df=True) |
|
|
|
quantile_transformer = QuantileTransformer(output_distribution='normal') |
|
|
|
scaler = StandardScaler() |
|
scaler.set_output(transform="pandas") |
|
|
|
|
|
def predict(df, endpoint="simple"): |
|
|
|
df_cat = encoder.fit_transform(df[categorical_cols]) |
|
df_num_quantile = quantile_transformer.fit_transform(df[numeric_cols]) |
|
df_num_quantile = pd.DataFrame(df_num_quantile, columns=numeric_cols) |
|
df_num_scaled = scaler.fit_transform(df_num_quantile) |
|
|
|
|
|
preprocessed_df = pd.concat([df_num_scaled, df_cat], axis=1) |
|
|
|
|
|
model_columns = preprocessed_df.columns.tolist() |
|
preprocessed_df = preprocessed_df.reindex(columns=model_columns, fill_value=0) |
|
|
|
|
|
prediction = model.predict(preprocessed_df) |
|
|
|
response = [] |
|
for num_orders in prediction: |
|
|
|
num_orders = int(num_orders) |
|
|
|
output = { |
|
"predicted_num_orders": num_orders |
|
} |
|
response.append(output) |
|
|
|
return response |
|
|
|
class Demand(BaseModel): |
|
week: int |
|
center_id: str |
|
meal_id: str |
|
base_price: float |
|
emailer_for_promotion: int |
|
homepage_featured: int |
|
discount: float |
|
city_code: str |
|
region_code: str |
|
center_type: str |
|
op_area: float |
|
category: str |
|
cuisine: str |
|
|
|
class Demands(BaseModel): |
|
all_demands: list[Demand] |
|
|
|
@classmethod |
|
def return_list_of_dict(cls, demands: "Demands"): |
|
demand_list = [] |
|
for demand in demands.all_demands: |
|
demand_dict = demand.dict() |
|
demand_list.append(demand_dict) |
|
return demand_list |
|
|
|
|
|
|
|
@app.get("/") |
|
def root(): |
|
return {"message": "Welcome to the Product Demand Prediction API! This API provides endpoints for predicting product demand based on input data."} |
|
|
|
|
|
@app.post("/predict") |
|
def predict_demand(demand: Demand): |
|
|
|
data = pd.DataFrame(demand.dict(), index=[0]) |
|
predicted_demand = predict(df=data) |
|
return predicted_demand |
|
|
|
|
|
@app.post("/predict_multiple") |
|
def predict_demand_for_multiple_demands(demands: Demands): |
|
"""Make prediction with the passed data""" |
|
data = pd.DataFrame(Demands.return_list_of_dict(demands)) |
|
predicted_demand = predict(df=data, endpoint="multi") |
|
return {"predicted_demand": predicted_demand} |
|
|
|
if __name__ == "__main__": |
|
uvicorn.run("main:app", reload=True) |