Como criar uma rotina de previsão personalizada com o scikit-learn

Logotipo do Colab Executar este tutorial como um notebook no Colab Logotipo do GitHub Ver o notebook no GitHub

Visão geral

Neste tutorial, você aprenderá como implantar um modelo treinado do scikit-learn no AI Platform Prediction e exibir previsões usando uma rotina personalizada. Isso permite personalizar como o AI Platform Prediction responderá a cada solicitação de previsão.

Neste exemplo, você usará uma rotina de previsão personalizada para pré-processar a entrada de previsão escalonando-a e para pós-processar a saída da previsão por meio da conversão dos números de classe em strings de rótulo.

No tutorial, há várias etapas:

  • Treinamento no seu ambiente local de um modelo simples do scikit-learn (neste notebook)
  • Criação e implantação de uma rotina de previsão personalizada no AI Platform Prediction
  • Exibição das solicitações de previsão dessa implantação

Conjunto de dados

Neste tutorial, usamos o conjunto de dados Iris da R.A. Fisher. Ele é pequeno, mas muito usado para testar técnicas de machine learning. Cada instância tem quatro atributos numéricos, que são medidas diferentes de uma flor, e um rótulo de destino que a marca como um dos três tipos de iris: Iris setosa, Iris versicolor ou Iris virginica.

Neste tutorial, usamos a cópia do conjunto de dados Iris incluído na biblioteca do scikit-learn.

Objetivo

O objetivo é treinar um modelo que use as medidas de uma flor como entrada para prever o tipo de iris dela.

O foco deste tutorial está mais no uso desse modelo com o AI Platform Prediction do que na criação do modelo em si.

Custos

Neste tutorial, há componentes faturáveis do Google Cloud.

  • AI Platform Prediction
  • Cloud Storage

Consulte os preços do AI Platform Prediction e do Cloud Storage. Use a calculadora de preços para gerar uma estimativa de custo com base no uso projetado.

Antes de começar

É necessário realizar várias etapas antes de treinar e implantar um modelo no AI Platform Prediction:

  • Configure o ambiente de desenvolvimento local.
  • Configure um projeto do Google Cloud com o faturamento e as APIs necessárias ativadas.
  • Crie um bucket do Cloud Storage para armazenar o pacote de treinamento e o modelo treinado.

Configurar o ambiente de desenvolvimento local

Você precisa dos itens a seguir para concluir este tutorial:

  • Python 3
  • virtualenv
  • O SDK Google Cloud

No guia do Google Cloud sobre Como configurar um ambiente de desenvolvimento do Python, apresentamos instruções detalhadas para atender a esses requisitos. Veja a seguir um conjunto condensado de instruções:

  1. Instale o Python 3.

  2. Instale o virtualenv e crie um ambiente virtual que use o Python 3.

  3. Ative esse ambiente.

  4. Conclua as etapas na seção a seguir para instalar o SDK Google Cloud.

Configurar seu projeto do Google Cloud

  1. Sign in to your Google Cloud account. If you're new to Google Cloud, create an account to evaluate how our products perform in real-world scenarios. New customers also get $300 in free credits to run, test, and deploy workloads.
  2. In the Google Cloud console, on the project selector page, select or create a Google Cloud project.

    Go to project selector

  3. Make sure that billing is enabled for your Google Cloud project.

  4. Enable the AI Platform Training & Prediction and Compute Engine APIs.

    Enable the APIs

  5. Install the Google Cloud CLI.
  6. To initialize the gcloud CLI, run the following command:

    gcloud init
  7. In the Google Cloud console, on the project selector page, select or create a Google Cloud project.

    Go to project selector

  8. Make sure that billing is enabled for your Google Cloud project.

  9. Enable the AI Platform Training & Prediction and Compute Engine APIs.

    Enable the APIs

  10. Install the Google Cloud CLI.
  11. To initialize the gcloud CLI, run the following command:

    gcloud init

Autenticar a conta do GCP

