<jupyter_start><jupyter_text>MLflow Training TutorialThis `wine_quality.pynb` Jupyter notebook predicts the quality of wine using [sklearn.linear_model.ElasticNet](http://scikit-learn.org/stable/modules/generated/sklearn.linear_model.ElasticNet.html).  > This is the Jupyter notebook version of the `train.py` exampleAttribution* The data set used in this example is from http://archive.ics.uci.edu/ml/datasets/Wine+Quality* <NAME>, <NAME>, <NAME>, <NAME> and <NAME>.* Modeling wine preferences by data mining from physicochemical properties. In Decision Support Systems, Elsevier, 47(4):547-553, 2009.  Goals- Read in data- Split data for training and testing- Train model- Log parameters, metrics, and model- Use MLflow user-interface - Register model and set for productions- Use model for predictions<jupyter_code>import pandas as pd
import numpy as np
from sklearn.metrics import mean_squared_error, mean_absolute_error, r2_score
from sklearn.model_selection import train_test_split
from sklearn.linear_model import ElasticNet
from mlflow.tracking import MlflowClient
from pprint import pprint

import mlflow
import mlflow.sklearn<jupyter_output><empty_output><jupyter_text>Make a function with relavant metrics for ElasticNet<jupyter_code>def eval_metrics(actual, pred):
    rmse = np.sqrt(mean_squared_error(actual, pred))
    mae = mean_absolute_error(actual, pred)
    r2 = r2_score(actual, pred)
    return rmse, mae, r2<jupyter_output><empty_output><jupyter_text>Read the wine-quality csv file from the URL<jupyter_code># Read the wine-quality csv file from the URL
csv_url =\
    'http://archive.ics.uci.edu/ml/machine-learning-databases/wine-quality/winequality-red.csv'
data = pd.read_csv(csv_url, sep=';')
data.head()<jupyter_output><empty_output><jupyter_text>Split the data into training and test sets. (0.75, 0.25) split.<jupyter_code>train, test = train_test_split(data)<jupyter_output><empty_output><jupyter_text>The predicted column is "quality" which is an integer between [3, 9]<jupyter_code>train_x = train.drop(["quality"], axis=1)
test_x = test.drop(["quality"], axis=1)
train_y = train[["quality"]]
test_y = test[["quality"]]<jupyter_output><empty_output><jupyter_text>Define our hyperparameters for Elastic Net (Linear Regression)<jupyter_code>alpha = 0.333
l1_ratio = 0.666<jupyter_output><empty_output><jupyter_text>Connect to a databank in cloud to store our models in<jupyter_code>mlflow.set_tracking_uri('sqlite:///mlflow.db')<jupyter_output><empty_output><jupyter_text>Train model while MLflow tracks and logs the parameters, metrics, and models<jupyter_code># MLflow Tracking is based on the concept of 'runs'
# Runs are just the execution of some sort of Data Science code

with mlflow.start_run():
    # Execute ElasticNet
    lr = ElasticNet(alpha=alpha, l1_ratio=l1_ratio, random_state=42)
    lr.fit(train_x, train_y)

    # Evaluate Metrics
    predicted_qualities = lr.predict(test_x)
    (rmse, mae, r2) = eval_metrics(test_y, predicted_qualities)

    # Print out metrics
    print("Elasticnet model (alpha=%f, l1_ratio=%f):" % (alpha, l1_ratio))
    print("  RMSE: %s" % rmse)
    print("  MAE: %s" % mae)
    print("  R2: %s" % r2)

    # Log parameter to MLflow
    mlflow.log_param("alpha", alpha)
    mlflow.log_param("l1_ratio", l1_ratio)
    
    # Log metrics to MLflow
    mlflow.log_metric("rmse", rmse)
    mlflow.log_metric("r2", r2)
    mlflow.log_metric("mae", mae)

    # Log model to MLflow
    mlflow.sklearn.log_model(lr, "Test")<jupyter_output><empty_output><jupyter_text>Now using CLI cd into the current directory and enter the command:  mlflow ui --backend-store-uri sqlite:///mlflow.db<jupyter_code># explore user interface and register the model<jupyter_output><empty_output><jupyter_text>Create Client object to retrieve data from our MLflow server<jupyter_code>client = MlflowClient()<jupyter_output><empty_output><jupyter_text>Get a list of our registered models<jupyter_code>client.list_registered_models()
for rm in client.list_registered_models():
    pprint(dict(rm), indent=4)<jupyter_output><empty_output><jupyter_text>Check to see if we have any models in production<jupyter_code>production_models = [m.latest_versions[0] for m
                     in client.list_registered_models()
                     if m.latest_versions[0].current_stage == 'Production']
model_path = None
if len(production_models) == 0:
    print('No models flagged as production')
else: 
    model_path = production_models[0].source
    print(f'Model Path = {model_path}')<jupyter_output><empty_output><jupyter_text>Load model for use<jupyter_code>predict_func = mlflow.pyfunc.load_model(model_path)<jupyter_output><empty_output><jupyter_text>Use a small batch of features to make predictions<jupyter_code>small_batch = test_x[0:3]
predictions = predict_func.predict(small_batch)
print(f'\n----------------------\nPredictions: {predictions}')<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.10926076360682373, 'fraction_numerical': 0.011372867587327376, 'mean_word_length': 5.628532974427995, 'pattern_counts': {'":': 0, '<': 62, '<?xml version=': 0, '>': 63, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '14', 'dir': 'jupyter-structured-clean-dedup', 'id': '629492', 'license': 'Unlicense', 'n_tokens_mistral': 1703, 'n_tokens_neox': 1639, 'n_words': 403, 'path': 'wine_quality.ipynb', 'repo_name': 'SamuelAdamsMcGuire/mlflow_demo', 'size': '4939'}