Previsione con una pipeline scikit-learn personalizzata

Logo Colab Esegui questo tutorial come blocco note in Colab Logo di GitHub Visualizza il blocco note su GitHub

Questo tutorial mostra come utilizzare AI Platform Prediction per eseguire il deployment di una pipeline scikit-learn che utilizza trasformatori personalizzati.

Le pipeline scikit-learn consentono di comporre più stimati. Ad esempio, puoi utilizzare i transformer per pre-elaborare i dati e passare i dati trasformati a un classificatore. scikit-learn offre numerosi trasformatori nel pacchetto sklearn.

Puoi anche utilizzare la classe FunctionTransformer o TransformerMixin di scikit-learn per creare il tuo trasformatore personalizzato. Se vuoi eseguire il deployment di una pipeline che utilizza trasformatori personalizzati in AI Platform Prediction, devi fornire quel codice ad AI Platform Prediction come pacchetto di distribuzione di origine.

Questo tutorial presenta un problema di esempio relativo ai dati del censimento per illustrarti i seguenti passaggi:

  • Addestramento di una pipeline scikit-learn con trasformatori personalizzati su AI Platform Training
  • Deployment della pipeline addestrata e del codice personalizzato in AI Platform Prediction
  • Gestione delle richieste di previsione da quel deployment

Set di dati

Questo tutorial utilizza il set di dati relativo al reddito del censimento degli Stati Uniti fornito da UC Irvine Machine Learning Repository. Questo set di dati contiene informazioni su persone provenienti da un database del Censimento del 1994, tra cui età, istruzione, stato civile, occupazione e se guadagnano più di 50.000 dollari all'anno.

I dati utilizzati in questo tutorial sono disponibili in un bucket Cloud Storage pubblico: gs://cloud-samples-data/ai-platform/sklearn/census_data/

Scopo

L'obiettivo è addestrare una pipeline scikit-learn che preveda se una persona guadagna più di 50.000 $all'anno (etichetta target) in base ad altre informazioni di Census sulla persona (caratteristiche).

Questo tutorial è incentrato più sull'utilizzo di questo modello con AI Platform Prediction che sulla progettazione del modello stesso. Tuttavia, quando si creano sistemi di machine learning, è sempre importante tenere conto dei potenziali problemi e delle conseguenze indesiderate. Consulta l'esercizio relativo al corso accelerato sul machine learning sull'equità per saperne di più sulle fonti di bias nel set di dati del censimento e sull'equità del machine learning in modo più generale.

Costi

Questo tutorial utilizza i componenti fatturabili di Google Cloud:

  • AI Platform Training
  • AI Platform Prediction
  • Cloud Storage

Scopri di più sui prezzi di AI Platform Training, sui prezzi di AI Platform Prediction e sui prezzi di Cloud Storage e utilizzare il Calcolatore prezzi per generare una stima dei costi in base all'utilizzo previsto.

Prima di iniziare

Prima di poter addestrare ed eseguire il deployment di un modello su AI Platform Prediction, devi eseguire diverse operazioni:

  • Configura l'ambiente di sviluppo locale.
  • Configurare un progetto Google Cloud con fatturazione e le API necessarie abilitate.
  • Creare un bucket Cloud Storage per archiviare il pacchetto di addestramento e il modello addestrato.

Configura l'ambiente di sviluppo locale

Per completare questo tutorial, sono necessari:

  • Python 3
  • virtualenv
  • Google Cloud SDK

La guida di Google Cloud alla configurazione di un ambiente di sviluppo Python fornisce istruzioni dettagliate per soddisfare questi requisiti. I seguenti passaggi forniscono un insieme ridotto di istruzioni:

  1. Installa Python. 3.

  2. Installa virtualenv e crea un ambiente virtuale che utilizza Python 3.

  3. Attiva l'ambiente.

  4. Completa i passaggi nella sezione seguente per installare Google Cloud SDK.

