Amit-kr26's picture
HF Spaces deployment
c9f187d
Raw
History Blame Contribute Delete
3.25 kB
"""MLflow model registry helpers."""
import mlflow
import mlflow.pyfunc
import mlflow.sklearn
import mlflow.xgboost
import pandas as pd
from mlflow.tracking import MlflowClient
from sqlalchemy import Engine, text
def register_model(
run_id: str,
model_name: str,
model_uri_suffix: str,
stage: str = "Production",
) -> None:
"""Register a logged model and transition it to the given stage."""
client = MlflowClient()
model_uri = f"runs:/{run_id}/{model_uri_suffix}"
# Create registered model if it doesn't exist
try:
client.create_registered_model(model_name)
except Exception:
pass # Already exists
version = client.create_model_version(
name=model_name,
source=model_uri,
run_id=run_id,
)
client.transition_model_version_stage(
name=model_name,
version=version.version,
stage=stage,
archive_existing_versions=True,
)
print(f" Registered '{model_name}' version {version.version}{stage}")
def load_production_model(model_name: str):
"""Load the Production-stage model from the MLflow registry."""
return mlflow.pyfunc.load_model(f"models:/{model_name}/Production")
def write_scores_to_warehouse(
engine: Engine,
scores_df: pd.DataFrame,
) -> int:
"""
Bulk-update dim_customers with ML-derived scores.
scores_df must have column 'customer_unique_id' plus any subset of:
churn_probability, segment_label, rfm_segment, clv_score.
Uses a single connection so temp table is visible across all statements.
"""
possible_cols = ["customer_unique_id", "churn_probability", "segment_label", "rfm_segment", "clv_score"]
cols = [c for c in possible_cols if c in scores_df.columns]
df = scores_df[cols].drop_duplicates("customer_unique_id").copy()
with engine.begin() as conn:
conn.execute(text("DROP TABLE IF EXISTS _scores_staging"))
conn.execute(text("""
CREATE TEMP TABLE _scores_staging (
customer_unique_id TEXT,
churn_probability NUMERIC(5,4),
segment_label INTEGER,
rfm_segment TEXT,
clv_score NUMERIC(10,4)
)
"""))
# Insert using pandas within same connection
ncols = len(cols)
chunk = max(1, 65535 // ncols)
df.to_sql(
"_scores_staging",
con=conn,
if_exists="append",
index=False,
method="multi",
chunksize=chunk,
)
conn.execute(text("""
UPDATE warehouse.dim_customers dc
SET
churn_probability = COALESCE(s.churn_probability, dc.churn_probability),
segment_label = COALESCE(s.segment_label, dc.segment_label),
rfm_segment = COALESCE(s.rfm_segment, dc.rfm_segment),
clv_score = COALESCE(s.clv_score, dc.clv_score),
_updated_at = now()
FROM _scores_staging s
WHERE dc.customer_unique_id = s.customer_unique_id
"""))
result = conn.execute(text("SELECT COUNT(*) FROM _scores_staging"))
return result.scalar()