Snowpark ML Modeling : modèle de développement ML¶
Note
L’API Snowpark ML Modeling est généralement disponible à partir du paquet version 1.1.1.
L’API Snowpark ML Modeling utilise des frameworks Python familiers tels que scikit-learn et XGBoost pour le prétraitement des données, l’ingénierie des fonctions et l’entraînement des modèles à l’intérieur de Snowflake.
Les avantages du développement de modèles avec Snowpark ML Modeling incluent :
Ingénierie des fonctions et prétraitement : Améliorer les performances et l’évolutivité avec une exécution distribuée pour les fonctions de prétraitement scikit-learn fréquemment utilisées.
Entraînement des modèles : Accélérer l’entraînement pour les modèles scikit-learn, XGBoost et LightGBM sans avoir à créer manuellement des procédures stockées ou des fonctions définies par l’utilisateur (UDFs), en tirant parti de l’optimisation distribuée des hyperparamètres.
L’API Snowpark ML Modeling fournit des estimateurs et des transformateurs qui comportent des APIs similaires à celles des bibliothèques scikit-learn, xgboost et lightgbm. Vous pouvez utiliser ces APIs pour construire et entraîner des modèles de machine learning qui peuvent être utilisés avec Snowpark ML Operations, comme le registre des modèles de Snowpark.
Astuce
Voir Introduction au machine learning avec Snowpark ML pour un exemple de workflow de bout en bout dans Snowpark ML, y compris l’API de modélisation.
Note
Cette rubrique suppose que Snowpark ML et ses dépendances de modélisation sont déjà installés. Voir Installation de Snowpark ML.
Exemples¶
Examinez les exemples suivants pour vous faire une idée des similitudes entre l’API Snowpark ML Modeling et les bibliothèques de machine learning que vous connaissez peut-être.
Prétraitement¶
Cet exemple illustre l’utilisation des fonctions de prétraitement et de transformation des données de Snowpark ML Modeling. Les deux fonctions de prétraitement utilisées dans l’exemple (MixMaxScaler
et OrdinalEncoder
) utilisent le moteur de traitement distribué de Snowflake pour améliorer considérablement les performances par rapport aux implémentations côté client ou des procédures stockées. Pour plus de détails, voir Prétraitement distribué.
import numpy as np
import pandas as pd
import random
import string
from sklearn.datasets import make_regression
from snowflake.ml.modeling.preprocessing import MinMaxScaler, OrdinalEncoder
from snowflake.ml.modeling.pipeline import Pipeline
from snowflake.snowpark import Session
# Create a session with your preferred method
# session =
NUMERICAL_COLS = ["X1", "X2", "X3"]
CATEGORICAL_COLS = ["C1", "C2", "C3"]
FEATURE_COLS = NUMERICAL_COLS + CATEGORICAL_COLS
CATEGORICAL_OUTPUT_COLS = ["C1_OUT", "C2_OUT", "C3_OUT"]
FEATURE_OUTPUT_COLS = ["X1_FEAT_OUT", "X2_FEAT_OUT", "X3_FEAT_OUT", "C1_FEAT_OUT", "C2_FEAT_OUT", "C3_FEAT_OUT"]
# Create a dataset with numerical and categorical features
X, _ = make_regression(
n_samples=1000,
n_features=3,
noise=0.1,
random_state=0,
)
X = pd.DataFrame(X, columns=NUMERICAL_COLS)
def generate_random_string(length):
return "".join(random.choices(string.ascii_uppercase, k=length))
categorical_feature_length = 2
categorical_features = {}
for c in CATEGORICAL_COLS:
categorical_column = [generate_random_string(categorical_feature_length) for _ in range(X.shape[0])]
categorical_features[c] = categorical_column
X = X.assign(**categorical_features)
features_df = session.create_dataframe(X)
# Fit a pipeline with OrdinalEncoder and MinMaxScaler on Snowflake
pipeline = Pipeline(
steps=[
(
"OE",
OrdinalEncoder(
input_cols=CATEGORICAL_COLS,
output_cols=CATEGORICAL_OUTPUT_COLS,
)
),
(
"MMS",
MinMaxScaler(
input_cols=NUMERICAL_COLS + CATEGORICAL_OUTPUT_COLS,
output_cols=FEATURE_OUTPUT_COLS,
)
),
]
)
pipeline.fit(features_df)
# Use the pipeline to transform a dataset.
result = pipeline.transform(features_df)
Formation¶
Cet exemple montre comment former un modèle de classificateur xgboost simple en utilisant Snowpark ML Modeling, puis comment exécuter des prédictions. Ici, l’API Snowpark ML est similaire à xgboost, avec seulement quelques différences près dans la façon dont les colonnes sont spécifiées. Pour plus de détails sur ces différences, voir Différences générales entre les API.
import pandas as pd
from sklearn.datasets import make_classification
from snowflake.ml.modeling.xgboost import XGBClassifier
from snowflake.ml.utils.connection_params import SnowflakeLoginOptions
from snowflake.snowpark import Session
# Create a session with your preferred method
# session =
FEATURE_COLS = ["X1", "X2", "X3", "X4", "X5", "X6"]
LABEL_COLS = ["Y"]
OUTPUT_COLS = ["PREDICTIONS"]
# Set up data.
X, y = make_classification(
n_samples=40000,
n_features=6,
n_informative=4,
n_redundant=1,
random_state=0,
shuffle=True,
)
X = pd.DataFrame(X, columns=FEATURE_COLS)
y = pd.DataFrame(y, columns=LABEL_COLS)
features_pandas = pd.concat([X, y], axis=1)
features_df = session.create_dataframe(features_pandas)
# Train an XGBoost model on snowflake.
xgboost_model = XGBClassifier(
input_cols=FEATURE_COLS,
label_cols=LABEL_COLS,
output_cols=OUTPUT_COLS
)
xgboost_model.fit(features_df)
# Use the model to make predictions.
predictions = xgboost_model.predict(features_df)
predictions[OUTPUT_COLS].show()
Prétraitement et formation des fonctions sur des données non synthétiques¶
Cet exemple utilise les données de particules gamma haute énergie d’un télescope Cherenkov atmosphérique au sol. Le télescope observe les particules gamma haute énergie, en tirant parti du rayonnement émis par les particules chargées produites dans les gerbes électromagnétiques initiées par les rayons gamma. Le détecteur enregistre le rayonnement Cherenkov (des longueurs d’onde visibles à ultraviolettes) qui traverse l’atmosphère, ce qui permet de reconstruire les paramètres de gerbe gamma. Le télescope détecte également les rayons d’hadrons abondants dans les gerbes cosmiques et qui produisent des signaux qui imitent les rayons gamma.
L’objectif est de développer un modèle de classification permettant de distinguer les rayons gamma des rayons d’hadrons. Le modèle permet aux scientifiques de filtrer le bruit de fond et de se concentrer sur les véritables signaux de rayons gamma. Les rayons gamma permettent aux scientifiques d’observer des événements cosmiques tels que la naissance et la mort des étoiles, les explosions cosmiques et le comportement de la matière dans des conditions extrêmes.
Les données des particules peuvent être téléchargées à partir du Télescope gamma MAGIC. Téléchargez et décompressez les données, définissez la variable DATA_FILE_PATH
pour qu’elle pointe vers le fichier de données, et exécutez le code ci-dessous pour le charger dans Snowflake.
DATA_FILE_PATH = "~/Downloads/magic+gamma+telescope/magic04.data"
# Setup
from snowflake.ml.utils.connection_params import SnowflakeLoginOptions
from snowflake.snowpark import Session
import posixpath
import os
##
# Note: Create session https://docs.snowflake.com/en/developer-guide/snowpark/reference/python/latest/api/snowflake.snowpark.Session
##
session = Session.builder.configs(SnowflakeLoginOptions()).create()
session.sql("""
CREATE OR REPLACE TABLE Gamma_Telescope_Data(
F_LENGTH FLOAT,
F_WIDTH FLOAT,
F_SIZE FLOAT,
F_CONC FLOAT,
F_CONC1 FLOAT,
F_ASYM FLOAT,
F_M3_LONG FLOAT,
F_M3_TRANS FLOAT,
F_ALPHA FLOAT,
F_DIST FLOAT,
CLASS VARCHAR(10))
""").collect()
session.sql("CREATE OR REPLACE STAGE SNOWPARK_ML_TEST_DATA_STAGE").collect()
session.file.put(
DATA_FILE_PATH,
"SNOWPARK_ML_TEST_DATA_STAGE/magic04.data",
auto_compress=False,
overwrite=True,
)
session.sql("""
COPY INTO Gamma_Telescope_Data FROM @SNOWPARK_ML_TEST_DATA_STAGE/magic04.data
FILE_FORMAT = (TYPE = 'CSV' field_optionally_enclosed_by='"',SKIP_HEADER = 0);
""").collect()
session.sql("select * from Gamma_Telescope_Data limit 5").collect()
Une fois les données chargées, utilisez le code suivant pour effectuer la formation et des prédictions, en procédant comme suit.
Prétraitez les données :
Remplacez les valeurs manquantes par la moyenne.
Centrez les données à l’aide d’une échelle standard.
Formez un classificateur xgboost pour déterminer le type d’événements.
Testez la précision du modèle sur les ensembles de données de formation et de test.
from snowflake.ml.utils.connection_params import SnowflakeLoginOptions
from snowflake.snowpark import Session, DataFrame
from snowflake.ml.modeling.preprocessing import StandardScaler
from snowflake.ml.modeling.impute import SimpleImputer
from snowflake.ml.modeling.pipeline import Pipeline
from snowflake.ml.modeling.xgboost import XGBClassifier
from snowflake.ml.modeling.metrics import accuracy_score
##
# Note: Create session https://docs.snowflake.com/en/developer-guide/snowpark/reference/python/latest/api/snowflake.snowpark.Session
##
session = Session.builder.configs(SnowflakeLoginOptions()).create()
# Step 1: Create train and test dataframes
all_data = session.sql("select *, IFF(CLASS = 'g', 1.0, 0.0) as LABEL from Gamma_Telescope_Data").drop("CLASS")
train_data, test_data = all_data.random_split(weights=[0.9, 0.1], seed=0)
# Step 2: Construct training pipeline with preprocessing and modeling steps
FEATURE_COLS = [c for c in train_data.columns if c != "LABEL"]
LABEL_COLS = ["LABEL"]
pipeline = Pipeline(steps = [
("impute", SimpleImputer(input_cols=FEATURE_COLS, output_cols=FEATURE_COLS)),
("scaler", StandardScaler(input_cols=FEATURE_COLS, output_cols=FEATURE_COLS)),
("model", XGBClassifier(input_cols=FEATURE_COLS, label_cols=LABEL_COLS))
])
# Step 3: Train
pipeline.fit(train_data)
# Step 4: Eval
predict_on_training_data = pipeline.predict(train_data)
training_accuracy = accuracy_score(df=predict_on_training_data, y_true_col_names=["LABEL"], y_pred_col_names=["OUTPUT_LABEL"])
predict_on_test_data = pipeline.predict(test_data)
eval_accuracy = accuracy_score(df=predict_on_test_data, y_true_col_names=["LABEL"], y_pred_col_names=["OUTPUT_LABEL"])
print(f"Training accuracy: {training_accuracy} \nEval accuracy: {eval_accuracy}")
Optimisation distribuée des hyperparamètres¶
Cet exemple montre comment exécuter l’optimisation distribuée des hyperparamètres en utilisant GridSearchCV
de scikit-learn de l’implémentation de Snowpark ML. Les cycles individuels sont exécutés en parallèle via les ressources de calcul d’entrepôt distribué. Pour plus de détails sur l’optimisation distribuée des hyperparamètres, voir Optimisation distribuée des hyperparamètres.
from snowflake.snowpark import Session, DataFrame
from snowflake.ml.utils.connection_params import SnowflakeLoginOptions
from sklearn.datasets import make_classification
from snowflake.snowpark import Session, DataFrame
from snowflake.ml.modeling.xgboost import XGBClassifier
from snowflake.ml.modeling.model_selection.grid_search_cv import GridSearchCV
FEATURE_COLS = ["X1", "X2", "X3", "X4", "X5", "X6"]
LABEL_COLS = ["Y"]
OUTPUT_COLS = ["PREDICTIONS"]
# Create a session using your favorite login option.
# In this example we use a session builder with `SnowflakeLoginOptions`.
session = Session.builder.configs(SnowflakeLoginOptions()).create()
# Set up data.
def set_up_data(session: Session, n_samples: int) -> DataFrame:
X, y = make_classification(
n_samples=n_samples,
n_features=6,
n_informative=2,
n_redundant=0,
random_state=0,
shuffle=True,
)
X = pd.DataFrame(X, columns=FEATURE_COLS)
y = pd.DataFrame(y, columns=LABEL_COLS)
features_pandas = pd.concat([X, y], axis=1)
features_pandas.head()
features_df = session.create_dataframe(features_pandas)
return features_df
features_df = set_up_data(session, 10**4)
# Create a warehouse to use for the tuning job.
session.sql(
"""
CREATE or replace warehouse HYPERPARAM_WH
WITH WAREHOUSE_SIZE = 'X-SMALL'
WAREHOUSE_TYPE = 'Standard'
AUTO_SUSPEND = 60
AUTO_RESUME = TRUE
INITIALLY_SUSPENDED = FALSE;"""
).collect()
session.use_warehouse("HYPERPARAM_WH")
# Tune an XGB Classifier model using sklearn GridSearchCV.
DISTRIBUTIONS = dict(
n_estimators=[10, 50],
learning_rate=[0.01, 0.1, 0.2],
)
estimator = XGBClassifier()
grid_search_cv = GridSearchCV(estimator=estimator, param_grid=DISTRIBUTIONS, input_cols=FEATURE_COLS, label_cols=LABEL_COLS, output_cols=OUTPUT_COLS)
grid_search_cv.fit(features_df)
# Use the best model to make predictions.
predictions = grid_search_cv.predict(features_df)
predictions[OUTPUT_COLS].show()
# Retrieve sklearn model, and print the best score
sklearn_grid_search_cv = grid_search_cv.to_sklearn()
print(sklearn_grid_search_cv.best_score_)
Pour bien comprendre la puissance de l’optimisation distribuée, il faut s’entraîner sur un million de lignes de données.
large_features_df = set_up_data(session, 10**6)
# Scale up the warehouse for a faster fit. This takes 2m15s to run on an L warehouse versus 4m5s on a XS warehouse.
session.sql(f"ALTER WAREHOUSE {session.get_current_warehouse()} SET WAREHOUSE_SIZE='LARGE'").collect()
grid_search_cv.fit(large_features_df)
print(grid_search_cv.to_sklearn().best_score_)
Classes Snowpark ML Modeling¶
Toutes les classes Snowpark ML Modeling et les classes de prétraitement se trouvent dans l’espace de noms snowflake.ml.modeling
. Les modules Snowpark ML portent le même nom que les modules correspondants de l’espace de noms sklearn
. Par exemple, le module Snowpark ML correspondant à sklearn.calibration
est snowflake.ml.modeling.calibration
. Les modules xgboost
et lightgbm
correspondent respectivement à snowflake.ml.modeling.xgboost
et snowflake.ml.modeling.lightgbm
.
L’API Snowpark ML Modeling fournit des wrappers pour les classes scikit-learn, xgboost et lightgbm sous-jacentes, la majorité d’entre elles étant exécutées sous forme de procédures stockées (sur un seul nœud d’entrepôt) dans l’entrepôt virtuel. Toutes les classes de scikit-learn ne sont pas prises en charge dans Snowpark ML. Voir la Référence API Snowpark ML pour une liste des classes actuellement disponibles.
Certaines classes (notamment les classes métriques et de prétraitement) prennent en charge l’exécution distribuée et peuvent offrir des avantages significatifs en termes de performances par rapport à l’exécution locale des mêmes opérations. Pour plus d’informations, voir Prétraitement distribué et Optimisation distribuée des hyperparamètres. Le tableau ci-dessous répertorie les classes spécifiques qui prennent en charge l’exécution distribuée.
Nom du module Snowpark ML |
Classes distribuées |
---|---|
|
|
|
|
|
|
|
|
Différences générales entre les API¶
Astuce
Consultez la référence d” API Snowpark ML pour plus de détails sur la modélisation des API.
Snowpark ML Modeling comprend des algorithmes de prétraitement, de transformation et de prédiction des données basés sur scikit-learn, xgboost et lightgbm. Les classes Python de Snowpark remplacent les classes correspondantes des paquets d’origine, avec des signatures similaires. Cependant, ces APIs sont conçues pour fonctionner avec des DataFrames Snowpark plutôt qu’avec des tableaux NumPy.
Bien que l’API de Snowpark ML Modeling soit similaire à celle de scikit-learn, il existe quelques différences clés. Cette section explique comment appeler les méthodes __init__
(constructeur), fit
, et predict
pour les classes d’estimateurs et de transformateurs fournies dans Snowpark ML.
Le constructeur de toutes les classes Python de Snowpark ML accepte cinq paramètres supplémentaires (
input_cols
,output_cols
,sample_weight_col
,label_cols
, etdrop_input_cols
) en plus des paramètres acceptés par les classes équivalentes dans scikit-learn, xgboost ou lightgbm. Il s’agit de chaînes ou de séquences de chaînes qui spécifient les noms des colonnes d’entrée, des colonnes de sortie, de la colonne de poids de l’échantillon et des colonnes de balises dans un DataFrame Snowpark ou Pandas.Les méthodes
fit
etpredict
de Snowpark ML acceptent un seul DataFrame plutôt que des tableaux séparés représentant les données d’entrée, les balises et les poids. Avec Snowpark ML, vous spécifiez les noms des colonnes à utiliser à ces fins lorsque vous instanciez la classe ; ces noms sont ensuite utilisés pour trouver les colonnes requises dans le DataFrame que vous transmettez àfit
oupredict
. Consultez fit et predict.Les méthodes
transform
etpredict
de Snowpark ML renvoient un DataFrame contenant toutes les colonnes du DataFrame transmis à la méthode, avec le résultat de la prédiction stocké dans des colonnes supplémentaires. (Vous pouvez effectuer une transformation sur place en spécifiant les noms de colonne d’entrée correspondant aux noms de colonne de sortie, ou supprimer les colonnes d’entrée en transmettantdrop_input_cols = True
.) Les équivalents scikit-learn, xgboost et lightgbm renvoient des tableaux contenant uniquement les résultats.Les transformateurs Snowpark Python n’ont pas de méthode
fit_transform
. Cependant, comme avec scikit-learn, la validation des paramètres n’est effectuée que dans la méthodefit
. Vous devez donc appelerfit
à un moment donné avanttransform
, même si le transformateur n’effectue aucun ajustement.fit
renvoie le transformateur, de sorte que les appels de méthode peuvent être chaînés, par exempleBinarizer(threshold=0.5).fit(df).transform(df)
.Les transformateurs Snowpark ML n’ont pas de méthode
inverse_transform
. Cette méthode n’est pas nécessaire avec Snowpark ML, car la représentation d’origine reste disponible dans les colonnes d’entrée du DataFrame d’entrée, qui sont préservées à moins que vous n’effectuiez explicitement une transformation sur place en spécifiant les mêmes noms pour les colonnes d’entrée et de sortie.
Vous pouvez convertir n’importe quel objet de modélisation Snowpark ML en objet scikit-learn, xgboost ou lightgbm correspondant, ce qui vous permet d’utiliser l’ensemble des méthodes et attributs du type sous-jacent. Voir Récupération du modèle sous-jacent.
Construction d’un modèle¶
En plus des paramètres acceptés par les classes de modèles scikit-learn individuelles, toutes les classes Snowpark ML Modeling acceptent les paramètres supplémentaires suivants lors de l’instanciation.
Ces paramètres sont tous techniquement facultatifs, mais vous souhaiterez souvent spécifier input_cols
, output_cols
, ou les deux. label_cols
et sample_weight_col
sont nécessaires dans les situations spécifiques indiquées dans la table, mais peuvent être omis dans d’autres cas.
Astuce
Tous les noms de colonne doivent respecter les conditions d’identificateur Snowflake. Pour préserver la casse ou utiliser des caractères spéciaux (autres que le signe dollar et le trait de soulignement) lors de la création d’une table, les noms de colonnes doivent être placés entre guillemets doubles. Utilisez les noms de colonne tout en majuscules dans la mesure du possible pour maintenir la compatibilité avec la sensibilité à la casse des DataFrames Pandas.
from snowflake.ml.modeling.preprocessing import MinMaxScaler
from snowflake.snowpark import Session
# Snowflake identifiers are not case sensitive by default.
# These column names will be automatically updated to ["COLUMN_1", "COLUMN_2", "COLUMN_3"] by the Snowpark DataFrame.
schema = ["column_1", "column_2", "column_3"]
df = session.create_dataframe([[1, 2, 3]], schema = schema)
df.show()
--------------------------------------
|"COLUMN_1" |"COLUMN_2" |"COLUMN_3"|
--------------------------------------
|1 |2 |3 |
--------------------------------------
# Identify the column names using the Snowflake identifier.
input_cols = ["COLUMN_1", "COLUMN_2", "COLUMN_3"]
mms = MinMaxScaler(input_cols=input_cols)
mms.fit(df)
# To maintain lower case column names, include a double quote within the string.
schema = ['"column_1"', '"column_2"', '"column_3"']
df = session.create_dataframe([[1, 2, 3]], schema = schema)
df.show()
----------------------------------------
|'"column_1"'|'"column_2"'|'"column_3"'|
----------------------------------------
|1 |2 |3 |
----------------------------------------
# Since no conversion took place, the schema labels can be used as the column identifiers.
mms = MinMaxScaler(input_cols=schema)
mms.fit(df)
Paramètre |
Description |
---|---|
|
Chaîne ou liste de chaînes représentant les noms des colonnes qui contiennent des fonctions. Si vous omettez ce paramètre, toutes les colonnes du DataFrame d’entrée, à l’exception des colonnes spécifiées par les paramètres |
|
Chaîne ou liste de chaînes représentant les noms des colonnes qui contiennent des balises. Vous devez spécifier des colonnes de balises pour les estimateurs supervisés, car l’inférence de ces colonnes n’est pas possible. Ces colonnes de balises sont utilisées comme cibles pour les prédictions du modèle et doivent être clairement distinguées des |
|
Chaîne ou liste de chaînes représentant les noms des colonnes qui stockeront la sortie des opérations Si vous omettez ce paramètre, les noms des colonnes de sortie sont dérivés via l’ajout d’un préfixe Pour la transformation en place, transmettez les mêmes noms pour |
|
Chaîne ou liste de chaînes indiquant les noms des colonnes à exclure de la formation, de la transformation et de l’inférence. Les colonnes intermédiaires restent intactes entre les DataFrames d’entrée et de sortie. Cette option s’avère utile lorsque vous souhaitez éviter d’utiliser des colonnes spécifiques, telles que les colonnes d’index, lors de la formation ou de l’inférence, mais que vous ne transmettez pas de |
|
Chaîne représentant le nom de la colonne contenant les poids des exemples. Cet argument est nécessaire pour les ensembles de données pondérés. |
|
Valeur booléenne indiquant si les colonnes d’entrée sont supprimées du résultat DataFrame. La valeur par défaut est |
Exemple¶
Le constructeur DecisionTreeClassifier
n’a pas d’arguments obligatoires dans scikit-learn ; tous les arguments ont des valeurs par défaut. Ainsi, dans scikit-learn, vous pourriez écrire :
from sklearn.tree import DecisionTreeClassifier
model = DecisionTreeClassifier()
Dans Snowpark ML, vous devez spécifier les noms des colonnes (ou accepter les valeurs par défaut en ne les spécifiant pas). Dans cet exemple, ils sont explicitement spécifiés.
Vous pouvez initialiser un Snowpark ML DecisionTreeClassifier
en transmettant les arguments directement au constructeur ou en les définissant comme attributs du modèle après l’instanciation. (Les attributs peuvent être modifiés à tout moment.)
En tant qu’arguments du constructeur :
from snowflake.ml.modeling.tree import DecisionTreeClassifier model = DecisionTreeClassifier( input_cols=feature_column_names, label_cols=label_column_names, sample_weight_col=weight_column_name, output_cols=expected_output_column_names )
En définissant des attributs du modèle :
from snowflake.ml.modeling.tree import DecisionTreeClassifier model = DecisionTreeClassifier() model.set_input_cols(feature_column_names) model.set_label_cols(label_column_names) model.set_sample_weight_col(weight_column_name) model.set_output_cols(output_column_names)
fit
¶
La méthode fit
d’un classificateur Snowpark ML prend un seul DataFrame Snowpark ou Pandas contenant toutes les colonnes, y compris les fonctions, les balises et les poids. Cela diffère de la méthode fit
de scikit-learn, qui prend des entrées séparées pour les fonctions, les balises et les poids.
Dans scikit-learn, l’appel à la méthode DecisionTreeClassifier.fit
ressemble à ceci :
model.fit(
X=df[feature_column_names], y=df[label_column_names], sample_weight=df[weight_column_name]
)
Dans Snowpark ML, il vous suffit de transmettre le DataFrame. Vous avez déjà défini les noms des colonnes d’entrée, de balise et de poids lors de l’initialisation ou à l’aide des méthodes setter, comme indiqué dans Construction d’un modèle.
model.fit(df)
predict
¶
La méthode predict
d’une classe Snowpark ML prend également un seul DataFrame Snowpark ou Pandas contenant toutes les colonnes de fonctions. Le résultat est un DataFrame qui contient toutes les colonnes du DataFrame d’entrée inchangées et les colonnes de sortie ajoutées. Vous devez extraire les colonnes de sortie de ce DataFrame. Cette méthode est différente de la méthode predict
de scikit-learn, qui ne renvoie que les résultats.
Exemple¶
Dans scikit-learn, predict
ne renvoie que les résultats de la prédiction :
prediction_results = model.predict(X=df[feature_column_names])
Pour obtenir uniquement les résultats de la prédiction dans Snowpark ML, extrayez les colonnes de sortie du DataFrame renvoyé. Ici, output_column_names
est une liste contenant les noms des colonnes de sortie :
prediction_results = model.predict(df)[output_column_names]
Prétraitement distribué¶
De nombreuses fonctions de prétraitement et de transformation de données dans Snowpark ML sont mises en œuvre via le moteur d’exécution distribuée de Snowflake, qui apporte des avantages significatifs en termes de performances par rapport à l’exécution sur un seul nœud (c’est-à-dire, les procédures stockées). Pour savoir quelles fonctions prennent en charge l’exécution distribuée, voir Classes Snowpark ML Modeling.
Le graphique ci-dessous illustre les chiffres des performances de grands ensembles de données publics, exécutés dans un entrepôt moyen optimisé par Snowpark, en comparant scikit-learn exécuté dans des procédures stockées aux implémentations distribuées de Snowpark ML. Dans de nombreux scénarios, votre code peut s’exécuter 25 à 50 fois plus vite via Snowpark ML Modeling.
Mode de distribution des ajustements (« fits »)¶
La méthode fit
d’un transformateur de prétraitement Snowpark ML accepte un DataFrame Snowpark ou pandas, ajuste l’ensemble de données et renvoie le transformateur ajusté.
Pour les DataFrames Snowpark, l’ajustement distribué utilise le moteur SQL. Le transformateur génère des requêtes SQL pour calculer les états nécessaires (tels que la moyenne, le maximum ou le nombre). Ces requêtes sont ensuite exécutées par Snowflake et les résultats sont matérialisés localement. Pour les états complexes qui ne peuvent être calculés dans SQL, le transformateur récupère des résultats intermédiaires auprès de Snowflake et effectue des calculs locaux sur les métadonnées.
Pour les transformateurs complexes qui nécessitent des tables d’états temporaires lors de la transformation (par exemple,
OneHotEncoder
ouOrdinalEncoder
), ces tables sont représentées localement via des DataFrames pandas.Les DataFrames pandas sont ajustés localement, de manière similaire à l’ajustement avec scikit-learn. Le transformateur crée un transformateur scikit-learn correspondant avec les paramètres fournis. Ensuite, le transformateur scikit-learn est ajusté, et le transformateur Snowpark ML dérive les états nécessaires de l’objet scikit-learn.
Mode de distribution des transformations¶
La méthode transform
d’un transformateur de prétraitement Snowpark ML accepte un DataFrame Snowpark ou Pandas, transforme l’ensemble de données et renvoie un ensemble de données transformé.
Pour les DataFrames Snowpark, la transformation distribuée est effectuée via le moteur SQL. Le transformateur ajusté génère un DataFrame Snowpark avec des requêtes SQL sous-jacentes représentant l’ensemble de données transformé. La méthode
transform
effectue une évaluation « paresseuse » (approximative) pour les transformations simples (par exemple,StandardScaler
ouMinMaxScaler
), de sorte qu’aucune transformation n’est en fait effectuée via la méthodetransform
.En revanche, certaines transformations complexes impliquent une exécution. Cela inclut des transformateurs qui nécessitent des tables d’états temporaires (telles que
OneHotEncoder
etOrdinalEncoder
) pendant la transformation. Dans ce cas, le transformateur crée une table temporaire à partir du DataFrame Pandas (qui stocke l’état de l’objet) pour les jointures et d’autres opérations. Il en va de même lorsque certains paramètres sont définis. Par exemple, lorsque le transformateur est défini de sorte à traiter les valeurs inconnues trouvées lors de la transformation en déclenchant des erreurs, il matérialise les données, y compris les colonnes, les valeurs inconnues, etc.Les DataFrames Pandas sont transformés localement, de manière similaire à la transformation avec scikit-learn. Le transformateur crée un transformateur scikit-learn correspondant via l’API
to_sklearn
et effectue la transformation en mémoire.
Optimisation distribuée des hyperparamètres¶
Le réglage des hyperparamètres fait partie intégrante du flux de travail de la science des données. L’API Snowpark ML fournit des implémentations distribuées des APIs GridSearchCV
et RandomizedSearchCV
scikit-learn pour permettre le réglage efficace des hyperparamètres dans des entrepôts à un ou plusieurs nœuds.
Astuce
Snowpark ML active par défaut l’optimisation distribuée des hyperparamètres. Pour la désactiver, utilisez l’importation Python suivante.
import snowflake.ml.modeling.parameters.disable_distributed_hpo
Note
Le plus petit entrepôt virtuel Snowflake (XS) ou l’entrepôt optimisé par Snowpark (M) comporte un nœud. Chaque taille supérieure successive double le nombre de nœuds.
Pour les entrepôts à un seul nœud (XS), la capacité totale du nœud est utilisée par défaut à l’aide du cadre de multitraitement joblib de scikit-learn.
Astuce
Dans un entrepôt à un seul nœud (entrepôt standard XS ou entrepôt optimisé par Snowpark M), si vous rencontrez des erreurs de manque de mémoire, essayez de réduire le parallélisme en spécifiant le paramètre n_jobs
. La valeur par défaut de n_jobs
, -1, utilise tous les cœurs.
Pour les entrepôts à plusieurs nœuds, les opérations fit
de votre tâche de réglage de validation croisée sont réparties entre les nœuds. Aucune modification de code n’est nécessaire pour monter en échelle. Les ajustements de l’estimateur sont exécutés en parallèle sur tous les cœurs disponibles sur tous les nœuds de l’entrepôt.
À titre d’illustration, considérons l”ensemble de données sur le logement en Californie fourni avec la bibliothèque scikit-learn. Il comprend 20 640 lignes de données fournissant les informations suivantes :
MedInc : Revenu moyen du groupe de pâtés de maisons
HouseAge : Âge moyen du foyer du groupe de pâtés de maisons
AveRooms : Nombre moyen de pièces par foyer
AveBedrms : Nombre moyen de chambres à coucher par foyer
Population : Population du groupe de pâtés de maisons
AveOccup : Nombre moyen de membres du foyer
Latitude et Longitude
La cible de l’ensemble de données est le revenu moyen, exprimé en centaines de milliers de dollars.
Dans cet exemple, nous effectuons une validation croisée via une recherche par grille sur une régression de forêt aléatoire afin de trouver la meilleure combinaison d’hyperparamètres pour prédire le revenu moyen.
from snowflake.ml.modeling.ensemble.random_forest_regressor import RandomForestRegressor
from snowflake.ml.modeling.model_selection.grid_search_cv import GridSearchCV
from sklearn import datasets
def load_housing_data() -> DataFrame:
input_df_pandas = datasets.fetch_california_housing(as_frame=True).frame
# Set the columns to be upper case for consistency with Snowflake identifiers.
input_df_pandas.columns = [c.upper() for c in input_df_pandas.columns]
input_df = session.create_dataframe(input_df_pandas)
return input_df
input_df = load_housing_data()
# Use all the columns besides the median value as the features
input_cols = [c for c in input_df.columns if not c.startswith("MEDHOUSEVAL")]
# Set the target median value as the only label columns
label_cols = [c for c in input_df.columns if c.startswith("MEDHOUSEVAL")]
DISTRIBUTIONS = dict(
max_depth=[80, 90, 100, 110],
min_samples_leaf=[1,3,10],
min_samples_split=[1.0, 3,10],
n_estimators=[100,200,400]
)
estimator = RandomForestRegressor()
n_folds = 5
clf = GridSearchCV(estimator=estimator, param_grid=DISTRIBUTIONS, cv=n_folds, input_cols=input_cols, label_cols=label_col)
clf.fit(input_df)
Cet exemple s’exécute en un peu plus de 7 minutes sur un entrepôt moyen (Medium) (un seul nœud) optimisé par Snowpark, et ne prend que 3 minutes pour s’exécuter sur un entrepôt X-Large.
Déploiement et exécution de votre modèle¶
Le résultat de l’entraînement d’un modèle est un objet de modèle Python Snowpark ML. Vous pouvez utiliser le modèle entraîné pour faire des prédictions en appelant la méthode predict
du modèle. Cela crée une fonction temporaire définie par l’utilisateur pour exécuter le modèle dans votre entrepôt virtuel Snowflake. Cette fonction est automatiquement supprimée à la fin de votre session Snowpark ML (par exemple, lorsque votre script se termine, ou lorsque vous fermez votre Jupyter Notebook).
Pour conserver la fonction définie par l’utilisateur après la fin de votre session, vous pouvez la créer manuellement. Consultez les guide de démarrage rapide sur le thème pour plus d’informations.
Le registre des modèles de Snowpark ML, une fonction à venir, prend également en charge les modèles persistants et facilite leur recherche et leur déploiement. Voir le Guide de démarrage rapide pour une introduction au registre de modèle ainsi que d’autres fonctions de Snowpark ML.
Pipeline pour les transformations multiples¶
Avec scikit-learn, il est courant d’exécuter une série de transformations en utilisant un pipeline. Les pipelines scikit-learn ne fonctionnent pas avec les classes Snowpark ML, c’est pourquoi Snowpark ML fournit une version Snowpark Python de sklearn.pipeline.Pipeline
pour exécuter une série de transformations. Cette classe se trouve dans le paquet snowflake.ml.modeling.pipeline
et fonctionne de la même manière que la version scikit-learn.
Récupération du modèle sous-jacent¶
Les modèles Snowpark ML peuvent être « décapsulés » (unwrapped), c’est-à-dire convertis en modèles tiers sous-jacents, à l’aide des méthodes suivantes (selon la bibliothèque) :
to_sklearn
to_xgboost
to_lightgbm
L’ensemble des attributs et méthodes du modèle sous-jacent sont ensuite accessibles et peuvent être exécutés localement par rapport à l’estimateur. Par exemple, dans l”exemple GridSearchCV, nous convertissons l’estimateur de recherche par grille en un objet scikit-learn afin de récupérer le meilleur score.
best_score = grid_search_cv.to_sklearn().best_score_
Limites connues¶
Les estimateurs et transformateurs de Snowpark ML ne prennent actuellement pas en charge les entrées ou les réponses clairsemées. Si vous disposez de données clairsemées, convertissez-les dans un format dense avant de les transmettre aux estimateurs ou transformateurs de Snowpark ML.
Le paquet Snowpark ML ne prend actuellement pas en charge les types de données matricielles. Toute opération sur les estimateurs et les transformateurs qui produirait une matrice comme résultat échoue.
Il n’est pas garanti que l’ordre des lignes dans les données de résultat corresponde à l’ordre des lignes dans les données d’entrée.
Dépannage¶
Ajout de plus de détails à l’enregistrement¶
Snowpark ML utilise la journalisation de Snowpark Python. Par défaut, Snowpark ML enregistre les messages de niveau INFO sur la sortie standard. Pour obtenir des journaux qui sont plus détaillés, qui peuvent vous aider à résoudre les problèmes avec Snowpark ML, vous pouvez changer le niveau pour l’un des niveaux pris en charge par.
DEBUG produit les journaux les plus détaillés. Pour définir le niveau de journalisation sur DEBUG :
import logging, sys
logging.basicConfig(stream=sys.stdout, level=logging.DEBUG)
Solutions aux problèmes courants¶
Le tableau suivant fournit quelques fournisseurs pour résoudre les problèmes éventuels liés à Snowflake ML Modeling.
Problème ou message d’erreur |
Cause possible |
Résolution |
---|---|---|
NameError, comme « name x is not defined », ImportError, ou ModuleNotFoundError |
Erreur typographique dans le nom du module ou de la classe, ou Snowpark ML n’est pas installé |
Reportez-vous au tableau des classes de Snowpark ML Modeling pour connaître le nom correct du module et de la classe. Assurez-vous que le module Snowpark ML est installé (voir Installation de Snowpark ML). |
KeyError (« not in index » ou « none of [Index[..]] are in the [columns] ») |
Nom de colonne incorrect. |
Vérifiez et corrigez le nom de la colonne. |
SnowparkSQLException, « does not exist or not authorize » |
La table n’existe pas ou vous ne disposez pas de privilèges suffisants sur la table. |
Assurez-vous que la table existe et que le rôle de l’utilisateur dispose des privilèges appropriés. |
SnowparkSQLException, « invalid identifier PETALLENGTH » |
Nombre de colonnes incorrect (généralement une colonne manquante). |
Vérifiez le nombre de colonnes spécifié lors de la création de la classe de modèle et assurez-vous que vous transmettez le bon nombre. |
InvalidParameterError |
Un type ou une valeur inapproprié(e) a été transmis(e) en tant que paramètre. |
Vérifiez l’aide de la classe ou de la méthode à l’aide de la fonction |
TypeError, « unexpected keyword argument » |
Erreur typographique dans l’argument nommé. |
Vérifiez l’aide de la classe ou de la méthode à l’aide de la fonction |
ValueError, « array with 0 sample(s) » |
L’ensemble de données transmis est vide. |
Assurez-vous que l’ensemble de données n’est pas vide. |
SnowparkSQLException, « authentication token has expired » |
La session a expiré. |
Si vous utilisez un Jupyter notebook, redémarrez le noyau pour créer une nouvelle session. |
ValueError comme « cannot convert string to float » |
Inadéquation du type de données. |
Vérifiez l’aide de la classe ou de la méthode à l’aide de la fonction |
SnowparkSQLException, « cannot create temporary table » |
Une classe de modèle est utilisée dans une procédure stockée qui ne s’exécute pas avec les droits de l’appelant. |
Créez la procédure stockée avec les droits de l’appelant au lieu des droits du propriétaire. |
SnowparkSQLException, « function available memory exceeded » |
Votre ensemble de données est supérieur à 5 GB dans un entrepôt standard. |
Passez à un entrepôt optimisé pour Snowpark. |
OSError, « no space left on device » |
Votre modèle est supérieur à environ 500 MB dans un entrepôt standard. |
Passez à un entrepôt optimisé pour Snowpark. |
Version incompatible de xgboost ou erreur lors de l’importation de xgboost |
Vous avez effectué l’installation en utilisant |
Mettez à jour le paquet ou revenez à une version antérieure comme le demande le message d’erreur. |
AttributeError impliquant |
Tentative d’utilisation de l’une de ces méthodes sur un modèle d’un autre type. |
Utilisez |
Le noyau du Jupyter Notebook se bloque sur un Mac basé sur arm (puce M1 ou M2) : « Le noyau s’est bloqué pendant l’exécution du code dans la cellule actuelle ou dans une cellule précédente. » |
XGBoost ou une autre bibliothèque est installée avec une architecture incorrecte. |
Recréez un nouvel environnement conda avec |
Autres lectures¶
Consultez la documentation des bibliothèques d’origine pour obtenir des informations complètes sur leurs fonctionnalités.
Reconnaissance¶
Certaines parties de ce document sont dérivées de la documentation Scikit-learn, qui est sous licence BSD-3 « New » ou « Revised » et sous Copyright © 2007-2023 The scikit-learn developers. Tous droits réservés.
Certaines parties de ce document sont dérivées de la documentation de XGboost, qui est couverte par la licence Apache 2.0, janvier 2004 et qui est sous Copyright © 2019. Tous droits réservés.
Certaines parties de ce document sont dérivées de la documentation LightGBM, qui est sous licence MIT et sous copyright © Microsoft Corp. Tous droits réservés.