Configura il tuo progetto Google Cloud

  1. Accedi al tuo account Google Cloud. Se non conosci Google Cloud, crea un account per valutare le prestazioni dei nostri prodotti in scenari reali. I nuovi clienti ricevono anche 300 $di crediti gratuiti per l'esecuzione, il test e il deployment dei carichi di lavoro.
  2. Nella pagina del selettore di progetti della console Google Cloud, seleziona o crea un progetto Google Cloud.

    Vai al selettore progetti

  3. Assicurati che la fatturazione sia attivata per il tuo progetto Google Cloud.

  4. Abilita le API AI Platform Training & Prediction and Compute Engine.

    Abilita le API

  5. Installa Google Cloud CLI.
  6. Per initialize gcloud CLI, esegui questo comando:

    gcloud init
  7. Nella pagina del selettore di progetti della console Google Cloud, seleziona o crea un progetto Google Cloud.

    Vai al selettore progetti

  8. Assicurati che la fatturazione sia attivata per il tuo progetto Google Cloud.

  9. Abilita le API AI Platform Training & Prediction and Compute Engine.

    Abilita le API

  10. Installa Google Cloud CLI.
  11. Per initialize gcloud CLI, esegui questo comando:

    gcloud init

Autentica il tuo account Google Cloud

Per configurare l'autenticazione, devi creare una chiave dell'account di servizio e impostare una variabile di ambiente per il percorso del file alla chiave dell'account di servizio.

  1. Crea un account di servizio:

    1. Nella console Google Cloud, vai alla pagina Crea account di servizio.

      Vai a Crea account di servizio

    2. Inserisci un nome nel campo Nome account di servizio.
    3. (Facoltativo) Nel campo Descrizione account di servizio, inserisci una descrizione.
    4. Fai clic su Crea.
    5. Fai clic sul campo Seleziona un ruolo. In Tutti i ruoli, seleziona AI Platform > Amministratore AI Platform.
    6. Fai clic su Aggiungi un altro ruolo.
    7. Fai clic sul campo Seleziona un ruolo. In Tutti i ruoli, seleziona Archiviazione > Amministratore oggetti Storage.

    8. Fai clic su Fine per creare l'account di servizio.

      Non chiudere la finestra del browser. Lo utilizzerai nel passaggio successivo.

  2. Crea una chiave dell'account di servizio per l'autenticazione:

    1. Nella console Google Cloud, fai clic sull'indirizzo email dell'account di servizio che hai creato.
    2. Fai clic su Chiavi.
    3. Fai clic su Aggiungi chiave, quindi su Crea nuova chiave.
    4. Fai clic su Crea. Sul computer viene scaricato un file della chiave JSON.
    5. Fai clic su Chiudi.
  3. Imposta la variabile di ambiente GOOGLE_APPLICATION_CREDENTIALS sul percorso del file JSON che contiene la chiave dell'account di servizio. Questa variabile si applica solo alla sessione di shell attuale. Pertanto, se apri una nuova sessione, imposta di nuovo la variabile.

Crea un bucket Cloud Storage

Questo tutorial utilizza Cloud Storage in diversi modi:

  • Quando invii un job di addestramento utilizzando Cloud SDK, carichi un pacchetto Python contenente il tuo codice di addestramento in un bucket Cloud Storage. AI Platform Training esegue il codice da questo pacchetto.

  • In questo tutorial, AI Platform Training salva anche il modello addestrato risultante dal tuo job nello stesso bucket.

  • Per eseguire il deployment della pipeline scikit-learn che utilizza codice personalizzato nella AI Platform Prediction, devi caricare in Cloud Storage i trasformatori personalizzati utilizzati dalla pipeline.

Quando crei la risorsa della versione AI Platform Prediction che fornisce le previsioni, fornisci la pipeline scikit-learn addestrata e il tuo codice personalizzato come URI di Cloud Storage.

Imposta il nome del bucket Cloud Storage come variabile di ambiente. Deve essere univoco in tutti i bucket Cloud Storage:

BUCKET_NAME="your-bucket-name"

Seleziona una regione in cui sono disponibili AI Platform Training e AI Platform Prediction e crea un'altra variabile di ambiente. Ad esempio:

REGION="us-central1"

Crea il tuo bucket Cloud Storage in questa regione e, in seguito, utilizza la stessa regione per l'addestramento e la previsione. Esegui questo comando per creare il bucket, se non esiste già:

gsutil mb -l $REGION gs://$BUCKET_NAME

Creazione di un'applicazione di addestramento e del codice della pipeline personalizzato

Crea un'applicazione per addestrare una pipeline scikit-learn con i dati di Census. In questo tutorial, il pacchetto di addestramento contiene anche il codice personalizzato che la pipeline addestrata utilizza durante la previsione. Questo è un pattern utile, perché le pipeline sono generalmente progettate per utilizzare gli stessi trasformatori durante l'addestramento e la previsione.

Per creare una directory contenente tre file che corrisponda alla seguente struttura:

census_package/
    __init__.py
    my_pipeline.py
    train.py

Innanzitutto, crea la directory census_package/ vuota:

mkdir census_package

All'interno di census_package/, crea un file vuoto denominato __init__.py :

touch ./census_package/__init__.py

In questo modo è possibile importare census_package/ come pacchetto in Python.

Crea trasformatori personalizzati

scikit-learn fornisce numerosi trasformatori che puoi utilizzare come parte di una pipeline, ma ti consente anche di definire trasformatori personalizzati. Questi trasformatori possono anche apprendere uno stato salvato durante l'addestramento, che verrà poi utilizzato in seguito durante la previsione.

Estendi sklearn.base.TransformerMixin per definire tre Transformer:

  • PositionalSelector: dato un elenco di indici C e una matrice M, viene restituita una matrice con un sottoinsieme di colonne di M, indicate da C.

  • StripString: data una matrice di stringhe, vengono rimossi gli spazi vuoti da ogni stringa.

  • SimpleOneHotEncoder: un semplice encoder one-hot che può essere applicato a una matrice di stringhe.

Per farlo, scrivi il seguente codice in un file denominato census_package/my_pipeline.py.

import numpy as np
from sklearn.base import BaseEstimator, TransformerMixin

class PositionalSelector(BaseEstimator, TransformerMixin):
    def __init__(self, positions):
        self.positions = positions

    def fit(self, X, y=None):
        return self

    def transform(self, X):
        return np.array(X)[:, self.positions]

class StripString(BaseEstimator, TransformerMixin):
    def fit(self, X, y=None):
        return self

    def transform(self, X):
        strip = np.vectorize(str.strip)
        return strip(np.array(X))

class SimpleOneHotEncoder(BaseEstimator, TransformerMixin):
    def fit(self, X, y=None):
        self.values = []
        for c in range(X.shape[1]):
            Y = X[:, c]
            values = {v: i for i, v in enumerate(np.unique(Y))}
            self.values.append(values)
        return self

    def transform(self, X):
        X = np.array(X)
        matrices = []
        for c in range(X.shape[1]):
            Y = X[:, c]
            matrix = np.zeros(shape=(len(Y), len(self.values[c])), dtype=np.int8)
            for i, x in enumerate(Y):
                if x in self.values[c]:
                    matrix[i][self.values[c][x]] = 1
            matrices.append(matrix)
        res = np.concatenate(matrices, axis=1)
        return res

Definisci la pipeline e crea un modulo di formazione

Successivamente, crea un modulo di formazione per addestrare la pipeline scikit-learn su dati del censimento. Parte di questo codice prevede la definizione della pipeline.

Questo modulo di formazione ti consente di:

  • Scarica i dati di addestramento e li carica in un DataFrame panda che può essere utilizzato da scikit-learn.
  • Definisce la pipeline scikit-learn da addestrare. In questo esempio vengono utilizzate solo tre caratteristiche numeriche ('age', 'education-num' e 'hours-per-week') e tre caratteristiche categoriche ('workclass', 'marital-status' e 'relationship') dai dati di input. Trasforma le caratteristiche numeriche utilizzando l'integrazione di scikit-learn StandardScaler e trasforma quelle categoriche con il codificatore one-hot personalizzato che hai definito in my_pipeline.py. Poi combina i dati pre-elaborati come input per un classificatore.
  • Infine, esporta il modello utilizzando la versione di joblib inclusa in scikit-learn e la salva nel bucket Cloud Storage.

Scrivi il seguente codice a census_package/train.py:

import warnings
import argparse
from google.cloud import storage

import pandas as pd
import numpy as np
from sklearn.externals import joblib
from sklearn.preprocessing import StandardScaler
from sklearn.ensemble import GradientBoostingClassifier
from sklearn.pipeline import Pipeline, FeatureUnion, make_pipeline
import census_package.my_pipeline as mp
warnings.filterwarnings('ignore')

def download_data(bucket_name, gcs_path, local_path):
    bucket = storage.Client().bucket(bucket_name)
    blob = bucket.blob(gcs_path)
    blob.download_to_filename(local_path)

def upload_data(bucket_name, gcs_path, local_path):
    bucket = storage.Client().bucket(bucket_name)
    blob = bucket.blob(gcs_path)
    blob.upload_from_filename(local_path)

def get_features_target(local_path):
    strip = np.vectorize(str.strip)
    raw_df = pd.read_csv(local_path, header=None)
    target_index = len(raw_df.columns) - 1  # Last columns, 'income-level', is the target

    features_df = raw_df.drop(target_index, axis=1)
    features = features_df.as_matrix()
    target = strip(raw_df[target_index].values)
    return features, target

def create_pipeline():
    # We want to use 3 categorical and 3 numerical features in this sample.
    # Categorical features: age, education-num, and hours-per-week
    # Numerical features: workclass, marital-status, and relationship
    numerical_indices = [0, 4, 12]  # age, education-num, and hours-per-week
    categorical_indices = [1, 5, 7]  # workclass, marital-status, and relationship

    p1 = make_pipeline(mp.PositionalSelector(categorical_indices), mp.StripString(), mp.SimpleOneHotEncoder())
    p2 = make_pipeline(mp.PositionalSelector(numerical_indices), StandardScaler())

    feats = FeatureUnion([
        ('numericals', p1),
        ('categoricals', p2),
    ])

    pipeline = Pipeline([
        ('pre', feats),
        ('estimator', GradientBoostingClassifier(max_depth=4, n_estimators=100))
    ])
    return pipeline

def get_bucket_path(gcs_uri):
    if not gcs_uri.startswith('gs://'):
        raise Exception('{} does not start with gs://'.format(gcs_uri))
    no_gs_uri = gcs_uri[len('gs://'):]
    first_slash_index = no_gs_uri.find('/')
    bucket_name = no_gs_uri[:first_slash_index]
    gcs_path = no_gs_uri[first_slash_index + 1:]
    return bucket_name, gcs_path

if __name__ == '__main__':
    parser = argparse.ArgumentParser()
    parser.add_argument('--gcs_data_path', action="store", required=True)
    parser.add_argument('--gcs_model_path', action="store", required=True)

    arguments, others = parser.parse_known_args()

    local_path = '/tmp/adul.data'
    data_bucket, data_path = get_bucket_path(arguments.gcs_data_path)
    print('Downloading the data...')
    download_data(data_bucket, data_path, local_path)
    features, target = get_features_target(local_path)
    pipeline = create_pipeline()

    print('Training the model...')
    pipeline.fit(features, target)

    joblib.dump(pipeline, './model.joblib')

    model_bucket, model_path = get_bucket_path(arguments.gcs_model_path)
    upload_data(model_bucket, model_path, './model.joblib')
    print('Model was successfully uploaded.')

Addestramento della pipeline su AI Platform Training

Usa gcloud per inviare un job di addestramento ad AI Platform Training. Il seguente comando pacchettizza la tua applicazione di addestramento, la carica in Cloud Storage e indica ad AI Platform Training di eseguire il tuo modulo di addestramento.

L'argomento -- è un separatore: il servizio AI Platform Training non utilizza gli argomenti che seguono il separatore, ma il tuo modulo di formazione può comunque accedervi.

gcloud ai-platform jobs submit training census_training_$(date +"%Y%m%d_%H%M%S") \
  --job-dir gs://$BUCKET_NAME/custom_pipeline_tutorial/job \
  --package-path ./census_package \
  --module-name census_package.train \
  --region $REGION \
  --runtime-version 1.13 \
  --python-version 3.5 \
  --scale-tier BASIC \
  --stream-logs \
  -- \
  --gcs_data_path gs://cloud-samples-data/ai-platform/census/data/adult.data.csv \
  --gcs_model_path gs://$BUCKET_NAME/custom_pipeline_tutorial/model/model.joblib