Para configurar a autenticação, crie uma chave da conta de serviço e defina uma variável de ambiente para o caminho do arquivo dessa chave.

  1. Crie uma conta de serviço:

    1. No Console do Google Cloud, acesse a página Criar conta de serviço.

      Acesse "Criar conta de serviço"

    2. No campo Nome da conta de serviço, insira um nome.
    3. Opcional: no campo Descrição da conta de serviço, digite uma descrição.
    4. Clique em Criar.
    5. Clique no campo Selecionar um papel. Em Todos os papéis, selecione AI Platform > Administrador do AI Platform.
    6. Clique em Adicionar outro papel.
    7. Clique no campo Selecionar um papel. Em Todos os papéis, selecione Armazenamento > Administrador de objetos do Storage.

    8. Clique em Concluído para criar a conta de serviço.

      Não feche a janela do navegador. Você vai usá-la na próxima etapa.

  2. Crie uma chave da conta de serviço para autenticação:

    1. No console do Google Cloud, clique no endereço de e-mail da conta de serviço que você criou.
    2. Clique em Chaves.
    3. Clique em Adicionar chave e, depois, em Criar nova chave.
    4. Clique em Criar. O download de um arquivo de chave JSON é feito no seu computador.
    5. Clique em Fechar.
  3. Defina a variável de ambiente GOOGLE_APPLICATION_CREDENTIALS como o caminho do arquivo JSON que contém a chave da conta de serviço. Essa variável aplica-se apenas à sessão de shell atual. Portanto, se você abrir uma nova sessão, defina a variável novamente.

Criar um bucket do Cloud Storage

Para implantar uma rotina de predição personalizada, faça upload dos artefatos de modelo treinados e do código personalizado no Cloud Storage.

Defina o nome do bucket do Cloud Storage como uma variável de ambiente. Ele precisa ser exclusivo em todos os buckets do Cloud Storage:

BUCKET_NAME="your-bucket-name"

Selecione uma região em que o AI Platform Prediction esteja disponível e crie outra variável de ambiente.

REGION="us-central1"

Crie o bucket do Cloud Storage nessa região e, posteriormente, use a mesma região para treinamento e previsão. Execute o comando a seguir para criar o bucket, caso ele ainda não exista:

gcloud storage buckets create gs://$BUCKET_NAME --location=$REGION

Como criar e treinar um modelo do scikit-learn

Muitas vezes, não é possível usar os dados na forma bruta para treinar um modelo de machine learning. Mesmo quando é possível, o pré-processamento dos dados antes de usá-los para treinamento às vezes pode melhorar o modelo.

Se você espera que a entrada da predição tenha o mesmo formato que os dados de treinamento, aplique o pré-processamento idêntico durante o treinamento e a predição para garantir que o modelo faça predições consistentes.

Nesta seção, crie um módulo de pré-processamento e use-o como parte do treinamento. Em seguida, exporte um pré-processador com as características aprendidas durante o treinamento para usar posteriormente na rotina de predição personalizada.

Instalar dependências para treinamento local

O treinamento local requer várias dependências:

pip install numpy>=1.16.0 scikit-learn==0.20.2

Criar o pré-processador

É possível melhorar o modelo realizando o escalonamento dos dados de treinamento de modo que cada coluna de atributo numérico tenha uma média de 0 e um desvio padrão de 1.

Crie preprocess.py, que contém uma classe para fazer esse escalonamento:

import numpy as np

class MySimpleScaler(object):
  def __init__(self):
    self._means = None
    self._stds = None

  def preprocess(self, data):
    if self._means is None: # during training only
      self._means = np.mean(data, axis=0)

    if self._stds is None: # during training only
      self._stds = np.std(data, axis=0)
      if not self._stds.all():
        raise ValueError('At least one column has standard deviation of 0.')

    return (data - self._means) / self._stds

Uma instância de MySimpleScaler salva as médias e os desvios padrão de cada coluna de atributo no primeiro uso. Em seguida, ela usa essas estatísticas de resumo para escalonar os dados encontrados posteriormente.

