- Fri 05 May 2017
- DevOps
- M Hendra Herviawan
- #AWS, #Recommendation
In this tutorial, we deploy a machine learning microservice using AWS Lambda, AWS Api Gateway and Python 3.6
Before you begin, make sure you are running python 3 and you have a valid AWS account and your AWS credentials file is properly installed.
Introduction to dataset¶
In this project we are going to create product recommendation based on title item. This is not simplified the problem but we chose this strategy becouse it can give us better recommendation compaire to recommendation based on item discription.
import numpy as np
import pandas as pd
pd.set_option('display.max_colwidth', -1)
data_source = 'data/Jkt-Index-tiny.csv'
ds = pd.read_csv(data_source)
ds['title']
0 3G External Antena Modem Bolt Slim & Max 3dbi ts9 - e5776 - Black
1 4G LTE External Antenna for Modem Routers - CRC9 Connector - White
2 4G LTE External Antenna for Modem Routers - SMA Connector - White
3 4G LTE External Antenna for Modem Routers - TS9 Connector - White
4 4G LTE MIMO External Antenna for Modem Routers - Dual CRC9 Connector - White
5 4G LTE MIMO External Antenna for Modem Routers - Dual TS9 Connector - White
6 7dBi GSM 3G Magnetic Base Antenna MB-49A - Black
7 9dBi Rubber Antenna for 2.4Ghz Magnetic Base M24-9-SR-MB - Black
8 Antenna DVB-T for Huawei E510 - Black
9 Antenna for Router Network 2.4GHz 22dbi RP-SMA - Black
10 Antenna Penguat Sinyal Handphone 3G 12dbi with Phone Holder - Black
11 Antenna Sierra Wireless 875U 595U 8781U - Black
12 External Antenna for Huawei 4G LTE 10dbi - TS9 - White
13 FME Extension cable 5 Meter - No Color
14 GSM 3G Magnetic Base Antenna 4.0mm Plug - Black
15 GSM 3G Modem Antenna 4.0mm Plug for Huawei D602 - Black
16 Hame Little U USB Connector - White
17 Huawei Docking Station for Huawei E5830 E5832 - E5-1 Cradle - Gray Silver
18 Huawei HB4F1 Battery for Mifi E5830 E5832 E585 (E583x) Original - No Color
19 Kabel Antena Male to Male 1.5 Meter - White
20 Omni Minimax G45 Portable 4G LTE External Antenna 45dBi with TS9 Connector - White
21 Omni Outdoor Antenna OM-R11-07U + FME Extension Cable 5 meter - No Color
22 Pigtail Huawei - No Color
23 Pigtail Huawei E5331 - No Color
24 Pigtail Huawei U8300 - Black
25 Pigtail OPTION GlobeTrotter - No Color
26 Pigtail Sierra Wireless 312U - Black
27 Pigtail Sierra Wireless 753s 754s - Black
28 Pigtail Sierra Wireless 875 - No Color
29 Pigtail ZTE MF633 - No Color
30 Powerfull 3G Magnetic Antenna MB-11F (Hanya Antena panjang) - No Color
31 Powerfull 3G Magnetic Antenna MB-15F (Hanya antena pendek) - No Color
32 Softcover Edition RP-SMA Male to Female Cable 174 Antenna Extension Cable - 3m - Black
33 Yagi Antenna YG-R12-11U + FME Extension Cable 5 meter - No Color
34 Huawei E220 USB 7.2Mbps - Logo Vodafone (14 Days) - White
35 Huawei E220 USB 7.2Mbps - Logo Vodafone (NEW) - White
36 Huawei E3276 - 4G LTE 100 Mbps - Logo STC - White
37 Huawei E3372 4G LTE Cat4 USB Modem - 827F - Black
38 Huawei Vodafone K3765 HSDPA USB Stick - White
39 Huawei Vodafone K4305 HSPA 21.6 Mbps - White
40 Onda MDC833UP HSUPA 10.2Mbps - Black
41 Option iCON XY 7.2 Mbps - White
42 Sierra Wireless AirCard 308U HSPA+ 21.6Mbps - White
43 WWAN Ericsson KM266 Mini-Card DELL Wireless 5530 HSPA 3G with GPS - No Color
44 ZTE MF667 HSPA USB Modem Turkcell VINN 21.6 Mbps - Black
45 ZTE Vodafone HSPA 3G MiFi 42 Mbps R209-Z MF65 - White
46 ZTE Vodafone K3772-Z HSUPA 7.2 Mbps - White
Name: title, dtype: object
Creating a Python Flask API¶
create a project directory
$ mkdir serverless-recommendation-enggine
$ cd serverless-recommendation-enggine
Wrapt python with virtualenv
$ pip install virtualenv
$ virtualenv your_virtual_environment_name
$ source your_virtual_environment_name/bin/activate
Install Python Library
$ pip install zappa sklearn numpy scipy
Now, we’re ready to build our API. Create a directory api with a file called app.py and write this into it:
import io
import numpy as np
import boto3
import pickle
from flask import Flask, jsonify, request, json
import redis
BUCKET_NAME = 'zappa-oo5s5cklwld'
MODEL_FILE_NAME = 'model.pkl'
app = Flask(__name__)
S3 = boto3.client('s3', region_name='us-east-2')
def memoize(f):
memo = {}
def helper(x):
if x not in memo:
memo[x] = f(x)
return memo[x]
return helper
return json.dumps(result)
@app.route('/predicts3', methods=['POST'])
def predic_s3():
body_dict = request.get_json(silent=True)
idx = body_dict['idx']
prediction = predict_s3(idx)
result = {'prediction': prediction}
return json.dumps(result)
@memoize
def load_model_s3(key):
response = S3.get_object(Bucket=BUCKET_NAME, Key=key)
#model_str = (response['Body'].read())
with io.BytesIO(response["Body"].read()) as f:
# rewind the file
f.seek(0)
model = np.load(f)
return model
def predict_s3(idx):
cosine_similarities = load_model_s3(MODEL_FILE_NAME)
return cosine_similarities[idx].argsort()[:-6:-1][1:].tolist()
if __name__ == '__main__':
app.run(host= '0.0.0.0')
The code is basically self-explanatory. We make a Flask object, use the ‘route’ decorator functions to define our paths, and call a run function when we run it locally (which you can confirm by calling python api/app.py and visiting localhost:5000 in your browser.)
Configure AWS Lambda & API Gateway¶
We use a framework called Zappa to create and configure both AWS Lambda and the API Gateway automatically. Think of it as “serverless” web hosting for your Python apps.
That means infinite scaling, zero downtime, zero maintenance — and at a fraction of the cost of your current deployments!
Next, we initialize Zappa.
$ zappa init
Zappa has automatically created the a zappa_settings.json configuration file:
{
"dev": {
"app_function": "api.app.app",
"aws_region": "us-east-2",
"profile_name": "serverless-admin",
"project_name": "flask-aws",
"runtime": "python3.6",
"slim_handler": true,
"s3_bucket": "zappa-oo5s5cwld"
}
}
Testing the API locally¶
The API can be tested locally like a regular Flask application First, run the Flask app as usual:
$ python api/app.py
Second, make a test API call
import requests
url = 'http://localhost:5000/predic_s3'
data = '{ "idx": 8 }'
response = requests.post(url, data=data,headers={"Content-Type": "application/json"})
print(response)
Output:
{
"prediction": [
24,
15,
22,
12
]
}
Deploying to AWS Lambda¶
Now, we’re ready to deploy to AWS. It’s as simple as:
$ zappa deploy dev
And our serverless Machine Learning microservice is alive!
import requests
url = 'https://xxx.execute-api.us-east-2.amazonaws.com/dev/predic_s3'
data = '{ "idx": 8 }'
response = requests.post(url, data=data,headers={"Content-Type": "application/json"})
print(response)
Output:
{
"prediction": [
24,
15,
22,
12
]
}
Analize the prediction¶
To get recommendation we must create post request with json format :
{
"idx": 8
}
8 is index for "Antenna DVB-T for Huawei E510 - Black", and its similar to:
{
"prediction": [
24,
15,
22,
12
]
}
which is:
24 Pigtail Huawei U8300 - Black
15 GSM 3G Modem Antenna 4.0mm Plug for Huawei D602 - Black
22 Pigtail Huawei - No Color
12 External Antenna for Huawei 4G LTE 10dbi - TS9 - White
Name: title, dtype: object