Deployment della pipeline e gestione delle previsioni

Per gestire le previsioni da AI Platform Prediction, devi eseguire il deployment di una risorsa model e una risorsa di versione. Il model consente di organizzare più deployment se modifichi e addestra la pipeline più volte. La versione utilizza il modello addestrato e il codice personalizzato per fornire le previsioni.

Per eseguire il deployment di queste risorse, devi fornire due artefatti:

  • Una directory Cloud Storage contenente la pipeline addestrata. Il job di addestramento del passaggio precedente ha creato questo file al momento dell'esportazione di model.joblib nel tuo bucket.
  • Un pacchetto di distribuzione di origine .tar.gz in Cloud Storage contenente eventuali trasformatori personalizzati utilizzati dalla tua pipeline. Creala nel passaggio successivo.

Crea pacchetti di trasformatori personalizzati

Se esegui il deployment di una versione senza fornire il codice da my_pipeline.py, AI Platform Prediction non sarà in grado di importare i trasformatori personalizzati (ad esempio, mp.SimpleOneHotEncoder) e non sarà in grado di fornire previsioni.

Crea il seguente setup.py per definire un pacchetto di distribuzione di codice sorgente per il tuo codice:

import setuptools
setuptools.setup(name='census_package',
      packages=['census_package'],
      version="1.0",
      )

Quindi esegui questo comando per creare dist/census_package-1.0.tar.gz:

python setup.py sdist --formats=gztar

Infine, carica questo tarball nel bucket Cloud Storage:

gsutil cp ./dist/census_package-1.0.tar.gz gs://$BUCKET_NAME/custom_pipeline_tutorial/code/census_package-1.0.tar.gz

Creazione di risorse per modello e versione

Innanzitutto, definisci i nomi di modello e versione:

MODEL_NAME='CensusPredictor'
VERSION_NAME='v1'

Quindi utilizza il comando seguente per creare la risorsa del modello:

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

Infine, crea la risorsa versione fornendo i percorsi Cloud Storage della directory del modello (quella che contiene model.joblib) e il tuo codice personalizzato (census_package-1.0.tar.gz):

gcloud components install beta

gcloud beta ai-platform versions create $VERSION_NAME --model $MODEL_NAME \
  --origin gs://$BUCKET_NAME/custom_pipeline_tutorial/model/ \
  --runtime-version 1.13 \
  --python-version 3.5 \
  --framework SCIKIT_LEARN \
  --package-uris gs://$BUCKET_NAME/custom_pipeline_tutorial/code/census_package-1.0.tar.gz

Fornitura di previsioni online

Prova il deployment inviando una richiesta di previsione online. Innanzitutto, installa la libreria client delle API di Google per Python:

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

Quindi invia due istanze di dati del censimento alla versione di cui hai eseguito il deployment:

import googleapiclient.discovery

instances = [
  [39, 'State-gov', 77516, ' Bachelors .  ', 13, 'Never-married', 'Adm-clerical', 'Not-in-family',
   'White', 'Male', 2174, 0, 40, 'United-States', '<=50K'],
  [50, 'Self-emp-not-inc', 83311, 'Bachelors', 13, 'Married-civ-spouse', 'Exec-managerial', 'Husband',
   'White', 'Male', 0, 0, 13, 'United-States', '<=50K']
]

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'])

La versione passa i dati di input attraverso la pipeline addestrata e restituisce i risultati del classificatore: <=50K o >50K per ogni istanza, a seconda della previsione per la fascia di reddito della persona.

Eseguire la pulizia

Per eseguire la pulizia di tutte le risorse Google Cloud utilizzate in questo progetto, puoi eliminare il progetto Google Cloud che hai utilizzato per il tutorial.

In alternativa, puoi eseguire la pulizia delle singole risorse eseguendo i comandi seguenti:

# 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
gsutil -m rm -r gs://$BUCKET_NAME/custom_pipeline_tutorial

Passaggi successivi