Coltivare l’integrità dei dati nella scienza dei dati con Pandera |  di Alessandro Tomassini |  Dicembre 2023

 | Intelligenza-Artificiale

Immagine generata da DALL-E

Benvenuto in un viaggio esplorativo nella convalida dei dati con Pandera, uno strumento meno conosciuto ma potente nel toolkit del data scientist. Questo tutorial mira a illuminare il percorso per coloro che cercano di rafforzare le proprie pipeline di elaborazione dati con solide tecniche di convalida.

Pandera è una libreria Python che fornisce una convalida dei dati flessibile ed espressiva per le strutture dati dei panda. È progettato per conferire maggiore rigore e affidabilità alle fasi di elaborazione dei dati, garantendo che i dati siano conformi a formati, tipi e altri vincoli specificati prima di procedere con l’analisi o la modellazione.

Nell’intricato arazzo della scienza dei dati, dove i dati sono il filo conduttore fondamentale, garantirne la qualità e la coerenza è fondamentale. Pandera promuove l’integrità e la qualità dei dati attraverso una rigorosa convalida. Non si tratta solo di controllare i tipi o i formati dei dati; Pandera estende la sua vigilanza a convalide statistiche più sofisticate, rendendolo un alleato indispensabile nelle tue attività di data science. Nello specifico Pandera si distingue offrendo:

  1. Applicazione dello schema: garantisce che il tuo DataFrame aderisca a uno schema predefinito.
  2. Convalida personalizzabile: consente la creazione di regole di convalida complesse e personalizzate.
  3. Integrazione con Panda: Funziona perfettamente con i flussi di lavoro Panda esistenti.
fotografato da Carlo Deluvio SU Unsplash

Iniziamo con l’installazione di Pandera. Questo può essere fatto usando pip:

pip install pandera 

Uno schema in Pandera definisce la struttura prevista, i tipi di dati e i vincoli del tuo DataFrame. Inizieremo importando le librerie necessarie e definendo uno schema semplice.

import pandas as pd
from pandas import Timestamp
import pandera as pa
from pandera import Column, DataFrameSchema, Check, Index

schema = DataFrameSchema({
"name": Column(str),
"age": Column(int, checks=pa.Check.ge(0)), # age should be non-negative
"email": Column(str, checks=pa.Check.str_matches(r'^(a-zA-Z0-9_.+-)+@(a-zA-Z0-9-)+\.(a-zA-Z0-9-.)+$')) # email format
})

Questo schema specifica che il nostro DataFrame dovrebbe avere tre colonne: name (corda), age (intero, non negativo) e email (stringa, corrispondente a un’espressione regolare per la posta elettronica). Ora, con il nostro schema a posto, convalidiamo un DataFrame.

# Sample DataFrame
df = pd.DataFrame({
"name": ("Alice", "Bob", "Charlie"),
"age": (25, -5, 30),
"email": ("alice@example.com", "bob@example", "charlie@example.com")
})

# Validate
validated_df = schema(df)

In questo esempio, Pandera rilancerà a SchemaError perché l’età di Bob è negativa, il che viola il nostro schema.

SchemaError: <Schema Column(name=age, type=DataType(int64))> failed element-wise validator 0:
<Check greater_than_or_equal_to: greater_than_or_equal_to(0)>
failure cases:
index failure_case
0 1 -5

Uno dei punti di forza di Pandera è la sua capacità di definire funzioni di convalida personalizzate.

@pa.check_input(schema)
def process_data(df: pd.DataFrame) -> pd.DataFrame:
# Some code to process the DataFrame
return df

processed_df = process_data(df)

IL @pa.check_input decoratore garantisce che il DataFrame di input aderisca allo schema prima che la funzione lo elabori.

fotografato da Sigmund SU Unsplash

Ora esploriamo le convalide più complesse offerte da Pandera. Basandosi sullo schema esistente, possiamo aggiungere ulteriori colonne con vari tipi di dati e controlli più sofisticati. Introdurremo colonne per dati categoriali e dati data/ora e implementeremo controlli più avanzati come garantire valori univoci o fare riferimento ad altre colonne.

# Define the enhanced schema
enhanced_schema = DataFrameSchema(
columns={
"name": Column(str),
"age": Column(int, checks=(Check.ge(0), Check.lt(100))),
"email": Column(str, checks=(Check.str_matches(r'^(a-zA-Z0-9_.+-)+@(a-zA-Z0-9-)+\.(a-zA-Z0-9-.)+$'))),
"salary": Column(float, checks=Check.in_range(30000, 150000)),
"department": Column(str, checks=Check.isin(("HR", "Tech", "Marketing", "Sales"))),
"start_date": Column(pd.Timestamp, checks=Check(lambda x: x < pd.Timestamp("today"))),
"performance_score": Column(float, nullable=True)
},
index=Index(int, name="employee_id")
)

# Custom check function
def salary_age_relation_check(df: pd.DataFrame) -> pd.DataFrame:
if not all(df("salary") / df("age") < 3000):
raise ValueError("Salary to age ratio check failed")
return df

# Function to process and validate data
def process_data(df: pd.DataFrame) -> pd.DataFrame:
# Apply custom check
df = salary_age_relation_check(df)

# Validate DataFrame with Pandera schema
return enhanced_schema.validate(df)

In questo schema migliorato, abbiamo aggiunto:

  1. Dati categoriali: Il department la colonna viene convalidata rispetto a categorie specifiche.
  2. Dati data/ora: The start_date la colonna garantisce che le date siano nel passato.
  3. Colonna nullable: The performance_score la colonna può contenere valori mancanti.
  4. Convalida dell’indice: un indice employee_id di tipo intero è definito.
  5. Controllo complesso: una funzione personalizzata salary_age_relation_check garantisce una relazione logica tra stipendio ed età all’interno di ciascun dipartimento.
  6. Implementazione del controllo personalizzato nella funzione di elaborazione dati: integriamo il salary_age_relation_check logica direttamente nella nostra funzione di elaborazione dei dati.
  7. Uso di Pandera validate metodo: invece di utilizzare il file @pa.check_types decoratore, abbiamo convalidato manualmente DataFrame utilizzando il file validate metodo fornito da Pandera.

Ora creiamo un DataFrame di esempio df_example che corrisponde alla struttura e ai vincoli del nostro schema avanzato e lo convalida.

df_example = pd.DataFrame({
"employee_id": (1, 2, 3),
"name": ("Alice", "Bob", "Charlie"),
"age": (25, 35, 45),
"email": ("alice@example.com", "bob@example.com", "charlie@example.com"),
"salary": (50000, 80000, 120000),
"department": ("HR", "Tech", "Sales"),
"start_date": (Timestamp("2022-01-01"), Timestamp("2021-06-15"), Timestamp("2020-12-20")),
"performance_score": (4.5, 3.8, 4.2)
})

# Make sure the employee_id column is the index
df_example.set_index("employee_id", inplace=True)

# Process and validate data
processed_df = process_data(df_example)

Qui, Pandera rilancerà a SchemaError a causa di una mancata corrispondenza tra il tipo di dati previsto del file salary colonna dentro enhanced_schema (float che corrisponde a float64 nei tipi panda/Numpy) e il tipo di dati effettivo presente in df_example (int O int64 nei panda/tipi Numpy).

SchemaError: expected series 'salary' to have type float64, got int64
fotografato da Daniela Paola Alchapar SU Unsplash

Pandera può eseguire test di ipotesi statistiche come parte del processo di convalida. Questa funzionalità è particolarmente utile per convalidare le ipotesi sulla distribuzione dei dati o sulle relazioni tra le variabili.

Supponiamo che tu voglia assicurarti che lo stipendio medio nel tuo set di dati sia intorno a un certo valore, ad esempio £ 75.000. È possibile definire una funzione di controllo personalizzata per eseguire un t-test su un campione per valutare se la media di un campione (ad esempio, la media degli stipendi nel set di dati) differisce in modo significativo da una media nota (nel nostro caso, £ 75.000) .

from scipy.stats import ttest_1samp

# Define the custom check for the salary column
def mean_salary_check(series: pd.Series, expected_mean: float = 75000, alpha: float = 0.05) -> bool:
stat, p_value = ttest_1samp(series.dropna(), expected_mean)
return p_value > alpha

salary_check = Check(mean_salary_check, element_wise=False, error="Mean salary check failed")

# Correctly update the checks for the salary column by specifying the column name
enhanced_schema.columns("salary") = Column(float, checks=(Check.in_range(30000, 150000), salary_check), name="salary")

Nel codice sopra abbiamo:

  1. Definita la funzione di controllo personalizzato mean_salary_check che prende una serie di panda (il salary colonna nel nostro DataFrame) ed esegue il test t rispetto alla media prevista. La funzione ritorna True se il valore p del test t è maggiore del livello di significatività (alfa = 0,05), indicando che lo stipendio medio non è significativamente diverso da £ 75.000.
  2. Abbiamo quindi racchiuso questa funzione in un Pandera Checkspecificando element_wise=False per indicare che il controllo viene applicato all’intera serie anziché a ciascun elemento singolarmente.
  3. Infine, abbiamo aggiornato il salary nel nostro schema Pandera per includere questo nuovo controllo insieme a eventuali controlli esistenti.

Con questi passaggi, il nostro schema Pandera ora include un test statistico su salary colonna. Aumentiamo deliberatamente lo stipendio medio in df_example violare le aspettative dello schema in modo che Pandera rilanci a SchemaError .

# Change the salaries to exceede the expected mean of £75,000
df_example("salary") = df_example("salary") = (100000.0, 105000.0, 110000.0)
validated_df = enhanced_schema(df_example)
SchemaError: <Schema Column(name=salary, type=DataType(float64))> failed series or dataframe validator 1:
<Check mean_salary_check: Mean salary check failed>

Pandera eleva la convalida dei dati da un banale punto di controllo a un processo dinamico che comprende convalide statistiche anche complesse. Integrando Pandera nella tua pipeline di elaborazione dati, puoi individuare incoerenze ed errori in anticipo, risparmiando tempo, prevenendo grattacapi in futuro e aprendo la strada a un’analisi dei dati più affidabile e approfondita.

Per coloro che desiderano approfondire la propria comprensione di Pandera e delle sue capacità, le seguenti risorse rappresentano ottimi punti di partenza:

  1. Documentazione Pandera: una guida completa a tutte le caratteristiche e funzionalità di Pandera (Pandera Docs).
  2. Documentazione sui panda: poiché Pandera estende i panda, la familiarità con i panda è fondamentale (Documenti sui panda).

Non sono affiliato con Pandera in alcun modo, ne sono solo molto entusiasta 🙂

Fonte: towardsdatascience.com

Lascia un commento

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *