Exécuter ce tutoriel sous forme de notebook dans Colab | Afficher le notebook sur GitHub |
Ce tutoriel explique comment utiliser AI Platform Prediction pour déployer un pipeline scikit-learn qui utilise des transformateurs personnalisés.
scikit-learn
des pipelines
vous permettent de composer
plusieurs Estimators. Par exemple, vous pouvez utiliser des transformateurs pour prétraiter les données et les transmettre après transformation à un classificateur. La plate-forme scikit-learn fournit de nombreux transformateurs dans le package sklearn
.
Vous pouvez aussi utiliser la bibliothèque scikit-learn
FunctionTransformer
ou TransformerMixin
pour créer votre propre transformateur personnalisé. Si vous souhaitez déployer un pipeline utilisant des transformateurs personnalisés pour AI Platform Prediction, vous devez fournir ce code à AI Platform Prediction comme package de distribution source.
Ce tutoriel présente un exemple de problème lié aux données de recensement pour vous guider lors des étapes suivantes :
- Entraînement d'un pipeline scikit-learn avec des transformateurs personnalisés sur le service d'entraînement AI Platform
- Déploiement du pipeline entraîné et de votre code personnalisé sur le service de prédiction AI Platform
- Envoi des requêtes de prédiction issues de ce déploiement
Ensemble de données
Ce didacticiel utilise la fonction de recensement des revenus aux États-Unis Ensemble de données fourni par l'UC Irvine Machine Learning Repository Cet ensemble de données contient des informations sur les personnes issues d'une base de données du recensement 1994, comprenant des caractéristiques d'âge, de niveau d'études, d'état civil, de profession et indiquant si le revenu de la personne est supérieur à 50 000 dollars par an.
Les données utilisées dans ce tutoriel sont disponibles dans un bucket Cloud Storage public : gs://cloud-samples-data/ai-platform/sklearn/census_data/
Objectif
L'objectif est d'entraîner un pipeline scikit-learn, qui permet de prédire si un individu gagne plus de 50 000 $ par an (étiquette cible) à partir d'autres informations issues du recensement sur la personne (caractéristiques).
Ce tutoriel porte davantage sur l'utilisation de ce modèle avec AI Platform Prediction que sur la conception du modèle. Toutefois, lors de la création de systèmes de machine learning, il est important de considérer les problèmes potentiels et les conséquences inattendues qu'impliquent de tels modèles. Consultez l'exercice du cours d'initiation au machine learning relatif au principe d'équité pour en savoir plus sur les sources de biais dans l'ensemble de données du recensement, ainsi que sur le principe d'équité dans le domaine du machine learning en général.
Coûts
Ce tutoriel utilise des composants facturables de Google Cloud :
- AI Platform Training
- AI Platform Prediction
- Cloud Storage
Découvrez les tarifs d'AI Platform Training, les tarifs d'AI Platform Prediction et les tarifs de Cloud Storage, puis utilisez le simulateur de coûts pour générer une estimation des coûts en fonction de votre utilisation prévue.
Avant de commencer
Vous devez effectuer plusieurs opérations avant de pouvoir entraîner et déployer un modèle sur AI Platform Prediction :
- Configurer l'environnement de développement local
- Configurer un projet Google Cloud avec la facturation et les API nécessaires activées
- Créer un bucket Cloud Storage pour stocker le package d'entraînement et le modèle entraîné
Configurer l'environnement de développement local
Pour suivre ce tutoriel, vous avez besoin des éléments suivants :
- Python 3
- virtualenv
- Le SDK Google Cloud
Le guide Google Cloud Configurer un environnement de développement Python fournit des instructions détaillées permettant de répondre à ces exigences. Les étapes suivantes présentent un condensé de ces instructions :
Installez virtualenv et créez un environnement virtuel utilisant Python 3.
Activez cet environnement.
Effectuez les étapes de la section suivante pour installer le SDK Cloud.
Configurer un projet 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
Authentifier le compte GCP
Pour configurer l'authentification, vous devez créer une clé de compte de service et définir une variable d'environnement pour le chemin d'accès à la clé de compte de service.
-
Créez un compte de service :
-
Dans la console Google Cloud, accédez à la page Créer un compte de service.
- Dans le champ Nom du compte de service, saisissez un nom.
- Facultatif : Dans le champ Description du compte de service, saisissez une description.
- Cliquez sur Créer.
- Cliquez sur le champ Sélectionner un rôle. Sous Tous les rôles, sélectionnez AI Platform > Administrateur AI Platform.
- Cliquez sur Ajouter un autre rôle.
-
Cliquez sur le champ Sélectionner un rôle. Sous Tous les rôles, sélectionnez Stockage > Administrateur des objets de l'espace de stockage.
-
Cliquez sur Terminé pour créer le compte de service.
Ne fermez pas la fenêtre de votre navigateur. Vous en aurez besoin lors de la tâche suivante.
-
-
Créez une clé de compte de service pour l'authentification :
- Dans la console Google Cloud, cliquez sur l'adresse e-mail du compte de service que vous avez créé.
- Cliquez sur Keys (Clés).
- Cliquez sur AJOUTER UNE CLÉ -> Créer une clé.
- Cliquez sur Créer. Un fichier de clé JSON est téléchargé sur votre ordinateur.
- Cliquez sur Close (Fermer).
-
Définissez la variable d'environnement GOOGLE_APPLICATION_CREDENTIALS de façon à pointer vers le chemin du fichier JSON contenant la clé de votre compte de service. Cette variable ne s'applique qu'à la session d'interface système actuelle. Par conséquent, si vous ouvrez une nouvelle session, vous devez la définir à nouveau.
Créer un bucket Cloud Storage
Ce tutoriel utilise Cloud Storage de plusieurs manières :
Lorsque vous envoyez une tâche d'entraînement à l'aide du SDK Cloud, vous importez un package Python contenant votre code d'entraînement dans un bucket Cloud Storage. AI Platform Training exécute le code de ce package.
Dans ce tutoriel, le modèle entraîné résultant de la tâche est enregistré par AI Platform Training dans le même bucket.
Pour déployer votre pipeline scikit-learn qui utilise le code personnalisé pour AI Platform Prediction, vous devez importer les transformateurs personnalisés que votre pipeline utilise dans Cloud Storage.
Lors de la création de la ressource de version AI Platform Prediction qui diffuse les prédictions, vous fournissez le pipeline scikit-learn entraîné, ainsi que votre code personnalisé en tant qu'URI Cloud Storage.
Définissez le nom du bucket Cloud Storage en tant que variable d'environnement. Ce nom doit être unique dans tous les buckets Cloud Storage :
BUCKET_NAME="your-bucket-name"
Sélectionnez une région dans laquelle AI Platform Training et AI Platform Prediction sont disponibles, et créez une autre variable d'environnement. Exemple :
REGION="us-central1"
Créez le bucket Cloud Storage dans cette région, puis utilisez cette même région pour l'entraînement et les prédictions. Exécutez la commande suivante pour créer le bucket s'il n'existe pas déjà :
gcloud storage buckets create gs://$BUCKET_NAME --location=$REGION
Créer une application d'entraînement et un code de pipeline personnalisé
Créez une application pour entraîner un pipeline scikit-learn avec les données de recensement. Dans ce tutoriel, le package d'entraînement contient également le code personnalisé utilisé par le pipeline entraîné lors de la prédiction. Ce modèle est utile, car les pipelines sont généralement conçus pour utiliser les mêmes transformateurs lors des opérations d'entraînement et de prédiction.
Procédez comme suit pour créer un répertoire contenant trois fichiers correspondant à la structure suivante :
census_package/
__init__.py
my_pipeline.py
train.py
Commencez par créer le répertoire vide census_package/
:
mkdir census_package
Dans le répertoire census_package/
, créez un fichier vierge nommé __init__.py
:
touch ./census_package/__init__.py
Cette opération permet d'importer census_package/
en tant que package dans Python.
Créer des transformateurs personnalisés
La plate-forme scikit-learn fournit de nombreux transformateurs que vous pouvez utiliser dans le cadre d'un pipeline, mais elle vous permet également de définir vos propres transformateurs personnalisés. Ces transformateurs peuvent même apprendre un état enregistré pendant l'entraînement, qui sera utilisé plus tard au cours de la prédiction.
Prolonger
sklearn.base.TransformerMixin
pour définir trois transformateurs:
PositionalSelector
: à partir d'une liste d'indices C et d'une matrice M, ce transformateur renvoie une matrice contenant le sous-ensemble de colonnes de M correspondant à C.StripString
: à partir d'une matrice de chaînes, ce transformateur supprime les espaces de chaque chaîne.SimpleOneHotEncoder
: un objet one-hot simple encodeur qui peut être appliqué à une matrice de chaînes.
Pour ce faire, copiez le code suivant dans un fichier nommé 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
Définir un pipeline et créer un module d'entraînement
Créez ensuite un module d'entraînement pour entraîner votre pipeline scikit-learn sur les données de recensement. Une partie de ce code implique la définition du pipeline.
Ce module d'entraînement effectue les opérations suivantes :
- Il télécharge les données d'entraînement et les charge dans un objet
DataFrame
pandas pouvant être utilisé par scikit-learn. - Il définit le pipeline scikit-learn à entraîner. Cet exemple n'utilise que trois caractéristiques numériques (
'age'
,'education-num'
et'hours-per-week'
) et trois caractéristiques catégoriques ('workclass'
,'marital-status'
et'relationship'
) issues des données d'entrée. Elle transforme les caractéristiques numériques à l'aide de l'outil intégré scikit-learnStandardScaler
puis transforme les valeurs catégorielles grâce à l'encodeur one-hot personnalisé défini dansmy_pipeline.py
. Il combine ensuite les données prétraitées en entrées à utiliser avec un classificateur. - Enfin, il exporte le modèle à l'aide de la version de
joblib
incluse dans scikit-learn et l'enregistre dans votre bucket Cloud Storage.
Écrivez le code suivant dans 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.')
Entraîner le pipeline sur AI Platform Training
Utilisez gcloud
pour envoyer une tâche d'entraînement à AI Platform Training. La commande suivante permet d'empaqueter votre application d'entraînement, de l'importer dans Cloud Storage et d'indiquer à AI Platform Training d'exécuter votre module d'entraînement.
L'argument --
est un séparateur : le service AI Platform Training n'utilise pas d'arguments qui suivent le séparateur, mais votre module d'entraînement peut toujours y accéder.
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
Déployer le pipeline et diffuser les prédictions
Pour diffuser des prédictions depuis AI Platform Prediction, vous devez déployer une ressource de modèle et une ressource de version. Le modèle vous aide à organiser plusieurs déploiements si vous modifiez et entraînez votre pipeline plusieurs fois. La version utilise votre modèle entraîné et votre code personnalisé pour diffuser des prédictions.
Pour déployer ces ressources, vous devez fournir les deux artefacts suivants :
- Un bucket Cloud Storage contenant votre pipeline entraîné. La tâche d'entraînement de l'étape précédente a créé ce fichier lors de l'exportation de
model.joblib
vers votre bucket. - Un package de distribution source
.tar.gz
dans Cloud Storage contenant tous les transformateurs personnalisés utilisés par votre pipeline. Vous allez le créer lors de l'étape suivante.
Empaqueter les transformateurs personnalisés
Si vous déployez une version sans fournir le code de my_pipeline.py
, le service AI Platform Prediction ne pourra pas importer les transformateurs personnalisés (par exemple, mp.SimpleOneHotEncoder
), ni diffuser des prédictions.
Créez le fichier setup.py
suivant pour définir un package de distribution source pour votre code :
import setuptools
setuptools.setup(name='census_package',
packages=['census_package'],
version="1.0",
)
Exécutez ensuite la commande suivante pour créer dist/census_package-1.0.tar.gz
:
python setup.py sdist --formats=gztar
Enfin, importez ce package tarball sur le 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
Créer des ressources de modèle et de version
Commencez par définir les noms de modèle et de version :
MODEL_NAME='CensusPredictor'
VERSION_NAME='v1'
Créez ensuite la ressource de modèle à l'aide de la commande suivante :
gcloud ai-platform models create $MODEL_NAME \
--regions $REGION
Enfin, créez la ressource de version en fournissant des chemins d'accès Cloud Storage à votre répertoire de modèle (contenant model.joblib
) et à votre code personnalisé (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
Diffuser des prédictions en ligne
Testez votre déploiement en envoyant une requête de prédiction en ligne. Commencez par installer la bibliothèque cliente des API Google pour Python :
pip install --upgrade google-api-python-client
Envoyez ensuite deux instances issues des données de recensement à votre version déployée :
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 version transmet les données d'entrée via le pipeline entraîné et renvoie les résultats du classificateur : <=50K
ou >50K
pour chaque instance, en fonction de sa prédiction concernant la tranche de revenu de la personne.
Nettoyer
Pour nettoyer toutes les ressources Google Cloud utilisées dans ce projet, vous pouvez supprimez le bucket Google Cloud projet que vous avez utilisés pour ce tutoriel.
Vous pouvez également nettoyer des ressources individuelles en exécutant les commandes suivantes :
# 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
Étape suivante
- Découvrez comment utiliser des pipelines scikit-learn personnalisés avec AI Platform Prediction.
- Découvrez comment créer une routine de prédiction personnalisée (version bêta) pour encore plus de contrôle sur la manière dont AI Platform Prediction diffuse les prédictions.