Forum Discussion
ML model in Fabric: Get prediction probabilities
- 1 year ago
Hello Anonymous
The key idea is to create a custom PyFunc model that calls `predict_proba` or an equivalent function on your base model.
You can make MLFlowTransformer return probabilities by packaging a model whose predict function itself outputs probabilities, rather than just class labels. In other words, if the underlying model supports something like `predict_proba`, you need to ensure that the MLflow model’s prediction method calls that instead of `predict` when it runs.
One way to do this is to define a custom PyFunc model that wraps your existing classifier and overrides its predict method to invoke `predict_proba`. For a scikit-learn model, for example, you could do something like:import mlflow.pyfunc
import mlflow.sklearn
import sklearn
from sklearn.base import BaseEstimatorclass ProbaWrapper(mlflow.pyfunc.PythonModel):
def load_context(self, context):
import joblib
# Load the underlying model (scikit-learn, XGBoost, etc.)
self.model = mlflow.sklearn.load_model(context.artifacts["base_model"])def predict(self, context, model_input):
# Return probability outputs instead of classes
return self.model.predict_proba(model_input)# Train or load your existing model (e.g. a scikit-learn classifier).
# Then save it in MLflow with a 'base_model' artifact, wrapping it in ProbaWrapper:with mlflow.start_run():
mlflow.pyfunc.log_model(
artifact_path="proba_model",
python_model=ProbaWrapper(),
artifacts={"base_model": "<path_or_registered_model_reference>"},
)Register that model in Fabric, then use the MLFlowTransformer just as before (pointing `modelName` and `modelVersion` to this custom PyFunc model). The result of `model.transform(df)` will now be per-class probabilities instead of 0/1 predictions
Hope this helps
Hello Anonymous
The key idea is to create a custom PyFunc model that calls `predict_proba` or an equivalent function on your base model.
You can make MLFlowTransformer return probabilities by packaging a model whose predict function itself outputs probabilities, rather than just class labels. In other words, if the underlying model supports something like `predict_proba`, you need to ensure that the MLflow model’s prediction method calls that instead of `predict` when it runs.
One way to do this is to define a custom PyFunc model that wraps your existing classifier and overrides its predict method to invoke `predict_proba`. For a scikit-learn model, for example, you could do something like:
import mlflow.pyfunc
import mlflow.sklearn
import sklearn
from sklearn.base import BaseEstimator
class ProbaWrapper(mlflow.pyfunc.PythonModel):
def load_context(self, context):
import joblib
# Load the underlying model (scikit-learn, XGBoost, etc.)
self.model = mlflow.sklearn.load_model(context.artifacts["base_model"])
def predict(self, context, model_input):
# Return probability outputs instead of classes
return self.model.predict_proba(model_input)
# Train or load your existing model (e.g. a scikit-learn classifier).
# Then save it in MLflow with a 'base_model' artifact, wrapping it in ProbaWrapper:
with mlflow.start_run():
mlflow.pyfunc.log_model(
artifact_path="proba_model",
python_model=ProbaWrapper(),
artifacts={"base_model": "<path_or_registered_model_reference>"},
)
Register that model in Fabric, then use the MLFlowTransformer just as before (pointing `modelName` and `modelVersion` to this custom PyFunc model). The result of `model.transform(df)` will now be per-class probabilities instead of 0/1 predictions
Hope this helps
- Anonymous1 year agoNot applicable
Thank you! This will work.
Another way if I dont want to use wrappers is this solution:import pandas as pdimport mlflow.sklearndf = spark.sql("SELECT * from lakehouse.prep_data_score")#df = df.limit(100)df_pd = df.toPandas()med_key = df_pd.pop("MED_KEY")# Specify the model's path in the MLflow registrymodel_uri = "models:/churn_model/5" # Model name and version# Load the modelmodel = mlflow.sklearn.load_model(model_uri)features = model.feature_names_in_predictions = model.predict_proba(df_pd[features])