{"id":764,"date":"2021-01-20T03:01:55","date_gmt":"2021-01-20T03:01:55","guid":{"rendered":"https:\/\/salarydistribution.com\/machine-learning\/2021\/01\/20\/automating-amazon-personalize-solution-using-the-aws-step-functions-data-science-sdk\/"},"modified":"2021-01-20T03:01:55","modified_gmt":"2021-01-20T03:01:55","slug":"automating-amazon-personalize-solution-using-the-aws-step-functions-data-science-sdk","status":"publish","type":"post","link":"https:\/\/salarydistribution.com\/machine-learning\/2021\/01\/20\/automating-amazon-personalize-solution-using-the-aws-step-functions-data-science-sdk\/","title":{"rendered":"Automating Amazon Personalize solution using the AWS Step Functions Data Science SDK"},"content":{"rendered":"<div id=\"\">\n<p>Machine learning (ML)-based recommender systems aren\u2019t a new concept across organizations such as retail, media and entertainment, and education, but developing such a system can be a resource-intensive task\u2014from data labelling, training and inference, to scaling. You also need to apply continuous integration, continuous deployment, and continuous training to your ML model, or MLOps. The MLOps model helps build code and integration across ML tools and frameworks. Moreover, building a recommender system requires managing and orchestrating multiple workflows, for example waiting for your training jobs to finish and trigger deployments.<\/p>\n<p>In this post, we show you how to use <a href=\"https:\/\/aws.amazon.com\/personalize\/\" target=\"_blank\" rel=\"noopener noreferrer\">Amazon Personalize<\/a> to create a serverless recommender system for movie recommendations with no ML experience required. Creating an Amazon Personalize solution workflow involves multiple steps, such as<a href=\"https:\/\/docs.aws.amazon.com\/personalize\/latest\/dg\/data-prep.html\" target=\"_blank\" rel=\"noopener noreferrer\"> preparing and importing the data<\/a>, <a href=\"https:\/\/docs.aws.amazon.com\/personalize\/latest\/dg\/working-with-predefined-recipes.html\" target=\"_blank\" rel=\"noopener noreferrer\">choosing a recipe<\/a> and <a href=\"https:\/\/docs.aws.amazon.com\/personalize\/latest\/dg\/training-deploying-solutions.html\" target=\"_blank\" rel=\"noopener noreferrer\">creating a solution<\/a> and finally generating recommendations. End-users or your data scientists can orchestrate these steps using <a href=\"http:\/\/aws.amazon.com\/lambda\" target=\"_blank\" rel=\"noopener noreferrer\">AWS Lambda<\/a> functions and <a href=\"http:\/\/aws.amazon.com\/step-functions\" target=\"_blank\" rel=\"noopener noreferrer\">AWS Step Functions<\/a>. However, writing JSON code to manage such workflows can be complicated for your data scientists.<\/p>\n<p>You can orchestrate an Amazon Personalize workflow using the <a href=\"https:\/\/docs.aws.amazon.com\/step-functions\/latest\/dg\/concepts-python-sdk.html\" target=\"_blank\" rel=\"noopener noreferrer\">AWS Step Functions Data Science SDK for Python<\/a> using an <a href=\"https:\/\/aws.amazon.com\/sagemaker\/\" target=\"_blank\" rel=\"noopener noreferrer\">Amazon SageMaker<\/a> Jupyter notebook. The AWS Step Functions Data Science SDK is an open-source library that allows data scientists to easily create workflows that process and publish ML models using Amazon SageMaker Jupyter notebooks and Step Functions. You can create multi-step ML workflows in Python that orchestrate AWS infrastructure at scale, without having to provision and integrate the AWS services separately.<\/p>\n<h2>Solution and services overview<\/h2>\n<p>We have orchestrated the Amazon Personalize training workflow steps such as<a href=\"https:\/\/docs.aws.amazon.com\/personalize\/latest\/dg\/data-prep.html\" target=\"_blank\" rel=\"noopener noreferrer\"> preparing and importing the data<\/a>, <a href=\"https:\/\/docs.aws.amazon.com\/personalize\/latest\/dg\/working-with-predefined-recipes.html\" target=\"_blank\" rel=\"noopener noreferrer\">choosing a recipe<\/a> and <a href=\"https:\/\/docs.aws.amazon.com\/personalize\/latest\/dg\/training-deploying-solutions.html\" target=\"_blank\" rel=\"noopener noreferrer\">creating a solution<\/a> using AWS Step functions and AWS lambda functions to create a below Amazon Personalize end to end automated workflow:<\/p>\n<p><img decoding=\"async\" loading=\"lazy\" class=\"alignnone size-full wp-image-20616\" src=\"https:\/\/d2908q01vomqb2.cloudfront.net\/f1f836cb4ea6efb2a0b1b99f41ad8b103eff4b59\/2021\/01\/12\/ML-1267-1.jpg\" alt=\"AWS Step functions and AWS lambda functions to create a below Amazon Personalize end to end automated workflow:\" width=\"800\" height=\"102\"><\/p>\n<p>We walk you through the below steps using the accompanying<a href=\"https:\/\/github.com\/aws-samples\/personalize-data-science-sdk-workflow\/blob\/master\/Personalize-Stepfunction-Workflow.ipynb\" target=\"_blank\" rel=\"noopener noreferrer\"> Amazon SageMaker Jupyter notebook<\/a>. In order to create the above Amazon Personalize workflow, we are going to follow below detailed steps:<\/p>\n<ol>\n<li>Complete the prerequisites of setting up permissions and preparing the dataset.<\/li>\n<li>Set up AWS Lambda function and AWS Step function task states.<\/li>\n<li>Add wait conditions to each AWS Step function task states.<\/li>\n<li>Add a control flow and link the states.<\/li>\n<li>Define and run the workflows by combining all the above steps.<\/li>\n<li>Generate recommendations.<\/li>\n<\/ol>\n<h2>Prerequisites<\/h2>\n<p>Before you build your workflow and generate recommendations, you must set up a notebook instance, <a href=\"http:\/\/aws.amazon.com\/iam\" target=\"_blank\" rel=\"noopener noreferrer\">AWS Identity and Access Management<\/a> (IAM) roles, and create an <a href=\"http:\/\/aws.amazon.com\/s3\" target=\"_blank\" rel=\"noopener noreferrer\">Amazon Simple Storage Service<\/a> (Amazon S3) bucket.<\/p>\n<h3>Creating a notebook instance in Amazon SageMaker<\/h3>\n<p>Create an Amazon SageMaker notebook Instance by following instructions <a href=\"https:\/\/docs.aws.amazon.com\/sagemaker\/latest\/dg\/gs-setup-working-env.html\" target=\"_blank\" rel=\"noopener noreferrer\">here<\/a>. For creating IAM role for your notebook, make sure your notebook IAM role has AmazonS3FullAccess and\u00a0AmazonPersonalizeFullAccess in order to access Amazon S3 and Amazon Personalize APIs through the Sagemaker notebook.<\/p>\n<ol>\n<li>When the notebook is active, choose Open Jupyter.<\/li>\n<li>On the Jupyter dashboard, choose New.<\/li>\n<li>Choose Terminal.<\/li>\n<li>In the terminal, enter the following code:\n<div class=\"hide-language\">\n<div class=\"hide-language\">\n<pre class=\"unlimited-height-code\"><code class=\"lang-python\">cd SageMaker \r\ngit clone https:\/\/github.com\/aws-samples\/personalize-data-science-sdk-workflow.git<\/code><\/pre>\n<\/p><\/div>\n<\/p><\/div>\n<\/li>\n<\/ol>\n<ol start=\"5\">\n<li>Open the notebook by choosing Personalize-Stepfunction-Workflow.ipynb in the root folder.<\/li>\n<\/ol>\n<p>You\u2019re now ready to run the following steps through the notebook cells. You can find the complete notebook for this solution in the <a href=\"https:\/\/github.com\/aws-samples\/personalize-data-science-sdk-workflow\/blob\/master\/Personalize-Stepfunction-Workflow.ipynb\" target=\"_blank\" rel=\"noopener noreferrer\">GitHub repo<\/a>.<\/p>\n<h3>Setting up Step Function Execution role<\/h3>\n<p>You need a Step Functions execution role so that you can create and invoke workflows in Step Functions. For instructions, see <a href=\"https:\/\/docs.aws.amazon.com\/step-functions\/latest\/dg\/procedure-create-iam-role.html#create-role-for-step-functions\" target=\"_blank\" rel=\"noopener noreferrer\">Create a role for Step Functions<\/a> or go through the steps in the notebook <a href=\"https:\/\/github.com\/aws-samples\/amazon-personalize-samples\/blob\/master\/next_steps\/operations\/ml_ops_ds_sdk\/Personalize-Stepfunction-Workflow.ipynb\" target=\"_blank\" rel=\"noopener noreferrer\">Create an execution role for Step Functions<\/a>.<\/p>\n<p><a href=\"https:\/\/docs.aws.amazon.com\/step-functions\/latest\/dg\/procedure-create-iam-role.html#attach-inline-policy\" target=\"_blank\" rel=\"noopener noreferrer\">Attach an inline policy<\/a> to the role you created for notebook instance in previous step. Enter the <strong>JSON policy<\/strong> by copying the policy from the notebook.<\/p>\n<h3><strong>Preparing your dataset<\/strong><\/h3>\n<p>To prepare your dataset, complete the following steps:<\/p>\n<ol>\n<li>Create an S3 bucket to store the training dataset and provide the bucket name and file name as \u2019movie-lens-100k.csv\u2019 in the <a href=\"https:\/\/github.com\/aws-samples\/personalize-data-science-sdk-workflow\/blob\/master\/Personalize-Stepfunction-Workflow.ipynb\" target=\"_blank\" rel=\"noopener noreferrer\">notebook<\/a> step Setup S3 location and filename. See the following code:\n<div class=\"hide-language\">\n<pre><code class=\"lang-bash\">bucket = \"<em><span>&lt;<strong>SAMPLE BUCKET NAME<\/strong>&gt;<\/span><\/em>\" # replace with the name of your S3 bucket\r\nfilename = \"<em><span>&lt;<strong>SAMPLE FILE NAME<\/strong>&gt;<\/span><\/em>\" # replace with a name that you want to save the dataset under<\/code><\/pre>\n<\/p><\/div>\n<\/li>\n<\/ol>\n<ol start=\"2\">\n<li>Attach the policy to the S3 bucket by running the Attach policy to Amazon S3 bucket step in the notebook.<\/li>\n<li>Create an IAM role for Amazon Personalize by running the Create Personalize Role step in the <a href=\"https:\/\/github.com\/aws-samples\/personalize-data-science-sdk-workflow\/blob\/master\/Personalize-Stepfunction-Workflow.ipynb\" target=\"_blank\" rel=\"noopener noreferrer\">notebook<\/a> using Python boto3 <a href=\"https:\/\/boto3.amazonaws.com\/v1\/documentation\/api\/latest\/reference\/services\/iam.html\" target=\"_blank\" rel=\"noopener noreferrer\">create_role API<\/a>.<\/li>\n<\/ol>\n<ol start=\"4\">\n<li>To preprocess the dataset and upload to Amazon S3, run the Data-Preparation step of the following notebook cell to download the <a href=\"http:\/\/files.grouplens.org\/datasets\/movielens\/ml-100k.zip\" target=\"_blank\" rel=\"noopener noreferrer\">movie-lens<\/a> dataset and select the movies that have a rating of 2 or above from the dataset:\n<div class=\"hide-language\">\n<pre><code class=\"lang-bash\">!wget -N http:\/\/files.grouplens.org\/datasets\/movielens\/ml-100k.zip\r\n!unzip -o ml-100k.zip\r\ndata = pd.read_csv('.\/ml-100k\/u.data', sep='t', names=['USER_ID', 'ITEM_ID', 'RATING', 'TIMESTAMP'])\r\npd.set_option('display.max_rows', 5)\r\ndata<\/code><\/pre>\n<\/p><\/div>\n<\/li>\n<\/ol>\n<p>The following screenshot shows your output.<\/p>\n<p><img decoding=\"async\" loading=\"lazy\" class=\"alignnone size-full wp-image-20617\" src=\"https:\/\/d2908q01vomqb2.cloudfront.net\/f1f836cb4ea6efb2a0b1b99f41ad8b103eff4b59\/2021\/01\/12\/ML-1267-2.jpg\" alt=\"The following screenshot shows your output.\" width=\"592\" height=\"317\"><\/p>\n<ol start=\"5\">\n<li>Run the following code to upload your data to the S3 bucket that you created before:\n<div class=\"hide-language\">\n<pre><code class=\"lang-bash\">data = data[data['RATING'] &gt; 2] # keep only movies rated 2 and above\r\ndata2 = data[['USER_ID', 'ITEM_ID', 'TIMESTAMP']] \r\ndata2.to_csv(filename, index=False)\r\n\r\nboto3.Session().resource('s3').Bucket(bucket).Object(filename).upload_file(filename)<\/code><\/pre>\n<\/p><\/div>\n<\/li>\n<\/ol>\n<h2>Set up AWS Lambda function and AWS Step function task states.<\/h2>\n<p>After you complete the prerequisite steps, you would need do to below:<\/p>\n<ol>\n<li>Setup Lambda functions in the AWS Console: You need to setup AWS Lambda function for each Amazon Personalize tasks such as creating a dataset, choosing a recipe and creating a solution using <a href=\"https:\/\/docs.aws.amazon.com\/personalize\/latest\/dg\/getting-started-python.html\" target=\"_blank\" rel=\"noopener noreferrer\">Amazon Personalize AWS SDK for Python (Boto3)<\/a>. With the Python code provided in the <a href=\"https:\/\/github.com\/aws-samples\/personalize-data-science-sdk-workflow\/tree\/master\/lambda\" target=\"_blank\" rel=\"noopener noreferrer\">Lambda GitHub repo<\/a>. This repository has python code for various lambda functions, you need to copy the code and create lambda functions following the steps in this documentation \u201c<a href=\"https:\/\/docs.aws.amazon.com\/lambda\/latest\/dg\/lambda-python.html\" target=\"_blank\" rel=\"noopener noreferrer\">build a Lambda function on the Lambda console<\/a>.\u201d<\/li>\n<\/ol>\n<p><strong>Note<\/strong>: While creating an execution role, make sure you provide <code>AmazonPersonalizeFullAccess<\/code> along with <code>AWSLambdaBasicExecutionRole<\/code> permission policy to the lambda role.<\/p>\n<ol start=\"2\">\n<li>Orchestrate each of these lambda function as <a href=\"https:\/\/docs.aws.amazon.com\/step-functions\/latest\/dg\/amazon-states-language-task-state.html\" target=\"_blank\" rel=\"noopener noreferrer\">AWS Step function task states<\/a>: A\u00a0Task\u00a0state represents a single unit of work performed by a state machine. AWS Step Functions can invoke Lambda functions directly from a task state. For more information see <a href=\"https:\/\/docs.aws.amazon.com\/step-functions\/latest\/dg\/tutorial-creating-lambda-state-machine.html\" target=\"_blank\" rel=\"noopener noreferrer\">Creating a Step Functions State Machine That Uses Lambda<\/a>. Below is a step function workflow diagram to orchestrate the lambda functions we are going to cover in this section:<\/li>\n<\/ol>\n<p><img decoding=\"async\" loading=\"lazy\" class=\"alignnone size-full wp-image-20618\" src=\"https:\/\/d2908q01vomqb2.cloudfront.net\/f1f836cb4ea6efb2a0b1b99f41ad8b103eff4b59\/2021\/01\/12\/ML-1267-3.jpg\" alt=\"Below is a step function workflow diagram to orchestrate the lambda functions we are going to cover in this section:\" width=\"721\" height=\"669\"><\/p>\n<p>We already created Lambda functions for each of the Amazon Personalize steps using the <a href=\"https:\/\/docs.aws.amazon.com\/personalize\/latest\/dg\/getting-started-python.html\" target=\"_blank\" rel=\"noopener noreferrer\">Amazon Personalize AWS SDK for Python (Boto3)<\/a> with the Python code provided in the <a href=\"https:\/\/github.com\/aws-samples\/personalize-data-science-sdk-workflow\/tree\/master\/lambda\" target=\"_blank\" rel=\"noopener noreferrer\">Lambda GitHub repo<\/a>. We deep dive and explain each step in this section. Alternatively, you can <a href=\"https:\/\/docs.aws.amazon.com\/lambda\/latest\/dg\/lambda-python.html\" target=\"_blank\" rel=\"noopener noreferrer\">build a Lambda function on the Lambda console<\/a>.<\/p>\n<h3>Creating a schema<\/h3>\n<p>Before you add a dataset to Amazon Personalize, you must define a schema for that dataset. For more information, see <a href=\"https:\/\/docs.aws.amazon.com\/personalize\/latest\/dg\/how-it-works-dataset-schema.html\" target=\"_blank\" rel=\"noopener noreferrer\">Datasets and Schemas<\/a>. First we would create a step function task state to create a schema using below code in the <a href=\"https:\/\/github.com\/aws-samples\/personalize-data-science-sdk-workflow\/blob\/master\/Personalize-Stepfunction-Workflow.ipynb\" target=\"_blank\" rel=\"noopener noreferrer\">walkthrough notebook<\/a>.<\/p>\n<div class=\"hide-language\">\n<pre><code class=\"lang-python\">lambda_state_schema = LambdaStep(\r\n    state_id=\"create schema\",\r\n    parameters={  \r\n        \"FunctionName\": \"stepfunction-create-schema\", #replace with the name of the function you created\r\n        \"Payload\": {  \r\n           \"input\": \"personalize-stepfunction-schema\"\r\n        }\r\n    },\r\n    result_path='$'    \r\n)<\/code><\/pre>\n<\/p><\/div>\n<p>The above step function is invoking the AWS lambda function Lambda function <a href=\"https:\/\/github.com\/aws-samples\/personalize-data-science-sdk-workflow\/blob\/master\/lambda\/stepfunction-create-schema.py\" target=\"_blank\" rel=\"noopener noreferrer\">stepfunction-create-schema.py<\/a>. This lambda code snippet above is uses <a href=\"https:\/\/boto3.amazonaws.com\/v1\/documentation\/api\/latest\/reference\/services\/personalize.html#Personalize.Client.create_schema\" target=\"_blank\" rel=\"noopener noreferrer\">Personalize.create_schema() boto 3 APIs<\/a> to create schema.<\/p>\n<div class=\"hide-language\">\n<pre><code class=\"lang-python\">import boto3\r\n\r\nclient = boto3.client('personalize')\r\ncreate_schema_response = personalize.create_schema(\r\n        name = event['input'],\r\n        schema = json.dumps(schema)\r\n    )<\/code><\/pre>\n<\/p><\/div>\n<p>This API creates an Amazon Personalize schema from the specified schema string. The schema you create must be in Avro JSON format.<\/p>\n<h3>Creating a dataset group<\/h3>\n<p>After you create a schema, similarly, we are going to create a step function task states for creating a dataset group .A dataset group contains related datasets that supply data for training a model. A dataset group can contain at most three datasets, one for each type of dataset: Interactions, Items and Users.<\/p>\n<p>To train a model (create a solution), you need a dataset group that contains an Interactions dataset.<\/p>\n<p>Run the notebook steps to create state id \u201ccreate dataset\u201d below:<\/p>\n<div class=\"hide-language\">\n<pre><code class=\"lang-python\">lambda_state_createdataset = LambdaStep(\r\n    state_id=\"create dataset\",\r\n    parameters={  \r\n        \"FunctionName\": \"stepfunctioncreatedataset\", #replace with the name of the function you created\r\n        \r\n        \"Payload\": {  \r\n           \"schemaArn.$\": '$.schemaArn',\r\n           \"datasetGroupArn.$\": '$.datasetGroupArn',        \r\n        } \r\n        \r\n        \r\n    },\r\n    result_path = '$'\r\n)<\/code><\/pre>\n<\/p><\/div>\n<p>The above step function task state is invoking the AWS lambda function <a href=\"https:\/\/github.com\/aws-samples\/personalize-data-science-sdk-workflow\/blob\/master\/lambda\/stepfunctioncreatedatagroup.py\" target=\"_blank\" rel=\"noopener noreferrer\">stepfunctioncreatedatagroup.py<\/a>. Below is a code snippet of using <a href=\"https:\/\/boto3.amazonaws.com\/v1\/documentation\/api\/latest\/reference\/services\/personalize.html#Personalize.Client.create_dataset\" target=\"_blank\" rel=\"noopener noreferrer\">personalize.create_dataset()<\/a> to create a dataset:<\/p>\n<div class=\"hide-language\">\n<pre><code class=\"lang-python\">create_dataset_response = personalize.create_dataset(\r\n\r\nname = \"personalize-stepfunction-dataset\",\r\n\r\ndatasetType = dataset_type,\r\n\r\ndatasetGroupArn = event['datasetGroupArn'],\r\n\r\nschemaArn = event['schemaArn']\r\n\r\n)<\/code><\/pre>\n<\/p><\/div>\n<p>This API creates an empty dataset and adds it to the specified dataset group.<\/p>\n<h3>Creating a dataset<\/h3>\n<p>In this step, you create a step function task state for automating an empty dataset and add it to the specified dataset group.<\/p>\n<p>Run through the notebook steps to <a href=\"https:\/\/github.com\/aws-samples\/personalize-data-science-sdk-workflow\/blob\/master\/Personalize-Stepfunction-Workflow.ipynb\" target=\"_blank\" rel=\"noopener noreferrer\">create a dataset<\/a> step function. You can review the underlying AWS Lambda function <a href=\"https:\/\/github.com\/aws-samples\/personalize-data-science-sdk-workflow\/blob\/master\/lambda\/stepfunctioncreatedataset.py\" target=\"_blank\" rel=\"noopener noreferrer\">stepfunctioncreatedataset.py<\/a>. We use the same API <a href=\"https:\/\/boto3.amazonaws.com\/v1\/documentation\/api\/latest\/reference\/services\/personalize.html#Personalize.Client.create_dataset\" target=\"_blank\" rel=\"noopener noreferrer\">personalize.create_dataset<\/a> Python boto3 API to automate dataset creation which we used to create a dataset group in above step.<\/p>\n<h3>Importing your data<\/h3>\n<p>When you complete <a href=\"https:\/\/docs.aws.amazon.com\/personalize\/latest\/dg\/data-prep-ds-group.html\" target=\"_blank\" rel=\"noopener noreferrer\">Step 1: Creating a Dataset Group<\/a> and <a href=\"https:\/\/docs.aws.amazon.com\/personalize\/latest\/dg\/data-prep-creating-datasets.html\" target=\"_blank\" rel=\"noopener noreferrer\">Step 2: Creating a Dataset and a Schema<\/a>, you\u2019re ready to import your training data into Amazon Personalize. When you import data, you can choose to import records in bulk, import records individually, or both, depending on your business requirements and the amount of historical data you have collected. If you have a large amount of historical records, we recommend you import data in bulk and add data incrementally as necessary.<\/p>\n<p>Run through the <a href=\"https:\/\/github.com\/aws-samples\/personalize-data-science-sdk-workflow\/blob\/master\/Personalize-Stepfunction-Workflow.ipynb\" target=\"_blank\" rel=\"noopener noreferrer\">notebook steps<\/a> to create a step functions task state to <a href=\"https:\/\/github.com\/aws-samples\/personalize-data-science-sdk-workflow\/blob\/master\/Personalize-Stepfunction-Workflow.ipynb\" target=\"_blank\" rel=\"noopener noreferrer\">import a dataset<\/a> with state_id=\u201dcreate dataset import job\u201d. Let\u2019s review the code snippet for underlying Lambda function <a href=\"https:\/\/github.com\/aws-samples\/personalize-data-science-sdk-workflow\/blob\/master\/lambda\/stepfunction-createdatasetimportjob.py\" target=\"_blank\" rel=\"noopener noreferrer\">stepfunction-createdatasetimportjob.py<\/a>.<\/p>\n<div class=\"hide-language\">\n<pre><code class=\"lang-python\">create_dataset_import_job_response = personalize.create_dataset_import_job(\r\n\r\njobName = \"stepfunction-dataset-import-job\",\r\n\r\ndatasetArn = datasetArn,\r\n\r\ndataSource = {\r\n\r\n\"dataLocation\": \"s3:\/\/{}\/{}\".format(bucket, filename)\r\n\r\n},\r\n\r\nroleArn = roleArn\r\n\r\n)<\/code><\/pre>\n<\/p><\/div>\n<p>We are using <a href=\"https:\/\/boto3.amazonaws.com\/v1\/documentation\/api\/latest\/reference\/services\/personalize.html#Personalize.Client.create_dataset_import_job\" target=\"_blank\" rel=\"noopener noreferrer\">personalize.create_dataset_import_job()<\/a> boto3 APIs to import the dataset in the above lambda code. This API creates a job that imports training data from your data source (an Amazon S3 bucket) to an Amazon Personalize dataset.<\/p>\n<h3>Creating a solution<\/h3>\n<p>After you <a href=\"https:\/\/docs.aws.amazon.com\/personalize\/latest\/dg\/data-prep.html\" target=\"_blank\" rel=\"noopener noreferrer\">prepare and import the data<\/a>, you\u2019re ready to create a solution. A solution refers to the combination of an Amazon Personalize recipe, customized parameters, and one or more solution versions (trained models). A <em>recipe<\/em> is an Amazon Personalize term specifying an appropriate algorithm to train for a given use case. After you create a solution with a solution version, you can <a href=\"https:\/\/docs.aws.amazon.com\/personalize\/latest\/dg\/campaigns.html\" target=\"_blank\" rel=\"noopener noreferrer\">create a campaign<\/a> to deploy the solution version and get recommendations. We will create a step function task states for choosing a recipe and creating a solution.<\/p>\n<h3>Choosing a recipe, configuring a solution and creating a solution version<\/h3>\n<p>Run the <a href=\"https:\/\/github.com\/aws-samples\/personalize-data-science-sdk-workflow\/blob\/master\/lambda\/stepfunction_create_solution_version.py\" target=\"_blank\" rel=\"noopener noreferrer\">notebook cell<\/a> Choose a recipe to create a step function task state to generate state ID state_id=\u201dselect recipe and create solution\u201d. This state is representing the AWS lambda function \u00a0<a href=\"https:\/\/github.com\/aws-samples\/personalize-data-science-sdk-workflow\/blob\/master\/lambda\/stepfunction_select-recipe_create-solution.py\" target=\"_blank\" rel=\"noopener noreferrer\">stepfunction_select-recipe_create-solution.py<\/a>. Below is the code snippet:<\/p>\n<div class=\"hide-language\">\n<pre><code class=\"lang-python\">list_recipes_response = personalize.list_recipes()\r\n\r\nrecipe_arn = \"arn:aws:personalize:::recipe\/aws-user-personalization\" # aws-user-personalization selected for demo purposes\r\n\r\n#list_recipes_response\r\n  create_solution_response = personalize.create_solution(\r\n\r\nname = \"stepfunction-solution\",\r\n\r\ndatasetGroupArn = event['dataset_group_arn'],\r\n\r\nrecipeArn = recipe_arn\r\n\r\n)<\/code><\/pre>\n<\/p><\/div>\n<p>We are using <a href=\"https:\/\/boto3.amazonaws.com\/v1\/documentation\/api\/latest\/reference\/services\/personalize.html#Personalize.Client.list_recipes\" target=\"_blank\" rel=\"noopener noreferrer\">personalize.list_recipes()<\/a> boto3 APIs to return a list of available recipes and <a href=\"https:\/\/boto3.amazonaws.com\/v1\/documentation\/api\/latest\/reference\/services\/personalize.html#Personalize.Client.create_solution\" target=\"_blank\" rel=\"noopener noreferrer\">personalize.craete_solution()<\/a> boto 3 API to create the configuration for training a model. A trained model is known as a solution.<\/p>\n<p>We use the algorithm <a href=\"https:\/\/docs.aws.amazon.com\/personalize\/latest\/dg\/native-recipe-new-item-USER_PERSONALIZATION.html\" target=\"_blank\" rel=\"noopener noreferrer\"><code>aws-user-personalization<\/code><\/a> for this post. For more information, see <a href=\"https:\/\/docs.aws.amazon.com\/personalize\/latest\/dg\/working-with-predefined-recipes.html\" target=\"_blank\" rel=\"noopener noreferrer\">Choosing a Recipe<\/a> and <a href=\"https:\/\/docs.aws.amazon.com\/personalize\/latest\/dg\/customizing-solution-config.html\" target=\"_blank\" rel=\"noopener noreferrer\">\u00a0Configuring a Solution<\/a>.<\/p>\n<p>After you choose a recipe and configure your solution, you\u2019re ready to create a solution version, which refers to a trained ML model.<\/p>\n<p>Run the <a href=\"https:\/\/github.com\/aws-samples\/personalize-data-science-sdk-workflow\/blob\/master\/Personalize-Stepfunction-Workflow.ipynb\" target=\"_blank\" rel=\"noopener noreferrer\">notebook cell<\/a> Create Solution Version to create a step function task state with the State ID state_id=\u201d create solution version\u201d and recipes using the underlying Lambda function <a href=\"https:\/\/github.com\/aws-samples\/personalize-data-science-sdk-workflow\/blob\/master\/lambda\/stepfunction_create_solution_version.py\" target=\"_blank\" rel=\"noopener noreferrer\">stepfunction_create_solution_version.py<\/a>. Below is the lambda code snippet using <a href=\"https:\/\/boto3.amazonaws.com\/v1\/documentation\/api\/latest\/reference\/services\/personalize.html#Personalize.Client.create_solution_version\" target=\"_blank\" rel=\"noopener noreferrer\">personalize.create_solution_version()<\/a> boto3 API which trains or retrains an active solution.<\/p>\n<div class=\"hide-language\">\n<pre><code class=\"lang-python\">create_solution_version_response = personalize.create_solution_version(\r\n\r\n\r\nsolutionArn = event['solution_arn']\r\n\r\n)<\/code><\/pre>\n<\/p><\/div>\n<p>A solution is created using the CreateSolution operation and must be in the ACTIVE state before calling CreateSolutionVersion . A new version of the solution is created every time you call this operation. For more information, see <a href=\"https:\/\/docs.aws.amazon.com\/personalize\/latest\/dg\/creating-a-solution-version.html\" target=\"_blank\" rel=\"noopener noreferrer\">Creating a Solution Version<\/a>.<\/p>\n<h3>Creating a campaign<\/h3>\n<p>A campaign is used to make recommendations for your users. You create a campaign by deploying a solution version.<\/p>\n<p>Run the <a href=\"https:\/\/github.com\/aws-samples\/personalize-data-science-sdk-workflow\/blob\/master\/Personalize-Stepfunction-Workflow.ipynb\" target=\"_blank\" rel=\"noopener noreferrer\">notebook cell<\/a> Create Campaign to create step function task state with the state ID state_id=\u201d create campaign\u201d using the underlying Lambda function <a href=\"https:\/\/github.com\/aws-samples\/personalize-data-science-sdk-workflow\/blob\/master\/lambda\/stepfunction_getsolution_metric_create_campaign.py\" target=\"_blank\" rel=\"noopener noreferrer\">stepfunction_getsolution_metric_create_campaign.py<\/a>. This lambda is using below API<\/p>\n<div class=\"hide-language\">\n<pre><code class=\"lang-python\">get_solution_metrics_response = personalize.get_solution_metrics(\r\n        solutionVersionArn = event['solution_version_arn']\r\n    )\r\n\r\n    create_campaign_response = personalize.create_campaign(\r\n        name = \"stepfunction-campaign\",\r\n        solutionVersionArn = event['solution_version_arn'],\r\n        minProvisionedTPS = 1\r\n    )<\/code><\/pre>\n<\/p><\/div>\n<p><a href=\"https:\/\/boto3.amazonaws.com\/v1\/documentation\/api\/latest\/reference\/services\/personalize.html#Personalize.Client.get_solution_metrics\" target=\"_blank\" rel=\"noopener noreferrer\">personalize.get_solution_metrics()<\/a> gets the metrics for the specified solution version and <a href=\"https:\/\/boto3.amazonaws.com\/v1\/documentation\/api\/latest\/reference\/services\/personalize.html#Personalize.Client.create_campaign\" target=\"_blank\" rel=\"noopener noreferrer\">personalize.create_campaign()<\/a> creates a campaign by deploying a solution version.<\/p>\n<p>In this section, we covered all the Step function task states and their AWS lambda functions needed to orchestrate the Amazon Personalize workflow. Go to next section to add the wait states to these step function states.<\/p>\n<h2>Adding a wait state to your steps<\/h2>\n<p>In this section, we add wait states because these steps need to wait for previous steps to finish before running the next step. For example, you should create a dataset after you create a dataset group.<\/p>\n<p>Run the notebook steps from Wait for Schema to be ready to Wait for Campaign to be ACTIVE to make sure these Step Functions or Lambda steps are waiting for each step to run before they trigger the next step.<\/p>\n<p>The following code is an example of what a wait state looks like to wait for the schema to be created:<\/p>\n<div class=\"hide-language\">\n<pre><code class=\"lang-python\">wait_state_schema = Wait(\r\n    state_id=\"Wait for create schema - 5 secs\",\r\n    seconds=5\r\n)<\/code><\/pre>\n<\/p><\/div>\n<p>We added a wait time of 5 seconds for the state ID, which means it should wait for 5 seconds before going to next state.<\/p>\n<h2>Adding a control flow and linking states by using the choice state<\/h2>\n<p>The AWS Step Functions Data Science SDK\u2019s <a href=\"https:\/\/aws-step-functions-data-science-sdk.readthedocs.io\/en\/stable\/states.html#stepfunctions.steps.states.Choice\" target=\"_blank\" rel=\"noopener noreferrer\">choice state<\/a> supports branching logic based on the outputs from previous steps. You can create dynamic and complex workflows by adding this state.<\/p>\n<p>After you define these steps, chain them together into a logical sequence. Run all the notebook steps to add choices while automating Amazon Personalize datasets, recipes, solutions, and the campaign.<\/p>\n<p>The following code is an example of the choice state for the create_campaign workflow:<\/p>\n<div class=\"hide-language\">\n<pre><code class=\"lang-python\">create_campaign_choice_state = Choice(\r\n    state_id=\"Is the Campaign ready?\"\r\n)\r\ncreate_campaign_choice_state.add_choice(\r\n    rule=ChoiceRule.StringEquals(variable=lambda_state_campaign_status.output()['Payload']['status'], value='ACTIVE'),\r\n    next_step=Succeed(\"CampaignCreatedSuccessfully\")     \r\n)\r\ncreate_campaign_choice_state.add_choice(\r\n    ChoiceRule.StringEquals(variable=lambda_state_campaign_status.output()['Payload']['status'], value='CREATE PENDING'),\r\n    next_step=wait_state_campaign\r\n)\r\ncreate_campaign_choice_state.add_choice(\r\n    ChoiceRule.StringEquals(variable=lambda_state_campaign_status.output()['Payload']['status'], value='CREATE IN_PROGRESS'),\r\n    next_step=wait_state_campaign\r\n)\r\n\r\ncreate_campaign_choice_state.default_choice(next_step=Fail(\"CreateCampaignFailed\"))<\/code><\/pre>\n<\/p><\/div>\n<h2>Defining and running workflows<\/h2>\n<p>You create a workflow that runs a group of Lambda functions (steps) in a specific order for example one Lambda function\u2019s output passes to the next Lambda function\u2019s input. We\u2019re now ready to define the workflow definition for each step in Amazon Personalize:<\/p>\n<ul>\n<li>Dataset workflow<\/li>\n<li>Dataset import workflow<\/li>\n<li>Recipe and solution workflow<\/li>\n<li>Create campaign workflow<\/li>\n<li>Main workflow to orchestrate the four preceding workflows for Amazon Personalize<\/li>\n<\/ul>\n<p>After completing these steps, we can run our main workflow. To learn more about Step function workflows refer this <a href=\"https:\/\/docs.aws.amazon.com\/step-functions\/latest\/dg\/welcome.html\" target=\"_blank\" rel=\"noopener noreferrer\">link<\/a>.<\/p>\n<h3>Dataset workflow<\/h3>\n<p>Run the following code to generate a workflow definition for dataset creation using the Lambda function state defined by Step Functions:<\/p>\n<div class=\"hide-language\">\n<pre><code class=\"lang-python\">Dataset_workflow_definition=Chain([lambda_state_schema,\r\n                                   wait_state_schema,\r\n                                   lambda_state_datasetgroup,\r\n                                   wait_state_datasetgroup,\r\n                                   lambda_state_datasetgroupstatus\r\n                                  ])\r\nDataset_workflow = Workflow(\r\n    name=\"Dataset-workflow\",\r\n    definition=Dataset_workflow_definition,\r\n    role=workflow_execution_role\r\n)<\/code><\/pre>\n<\/p><\/div>\n<p>The following screenshot shows the dataset workflow view.<\/p>\n<p><img decoding=\"async\" loading=\"lazy\" class=\"alignnone wp-image-20643 size-full\" src=\"https:\/\/d2908q01vomqb2.cloudfront.net\/f1f836cb4ea6efb2a0b1b99f41ad8b103eff4b59\/2021\/01\/12\/New-1.jpg\" alt=\"The following screenshot shows the dataset workflow view.\" width=\"1657\" height=\"403\"><\/p>\n<h3>Dataset import workflow<\/h3>\n<p>Run the following code to generate a workflow definition for dataset creation using the Lambda function state defined by Step Functions:<\/p>\n<div class=\"hide-language\">\n<pre><code class=\"lang-python\">DatasetImport_workflow_definition=Chain([lambda_state_createdataset,\r\n                                   wait_state_dataset,\r\n                                   lambda_state_datasetimportjob,\r\n                                   wait_state_datasetimportjob,\r\n                                   lambda_state_datasetimportjob_status,\r\n                                   datasetimportjob_choice_state\r\n                                  ])<\/code><\/pre>\n<\/p><\/div>\n<p>The following screenshot shows the dataset Import workflow view.<\/p>\n<p><img decoding=\"async\" loading=\"lazy\" class=\"alignnone wp-image-20644 size-full\" src=\"https:\/\/d2908q01vomqb2.cloudfront.net\/f1f836cb4ea6efb2a0b1b99f41ad8b103eff4b59\/2021\/01\/12\/New-2.jpg\" alt=\"The following screenshot shows the dataset Import workflow view.\" width=\"1662\" height=\"463\"><\/p>\n<h3>Recipe and solution workflow<\/h3>\n<p>Run the notebook to generate a workflow definition for dataset creation using the Lambda function state defined by Step Functions:<\/p>\n<div class=\"hide-language\">\n<pre><code class=\"lang-python\">Create_receipe_sol_workflow_definition=Chain([lambda_state_select_receipe_create_solution,\r\n                                   wait_state_receipe,\r\n                                   lambda_create_solution_version,\r\n                                   wait_state_solutionversion,\r\n                                   lambda_state_solutionversion_status,\r\n                                   solutionversion_choice_state\r\n                                  ])<\/code><\/pre>\n<\/p><\/div>\n<p>The following screenshot shows the create recipe workflow view.<\/p>\n<p><img decoding=\"async\" loading=\"lazy\" class=\"alignnone wp-image-20645 size-full\" src=\"https:\/\/d2908q01vomqb2.cloudfront.net\/f1f836cb4ea6efb2a0b1b99f41ad8b103eff4b59\/2021\/01\/12\/New-3.jpg\" alt=\"The following screenshot shows the create recipe workflow view.\" width=\"1673\" height=\"460\"><\/p>\n<h3>Campaign workflow<\/h3>\n<p>Run the notebook to generate a workflow definition for dataset creation using the Lambda function state defined by Step Functions:<\/p>\n<div class=\"hide-language\">\n<pre><code class=\"lang-python\">Create_Campaign_workflow_definition=Chain([lambda_create_campaign,\r\n                                   wait_state_campaign,\r\n                                   lambda_state_campaign_status,\r\n                                   wait_state_datasetimportjob,\r\n                                   create_campaign_choice_state\r\n                                  ])<\/code><\/pre>\n<\/p><\/div>\n<p>The following screenshot shows the campaign workflow view.<\/p>\n<p><img decoding=\"async\" loading=\"lazy\" class=\"alignnone wp-image-20646 size-full\" src=\"https:\/\/d2908q01vomqb2.cloudfront.net\/f1f836cb4ea6efb2a0b1b99f41ad8b103eff4b59\/2021\/01\/12\/New-4.jpg\" alt=\"The following screenshot shows the campaign workflow view.\" width=\"1578\" height=\"432\"><\/p>\n<h3>Main workflow<\/h3>\n<p>Now we automate all four workflow definitions by combining them into a single workflow definition in order to automate all the task states to create the dataset, recipe, solution, and campaign in Amazon Personalize, including the wait times and choice states. Run the following notebook cell to generate a main workflow definition:<\/p>\n<div class=\"hide-language\">\n<pre><code class=\"lang-python\">Main_workflow_definition=Chain([call_dataset_workflow_state,\r\n                                call_datasetImport_workflow_state,\r\n                                call_receipe_solution_workflow_state,\r\n                                call_campaign_solution_workflow_state\r\n                               ])<\/code><\/pre>\n<\/p><\/div>\n<h3>Running the workflow<\/h3>\n<p>Run the following code to trigger an Amazon Personalize automated workflow to create a dataset, recipe, solution, and campaign using the underlying Lambda function and Step Functions states:<\/p>\n<div class=\"hide-language\">\n<pre><code class=\"lang-bash\">Main_workflow_execution = Main_workflow.execute()\r\nMain_workflow_execution.render_progress()<\/code><\/pre>\n<\/p><\/div>\n<p><img decoding=\"async\" loading=\"lazy\" class=\"alignnone size-full wp-image-20623\" src=\"https:\/\/d2908q01vomqb2.cloudfront.net\/f1f836cb4ea6efb2a0b1b99f41ad8b103eff4b59\/2021\/01\/12\/ML-1267-8.jpg\" alt=\"Run the following code to trigger an Amazon Personalize automated workflow to create a dataset\" width=\"800\" height=\"97\"><\/p>\n<p>\u00a0<\/p>\n<table border=\"1px\" cellpadding=\"5px\">\n<tbody>\n<tr>\n<td width=\"338\">Dataset Workflow<\/td>\n<td width=\"376\">Dataset Import Workflow<\/td>\n<\/tr>\n<tr>\n<td width=\"338\"><img decoding=\"async\" loading=\"lazy\" class=\"alignnone size-full wp-image-20624\" src=\"https:\/\/d2908q01vomqb2.cloudfront.net\/f1f836cb4ea6efb2a0b1b99f41ad8b103eff4b59\/2021\/01\/12\/ML-1267-9-1.jpg\" alt=\"\" width=\"648\" height=\"480\"><\/td>\n<td width=\"376\"><img decoding=\"async\" loading=\"lazy\" class=\"alignnone size-full wp-image-20625\" src=\"https:\/\/d2908q01vomqb2.cloudfront.net\/f1f836cb4ea6efb2a0b1b99f41ad8b103eff4b59\/2021\/01\/12\/ML-1267-9-2.jpg\" alt=\"\" width=\"648\" height=\"359\"><\/td>\n<\/tr>\n<tr>\n<td width=\"338\">Create recipe and Solution Workflow<\/td>\n<td width=\"376\">Campaign Workflow<\/td>\n<\/tr>\n<tr>\n<td width=\"338\"><img decoding=\"async\" loading=\"lazy\" class=\"alignnone size-full wp-image-20626\" src=\"https:\/\/d2908q01vomqb2.cloudfront.net\/f1f836cb4ea6efb2a0b1b99f41ad8b103eff4b59\/2021\/01\/12\/ML-1267-9-3.jpg\" alt=\"\" width=\"648\" height=\"391\"><\/td>\n<td width=\"376\"><img decoding=\"async\" loading=\"lazy\" class=\"alignnone size-full wp-image-20627\" src=\"https:\/\/d2908q01vomqb2.cloudfront.net\/f1f836cb4ea6efb2a0b1b99f41ad8b103eff4b59\/2021\/01\/12\/ML-1267-9-4.jpg\" alt=\"\" width=\"648\" height=\"423\"><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>Alternatively you can <a href=\"https:\/\/console.aws.amazon.com\/states\/home?region=us-east-1#\/executions\/details\/arn:aws:states:us-east-1:261602857181:execution:Main-workflow:5eb76532-8e91-4f66-82a8-75dfa4be9a3b\" target=\"_blank\" rel=\"noopener noreferrer\">Inspect in AWS Step Functions console<\/a> to see the status of each step in progress.<\/p>\n<p>To see detailed progress of each step whether its success or failed run the code below:<\/p>\n<div class=\"hide-language\">\n<pre><code class=\"lang-bash\">Main_workflow_execution.list_events(html=True)<\/code><\/pre>\n<\/p><\/div>\n<p><img decoding=\"async\" loading=\"lazy\" class=\"alignnone size-full wp-image-20628\" src=\"https:\/\/d2908q01vomqb2.cloudfront.net\/f1f836cb4ea6efb2a0b1b99f41ad8b103eff4b59\/2021\/01\/12\/ML-1267-10.jpg\" alt=\"To see detailed progress of each step whether its success or failed run the code below:\" width=\"800\" height=\"395\"><\/p>\n<p>Note: Wait till the above execution finishes.<\/p>\n<h2>Generating recommendations<\/h2>\n<p>Now that you have a successful campaign, you can use it to generate a recommendation workflow. The following screenshot shows your recommendation workflow view.<\/p>\n<p><img decoding=\"async\" loading=\"lazy\" class=\"alignnone wp-image-20647 size-full\" src=\"https:\/\/d2908q01vomqb2.cloudfront.net\/f1f836cb4ea6efb2a0b1b99f41ad8b103eff4b59\/2021\/01\/12\/New-5.jpg\" alt=\"The following screenshot shows your recommendation workflow view.\" width=\"756\" height=\"158\"><\/p>\n<h4>Running the recommendation workflow<\/h4>\n<p>Run the following code to trigger a recommendation workflow using the underlying Lambda function and Step Functions states:<\/p>\n<div class=\"hide-language\">\n<pre><code class=\"lang-python\">recommendation_workflow_execution = recommendation_workflow.execute()\r\nrecommendation_workflow_execution.render_progress()<\/code><\/pre>\n<\/p><\/div>\n<p><img decoding=\"async\" loading=\"lazy\" class=\"alignnone size-full wp-image-20630\" src=\"https:\/\/d2908q01vomqb2.cloudfront.net\/f1f836cb4ea6efb2a0b1b99f41ad8b103eff4b59\/2021\/01\/12\/ML-1267-12.jpg\" alt=\"Run the following code to trigger a recommendation workflow using the underlying Lambda function and Step Functions states:\" width=\"633\" height=\"563\"><\/p>\n<p>Use the following code to display the movie recommendations generated by the workflow:<\/p>\n<div class=\"hide-language\">\n<pre><code class=\"lang-python\">item_list = recommendation_workflow_execution.get_output()['Payload']['item_list']\r\n\r\nprint(\"Recommendations:\")\r\nfor item in item_list:\r\n    np.int(item['itemId'])\r\n    item_title = items.loc[items['ITEM_ID'] == np.int(item['itemId'])].values[0][-1]\r\n    print(item_title)<\/code><\/pre>\n<\/p><\/div>\n<p>You can find the complete notebook for this solution in the <a href=\"https:\/\/github.com\/aws-samples\/personalize-data-science-sdk-workflow.git\" target=\"_blank\" rel=\"noopener noreferrer\">GitHub repo<\/a>.<\/p>\n<h2>Cleaning up<\/h2>\n<p>Make sure to clean up the Amazon Personalize and the state machines created in this post to avoid incurring any charges. On the Amazon Personalize console, delete these resources in the following order:<\/p>\n<ol>\n<li><a href=\"https:\/\/docs.aws.amazon.com\/personalize\/latest\/dg\/API_DescribeCampaign.html\" target=\"_blank\" rel=\"noopener noreferrer\">Campaign<\/a><\/li>\n<li><a href=\"https:\/\/docs.aws.amazon.com\/personalize\/latest\/dg\/API_DescribeRecipe.html\" target=\"_blank\" rel=\"noopener noreferrer\">Receipts<\/a><\/li>\n<li><a href=\"https:\/\/docs.aws.amazon.com\/personalize\/latest\/dg\/API_DeleteSolution.html\" target=\"_blank\" rel=\"noopener noreferrer\">Solutions<\/a><\/li>\n<li><a href=\"https:\/\/docs.aws.amazon.com\/personalize\/latest\/dg\/API_DeleteDataset.html\" target=\"_blank\" rel=\"noopener noreferrer\">Dataset<\/a><\/li>\n<li><a href=\"https:\/\/docs.aws.amazon.com\/personalize\/latest\/dg\/API_DeleteDatasetGroup.html\" target=\"_blank\" rel=\"noopener noreferrer\">Dataset groups<\/a><\/li>\n<\/ol>\n<h2>Summary<\/h2>\n<p>Amazon Personalize makes it easy for developers to add highly personalized recommendations to customers who use their applications. It uses the same machine learning (ML) technology used by Amazon.com for real-time personalized recommendations \u2013 no ML expertise required. This post shows how to use the AWS Step Functions Data Science SDK to automate the process of orchestrating Amazon Personalize workflows such as such as dataset group, dataset, dataset import job, solution, solution version, campaign, and recommendations. This automation of creating a recommender function using Step Functions can improve the CI\/CD pipeline of the model training and deployment process.<\/p>\n<p>For additional technical documentation and example notebooks related to the SDK, see <a href=\"https:\/\/aws.amazon.com\/about-aws\/whats-new\/2019\/11\/introducing-aws-step-functions-data-science-sdk-amazon-sagemaker\/\" target=\"_blank\" rel=\"noopener noreferrer\">Introducing the AWS Step Functions Data Science SDK for Amazon SageMaker<\/a>.<\/p>\n<hr>\n<h3>About the Authors<\/h3>\n<p><img decoding=\"async\" loading=\"lazy\" class=\"wp-image-20648 size-full alignleft\" src=\"https:\/\/d2908q01vomqb2.cloudfront.net\/f1f836cb4ea6efb2a0b1b99f41ad8b103eff4b59\/2021\/01\/12\/Screen-Shot-2020-09-17-at-1.05.22-PM.png\" alt=\"Neel Sendas\" width=\"100\" height=\"114\"><strong>Neel Sendas<\/strong> is a Senior Technical Account Manager at Amazon Web Services. Neel works with enterprise customers to design, deploy, and scale cloud applications to achieve their business goals. He has worked on various ML use cases, ranging from anomaly detection to predictive product quality for manufacturing and logistics optimization. When he is not helping customers, he dabbles in golf and salsa dancing.<\/p>\n<p>\u00a0<\/p>\n<p><img decoding=\"async\" loading=\"lazy\" class=\"size-full wp-image-16219 alignleft\" src=\"https:\/\/d2908q01vomqb2.cloudfront.net\/f1f836cb4ea6efb2a0b1b99f41ad8b103eff4b59\/2020\/09\/23\/Mona.jpg\" alt=\"\" width=\"100\" height=\"134\"><strong>Mona Mona<\/strong> is an AI\/ML Specialist Solutions Architect based out of Arlington, VA. She works with the World Wide Public Sector team and helps customers adopt machine learning on a large scale. She is passionate about NLP and ML explain-ability areas in AI\/ML.<\/p>\n<\/p><\/div>\n","protected":false},"excerpt":{"rendered":"<p>https:\/\/aws.amazon.com\/blogs\/machine-learning\/automating-amazon-personalize-solution-using-the-aws-step-functions-data-science-sdk\/<\/p>\n","protected":false},"author":0,"featured_media":765,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[3],"tags":[],"_links":{"self":[{"href":"https:\/\/salarydistribution.com\/machine-learning\/wp-json\/wp\/v2\/posts\/764"}],"collection":[{"href":"https:\/\/salarydistribution.com\/machine-learning\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/salarydistribution.com\/machine-learning\/wp-json\/wp\/v2\/types\/post"}],"replies":[{"embeddable":true,"href":"https:\/\/salarydistribution.com\/machine-learning\/wp-json\/wp\/v2\/comments?post=764"}],"version-history":[{"count":0,"href":"https:\/\/salarydistribution.com\/machine-learning\/wp-json\/wp\/v2\/posts\/764\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/salarydistribution.com\/machine-learning\/wp-json\/wp\/v2\/media\/765"}],"wp:attachment":[{"href":"https:\/\/salarydistribution.com\/machine-learning\/wp-json\/wp\/v2\/media?parent=764"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/salarydistribution.com\/machine-learning\/wp-json\/wp\/v2\/categories?post=764"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/salarydistribution.com\/machine-learning\/wp-json\/wp\/v2\/tags?post=764"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}