<jupyter_start><jupyter_text>Automated Machine Learning with SAS Viya MLPA APIThis example leverages the [MLPA API on SAS Viya](https://developer.sas.com/apis/rest/MachineLearningPipeline/) to perform automated machine learning from an in memory data set loaded to CAS to a trained machine learning model. This final model is a result of a pipeline search and automated feature engineering. The example extends beyond the trained model in demonstrating publishing the model to a scoring environment and real time scoring using MAS, SAS’ realtime scoring environment.  Authentication -- optional stepIf you have registered a client (see the authentication use case), uncomment the code below to generate an access token.<jupyter_code># import requests, json, base64
# sasserver = ""
# username = ""
# password = ""
# client_id = ""
# client_secret = ""
# url = sasserver + "/SASLogon/oauth/token"
# data = {
#     'grant_type': 'password',
#     'username': username,
#     'password': password
# }
# headers = {'Accept': 'application/json'}
# response = requests.post(url, headers=headers, data=data, auth=(client_id, client_secret), verify=False).json()
# access_token = response["access_token"]
# print("The access token is: " + access_token)<jupyter_output><empty_output><jupyter_text>Import modules, variable assignmentThe first step of the process is to import the required packages and assign variable values.<jupyter_code>import requests, json, uuid, time

# Variables to assign
sasserver            = ''
datasetName          = 'hmeq'
target               = 'BAD'
publicUri            = '/dataTables/dataSources/cas~fs~cas-shared-default~fs~Public/tables/'
access_token        = ''<jupyter_output><empty_output><jupyter_text>Create a unique project name by append uuid to data set name.<jupyter_code>projectName = datasetName + "-" + str(uuid.uuid4())<jupyter_output><empty_output><jupyter_text>Create an Automated Machine Learning ProjectCreate MLPA project with a REST request. You can see project parameters printed below. Please note that there is no need to inspect these values in practice. This is for demonstration purposes only.<jupyter_code>tokenUri = "/mlPipelineAutomation/projects"
headers = {
    'Authorization': 'Bearer ' + access_token,
    'Accept': "application/vnd.sas.analytics.ml.pipeline.automation.project+json",
    'Content-Type': "application/json"
}
payload = {
    'dataTableUri': publicUri + datasetName,
    'type': 'predictive',
    'name': projectName,
    'description': 'Project generated for test',
    'settings': {
        'autoRun': True,
        'maxModelingTime': 15
    },
    'analyticsProjectAttributes': {
        'targetVariable': target
    }
}
payload_data = json.dumps(payload, indent=4)
response = requests.request("POST", sasserver + tokenUri, data=payload_data, headers=headers, verify=False)
response_txt = response.text

if response.status_code >= 400:
    print("Error in execute Rest Call with status_code: " + str(response.status_code))
    print(response_txt)

mlpaProject = json.loads(response_txt)
print(mlpaProject)

mlpa_proj_id = mlpaProject["id"]
print(mlpa_proj_id)<jupyter_output><empty_output><jupyter_text>Poll every 20 seconds until MLPA project state is completed**Note:** from time-to-time this step may hit a connection error. This does not mean the mlpa project is not still building / running.  Either re-run this step to pick up where the project is currently, or access SAS Model Studio for further details and progress.<jupyter_code>projectStateLink = list(filter(lambda x: x["rel"] == "state", mlpaProject["links"]))[0]
headers = {
    'Authorization': 'Bearer ' + access_token,
    'Accept': projectStateLink["type"]
}

attempts = 0
maxAttempts = 60*60/20
while True:
    attempts = attempts + 1
    projectState = requests.request(projectStateLink["method"], sasserver + projectStateLink["uri"], headers=headers).text
    print("Polling project state: Attempt " + str(attempts) + ", state is " + projectState)

    if projectState == "completed" or projectState == "failed" or attempts > maxAttempts:
        break;

    time.sleep(20)

print("Final MLPA project state is " + projectState + ', polled for approx ' + str(attempts*20/60) + ' minutes')<jupyter_output><empty_output><jupyter_text>Optional step to display settingsAs an optional post processing step, you can print settings and attributes of newly created MLPA project.<jupyter_code>for key, val in mlpaProject['settings'].items():
    print(key + '=' + str(val))
for key, val in mlpaProject['analyticsProjectAttributes'].items():
    print(key + '=' + str(val))<jupyter_output><empty_output><jupyter_text>Get Champion ModelGet the champion model i.e. the model that performs best based on the default performance criterion for this type of machine learning problem<jupyter_code>tokenUri = "/mlPipelineAutomation/projects/" + mlpaProject["id"] + "/championModel"
headers = {
    'authorization': 'Bearer ' + access_token,
    'Content-type': "application/vnd.sas.analytics.ml.pipeline.automation.project.champion.model+json"
}


fullResponse=False
response = requests.request('GET', sasserver + tokenUri, json=[], headers=headers)
response_txt = response.text

if response.status_code >= 400:
    print("Error in executing Rest Call with status_code: " + str(response.status_code))
    print(response_txt)

if fullResponse:
    response,champModel =  response, json.loads(response_txt)
else:
    champModel = json.loads(response_txt)

print('Champion model is ' + champModel['championModelName'])<jupyter_output><empty_output><jupyter_text>Model Deployment and ScoringPublish champion model to MAS (maslocal destination). Please note that you should have licensed the Model Manager product to utilize this end point. Otherwise, you could score new data either as individual instances or batch in CAS.<jupyter_code>headers = {
    'authorization': 'Bearer ' + access_token
}

publishChampModelResponse = requests.request(
    "PUT",
    sasserver + tokenUri + "/" + "?action=publish&destinationName=maslocal",
    json=[],
    headers=headers)

print(publishChampModelResponse)

if publishChampModelResponse.status_code == 200:
    print("Publishing champion model to MAS (maslocal destination) successful")
else:
    print("Error in publish champion model call, status_code: " + str(publishChampModelResponse.status_code))
    print(publishChampModelResponse.text)<jupyter_output><empty_output><jupyter_text>Score new dataOnce the model deployment is complete, just test the deployment with new data as shown below.<jupyter_code>scoreDatalLink = list(filter(lambda x: x["rel"] == 'scoreData', champModel["links"]))[0]
headers = {
    'authorization': 'Bearer ' + access_token,
    'Content-type': scoreDatalLink["type"] + "+json"
}
scoreRow = {
    "scoreType": "Individual",
    "destinationName" : "maslocal",
    "inputs": [
        {"name": "CLAGE", "value": 300},
        {"name": "CLNO", "value": 21},
        {"name": "DEBTINC", "value": 24.5},
        {"name": "DELINQ", "value": 0},
        {"name": "DEROG", "value": 1},
        {"name": "JOB", "value": "Other"},
        {"name": "REASON", "value": "DebtCon"},
        {"name": "LOAN", "value": 21500},
        {"name": "MORTDUE", "value": 7806},
        {"name": "NINQ", "value": 4},
        {"name": "VALUE", "value": 95678},
        {"name": "YOJ", "value": 4}
    ]
}

response = requests.request(scoreDatalLink["method"], sasserver + scoreDatalLink["uri"], json=scoreRow, headers=headers)
response_txt = response.text
fullResponse=False

if response.status_code >= 400:
    print("Error in executing rest call with status_code: " + str(response.status_code))
    print(response_txt)

if fullResponse:
    fullResponse, scoredData =  response, json.loads(response_txt)
else:
    scoredData =  json.loads(response_txt)



for itm in scoredData["outputs"]:
    if "value" in itm:
        print(itm["name"] + ": " + str(itm["value"]))<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.12238244514106583, 'fraction_numerical': 0.007774294670846395, 'mean_word_length': 4.847507331378299, 'pattern_counts': {'":': 27, '<': 37, '<?xml version=': 0, '>': 41, 'https://': 1, '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': '446387', 'license': 'Apache-2.0', 'n_tokens_mistral': 2422, 'n_tokens_neox': 2340, 'n_words': 679, 'path': 'python/auto-machine-learning/auto-machine-learning.ipynb', 'repo_name': 'sassoftware/rest-api-use-cases', 'size': '7975'}