Esegui questo tutorial come blocco note in Colab | Visualizza il notebook su GitHub |
Questo tutorial mostra come utilizzare AI Platform Prediction per eseguire il deployment di una pipeline di scikit-learn che utilizza trasformatori personalizzati.
Le pipeline di scikit-learn ti consentono di comporre più stimatori. Ad esempio, puoi utilizzare i trasformatori per pre-elaborare i dati e trasmetterli a un classificatore. scikit-learn fornisce molti 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 il codice a
AI Platform Prediction come pacchetto di distribuzione di origine.
Questo tutorial presenta un problema di esempio che coinvolge i dati del censimento per illustrare i seguenti passaggi:
- Addestramento di una pipeline di scikit-learn con trasformatori personalizzati in AI Platform Training
- Esegui il deployment della pipeline addestrata e del tuo codice personalizzato in AI Platform Prediction
- Pubblicazione delle richieste di previsione da quel deployment
Set di dati
Questo tutorial utilizza il set di dati sul reddito del censimento degli Stati Uniti fornito dal repository UC Irvine Machine Learning. Questo set di dati contiene informazioni su persone di un database del censimento del 1994, tra cui età, istruzione, stato civile, professione e se guadagnano più di 50.000 $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/
Obiettivo
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 del censimento sulla persona (funzionalità).
Questo tutorial si concentra più sull'utilizzo di questo modello con AI Platform Prediction che sul design del modello stesso. Tuttavia, è sempre importante pensare ai potenziali problemi e alle conseguenze indesiderate durante la creazione di sistemi di machine learning. Consulta l'esercizio del Machine Learning Crash Course sull'equità per scoprire le fonti di bias nel set di dati del censimento, nonché l'equità del machine learning in 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, su quelli di AI Platform Prediction e su quelli di Cloud Storage e utilizza il Calcolatore prezzi per generare una stima dei costi in base all'utilizzo previsto.
Prima di iniziare
Prima di poter addestrare e implementare un modello su AI Platform Prediction, devi svolgere diverse operazioni:
- Configura l'ambiente di sviluppo locale.
- Configura un progetto Google Cloud con la fatturazione e le API necessarie abilitate.
- Crea un bucket Cloud Storage per archiviare il pacchetto di addestramento e il modello addestrato.
Configura l'ambiente di sviluppo locale
Per completare questo tutorial, devi disporre di quanto segue:
- 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 passaggi riportati di seguito forniscono un insieme di istruzioni condensate:
Installa virtualenv e crea un ambiente virtuale che utilizzi Python 3.
Attiva l'ambiente.
Completa i passaggi descritti nella sezione seguente per installare l'Google Cloud SDK.
Configurare il progetto Google Cloud
- 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.
-
In the Google Cloud console, on the project selector page, select or create a Google Cloud project.
-
Make sure that billing is enabled for your Google Cloud project.
-
Enable the AI Platform Training & Prediction and Compute Engine APIs.
- Install the Google Cloud CLI.
-
To initialize the gcloud CLI, run the following command:
gcloud init
-
In the Google Cloud console, on the project selector page, select or create a Google Cloud project.
-
Make sure that billing is enabled for your Google Cloud project.
-
Enable the AI Platform Training & Prediction and Compute Engine APIs.
- Install the Google Cloud CLI.
-
To initialize the gcloud CLI, run the following command:
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 della chiave dell'account di servizio.
-
Crea un account di servizio:
-
Nella console Google Cloud, vai alla pagina Crea account di servizio.
- Inserisci un nome nel campo Nome account di servizio.
- (Facoltativo) Nel campo Descrizione account di servizio, inserisci una descrizione.
- Fai clic su Crea.
- Fai clic sul campo Seleziona un ruolo. In Tutti i ruoli, seleziona AI Platform > Amministratore AI Platform.
- Fai clic su Aggiungi un altro ruolo.
-
Fai clic sul campo Seleziona un ruolo. In Tutti i ruoli, seleziona Storage > Storage Object Admin.
-
Fai clic su Fine per creare l'account di servizio.
Non chiudere la finestra del browser. Lo utilizzerai nel passaggio successivo.
-
-
Crea una chiave dell'account di servizio per l'autenticazione:
- Nella console Google Cloud, fai clic sull'indirizzo email dell'account di servizio che hai creato.
- Fai clic su Chiavi.
- Fai clic su Aggiungi chiave, quindi su Crea nuova chiave.
- Fai clic su Crea. Un file della chiave JSON viene scaricato sul computer.
- Fai clic su Chiudi.
-
Imposta la variabile di ambiente GOOGLE_APPLICATION_CREDENTIALS sul percorso del file JSON contenente la chiave dell'account di servizio. Questa variabile si applica solo alla sessione di shell corrente, quindi 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 codice di addestramento in un bucket Cloud Storage. AI Platform Training esegue il codice di questo pacchetto.
In questo tutorial, AI Platform Training salva anche il modello addestrato generato dal tuo job nello stesso bucket.
Per eseguire il deployment della pipeline scikit-learn che utilizza codice personalizzato in AI Platform Prediction, devi caricare gli strumenti di trasformazione personalizzati utilizzati dalla pipeline su Cloud Storage.
Quando crei la risorsa della versione di AI Platform Prediction che genera 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 bucket Cloud Storage in questa regione e, in un secondo momento, utilizza la stessa regione per l'addestramento e la previsione. Esegui il comando seguente per creare il bucket se non esiste già:
gcloud storage buckets create gs://$BUCKET_NAME --location=$REGION
Creazione di un'applicazione di addestramento e del codice della pipeline personalizzata
Crea un'applicazione per addestrare una pipeline scikit-learn con i dati del censimento. In questo tutorial, il pacchetto di addestramento contiene anche il codice personalizzato utilizzato dalla pipeline addestrata durante la previsione. Si tratta di 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 corrisponde alla seguente struttura:
census_package/
__init__.py
my_pipeline.py
train.py
Innanzitutto, crea la directory census_package/
vuota:
mkdir census_package
In 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.
Creare trasformatori personalizzati
scikit-learn fornisce molti strumenti di trasformazione che puoi utilizzare all'interno di una pipeline, ma ti consente anche di definire i tuoi strumenti di trasformazione personalizzati. Questi trasformatori possono persino apprendere uno stato salvato durante l'addestramento che viene utilizzato in un secondo momento durante la previsione.
Estendi
sklearn.base.TransformerMixin
per definire tre trasformatori:
PositionalSelector
: dato un elenco di indici C e una matrice M, restituisce una matrice con un sottoinsieme di colonne di M, indicato da C.StripString
: data una matrice di stringhe, rimuove gli spazi da ogni stringa.SimpleOneHotEncoder
: un semplice codificatore 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 il modulo di addestramento
A questo punto, crea un modulo di addestramento per addestrare la pipeline scikit-learn sui dati del censimento. Parte di questo codice prevede la definizione della pipeline.
Questo modulo di formazione consente di svolgere diverse attività:
- Scarica i dati di addestramento e li carica in un
DataFrame
Pandas che può essere utilizzato da Scikit-Learn. - Definisce la pipeline di scikit-learn da addestrare. Questo esempio utilizza 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 la funzione interna di scikit-learnStandardScaler
e quelle categoriche con l'encoder one-hot personalizzato definito inmy_pipeline.py
. Quindi combina i dati pre-elaborati come input per un classificatore. - Infine, esporta il modello utilizzando la versione di
joblib
inclusa in scikit-learn e lo salva nel tuo bucket Cloud Storage.
Scrivi il seguente codice in 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
Utilizza gcloud
per inviare un job di addestramento ad AI Platform Training. Il seguente
comando pacchettizza l'applicazione di addestramento, la carica su
Cloud Storage e indica ad AI Platform Training di eseguire il modulo di
addestramento.
L'argomento --
è un separatore: il servizio di AI Platform Training non utilizza gli argomenti che seguono il separatore, ma il modulo di addestramento 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
Esegui il deployment della pipeline e pubblica le previsioni
Per pubblicare le previsioni di AI Platform Prediction, devi eseguire il deployment di una risorsa modello e di una risorsa versione. Il modello ti aiuta a organizzare più deployment se modifichi e addestri 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 elementi:
- Una directory Cloud Storage contenente la pipeline addestrata. Il job di addestramento del passaggio precedente ha creato questo file durante l'esportazione di
model.joblib
nel tuo bucket. - Un pacchetto di distribuzione di origine
.tar.gz
in Cloud Storage contenente tutti gli strumenti di trasformazione personalizzati utilizzati dalla pipeline. Creala nel passaggio successivo.
Crea un pacchetto dei trasformatori personalizzati
Se esegui il deployment di una versione senza fornire il codice di my_pipeline.py
,
AI Platform Prediction non potrà importare i trasformatori personalizzati (ad es. mp.SimpleOneHotEncoder
) e non potrà fornire le previsioni.
Crea il seguente setup.py
per definire un pacchetto di distribuzione di origine per il tuo codice:
import setuptools
setuptools.setup(name='census_package',
packages=['census_package'],
version="1.0",
)
Quindi, esegui il seguente comando per creare dist/census_package-1.0.tar.gz
:
python setup.py sdist --formats=gztar
Infine, carica questo file tarball nel tuo bucket Cloud Storage:
gcloud storage cp ./dist/census_package-1.0.tar.gz gs://$BUCKET_NAME/custom_pipeline_tutorial/code/census_package-1.0.tar.gz
Creare risorse di modelli e versioni
Innanzitutto, definisci i nomi del modello e della versione:
MODEL_NAME='CensusPredictor'
VERSION_NAME='v1'
Utilizza quindi il seguente comando per creare la risorsa modello:
gcloud ai-platform models create $MODEL_NAME \
--regions $REGION
Infine, crea la risorsa della versione fornendo i percorsi Cloud Storage
alla directory del modello (quella che contiene model.joblib
) e al 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
Pubblicazione 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 è stato 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.
Pulizia
Per eliminare tutte le risorse Google Cloud utilizzate in questo progetto, puoi eliminare il progetto Google Cloud utilizzato per il tutorial.
In alternativa, puoi ripulire le singole risorse eseguendo i seguenti comandi:
# 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_pipeline_tutorial --recursive
Passaggi successivi
- Scopri di più su come utilizzare le pipeline scikit-learn personalizzate con AI Platform Prediction.
- Scopri come creare una routine di previsione personalizzata (beta) per un controllo ancora maggiore sulla modalità di generazione delle previsioni da parte di AI Platform Prediction.