Identificazione di un disallineamento addestramento/produzione con rilevamento delle novità

Mantieni tutto organizzato con le raccolte Salva e classifica i contenuti in base alle tue preferenze.
Questo documento è il quinto di una serie che mostra come monitorare i modelli ML per la previsione AI Platform per il rilevamento delle deviazioni dei dati. Questa guida mostra come calcolare un punteggio di deviazione complessivo per la pubblicazione di richieste-risposta in BigQuery utilizzando un modello di rilevamento dell'attualità. La guida si basa sui concetti e sulle attività descritti nelle sezioni Registrare le richieste di pubblicazione utilizzando AI Platform Prediction e Analizzare i log di previsione di AI Platform in BigQuery.

Questa guida è rivolta ai data scientist e ai ML engineer che vogliono mantenere le prestazioni dei loro modelli di ML in produzione determinando se i dati di distribuzione si spostano nel tempo e calcolando l'entità di questa deviazione (se presente).

che contiene i seguenti documenti:

Il codice per il processo descritto in questo documento è incorporato nei blocchi note Jupyter. I blocchi note si trovano in un repository GitHub.

Panoramica

Il monitoraggio delle prestazioni predittive di un modello di machine learning (ML) in produzione è un'area cruciale delle MLOps. Le prestazioni predittive di un modello di cui è stato eseguito il deployment potrebbero diminuire nel tempo. Questo decadimento può verificarsi per diversi motivi, tra cui una discrepanza tra i dati di addestramento e pubblicazione, il contesto aziendale in evoluzione o un ambiente tecnico in evoluzione.

Il seguente diagramma mostra la procedura descritta in questa guida:

Flusso di processo.

Deviazione a livello di funzionalità rispetto a deviazione a livello di set di dati

Le guide precedenti di questa serie hanno descritto come utilizzare la convalida dei dati di TensorFlow (TFDV) per rilevare disallineamenti e anomalie di distribuzione in un set di dati. TFDV utilizza uno schema di riferimento e statistiche di riferimento generate dai dati di addestramento per rilevare le anomalie nei nuovi dati.

Puoi utilizzare TFDV per identificare disallineamenti e anomalie, come le seguenti per ogni funzionalità:

  • Il tipo di dati di una funzionalità non è quello previsto.
  • I valori di un elemento numerico non rientrano nell'intervallo previsto.
  • La percentuale dei valori mancanti in una funzionalità specifica è al di sotto di una soglia predefinita.
  • In una funzionalità di categoria vengono rilevate categorie nuove o mancanti.
  • La distribuzione dei valori di una funzionalità non è quella prevista.

In pratica, la maggior parte dei disallineamenti e delle anomalie di pubblicazione dei corsi è dovuta a problemi nelle singole funzionalità. Ad esempio, gli errori o gli aggiornamenti nelle pipeline di importazione ed elaborazione dei dati potrebbero introdurre valori mancanti, nuovi valori, valori fuori intervallo o valori con tipi di dati errati. Potresti anche notare incoerenze nei tipi di schemi di dati in una delle seguenti circostanze:

  • Le origini dati cambiano.
  • Integra nuove origini dati.
  • Il modello deve essere utilizzato in un nuovo dominio (ad esempio, in una nuova posizione geografica).

TFDV può rilevare disallineamenti e anomalie a livello di funzionalità, come questi, che ti consentono di intervenire. Ad esempio, puoi aggiornare la logica di pre-elaborazione, aggiungere un nuovo vocabolario a funzionalità categoriche ed eliminare dati errati e reimpostare il modello se necessario.

Tuttavia, in alcuni casi, le singole funzionalità nel set di dati potrebbero non avere un disallineamento significativo relativo allo schema di riferimento e alle statistiche di riferimento. Anche in questo caso, la distribuzione delle probabilità congiunte di queste caratteristiche mostra un cambiamento. Questa modifica rappresenta un tipo di variazione covariata. Questo tipo di cambiamento di solito si verifica all'emergere di nuovi dati e tendenze nei dati a causa dei cambiamenti dinamici dell'ambiente. Alcuni esempi potrebbero essere i cambiamenti dei prezzi degli immobili rispetto alle località o la popolarità degli articoli di moda tra diversi gruppi demografici. Anche la variazione covariata è soggetta alla stagionalità, perché le relazioni statistiche tra le funzionalità di input potrebbero cambiare periodicamente in risposta a stagioni ed eventi diversi.

