# ---
# jupyter:
#   jupytext:
#     text_representation:
#       extension: .py
#       format_name: light
#       format_version: '1.5'
#       jupytext_version: 1.14.4
#   kernel_info:
#     name: python3-azureml
#   kernelspec:
#     display_name: Python 3
#     language: python
#     name: python3
# ---

# + [markdown] id="sUB2Vbtufvz2"
# # Hyperparameter Tuning using HyperDrive

# + [markdown] gather={"logged": 1598531914256} id="wPCOgUqtfv0C"
# ## Create an experiment in workspace

# + gather={"logged": 1598531917374} id="YoSl4ZRVfv0D" jupyter={"outputs_hidden": false, "source_hidden": false} nteract={"transient": {"deleting": false}} outputId="82bc8561-20c3-4f0b-b88f-ac6501fbfa43"
from azureml.core import Workspace, Experiment

#Define a workspace
ws = Workspace.from_config()

#Create an experiment
exp = Experiment(workspace=ws, name="Hyperparameter_Tuning")
print('Workspace name: ' + ws.name, 
      'Azure region: ' + ws.location, 
      'Subscription id: ' + ws.subscription_id, 
      'Resource group: ' + ws.resource_group, sep = '\n')
run = exp.start_logging()

# + [markdown] id="m0j6RLjvfv0F"
# ## Create a compute cluster

# + id="cCFhhMdYfv0F" outputId="4f4bda69-a027-4372-bfe7-cea5070c4122"
from azureml.core.compute import ComputeTarget, AmlCompute
from azureml.core.compute_target import ComputeTargetException

#Create a new cluster to run the experiment using vm_size of STANDARD_D2_V2 and max_nodes of 4. 
cpu_cluster_name = "cpucluster"
try:
    cpu_cluster = ComputeTarget(workspace=ws, name=cpu_cluster_name)
    print("Found an existing cluster.\n")
except ComputeTargetException:
    print("Creating a new cluster.\n")
    compute_config = AmlCompute.provisioning_configuration(vm_size='STANDARD_D2_V2', max_nodes=4)
    cpu_cluster = ComputeTarget.create(ws, cpu_cluster_name, compute_config)
cpu_cluster.wait_for_completion()

#If the cluster exist already for the current cluster, print it's detailed status using get_status(). If not, create and print.
print("Cluster details: ", cpu_cluster.get_status().serialize())

# + [markdown] id="bSNWuArxgfr7"
# ## Dataset overview

# + [markdown] id="ms89sdCdgmmB"
# This project demonstrates the usage of different Machine Learning Algorithms on the Kaggle's Titanic dataset. We are performing classification in this case. The titanic dataset consists of features related to a passenger and the response is if a passenger survived the titanic disaster or not (Survived-1/0).

# + id="aJJzGS-5gox5"
import pandas as pd

#Loading the titanic dataset
df = pd.read_csv('https://raw.githubusercontent.com/parvatijay2901/Machine-Learning-with-the-Titanic-dataset-on-Azure/main/Training_data.csv')

df.head()

# + [markdown] id="_VgCBVBOgwg_"
# Further in train.py we are analysing and transforming the dataset. We are also splitting it into train and test sets. 

# + [markdown] gather={"logged": 1598531923519} id="i4nsG_d4fv0G" jupyter={"outputs_hidden": false, "source_hidden": false} nteract={"transient": {"deleting": false}}
# ## Hyperdrive Configuration

# + [markdown] id="e73JCsLJg7Zp"
# Hyperparameters are adjustable parameters that controls the model training process. Hyperparameters of logistic regression are max-iterations "choice(100, 150, 200, 250, 300)" and regularization strength "uniform(0.01,1)". HyperDrive package(HyperDriveConfig) helps helps us to choose the parameters automatically. Hyperparameter tuning is the process of finding the configuration of hyperparameters that results in the best performance. BayesianParameterSampling is used in this case. With the help of hyperdrive, hyperparameters of Logistic Regression are optimized and accuracy is calculated. Logistic Regression is a binary classification algorithm(0 or 1). It uses logistic function called the sigmoid function in order to predict outcomes.

# + gather={"logged": 1598544893076} id="7IyLpWCcfv0H" jupyter={"outputs_hidden": false, "source_hidden": false} nteract={"transient": {"deleting": false}} outputId="ad71f3ce-2009-4d99-93bc-b4566e1b8b75"
from azureml.widgets import RunDetails
from azureml.train.sklearn import SKLearn
from azureml.train.hyperdrive.run import PrimaryMetricGoal
from azureml.train.hyperdrive.sampling import BayesianParameterSampling
from azureml.train.hyperdrive.runconfig import HyperDriveConfig
from azureml.train.hyperdrive.parameter_expressions import uniform
from azureml.train.hyperdrive.parameter_expressions import choice
import os

#Specify a parameter sampler (Bayesian sampling)
ps = BayesianParameterSampling({'--C': uniform(0.01,1),'--max_iter': choice(100, 150, 200, 250, 300)})

#Create a directory 'training'
if "training" not in os.listdir():
    os.mkdir("./training")

#Create a SKLearn estimator for use with train.py
est = SKLearn(source_directory='./',
                compute_target=cpu_cluster,
                entry_script='train.py')

#Create a HyperDriveConfig using the estimator and hyperparameter sampler.
hyperdrive_config = HyperDriveConfig(
                                   hyperparameter_sampling = ps,
                                   primary_metric_name = 'accuracy',
                                   primary_metric_goal = PrimaryMetricGoal.MAXIMIZE,
                                   max_total_runs = 20,
                                   max_concurrent_runs = 4,
                                   policy = None,
                                   estimator = est)

# + [markdown] gather={"logged": 1598544898497} id="JAcdMoQKfv0H" jupyter={"outputs_hidden": false, "source_hidden": false} nteract={"transient": {"deleting": false}}
# ## Run Details

# + [markdown] id="KIkpvdQ0iPn0"
# We are training the model on Logistic regression with different hyperparameters. Also, we are using Bayesian parameter sampling. The best run/model can be easily predicted after this step. 

# + colab={"referenced_widgets": ["101d43aec46d40aebf1560f4a5cfe9e2"]} gather={"logged": 1598544897941} id="i2-rojUVfv0I" jupyter={"outputs_hidden": false, "source_hidden": false} nteract={"transient": {"deleting": false}} outputId="b1b1d56b-d49f-4b44-82e0-87d54c31ce40"
#Submit the hyperdrive run
hd_run = exp.submit(hyperdrive_config)

#Launch the widget to view the progress and results
RunDetails(hd_run).show()

# + [markdown] id="v1xRMWFxfv0J"
# ## Retrieve and save the best model. 

# + gather={"logged": 1598546650307} id="I8Pa87Xnfv0J" jupyter={"outputs_hidden": false, "source_hidden": false} nteract={"transient": {"deleting": false}} outputId="a3ff95db-cb00-4d77-8e8f-2e7f1be164a8"
import joblib
from azureml.core.model import Model

#Get the best run.
best_run_hd = hd_run.get_best_run_by_primary_metric()
best_run_metrics_hd = best_run_hd.get_metrics()
print("Best Run Id: ", best_run_hd.id)
print("Accuracy: ", best_run_metrics_hd['accuracy'])

# + gather={"logged": 1598546657829} id="gdGE0_Cwfv0K" jupyter={"outputs_hidden": false, "source_hidden": false} nteract={"transient": {"deleting": false}} outputId="913705e5-28a3-44bc-d704-f49a1e8b8074"
#Save the best model.
model_hd = best_run_hd.register_model(model_name='hyperdrive_best_model', 
                                model_path='./outputs/model.pkl',
                                model_framework=Model.Framework.SCIKITLEARN, 
                                model_framework_version='0.19.1')
print("Model successfully saved.")

StarcoderdataJupyterScriptsDedupFiltered