Существует множество вариантов создания приложения с использованием Python, например Flask, Plotly, Streamlit. Однако, на мой взгляд, основным ограничением является время, необходимое для написания фреймворка. Если у нас нет сильных знаний CSS и HTML, приложение выглядит нелепо и лишено оригинальности. Я могу это сказать, потому что я начал играть с этими инструментами в первые годы работы специалистом по данным. Я быстро отказался от этого, потому что разработка приложения не входит в мои обязанности. Вместо этого я трачу время на анализ и развертывание моделей, а не на написание уродливых интерфейсов с плохим пользовательским интерфейсом.

Я также переключился, потому что в 2019 году друг рассказал мне о Coda. Coda принадлежит к семейству Notion, Airtable и всем этим инструментам для создания приложений без кода.

На самом деле, имея в руках эти инструменты, мы можем создавать отличные документы, удобные для пользователя, с массой опций. Они разрабатывают такие функции, как таблицы, графики, формулы и т. д., и нам нужно их использовать.

Если вы хотите узнать больше о Coda, посмотрите их галерею: https://coda.io/gallery.

За год я освоил использование Coda очень продвинутым способом и с их API. Мне удалось создать множество интеграций для извлечения данных из разных источников данных в один документ. Сначала использовал AWS Lambda, потом потихоньку перешел на Google Script.

На этой неделе Coda выпустила бета-версию, которая меняет правила игры.

Новая функция «Пакет»

Coda выпустила то, что они назвали Pack Studio. С помощью Pack Studio мы можем создать Pack (что-то вроде библиотеки на Python) за считанные минуты в нашем браузере, загружать его не требуется и требуется минимальное знание JavaScript. Это означает, что как пользователь мы можем писать код JavaScript в соответствии со своими потребностями. Скажи иначе; теперь мы можем делать все, например, извлекать, исследовать и преобразовывать данные прямо в документе.

Нет предела, кроме нашего воображения. Затем мы можем превратить Coda в еще более мощное приложение.

В этом посте я хочу рассказать, как создать API с помощью AWS, развернуть его в AWS ECR и использовать Lambda для получения ответа.

После этого я покажу вам, как написать простой пакет для вызова API и получения результатов в таблице Coda. В целом процесс не сложен, и мы можем развернуть любое приложение всего за несколько часов.

Ссылка для входа в приложение следующая: https://coda.io/@thomas-pernet/medium-post

В этом приложении есть таблица, в которой пользователь может написать свое имя, а затем получить связанный с ним пол. Как видите, приложение не навороченное, но отображает нужную мне информацию, и я не тратил на это много времени. Действительно, таблица и графики — это объекты без кода, их можно просто перетащить.

Кнопка «Нажми меня» содержит API с «имя» в качестве аргумента. Через пару секунд результат доступен в колонке «ПОЛ» с вероятностью.

Включите API с прогнозированием ML в приложении

Чтобы создать такое приложение, нам нужно выполнить четыре шага:

  1. Разработать модель
  2. Отправьте модель в AWS ECR и свяжите ее с AWS Lambda.
  3. Добавить шлюз API AWS в Lambda
  4. Напишите пакет в Coda

Общий процесс представлен на следующей диаграмме.

Пользователь вводит информацию в приложение и нажимает кнопку. Кнопка вызывает пакет Coda, содержащий API. API запускает лямбда-функцию, которая затем получает прогноз от AWS ECR.

Разработать модель

Я не буду тратить много времени на эту часть. Модель обучается на общедоступном наборе данных USA Names, доступном в Google BigQuery. Я обучил модель, используя архитектуру LSTM со слоем внедрения в качестве входных данных и плотным слоем в качестве выходных данных. Слой внедрения имеет 28 функций (27 букв алфавита и 1 пробел) и размер 258. Затем модель сохранена в AWS S3.

Отправьте модель в AWS ECR и свяжите ее с AWS Lambda.

Модель обучается с использованием Tensorflow, что означает невозможность загрузить zip-файл в Lambda (максимальный размер 290mo) или создать слой (тоже ограничение размера). Единственным решением было бы отправить код в AWS ECR.

На своем локальном компьютере я создал папку gender_prediction с тремя файлами:

  • app.py
  • Dockerfile
  • requirements.txt

app.py содержит коды для получения прогноза, а файл Dockerfile включает строку кода для создания образа. Для требований мне нужны только три библиотеки: tensorflow, pandas и numpy.

app.py имеет функцию lambda_handler, которая разбита на три части. Сначала извлеките имя из полезной нагрузки, загрузите модель, хранящуюся в контейнере, и сделайте прогноз. Ответ имеет три ключа: имя, пол и вероятность.

def lambda_handler(event, context):
    """
    """
    ## get the name from the API
    name = event['queryStringParameters']['name']
    ### it's a small model, so I upload it to ECR
    pred_model = load_model("model/genders.h5")
    ### get the prediction
    max_prediction = pred_model.predict(
        np.asarray(
            preprocess(
                pd.DataFrame(
                    [name],
                    columns=['semantic_0']
                ), column="semantic_0", train=False
            )
            .values.tolist()
        )
    )
    ### create the label
    gender= "MALE" if max_prediction >=.5 else "FEMALE" 
    ### create the response
    responseObject = {
            'statusCode' : 200,
            'body' : json.dumps({
            'name':name,
            'gender': gender,
            'probability':str(max_prediction)
            })
        }
return responseObject

Dockerfile содержит следующие строки кода. Это стандартный Dockerfile:

  1. Получить Python из образа AWS
  2. Установите несколько пакетов
  3. Установите библиотеки
  4. Скопируйте файл питона
  5. Создайте папку для копирования модели
  6. Разрешить Лямбде
  7. Установите CMD для обработчика
# Pull the base image with python 3.8 as a runtime for your Lambda
FROM public.ecr.aws/lambda/python:3.7
# Install OS packages
RUN yum -y install tar gzip \
    rh-python36 \
    rh-python36-python-virtualenv
    && yum clean all
# Copy the earlier created requirements.txt file to the container
COPY requirements.txt ./
# Install the python requirements from requirements.txt
RUN pip install -r requirements.txt
# Copy the earlier created app.py file to the container
COPY app.py ./
### copy model
RUN mkdir model
RUN curl -L https://github.com/thomaspernet/esg_metadata/raw/main/01_data_preprocessing/01_transform_tables/MODELS_AND_DATA/genders.h5 -o ./model/genders.h5
### give permissions for Lambda
RUN chmod 644 $(find . -type f)
RUN chmod 755 $(find . -type d)
# Set the CMD to your handler
CMD ["app.lambda_handler"]

Когда это будет сделано, нам нужно отправить образ в AWS ECR. AWS очень хорошо задокументирован со всеми шагами, которые необходимо выполнить для отправки изображения.

docker build -t  tensorflow-example .

# Create a ECR repository
aws ecr create-repository --repository-name tensorflow-example --image-scanning-configuration scanOnPush=true --region eu-west-2


# Tag the image to match the repository name
docker tag tensorflow-example:latest XXX.dkr.ecr.eu-west-2.amazonaws.com/tensorflow-example:latest


# Register docker to ECR
aws ecr get-login-password --region eu-west-2 | docker login --username AWS --password-stdin XXX.dkr.ecr.eu-west-2.amazonaws.com


# Push the image to ECR
docker push XX.dkr.ecr.eu-west-2.amazonaws.com/tensorflow-example:latest

Чтобы создать лямбда-функцию, выполните следующие шаги:

  1. В консоли Lambda выберите Функции.
  2. Выберите функцию «Создать».
  3. Выберите образ контейнера.
  4. В поле Имя функции введите имя, например gender_prediction.
  5. В качестве URI образа контейнера введите ранее созданный репозиторий tensorflow-example.
  6. Выберите Обзор изображений, чтобы выбрать последнее изображение.
  7. Щелкните Создать функцию, чтобы инициировать ее создание.
  8. Чтобы улучшить время выполнения Lambda, увеличьте память функции как минимум до 4 ГБ и время ожидания до 15 секунд в основных настройках.

Если мы выберем меньший размер памяти, Tensorflow не загрузится.

Добавить шлюз API AWS в Lambda

Добавьте AWS API Gateway в качестве триггера AWS Lambda. Когда это будет сделано, вы увидите конечную точку API.

Напишите пакет в Coda

Наконец, нам нужно создать пакет непосредственно в веб-браузере. Пакет написан на JavaScript, и Coda предоставляет несколько шаблонов, которым мы можем следовать, чтобы сделать запрос GET.

Когда мы создаем пакет, создается новый файл с некоторой строкой кодов. Мы будем использовать некоторые из них, чтобы сделать Pack.

Пак состоит из трех частей:

  • Схема
  • Функция
  • Домен

Схема

По умолчанию Coda нормализует результаты функции, что неудобно, так как результатом работы API является документ JSON. Подробнее о нормализации здесь.

Схема содержит тип ответа, т. е. объект, идентификатор ответа и первичный, который будет отображаться внутри чипа. Ключ properties включает схему.

const apiSchema = coda.makeObjectSchema({
type: coda.ValueType.Object,
id: 'name',
primary: 'gender',
properties: {
name: { type: coda.ValueType.String },
gender: { type: coda.ValueType.String },
probability: { type: coda.ValueType.String }
},
});

Вторая часть пакета содержит саму функцию:

  • addFormula — это функция построения формулы, которую я назвал predict_gender.
  • makeParameter — это функция для включения аргумента в формулу. Нам нужно только одно, имя.
  • Следующие три значения, resultType , isAction и schema, указывают формат вывода, и, поскольку это объект, прикрепленная схема (которую я определил ранее)
  • Последняя часть — это ответ функции. Я использовал context.fetcher.fetch для вызова API методом GET.
// Here, we add a new formula to this Pack.
pack.addFormula({
// This is the name that will be called in the formula builder.
// Remember, your formula name cannot have spaces in it.
name: "predict_gender",
description: "Get the gender derived from a surname. Prediction is made from an LSTM architecture",
// If your formula requires one or more inputs, you’ll define them here.
// Here, we're creating a string input called “name”.
parameters: [
coda.makeParameter({
type: coda.ParameterType.String,
name: "name",
description: "The name you would like to get the gender from",
}),
],
// The resultType defines what will be returned in your Coda doc. Here, we're
// returning a simple text string.
resultType: coda.ValueType.Object,
isAction: true,
schema: apiSchema,
// Everything inside this execute statement will happen anytime your Coda
// formula is called in a doc. An array of all user inputs is always the 1st
// parameter.
execute: async function ([name], context) {
let url = coda.withQueryParams("https://XXXXX.execute-api.eu-west-2.amazonaws.com/default/predict_gender", {
name: name
});
let response = await context.fetcher.fetch({
method: "GET",
url: url
});
return {
name: response.body['name'],
gender: response.body['gender'],
probability: response.body['probability'],
}
},
});

Наконец, нам нужно добавить домен

pack.addNetworkDomain("XXX.execute-api.eu-west-2.amazonaws.com");

И вуаля!

Мы можем вернуться в приложение, установить пакет и включить формулу в кнопку.

Ответ вставляется в столбец RESPONSE и для получения ключей мы можем использовать функцию ParseJSON

Чтобы увидеть мое портфолио проектов по науке о данных, перейдите по этой ссылке: https://coda.io/@thomas-pernet/thomas-portfolio