Isso permite armazenar as características da distribuição de treinamento e usá-las em um pré-processamento idêntico no momento da predição.

Treinar o modelo

Em seguida, use preprocess.MySimpleScaler para pré-processar os dados da íris e depois treine um modelo usando o scikit-learn.

Por fim, exporte seu modelo treinado como um arquivo do joblib (.joblib) e sua instância MySimpleScaler como um arquivo do pickle (.pkl):

import pickle

from sklearn.datasets import load_iris
from sklearn.ensemble import RandomForestClassifier
from sklearn.externals import joblib

from preprocess import MySimpleScaler

iris = load_iris()
scaler = MySimpleScaler()
X = scaler.preprocess(iris.data)
y = iris.target

model = RandomForestClassifier()
model.fit(X, y)

joblib.dump(model, 'model.joblib')
with open ('preprocessor.pkl', 'wb') as f:
  pickle.dump(scaler, f)

Como implantar uma rotina de previsão personalizada

Para implantar uma rotina de predição personalizada a fim de exibir as predições do modelo treinado, faça o seguinte:

  • Crie um preditor personalizado para processar as solicitações.
  • Empacote o preditor e o módulo de pré-processamento.
  • Faça upload dos artefatos do modelo e do código personalizado no Cloud Storage.
  • Implante a rotina de previsão personalizada no AI Platform Prediction.

Criar um previsor personalizado

Para implantar uma rotina de predição personalizada, crie uma classe que implemente a interface do Preditor. Isso informa ao AI Platform Prediction como carregar o modelo e processar as solicitações de previsão.

Grave o seguinte código em predictor.py:

import os
import pickle

import numpy as np
from sklearn.datasets import load_iris
from sklearn.externals import joblib

class MyPredictor(object):
  def __init__(self, model, preprocessor):
    self._model = model
    self._preprocessor = preprocessor
    self._class_names = load_iris().target_names

  def predict(self, instances, **kwargs):
    inputs = np.asarray(instances)
    preprocessed_inputs = self._preprocessor.preprocess(inputs)
    if kwargs.get('probabilities'):
      probabilities = self._model.predict_proba(preprocessed_inputs)
      return probabilities.tolist()
    else:
      outputs = self._model.predict(preprocessed_inputs)
      return [self._class_names[class_num] for class_num in outputs]

  @classmethod
  def from_path(cls, model_dir):
    model_path = os.path.join(model_dir, 'model.joblib')
    model = joblib.load(model_path)

    preprocessor_path = os.path.join(model_dir, 'preprocessor.pkl')
    with open(preprocessor_path, 'rb') as f:
      preprocessor = pickle.load(f)

    return cls(model, preprocessor)

Além de usar o pré-processador que você definiu durante o treinamento, esse previsor executa uma etapa pós-processamento que converte a saída da previsão de índices de classe (0, 1 ou 2) em strings de rótulo (o nome do tipo de flor).

No entanto, se o previsor receber um argumento de palavra-chave probabilities com o valor True, ele retornará uma matriz de probabilidades, denotando a probabilidade de cada uma das três classes ser o rótulo correto (de acordo com o modelo). Na última parte deste tutorial, mostramos como inserir um argumento de palavra-chave durante a previsão.

Empacotar o código personalizado

Você precisa empacotar predictor.py e preprocess.py como um pacote de distribuição de origem .tar.gz. Depois, forneça esse pacote ao AI Platform Prediction para que seu código personalizado seja usado para exibir previsões.

Escreva o seguinte setup.py para definir seu pacote:

from setuptools import setup

setup(
    name='my_custom_code',
    version='0.1',
    scripts=['predictor.py', 'preprocess.py'])

Execute o seguinte comando para criar dist/my_custom_code-0.1.tar.gz:

python setup.py sdist --formats=gztar

Fazer upload dos artefatos do modelo e do código personalizado no Cloud Storage

Antes de implantar o modelo para a exibição de previsões, o AI Platform Prediction precisa acessar os seguintes arquivos no Cloud Storage:

  • model.joblib (artefato do modelo)
  • preprocessor.pkl (artefato do modelo)
  • my_custom_code-0.1.tar.gz (código personalizado)

Os artefatos do modelo precisam ser armazenados juntos em um diretório de modelo que o Predictor pode acessar como o argumento model_dir no método de classe from_path. O código personalizado não precisa estar no mesmo diretório. Execute os comandos a seguir para fazer upload dos arquivos:

gcloud storage cp ./dist/my_custom_code-0.1.tar.gz gs://$BUCKET_NAME/custom_prediction_routine_tutorial/my_custom_code-0.1.tar.gz
gcloud storage cp model.joblib preprocessor.pkl gs://$BUCKET_NAME/custom_prediction_routine_tutorial/model/

Implantar a rotina de previsão personalizada

Crie um recurso de modelo e um de versão para implantar uma rotina de previsão personalizada. Primeiramente, defina as variáveis de ambiente com os nomes dos recursos:

MODEL_NAME='IrisPredictor'
VERSION_NAME='v1'

Em seguida, crie o modelo:

gcloud ai-platform models create $MODEL_NAME \
  --regions $REGION

Na sequência, crie uma versão. Nesta etapa, insira os caminhos para os artefatos e o código personalizado que você enviou ao Cloud Storage:

gcloud components install beta

gcloud beta ai-platform versions create $VERSION_NAME \
  --model $MODEL_NAME \
  --runtime-version 1.13 \
  --python-version 3.5 \
  --origin gs://$BUCKET_NAME/custom_prediction_routine_tutorial/model/ \
  --package-uris gs://$BUCKET_NAME/custom_prediction_routine_tutorial/my_custom_code-0.1.tar.gz \
  --prediction-class predictor.MyPredictor

Saiba mais sobre as opções que precisam ser especificadas ao implantar uma rotina de previsão personalizada.

Como exibir previsões on-line

Teste a implantação enviando uma solicitação de predição on-line. Instale primeiro a biblioteca de cliente de APIs do Google para Python:

pip install --upgrade google-api-python-client

Em seguida, envie duas instâncias de dados da iris para a versão implantada executando o código Python abaixo:

import googleapiclient.discovery

instances = [
  [6.7, 3.1, 4.7, 1.5],
  [4.6, 3.1, 1.5, 0.2],
]

service = googleapiclient.discovery.build('ml', 'v1')
name = 'projects/{}/models/{}/versions/{}'.format(PROJECT_ID, MODEL_NAME, VERSION_NAME)

response = service.projects().predict(
    name=name,
    body={'instances': instances}
).execute()

if 'error' in response:
    raise RuntimeError(response['error'])
else:
  print(response['predictions'])
['versicolor', 'setosa']

Como enviar argumentos de palavra-chave

Ao enviar uma solicitação de previsão para uma rotina de previsão personalizada, é possível inserir mais campos no corpo da solicitação. O método predict do Predictor os recebe como campos do dicionário **kwargs.

O código a seguir envia a mesma solicitação de antes, mas, desta vez, adiciona um campo probabilities ao corpo da solicitação:

response = service.projects().predict(
    name=name,
    body={'instances': instances, 'probabilities': True}
).execute()

if 'error' in response:
    raise RuntimeError(response['error'])
else:
  print(response['predictions'])
[[0.0, 1.0, 0.0], [1.0, 0.0, 0.0]]

Limpar

Para limpar todos os recursos do GCP usados neste projeto, exclua o projeto do GCP usado no tutorial.

Também é possível limpar recursos individuais com os comandos a seguir:

# Delete version resource
gcloud ai-platform versions delete $VERSION_NAME --quiet --model $MODEL_NAME

# Delete model resource
gcloud ai-platform models delete $MODEL_NAME --quiet

# Delete Cloud Storage objects that were created
gcloud storage rm gs://$BUCKET_NAME/custom_prediction_routine_tutorial --recursive

A seguir