Spaces:
Sleeping
Sleeping
Add app + predictor with HF artifact download
Browse files- app.py +3 -1
- predictor.py +5 -13
app.py
CHANGED
|
@@ -114,4 +114,6 @@ with gr.Blocks(title="Loan Approval Predictor") as demo:
|
|
| 114 |
|
| 115 |
btn_batch.click(fn=run_batch, inputs=file_in, outputs=[preview, file_out])
|
| 116 |
|
| 117 |
-
|
|
|
|
|
|
|
|
|
| 114 |
|
| 115 |
btn_batch.click(fn=run_batch, inputs=file_in, outputs=[preview, file_out])
|
| 116 |
|
| 117 |
+
|
| 118 |
+
if __name__ == "__main__":
|
| 119 |
+
demo.launch(server_name="0.0.0.0", server_port=7860)
|
predictor.py
CHANGED
|
@@ -1,28 +1,26 @@
|
|
| 1 |
from __future__ import annotations
|
| 2 |
|
| 3 |
-
from typing import Any, Dict
|
| 4 |
from pathlib import Path
|
|
|
|
|
|
|
| 5 |
|
| 6 |
import joblib
|
| 7 |
import numpy as np
|
| 8 |
import pandas as pd
|
| 9 |
from huggingface_hub import hf_hub_download
|
| 10 |
|
|
|
|
| 11 |
|
| 12 |
ARTIFACT_DIR = Path("artifacts")
|
| 13 |
ARTIFACT_DIR.mkdir(exist_ok=True)
|
| 14 |
|
| 15 |
-
REPO_ID = "Fola-lad/loan-artifacts" # model repo
|
| 16 |
-
|
| 17 |
-
|
| 18 |
def _get_artifact(filename: str) -> Path:
|
| 19 |
-
|
| 20 |
dst = ARTIFACT_DIR / filename
|
| 21 |
if not dst.exists():
|
| 22 |
-
|
| 23 |
return dst
|
| 24 |
|
| 25 |
-
|
| 26 |
missing_value_handler = joblib.load(_get_artifact("missing_value_handler.joblib"))
|
| 27 |
preprocessor = joblib.load(_get_artifact("preprocessor.joblib"))
|
| 28 |
model = joblib.load(_get_artifact("loan_model.joblib"))
|
|
@@ -44,13 +42,11 @@ CLEANED_FEATURE_COLS = [
|
|
| 44 |
|
| 45 |
EXPECTED_INPUT_COLS = ["Loan_ID"] + CLEANED_FEATURE_COLS
|
| 46 |
|
| 47 |
-
|
| 48 |
def _safe_log(series: pd.Series) -> np.ndarray:
|
| 49 |
v = pd.to_numeric(series, errors="coerce").fillna(0).to_numpy(dtype=float)
|
| 50 |
v = np.where(v > 0, v, 1.0)
|
| 51 |
return np.log(v)
|
| 52 |
|
| 53 |
-
|
| 54 |
def feature_engineering(df: pd.DataFrame) -> pd.DataFrame:
|
| 55 |
df = df.copy()
|
| 56 |
|
|
@@ -70,7 +66,6 @@ def feature_engineering(df: pd.DataFrame) -> pd.DataFrame:
|
|
| 70 |
)
|
| 71 |
return df
|
| 72 |
|
| 73 |
-
|
| 74 |
def _normalize_input(df: pd.DataFrame) -> pd.DataFrame:
|
| 75 |
df = df.copy()
|
| 76 |
|
|
@@ -88,7 +83,6 @@ def _normalize_input(df: pd.DataFrame) -> pd.DataFrame:
|
|
| 88 |
|
| 89 |
return df
|
| 90 |
|
| 91 |
-
|
| 92 |
def _prepare_features(raw_df: pd.DataFrame):
|
| 93 |
raw_df = _normalize_input(raw_df)
|
| 94 |
|
|
@@ -100,7 +94,6 @@ def _prepare_features(raw_df: pd.DataFrame):
|
|
| 100 |
|
| 101 |
return preprocessor.transform(fe_df)
|
| 102 |
|
| 103 |
-
|
| 104 |
def predict_one(payload: Dict[str, Any]) -> Dict[str, Any]:
|
| 105 |
df = pd.DataFrame([payload])
|
| 106 |
X = _prepare_features(df)
|
|
@@ -111,7 +104,6 @@ def predict_one(payload: Dict[str, Any]) -> Dict[str, Any]:
|
|
| 111 |
|
| 112 |
return {"Loan_Status": str(label), "confidence": float(np.max(proba))}
|
| 113 |
|
| 114 |
-
|
| 115 |
def predict_batch(df: pd.DataFrame) -> pd.DataFrame:
|
| 116 |
X = _prepare_features(df)
|
| 117 |
|
|
|
|
| 1 |
from __future__ import annotations
|
| 2 |
|
|
|
|
| 3 |
from pathlib import Path
|
| 4 |
+
from typing import Any, Dict
|
| 5 |
+
from shutil import copyfile
|
| 6 |
|
| 7 |
import joblib
|
| 8 |
import numpy as np
|
| 9 |
import pandas as pd
|
| 10 |
from huggingface_hub import hf_hub_download
|
| 11 |
|
| 12 |
+
REPO_ID = "Fola-lad/loan-artifacts"
|
| 13 |
|
| 14 |
ARTIFACT_DIR = Path("artifacts")
|
| 15 |
ARTIFACT_DIR.mkdir(exist_ok=True)
|
| 16 |
|
|
|
|
|
|
|
|
|
|
| 17 |
def _get_artifact(filename: str) -> Path:
|
| 18 |
+
downloaded = hf_hub_download(repo_id=REPO_ID, filename=filename)
|
| 19 |
dst = ARTIFACT_DIR / filename
|
| 20 |
if not dst.exists():
|
| 21 |
+
copyfile(downloaded, dst)
|
| 22 |
return dst
|
| 23 |
|
|
|
|
| 24 |
missing_value_handler = joblib.load(_get_artifact("missing_value_handler.joblib"))
|
| 25 |
preprocessor = joblib.load(_get_artifact("preprocessor.joblib"))
|
| 26 |
model = joblib.load(_get_artifact("loan_model.joblib"))
|
|
|
|
| 42 |
|
| 43 |
EXPECTED_INPUT_COLS = ["Loan_ID"] + CLEANED_FEATURE_COLS
|
| 44 |
|
|
|
|
| 45 |
def _safe_log(series: pd.Series) -> np.ndarray:
|
| 46 |
v = pd.to_numeric(series, errors="coerce").fillna(0).to_numpy(dtype=float)
|
| 47 |
v = np.where(v > 0, v, 1.0)
|
| 48 |
return np.log(v)
|
| 49 |
|
|
|
|
| 50 |
def feature_engineering(df: pd.DataFrame) -> pd.DataFrame:
|
| 51 |
df = df.copy()
|
| 52 |
|
|
|
|
| 66 |
)
|
| 67 |
return df
|
| 68 |
|
|
|
|
| 69 |
def _normalize_input(df: pd.DataFrame) -> pd.DataFrame:
|
| 70 |
df = df.copy()
|
| 71 |
|
|
|
|
| 83 |
|
| 84 |
return df
|
| 85 |
|
|
|
|
| 86 |
def _prepare_features(raw_df: pd.DataFrame):
|
| 87 |
raw_df = _normalize_input(raw_df)
|
| 88 |
|
|
|
|
| 94 |
|
| 95 |
return preprocessor.transform(fe_df)
|
| 96 |
|
|
|
|
| 97 |
def predict_one(payload: Dict[str, Any]) -> Dict[str, Any]:
|
| 98 |
df = pd.DataFrame([payload])
|
| 99 |
X = _prepare_features(df)
|
|
|
|
| 104 |
|
| 105 |
return {"Loan_Status": str(label), "confidence": float(np.max(proba))}
|
| 106 |
|
|
|
|
| 107 |
def predict_batch(df: pd.DataFrame) -> pd.DataFrame:
|
| 108 |
X = _prepare_features(df)
|
| 109 |
|