{ "cells": [ { "cell_type": "markdown", "source": [ "Copyright (c) Recommenders contributors.\n", "\n", "Licensed under the MIT License." ], "metadata": {} }, { "cell_type": "markdown", "source": [ "# Building a Real-time Recommendation API\n", "\n", "This reference architecture shows the full lifecycle of building a recommendation system. It walks through the creation of appropriate azure resources, training a recommendation model using a Virtual Machine or Databricks, and deploying it as an API. It uses Azure Cosmos DB, Azure Machine Learning, and Azure Kubernetes Service. \n", "\n", "This architecture can be generalized for many recommendation engine scenarios, including recommendations for products, movies, and news. \n", "### Architecture\n", "![architecture](https://recodatasets.z20.web.core.windows.net/images/reco-arch.png \"Architecture\")\n", "\n", "**Scenario**: A media organization wants to provide movie or video recommendations to its users. By providing personalized recommendations, the organization meets several business goals, including increased click-through rates, increased engagement on site, and higher user satisfaction.\n", "\n", "In this reference, we train and deploy a real-time recommender service API that can provide the top 10 movie recommendations for a given user. \n", "\n", "### Components\n", "This architecture consists of the following key components:\n", "* [Azure Databricks](https://docs.microsoft.com/en-us/azure/azure-databricks/what-is-azure-databricks)1) is used as a development environment to prepare input data and train the recommender model on a Spark cluster. Azure Databricks also provides an interactive workspace to run and collaborate on notebooks for any data processing or machine learning tasks.\n", "* [Azure Kubernetes Service](https://docs.microsoft.com/en-us/azure/aks/intro-kubernetes)(AKS) is used to deploy and operationalize a machine learning model service API on a Kubernetes cluster. AKS hosts the containerized model, providing scalability that meets throughput requirements, identity and access management, and logging and health monitoring. \n", "* [Azure Cosmos DB](https://docs.microsoft.com/en-us/azure/cosmos-db/introduction) is a globally distributed database service used to store the top 10 recommended movies for each user. Azure Cosmos DB is ideal for this scenario as it provides low latency (10 ms at 99th percentile) to read the top recommended items for a given user. \n", "* [Azure Machine Learning Service](https://docs.microsoft.com/en-us/azure/machine-learning/service/) is a service used to track and manage machine learning models, and then package and deploy these models to a scalable Azure Kubernetes Service environment.\n", "\n", "1) Here, we are just giving an example of using Azure Databricks. Any platforms listed in [SETUP](../../SETUP.md) can be used as well.\n", "\n", "\n", "### Table of Contents.\n", "0. [File Imports](#0-File-Imports)\n", "1. [Service Creation](#1-Service-Creation)\n", "2. [Training and evaluation](#2-Training)\n", "3. [Operationalization](#3.-Operationalize-the-Recommender-Service)" ], "metadata": {} }, { "cell_type": "markdown", "source": [ "## Setup\n", "To run this notebook on Azure Databricks, you should setup Azure Databricks by following the appropriate sections in the repository [SETUP instructions](../../SETUP.md) and import this notebook into your Azure Databricks Workspace (see instructions [here](https://docs.azuredatabricks.net/user-guide/notebooks/notebook-manage.html#import-a-notebook)).\n", "\n", "Please note: This notebook **REQUIRES** that you add the dependencies to support **operationalization**. See [SETUP](../../SETUP.md) for details.\n" ], "metadata": {} }, { "cell_type": "markdown", "source": [ "## 0 File Imports" ], "metadata": {} }, { "cell_type": "code", "execution_count": 1, "source": [ "import os\n", "import sys\n", "import urllib\n", "\n", "from azure.common.client_factory import get_client_from_cli_profile\n", "import azure.mgmt.cosmosdb\n", "import azureml.core\n", "from azureml.core import Workspace\n", "from azureml.core.model import Model\n", "from azureml.core.compute import AksCompute, ComputeTarget\n", "from azureml.core.compute_target import ComputeTargetException\n", "from azureml.core.webservice import Webservice, AksWebservice\n", "from azureml.exceptions import WebserviceException\n", "from azureml.core import Environment\n", "from azureml.core.environment import CondaDependencies\n", "from azureml.core.model import InferenceConfig\n", "from azureml.core.environment import SparkPackage\n", "import pydocumentdb.document_client as document_client\n", "from pyspark.ml.recommendation import ALS\n", "from pyspark.sql.types import StructType, StructField\n", "from pyspark.sql.types import FloatType, IntegerType, LongType\n", "\n", "from recommenders.datasets import movielens\n", "from recommenders.datasets.cosmos_cli import find_collection, read_collection, read_database, find_database\n", "from recommenders.datasets.download_utils import maybe_download\n", "from recommenders.datasets.spark_splitters import spark_random_split\n", "from recommenders.evaluation.spark_evaluation import SparkRatingEvaluation, SparkRankingEvaluation\n", "from recommenders.utils.notebook_utils import is_databricks\n", "from recommenders.utils.timer import Timer\n", "from recommenders.utils.spark_utils import start_or_get_spark\n", "\n", "print(\"Azure SDK version:\", azureml.core.VERSION)" ], "outputs": [ { "output_type": "stream", "name": "stdout", "text": [ "Azure SDK version: 1.0.69\n" ] } ], "metadata": {} }, { "cell_type": "code", "execution_count": 3, "source": [ "# Start spark session if needed\n", "if not is_databricks():\n", " cosmos_connector = (\n", " \"https://search.maven.org/remotecontent?filepath=com/microsoft/azure/\"\n", " \"azure-cosmosdb-spark_2.3.0_2.11/1.3.3/azure-cosmosdb-spark_2.3.0_2.11-1.3.3-uber.jar\"\n", " )\n", " jar_filepath = maybe_download(url=cosmos_connector, filename=\"cosmos.jar\")\n", " spark = start_or_get_spark(\"ALS\", memory=\"10g\", jars=[jar_filepath])\n", " sc = spark.sparkContext\n", "print(sc)" ], "outputs": [ { "output_type": "display_data", "data": { "text/html": [ "\n", "
SparkContext
\n", "\n", " \n", "\n", "v2.4.3
local[*]
ALS