Di conseguenza, può essere utile calcolare un punteggio di deviazione complessivo a livello di set di dati per tutte le funzionalità. Questo punteggio di deviazione può rappresentare l'entità del disallineamento dei dati di pubblicazione. Il calcolo di un punteggio di deviazione complessivo semplifica il processo di monitoraggio della deviazione del set di dati nel tempo e consente di definire ed eseguire azioni in base a determinate soglie di punteggio di deviazione.

Metodi per il punteggio di una deviazione di un set di dati

Puoi utilizzare i seguenti metodi per calcolare un valore di deviazione a livello di set di dati anziché a livello di funzionalità:

  • Novità e rilevamento dei valori anomali
  • Test statistici in due campioni

Novità e rilevamento dei valori anomali

Negli algoritmi di rilevamento di anomalie e novità, l'obiettivo è imitare l'attività di rilevamento dei campioni fuori distribuzione. Puoi creare un modello utilizzando i dati di riferimento (addestramento), quindi utilizzare tale modello per identificare se un nuovo punto dati (pubblicazione) è un valore anomalo. Il punteggio di deviazione viene calcolato come percentuale dei punti dati che si prevede siano anomali nel set di dati di pubblicazione. Il vantaggio di questa tecnica è che non solo produce un punteggio di deviazione tra 0 e 100, ma identifica anche i punti dati considerati anomali.

Gli algoritmi di rilevamento di anomalie e novità includono:

Gli algoritmi utilizzati per rilevare i valori irregolari nei dati della serie temporale sono i residui spettrali e la codifica automatica da sequenza a sequenza.

Test statistici in due campioni

In due test statistici, esegui test di ipotesi statistiche per esaminare l'equivalenza della distribuzione dell'addestramento e della distribuzione. L'output di questi algoritmi è un p-value (tra 0 e 1) che indica la probabilità che i due set di dati provengano dalle stesse distribuzioni. Poiché il set di dati include diverse funzionalità, i semplici test statistici univariati non sono sufficienti. Pertanto, sono disponibili le seguenti opzioni:

Per ulteriori informazioni sulle tecniche di rilevamento delle deviazioni, consulta l'articolo Failing Loudly: An Empirical Study of Methods for Detecting Dataset Shift. Inoltre, vedi Alibi Detect, una libreria open source Python per il rilevamento delle deviazioni che copre dati tabulari, immagini e serie temporali.

Obiettivi

  • Scarica i dati suddivisi in addestramento e pubblicazione.
  • Addestra un modello di busta ellittica utilizzando i dati di addestramento.
  • Testare il modello su set di dati normali e mutati.
  • Implementare una pipeline Apache Beam per calcolare il punteggio di deviazione nei dati BigQuery con richiesta di risposta.
  • Esegui la pipeline e visualizza l'output del rilevamento della deviazione.

Costi

Questo tutorial utilizza i seguenti componenti fatturabili di Google Cloud:

Per generare una stima dei costi in base all'utilizzo previsto, utilizza il Calcolatore prezzi. I nuovi utenti di Google Cloud possono beneficiare di una prova gratuita.

Prima di iniziare

Prima di iniziare, devi completare la parte uno e la parte due di questa serie.

Una volta completate queste parti, hai quanto segue:

Il blocco note Jupyter per questo scenario

Un processo completo per questo flusso di lavoro viene codificato in un blocco note Jupyter nel repository GitHub associato al documento. I passaggi nel blocco note si basano sul set di dati CoverType di UCI Machine Learning Repository. Questo set di dati è lo stesso che è stato utilizzato per i dati di esempio nei documenti precedenti di questa serie.

Configurazione delle impostazioni del blocco note

