Danang08/data_mining
0
1from fastapi import FastAPI2from fastapi.middleware.cors import CORSMiddleware3from pydantic import BaseModel, Field4from catboost import CatBoostClassifier5import pandas as pd6import joblib7import os8 9MODEL_PATH = os.path.join("model_output", "catboost_return_model.cbm")10META_PATH = os.path.join("model_output", "model_metadata.pkl")11 12model = CatBoostClassifier()13model.load_model(MODEL_PATH)14metadata = joblib.load(META_PATH)15 16app = FastAPI(17 title="E-Commerce Return Risk Prediction API",18 description="Backend prediksi retur e-commerce menggunakan CatBoost dari notebook Colab UTS Danang.",19 version="1.0.0"20)21 22# Untuk tugas kuliah dibuat terbuka. Kalau production, batasi origin domain Vercel kamu.23app.add_middleware(24 CORSMiddleware,25 allow_origins=["*"],26 allow_credentials=True,27 allow_methods=["*"],28 allow_headers=["*"],29)30 31class TransactionInput(BaseModel):32 product_category: str = Field(..., example="Electronics")33 product_price: float = Field(..., example=250.0)34 quantity: int = Field(..., example=2)35 order_date: str = Field(..., example="2025-05-15")36 region: str = Field(..., example="Asia")37 payment_method: str = Field(..., example="CreditCard")38 delivery_days: int = Field(..., example=5)39 customer_rating: float = Field(..., example=4.2)40 discount_percent: float = Field(..., example=10.0)41 revenue: float = Field(..., example=450.0)42 43def create_features(input_dict: dict) -> pd.DataFrame:44 data = pd.DataFrame([input_dict])45 46 data["order_date"] = pd.to_datetime(data["order_date"], errors="coerce")47 data["order_year"] = data["order_date"].dt.year48 data["order_month"] = data["order_date"].dt.month49 data["order_day"] = data["order_date"].dt.day50 data["order_dayofweek"] = data["order_date"].dt.dayofweek51 data["is_weekend"] = data["order_dayofweek"].isin([5, 6]).astype(int)52 data["order_quarter"] = data["order_date"].dt.quarter53 54 data["price_after_discount"] = data["product_price"] * (1 - data["discount_percent"] / 100)55 data["estimated_total_price"] = data["price_after_discount"] * data["quantity"]56 57 data = data.drop(columns=["order_date"], errors="ignore")58 59 # Pastikan urutan kolom sama persis dengan saat training di Colab60 data = data[metadata["features"]]61 return data62 63@app.get("/")64def root():65 return {66 "message": "API Prediksi Retur E-Commerce aktif.",67 "model": "CatBoostClassifier",68 "threshold": metadata["best_threshold"],69 "features": metadata["features"]70 }71 72@app.get("/health")73def health():74 return {"status": "ok"}75 76@app.get("/metadata")77def get_metadata():78 return metadata79 80@app.post("/predict")81def predict(payload: TransactionInput):82 input_data = create_features(payload.model_dump())83 84 probability = float(model.predict_proba(input_data)[:, 1][0])85 threshold = float(metadata["best_threshold"])86 prediction = int(probability >= threshold)87 88 if probability >= 0.70:89 risk_level = "Tinggi"90 elif probability >= 0.40:91 risk_level = "Sedang"92 else:93 risk_level = "Rendah"94 95 return {96 "probability_return": round(probability, 4),97 "probability_percent": round(probability * 100, 2),98 "threshold": round(threshold, 2),99 "prediction": prediction,100 "label": "Risiko Retur Tinggi" if prediction == 1 else "Risiko Retur Rendah",101 "risk_level": risk_level102 }103 