<jupyter_start><jupyter_text>Train XGboost Model With Hyper-Params Using Serverless Functions<jupyter_code># nuclio: ignore
import nuclio<jupyter_output><empty_output><jupyter_text>Define function dependencies<jupyter_code>%%nuclio cmd 
pip install sklearn
pip install xgboost
pip install matplotlib
pip install mlrun
%nuclio config spec.build.baseImage = "python:3.6-jessie"<jupyter_output>%nuclio: setting spec.build.baseImage to 'python:3.6-jessie'<jupyter_text>Function code<jupyter_code>import xgboost as xgb
import os
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
import numpy as np
from sklearn.metrics import accuracy_score
from mlrun.artifacts import TableArtifact, PlotArtifact
import pandas as pd


def iris_generator(context, target=''):
    iris = load_iris()
    iris_dataset = pd.DataFrame(data=iris.data, columns=iris.feature_names)
    iris_labels = pd.DataFrame(data=iris.target, columns=['label'])
    iris_dataset = pd.concat([iris_dataset, iris_labels], axis=1)
    context.logger.info('saving iris dataframe to {}'.format(target))
    context.log_artifact(TableArtifact('iris_dataset', df=iris_dataset, target_path=target))
    

def xgb_train(context, 
              dataset='',
              model_name='model.bst',
              max_depth=6,
              num_class=10,
              eta=0.2,
              gamma=0.1,
              steps=20):

    df = pd.read_csv(dataset)
    X = df.drop(['label'], axis=1)
    y = df['label']
    
    X_train, X_test, Y_train, Y_test = train_test_split(X, y, test_size=0.2)
    dtrain = xgb.DMatrix(X_train, label=Y_train)
    dtest = xgb.DMatrix(X_test, label=Y_test)

    # Get params from event
    param = {"max_depth": max_depth,
             "eta": eta, "nthread": 4,
             "num_class": num_class,
             "gamma": gamma,
             "objective": "multi:softprob"}

    # Train model
    xgb_model = xgb.train(param, dtrain, steps)

    preds = xgb_model.predict(dtest)
    best_preds = np.asarray([np.argmax(line) for line in preds])

    # log results and artifacts
    context.log_result('accuracy', float(accuracy_score(Y_test, best_preds)))
    context.log_artifact('model', body=bytes(xgb_model.save_raw()), 
                         target_path=model_name, labels={'framework': 'xgboost'})
   
    
import matplotlib
import matplotlib.pyplot as plt
from io import BytesIO

def plot_iter(context, iterations, col='accuracy', num_bins=10):
    df = pd.read_csv(BytesIO(iterations.get()))
    x = df['output.{}'.format(col)]
    fig, ax = plt.subplots(figsize=(6,6))
    n, bins, patches = ax.hist(x, num_bins, density=1)
    ax.set_xlabel('Accuraccy')
    ax.set_ylabel('Count')
    context.log_artifact(PlotArtifact('myfig', body=fig))
# nuclio: end-code
# marks the end of a code section<jupyter_output><empty_output><jupyter_text>Import MLRUN, and run the data collection and training locally<jupyter_code>from mlrun import new_function, code_to_function, NewTask, mount_v3io, new_model_server, mlconf, get_run_db
# for local DB path use 'User/mlrun' instead 
mlconf.dbpath = 'http://mlrun-db:8080'<jupyter_output><empty_output><jupyter_text>Generate the iris dataset and store in a CSV<jupyter_code>df_path = '/User/mlrun/df.csv'
gen = new_function().run(name='iris_gen', handler=iris_generator, params={'target': df_path})<jupyter_output>[mlrun] 2019-11-18 12:02:55,255 starting run iris_gen uid=d04439c48b5d4708977cfa5b53ea2996  -> http://mlrun-db:8080
[mlrun] 2019-11-18 12:02:55,384 saving iris dataframe to /User/mlrun/df.csv<jupyter_text>Define a training task with Hyper parameters (GridSearch) and run locally<jupyter_code># create a task and test our function locally with multiple parameters
parameters = {
     "eta":       [0.05, 0.10, 0.20],
     "max_depth": [3, 4, 6, 8, 10],
     "gamma":     [0.0, 0.1, 0.3],
     }

task = NewTask(handler=xgb_train, out_path='/User/mlrun/data', inputs={'dataset': df_path}).with_hyper_params(parameters, 'max.accuracy')
run = new_function().run(task)<jupyter_output>[mlrun] 2019-11-18 12:03:10,209 starting run xgb_train uid=141cedd49d074792934da530076ddc63  -> http://mlrun-db:8080<jupyter_text>Deploy XGB function to Nuclio (with paralelism), and run remotely<jupyter_code># create the function from the notebook code + annotations, add volumes and parallel HTTP trigger
xgbfn = code_to_function('xgb', runtime='nuclio:mlrun')
xgbfn.add_volume('User','~/').with_http(workers=16).with_v3io()
# deploy the function to the cluster
xgbfn.deploy(project='iris')
nrun = xgbfn.run(task, handler='xgb_train')<jupyter_output>[mlrun] 2019-11-18 12:11:57,449 starting run xgb_train uid=42e9c80152664a948f62e7a0b5fbb67a  -> http://mlrun-db:8080<jupyter_text>Create a multi-stage KubeFlow Pipeline from our functions* Load Iris dataset into a CSV* Train a model using XGBoost with Hyper-parameter* Deploy the model using Nuclio-serving* Generate a plot of the training results<jupyter_code>import kfp
from kfp import dsl
artifacts_path = 'v3io:///users/admin/mlrun/kfp/{{workflow.uid}}/'
@dsl.pipeline(
    name='My XGBoost training pipeline',
    description='Shows how to use mlrun.'
)
def xgb_pipeline(
   eta = [0.1, 0.2, 0.3], gamma = [0.0, 0.1, 0.2, 0.3]
):

    ingest = xgbfn.as_step(name='ingest_iris', handler='iris_generator',
                          params = {'target': df_path},
                          outputs=['iris_dataset'], out_path=artifacts_path).apply(mount_v3io())

    
    train = xgbfn.as_step(name='xgb_train', handler='xgb_train',
                          hyperparams = {'eta': eta, 'gamma': gamma},
                          selector='max.accuracy',
                          inputs = {'dataset': ingest.outputs['iris_dataset']}, 
                          outputs=['model'], out_path=artifacts_path).apply(mount_v3io())

    
    plot = xgbfn.as_step(name='plot', handler='plot_iter',
                         inputs={'iterations': train.outputs['iteration_results']},
                         outputs=['iris_dataset'], out_path=artifacts_path).apply(mount_v3io())


    # define a nuclio-serving functions, generated from a notebook file
    srvfn = new_model_server('iris-serving', model_class='XGBoostModel', filename='nuclio_serving.ipynb')
    
    # deploy the model serving function with inputs from the training stage
    deploy = srvfn.with_v3io('User','~/').deploy_step(project = 'iris', models={'iris_v1': train.outputs['model']})<jupyter_output><empty_output><jupyter_text>Create a KubeFlow client and submit the pipeline with parameters<jupyter_code># for debug generate the pipeline dsl
#kfp.compiler.Compiler().compile(xgb_pipeline, 'mlrunpipe.yaml')
client = kfp.Client(namespace='default-tenant')
arguments = {'eta': [0.05, 0.10, 0.30], 'gamma': [0.0, 0.1, 0.2, 0.3]}
run_result = client.create_run_from_pipeline_func(xgb_pipeline, arguments, run_name='xgb 1', experiment_name='xgb')
# connect to the run db 
db = get_run_db().connect()
# query the DB with filter on workflow ID (only show this workflow) 
db.list_runs('', labels=f'workflow={run_result.run_id}').show()
# use this to supress XGB FutureWarning
import warnings
warnings.simplefilter(action='ignore', category=FutureWarning)<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.126414573557825, 'fraction_numerical': 0.03243168644769528, 'mean_word_length': 4.2590711175616836, 'pattern_counts': {'":': 9, '<': 33, '<?xml version=': 0, '>': 36, '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': '9', 'dir': 'jupyter-structured-clean-dedup', 'id': '11418', 'license': 'Apache-2.0', 'n_tokens_mistral': 2669, 'n_tokens_neox': 2492, 'n_words': 537, 'path': 'xgboost/train_xgboost_serverless.ipynb', 'repo_name': 'marcelonyc/demos', 'size': '7246'}