In questa sezione preparerai l'ambiente Python per eseguire il codice per lo scenario.

  1. Se non hai già aperto l'istanza di blocchi note gestiti dall'utente dalla parte uno:

  2. In Google Cloud Console, vai alla pagina Blocchi note.

    Vai a Blocchi note

  3. Nella scheda Blocchi note gestiti dall'utente, seleziona il blocco note, quindi fai clic su Apri Jupyterlab. L'ambiente JupyterLab si apre nel browser.

  4. Nel browser di file, apri il file mlops-on-gcp, quindi vai alla directory skew-detection.

  5. Apri il blocco note 04-covertype-drift-detection_novelty_model.ipynb.

  6. Nel blocco note, in Impostazione, esegui la cella Installa pacchetti e dipendenze per installare i pacchetti Python richiesti e configurare le variabili di ambiente.

  7. In Configura impostazioni dell'ambiente Google Cloud, imposta le seguenti variabili:

    • PROJECT_ID: l'ID del progetto Google Cloud in cui viene registrato il set di dati BigQuery per i dati di richiesta-risposta.
    • BUCKET: nome del bucket Cloud Storage in cui sono archiviati gli artefatti prodotti.
    • BQ_DATASET_NAME: nome del set di dati BigQuery in cui sono archiviati i log richiesta-risposta.
    • BQ_TABLE_NAME: nome della tabella BigQuery in cui sono archiviati i log richiesta-risposta.
    • MODEL_NAME: il nome del modello di cui è stato eseguito il deployment in AI Platform Prediction.
    • MODEL_VERSION: il nome della versione del modello di cui è stato eseguito il deployment in AI Platform Prediction. La versione è nel formato vN; ad esempio, v1.
  8. Esegui le celle rimanenti in Configurazione per completare la configurazione dell'ambiente:

    1. Autentica il tuo account GCP
    2. Creare un'area di lavoro locale
  9. Esegui le celle nella sezione Scarica segmenti di dati per rendere i dati disponibili per il blocco note.

Addestrare un modello di rilevamento delle novità

Questa guida mostra come utilizzare una busta con ellittica come modello di rilevamento delle novità per calcolare un punteggio di deviazione complessivo dei dati per la richiesta di risposta che vengono registrati in BigQuery. In questa sezione ti mostreremo come fare:

  • Addestrare la busta ellittica utilizzando i dati di addestramento.
  • Testare la busta sia sui set di dati normali sia su quelli mutati.
  • Confrontare i punteggi delle deviazioni.

L'algoritmo della busta ellittica è un algoritmo parametrico che presuppone che i dati di addestramento provengano da una distribuzione nota (ad esempio, una distribuzione gaussiana). L'algoritmo cerca di definire la "forma" dei dati utilizzando una stima di covarianza stabile. Utilizzando questa stima, il modello può identificare i punti dati esterni che si trovano a una distanza specifica dalla forma di idoneità. Le distanza di mahalanobis dalla stima della covarianza possono essere misurate; queste distanze a loro volta possono essere utilizzate per calcolare una misura di periferia.

Pre-elaborazione dati

I dati richiedono un solo tipo di pre-elaborazione per addestrare il modello della busta ellittica: le caratteristiche categoriche devono essere codificate a caldo per produrre una rappresentazione numerica di queste funzionalità. Innanzitutto, il codice nel blocco note si adatta a un insieme di oggetti OneHotEncoder, uno per ogni caratteristica della categoria, utilizzando le categorie nei dati di addestramento. In secondo luogo, il codice utilizza i codificatori montati per trasformare le caratteristiche categoriche nel set di dati di input. Per eseguire le trasformazioni, il codice utilizza il metodo prepare_data, come mostrato nel seguente snippet di codice:

from sklearn.preprocessing import OneHotEncoder

encoders = dict()

for feature_name in CATEGORICAL_FEATURE_NAMES:
  encoder = OneHotEncoder(handle_unknown='ignore')
  encoder.fit(train_data[[feature_name]])
  encoders[feature_name] = encoder

def prepare_data(data_frame):

  if type(data_frame) != pd.DataFrame:
    data_frame = pd.DataFrame(data_frame)
  data_frame = data_frame.reset_index()
  for feature_name, encoder in encoders.items():
    encoded_feature = pd.DataFrame(
      encoder.transform(data_frame[[feature_name]]).toarray())
    data_frame = data_frame.drop(feature_name, axis=1)
    encoded_feature.columns = [feature_name+"_"+str(column)
                              for column in encoded_feature.columns]
    data_frame = data_frame.join(encoded_feature)
   return data_frame

Quando lavori con set di dati di grandi dimensioni (ad esempio, un set di dati con molte funzionalità, con molte immagini o con dati di testo che hanno un ampio vocabolario impostato), spesso riduci la dimensione prima di addestrare il modello. Le tecniche tipiche includono analisi dei componenti principali, codificatori e proiezione casuale.

Addestramento di modelli

Per addestrare il modello di busta ellittica, il codice esegue le seguenti operazioni:

  1. Prepara i dati di addestramento utilizzando il metodo prepare_data.

  2. Crea un'istanza di un oggetto EllipticEnvelope e imposta il valore contamination su 0, supponendo che non siano presenti valori anomali nei dati di addestramento.

  3. Addestra il modello utilizzando l'oggetto prepared_training_data chiamando il metodo model.fit.

Il seguente snippet di codice illustra questi passaggi:

from sklearn.covariance import EllipticEnvelope

prepared_training_data = prepare_data(train_data)
model = EllipticEnvelope(contamination=0.)
model.fit(prepared_training_data)

Test del modello

Per addestrare il modello a busta ellittica, il codice può calcolare la distanza mahalanobis tra un determinato punto dati e il modello che rappresenta una distribuzione congiunta dei dati di addestramento. Per calcolare la distanza, il codice chiama il metodo model.mahalanobis e trasmette il punto dati specificato. Tuttavia, per identificare la distanza a cui un punto dati è considerato un valore anomalo, il codice deve eseguire i seguenti passaggi:

  1. Calcola la media e la deviazione standard delle distanze di Mahalanobis per i punti dati di addestramento in relazione al modello. Questi valori vengono memorizzati nel modello come valori model._mean e model._stdv.

    Qualsiasi nuovo punto dati a una distanza di Mahalanobis maggiore della media + N unità di deviazione standard è considerato un valore anomalo.

  2. Calcola il punteggio di deviazione come rapporto tra il numero di punti outlier e la dimensione del set di dati di input (pubblicazione).

    Questa logica è mostrata nel seguente snippet di codice:

    def compute_drift_score(model, data_frame, stdv_units=2):
      distances = model.mahalanobis(data_frame)
      threshold = model._mean + (stdv_units * model._stdv)
      score = len([v for v in distances if v >= threshold]) / len(data_frame.index)
      return score
    

Per testare il comportamento del modello per il rilevamento delle deviazioni, il codice utilizza la suddivisione dati di valutazione, che si presume abbia una distribuzione simile ai dati di addestramento. Il codice crea una versione mutata di questo set di dati riordinando i valori di ciascuna colonna. In questo caso, la distribuzione univariata di ogni caratteristica non cambia. Tuttavia, la distribuzione multivariata (congiunta) dell'intero set di dati è stata modificata, perché la combinazione di valori delle caratteristiche di ciascun record è ora casuale.

Il set di dati mutato viene generato utilizzando il seguente codice:

def shuffle_values(dataframe):
 shuffeld_dataframe = dataframe.copy()
 for column_name in dataframe.columns:
   shuffeld_dataframe[column_name] = shuffeld_dataframe[column_name].sample(
       frac=1.0).reset_index(drop=True)

Quando viene calcolato il punteggio di deviazione sul set di dati di valutazione normale, viene rilevato meno dell'1% dei punti dati come valori anomali. Quando i punteggi di deviazione vengono calcolati sul set di dati mutato, circa il 62% dei punti dati viene rilevato come outlier.

Guida alla deviazione dal calcolo dei dati di gestione

Puoi utilizzare il modello addestrato a forma di busta ellittica per identificare un punteggio di deviazione nei dati di pubblicazione richiesta-risposta registrati in BigQuery. Il codice nel blocco note Jupyter fornisce un'implementazione della pipeline Apache Beam, che può essere eseguita su larga scala su Dataflow, per eseguire i seguenti passaggi:

  1. Leggi i dati non elaborati delle richieste dalla tabella rappresentata dal parametro args.bq_table_fullname, filtrata in base ai seguenti parametri:

    • args.model_name
    • args.model_version
    • args.start_time
    • args.end_time
  2. Raggruppa i record di richiesta utilizzando il metodo beam.BatchElements per migliorare la vettorizzazione. I record delle richieste vengono recuperati in formato JSON.

  3. Analizza i batch dei record recuperati in esempi strutturati utilizzando il metodo parse_batch_data.

  4. Pre-elabora i dati (utilizzando le funzionalità di codifica one-hot) utilizzando il metodo prepare_data.

  5. Assegna un punteggio a ogni record nei dati utilizzando l'istanza args.drift_model. Questo passaggio restituisce il numero di record del batch corrente che sono considerati outlier e il numero totale di record nel batch.

  6. Aggrega i risultati utilizzando il metodo beam.CombineGlobally.

  7. Produzione dell'oggetto risultato finale, che include i valori delle variabili outlier_count, record_count e drift_score.

  8. Scrivi i risultati come file JSON nella posizione specificata nella variabile args.output_file_path.

Il seguente snippet di codice mostra l'implementazione della pipeline Apache Beam per i passaggi per calcolare il punteggio di deviazione dei dati richiesta-risposta in BigQuery.

def run_pipeline(args):

 options = beam.options.pipeline_options.PipelineOptions(**args)
 args = namedtuple("options", args.keys())(*args.values())
 query = get_query(
     args.bq_table_fullname, args.model_name, args.model_version,
     args.start_time, args.end_time)

 print("Starting the Beam pipeline...")

 with beam.Pipeline(options=options) as pipeline:
   (
       pipeline
       | 'ReadBigQueryData' >> beam.io.Read(
           beam.io.BigQuerySource(query=query, use_standard_sql=True))
       | 'BatchRecords' >> beam.BatchElements(
           min_batch_size=100, max_batch_size=1000)
       | 'InstancesToBeamExamples' >> beam.Map(parse_batch_data)
       | 'PrepareData' >> beam.Map(prepare_data)
       | 'ScoreData' >> beam.Map(
           lambda data: score_data(data, args.drift_model, stdv_units=1))
       | 'CombineResults' >> beam.CombineGlobally(aggregate_scores)
       | 'ComputeRatio' >> beam.Map(
           lambda result: {
               "outlier_count": result['outlier_count'],
               "records_count": result['records_count'],
               "drift_score": result['outlier_count'] / result['records_count']
               })
        | 'WriteOutput' >> beam.io.WriteToText(
            file_path_prefix=args.output_file_path, num_shards=1, shard_name_template='')
   )

Quando esegui questa pipeline con i dati inclinati generati dal blocco note associato a questo documento, ottieni risultati simili ai seguenti:

outlier_count : 103
records_count : 1000
drift_score : 10.3%

Per ulteriori informazioni su come completare la tabella dei log richiesta-risposta utilizzando punti dati inclinati, consulta la sezione Simulazione di dati di pubblicazione nella guida Analisi dei log di previsione di AI Platform in BigQuery.

Esegui la pulizia

Per evitare che al tuo Account Google Cloud vengano addebitati costi relativi alle risorse utilizzate in questo tutorial, elimina il progetto che contiene le risorse oppure mantieni il progetto ed elimina le singole risorse.

Elimina il progetto

  1. In Google Cloud Console, vai alla pagina Gestisci risorse.

    Vai a Gestisci risorse

  2. Nell'elenco dei progetti, seleziona il progetto che vuoi eliminare, quindi fai clic su Elimina.
  3. Nella finestra di dialogo, digita l'ID del progetto e fai clic su Chiudi per eliminare il progetto.

Passaggi successivi