Condividi tramite


Esercitazione: Pulire i dati con dipendenze funzionali

In questa esercitazione si usano dipendenze funzionali per la pulizia dei dati. Esiste una dipendenza funzionale quando una colonna in un modello semantico (un set di dati di Power BI) è una funzione di un'altra colonna. Ad esempio, una colonna di codice postale potrebbe determinare i valori in una colonna di città. Una dipendenza funzionale si manifesta come una relazione uno-a-molti tra i valori in due o più colonne all'interno di un DataFrame. Questa esercitazione usa il set di dati Synthea per illustrare in che modo le relazioni funzionali possono aiutare a rilevare i problemi di qualità dei dati.

In questa esercitazione apprenderai a:

  • Applicare le conoscenze del dominio per formulare ipotesi sulle dipendenze funzionali in un modello semantico.
  • Familiarizzare con i componenti della libreria Python del collegamento semantico (SemPy) che consentono di automatizzare l'analisi della qualità dei dati. Questi componenti includono:
    • FabricDataFrame: una struttura simile a Pandas migliorata con informazioni semantiche aggiuntive.
    • Funzioni utili che automatizzano la valutazione delle ipotesi sulle dipendenze funzionali e che identificano le violazioni delle relazioni nei modelli semantici.

Prerequisiti

  • Selezionare Aree di lavoro nel riquadro di spostamento sinistro per trovare e selezionare l'area di lavoro. Questa area di lavoro diventa l'area di lavoro corrente.

Seguire la procedura nel Notebook

Per seguire questa esercitazione, utilizza il notebook data_cleaning_functional_dependencies_tutorial.ipynb.

Per aprire il notebook di accompagnamento per questa esercitazione, seguire le istruzioni riportate in Preparare il sistema per le esercitazioni di data science per importare il notebook nell'area di lavoro.

Se si preferisce copiare e incollare il codice da questa pagina, è possibile creare un nuovo notebook.

Assicurarsi di collegare un lakehouse al notebook prima di iniziare a eseguire il codice.

Configurare il notebook

In questa sezione viene configurato un ambiente notebook con i moduli e i dati necessari.

  1. Per Spark 3.4 e versioni successive, il collegamento semantico è disponibile nel runtime predefinito quando si usa Fabric e non è necessario installarlo. Se si usa Spark 3.3 o versioni precedenti, o se si vuole eseguire l'aggiornamento alla versione più recente di Semantic Link, è possibile eseguire il comando:

python %pip install -U semantic-link  

  1. Eseguire le importazioni necessarie di moduli che serviranno in un secondo momento:

    import pandas as pd
    import sempy.fabric as fabric
    from sempy.fabric import FabricDataFrame
    from sempy.dependencies import plot_dependency_metadata
    from sempy.samples import download_synthea
    
  2. Estrarre i dati di esempio. Per questa esercitazione si usa il set di dati Synthea di cartelle cliniche sintetiche (versione ridotta per semplicità):

    download_synthea(which='small')
    

Esplorare i dati

  1. Inizializzare un FabricDataFrame con il contenuto del file providers.csv:

    providers = FabricDataFrame(pd.read_csv("synthea/csv/providers.csv"))
    providers.head()
    
  2. Verificare la presenza di eventuali problemi di qualità dei dati con la funzione di find_dependencies SemPy tracciando un grafico delle dipendenze funzionali rilevate automaticamente:

    deps = providers.find_dependencies()
    plot_dependency_metadata(deps)
    

    Screenshot che mostra il grafico delle dipendenze funzionali.

    Il grafico delle dipendenze funzionali mostra che Id determina NAME e ORGANIZATION (indicate dalle frecce continue), il che è previsto, poiché Id è univoco:

  3. Confermare che Id sia univoco:

    providers.Id.is_unique
    

    Il codice restituisce True per confermare che Id sia effettivamente univoco.

Analisi approfondita delle dipendenze funzionali

Il grafico delle dipendenze funzionali mostra anche che ORGANIZATION determina ADDRESS e ZIP, come previsto. Tuttavia, ci si potrebbe aspettare che ZIP determini anche CITY, ma la freccia tratteggiata indica che la dipendenza è solo approssimativa, suggerendo un problema di qualità dei dati.

Ci sono altre peculiarità nel grafico. Ad esempio, NAME non determina GENDER, Id, SPECIALITY o ORGANIZATION. Potrebbe essere opportuno indagare su ognuna di queste peculiarità.

  1. Esaminare più da vicino la relazione approssimativa tra ZIP e CITY, usando la funzione list_dependency_violations di SemPy per visualizzare un elenco tabulare di violazioni:

    providers.list_dependency_violations('ZIP', 'CITY')
    
  2. Disegnare un grafico con la funzione di visualizzazione plot_dependency_violations di SemPy. Questo grafico è utile quando il numero di violazioni è ridotto:

    providers.plot_dependency_violations('ZIP', 'CITY')
    

    Screenshot che mostra il tracciato delle violazioni delle dipendenze.

    Il tracciato delle violazioni delle dipendenze mostra i valori per ZIP sul lato sinistro e i valori per CITY sul lato destro. Una linea collega un codice postale sul lato sinistro del tracciato grafico a una città sul lato destro dello stesso, se esiste almeno una riga che contiene entrambi i valori. Le linee vengono annotate con il conteggio delle righe corrispondenti. Ad esempio, sono presenti due righe con codice postale 02747-1242, una riga associata alla città "NORTH DARTHMOUTH" e l'altra a "DARTHMOUTH", come illustrato nel tracciato grafico precedente e nel seguente codice:

  3. Confermare le osservazioni precedenti effettuate con il tracciato grafico delle violazioni delle dipendenze eseguendo il seguente codice:

    providers[providers.ZIP == '02747-1242'].CITY.value_counts()
    
  4. Il tracciato grafico mostra anche che tra le righe in cui CITY è "DARTHMOUTH", nove righe hanno un ZIP di 02747-1262; una riga ha un ZIP di 02747-1242 e una riga ha un ZIP di 02747-2537. Confermare queste osservazioni con il seguente codice:

    providers[providers.CITY == 'DARTMOUTH'].ZIP.value_counts()
    
  5. Esistono altri codici postali associati a "DARTMOUTH", ma questi codici postali non vengono visualizzati nel grafico delle violazioni delle dipendenze, poiché non suggeriscono problemi di qualità dei dati. Ad esempio, il codice postale "02747-4302" è associato in modo univoco a "DARTMOUTH" e non appare nel grafico delle violazioni delle dipendenze. Confermare eseguendo il codice seguente:

    providers[providers.ZIP == '02747-4302'].CITY.value_counts()
    

Riepilogo dei problemi di qualità dei dati rilevati con SemPy

Tornando al grafico delle violazioni delle dipendenze, emergono diversi problemi interessanti relativi alla qualità dei dati in questo modello semantico:

  • Alcuni nomi di città sono interamente in maiuscolo. Questo problema si può risolvere facilmente usando i metodi di stringa.
  • Alcuni nomi di città hanno qualificatori (o prefissi), come "North" e "East". Ad esempio, il codice postale "2128" corrisponde una volta a "EAST BOSTON" e una volta "BOSTON". Un problema simile si verifica tra "NORTH DARTHMOUTH" e "DARTHMOUTH". È possibile provare a eliminare questi qualificatori o mappare i codici postali alla città con l'occorrenza più comune.
  • Ci sono errori di digitazioni in alcune città, ad esempio "PITTSFIELD" al posto di "PITTSFILED" e "NEWBURGPORT al posto di "NEWBURYPORT". Per "NEWBURGPORT" questo errore di digitazione potrebbe essere corretto utilizzando l'occorrenza più comune. Per "PITTSFIELD", avendo solo una singola occorrenza, risulta molto più difficile effettuare una disambiguazione automatica senza alcuna conoscenza esterna o uso di un modello linguistico.
  • In alcuni casi, i prefissi come "West" sono abbreviati in una singola lettera "W". Potenzialmente, questo problema potrebbe essere risolto con una semplice sostituzione, se tutte le occorrenze di "W" rappresentano "West".
  • Il codice postale "02130" corrisponde una volta a "BOSTON" e una a "Jamaica Plain". Questo problema non è facile da risolvere, ma se ci fossero più dati, effettuare il mapping dell'occorrenza più comune potrebbe essere una potenziale soluzione.

Eseguire la pulizia dei dati

  1. Risolvere i problemi relativi all'uso delle lettere maiuscole modificando le parole in modo che solo le iniziali delle parole siano maiuscole:

    providers['CITY'] = providers.CITY.str.title()
    
  2. Eseguire nuovamente il rilevamento delle violazioni per verificare che alcune ambiguità siano scomparse (il numero di violazioni è diminuito):

    providers.list_dependency_violations('ZIP', 'CITY')
    

    A questo punto, è possibile affinare i dati manualmente, ma una possibile operazione di pulizia dei dati prevede l'eliminazione delle righe che violano i vincoli funzionali tra le colonne dei dati, usando la funzione drop_dependency_violations di SemPy.

    Per ogni valore della variabile determinante, drop_dependency_violations seleziona il valore più comune della variabile dipendente ed elimina tutte le righe con altri valori. È consigliabile applicare questa operazione solo se si è certi che questa euristica statistica conduca ai risultati corretti per i dati. In caso contrario, è necessario scrivere un codice personalizzato per gestire le violazioni rilevate in base alle esigenze.

  3. Eseguire la funzione drop_dependency_violations nelle colonne ZIP e CITY:

    providers_clean = providers.drop_dependency_violations('ZIP', 'CITY')
    
  4. Elencare eventuali violazioni delle dipendenze tra ZIP e CITY:

    providers_clean.list_dependency_violations('ZIP', 'CITY')
    

    Il codice restituisce un elenco vuoto per indicare che non ci sono più violazioni del vincolo funzionale CITY -> ZIP.

Vedere altre esercitazioni per il collegamento semantico/SemPy: