
Le dataprofiler est une bibliothèque Python conçue pour faciliter l'analyse des données, la surveillance et la détection sensible des données .
Chargement des données avec une seule commande, la bibliothèque forme automatiquement et charge automatiquement des fichiers dans un dataframe. Profilant des données, la bibliothèque identifie le schéma, les statistiques, les entités (PII / NPI) et plus encore. Les profils de données peuvent ensuite être utilisés dans des applications ou des rapports en aval.
Le démarrage ne prend que quelques lignes de code (exemple CSV):
import json
from dataprofiler import Data , Profiler
data = Data ( "your_file.csv" ) # Auto-Detect & Load: CSV, AVRO, Parquet, JSON, Text, URL
print ( data . data . head ( 5 )) # Access data directly via a compatible Pandas DataFrame
profile = Profiler ( data ) # Calculate Statistics, Entity Recognition, etc
readable_report = profile . report ( report_options = { "output_format" : "compact" })
print ( json . dumps ( readable_report , indent = 4 ))Remarque: Le profileur de données est livré avec un modèle d'apprentissage en profondeur pré-formé, utilisé pour identifier efficacement les données sensibles (PII / NPI). Si vous le souhaitez, il est facile d'ajouter de nouvelles entités au modèle pré-formé existant ou d'insérer un nouveau pipeline pour la reconnaissance des entités.
Pour la documentation de l'API, visitez la page de documentation.
Si vous avez des suggestions ou trouvez un bogue, veuillez ouvrir un problème.
Si vous souhaitez contribuer, visitez la page contributive.
Pour installer le package complet à partir de PYPI : pip install DataProfiler[full]
Si vous souhaitez installer les dépendances ML sans générer des rapports, utilisez DataProfiler[ml]
Si les exigences ML sont trop strictes (par exemple, vous ne voulez pas installer TensorFlow), vous pouvez installer un package plus mince avec DataProfiler[reports] . Le package plus mince désactive la détection / reconnaissance de l'entité de données sensibles par défaut (LABLEUR)
Installer à partir de PYPI: pip install DataProfiler
Dans le cas de cette bibliothèque, un profil de données est un dictionnaire contenant des statistiques et des prédictions sur l'ensemble de données sous-jacent. Il existe des "statistiques globales" ou global_stats , qui contiennent des données de niveau de données et il existe des "statistiques de niveau de colonne / ligne" ou data_stats (chaque colonne est une nouvelle entrée de valeur clé).
Le format pour un profil structuré est ci-dessous:
"global_stats": {
"samples_used": int,
"column_count": int,
"row_count": int,
"row_has_null_ratio": float,
"row_is_null_ratio": float,
"unique_row_ratio": float,
"duplicate_row_count": int,
"file_type": string,
"encoding": string,
"correlation_matrix": list[list[int]], (*)
"chi2_matrix": list[list[float]],
"profile_schema": {
string: list[int]
},
"times": dict[string, float],
},
"data_stats": [
{
"column_name": string,
"data_type": string,
"data_label": string,
"categorical": bool,
"order": string,
"samples": list[str],
"statistics": {
"sample_size": int,
"null_count": int,
"null_types": list[string],
"null_types_index": {
string: list[int]
},
"data_type_representation": dict[string, float],
"min": [null, float, str],
"max": [null, float, str],
"mode": float,
"median": float,
"median_absolute_deviation": float,
"sum": float,
"mean": float,
"variance": float,
"stddev": float,
"skewness": float,
"kurtosis": float,
"num_zeros": int,
"num_negatives": int,
"histogram": {
"bin_counts": list[int],
"bin_edges": list[float],
},
"quantiles": {
int: float
},
"vocab": list[char],
"avg_predictions": dict[string, float],
"data_label_representation": dict[string, float],
"categories": list[str],
"unique_count": int,
"unique_ratio": float,
"categorical_count": dict[string, int],
"gini_impurity": float,
"unalikeability": float,
"precision": {
'min': int,
'max': int,
'mean': float,
'var': float,
'std': float,
'sample_size': int,
'margin_of_error': float,
'confidence_level': float
},
"times": dict[string, float],
"format": string
},
"null_replication_metrics": {
"class_prior": list[int],
"class_sum": list[list[int]],
"class_mean": list[list[int]]
}
}
]
(*) Actuellement, la mise à jour de la matrice de corrélation est activée. Il sera réinitialisé dans une mise à jour ultérieure. Les utilisateurs peuvent toujours l'utiliser comme souhaité avec l'option is_enable définie sur true.
Le format pour un profil non structuré est ci-dessous:
"global_stats": {
"samples_used": int,
"empty_line_count": int,
"file_type": string,
"encoding": string,
"memory_size": float, # in MB
"times": dict[string, float],
},
"data_stats": {
"data_label": {
"entity_counts": {
"word_level": dict[string, int],
"true_char_level": dict[string, int],
"postprocess_char_level": dict[string, int]
},
"entity_percentages": {
"word_level": dict[string, float],
"true_char_level": dict[string, float],
"postprocess_char_level": dict[string, float]
},
"times": dict[string, float]
},
"statistics": {
"vocab": list[char],
"vocab_count": dict[string, int],
"words": list[string],
"word_count": dict[string, int],
"times": dict[string, float]
}
}
Le format d'un profil de graphique est ci-dessous:
"num_nodes": int,
"num_edges": int,
"categorical_attributes": list[string],
"continuous_attributes": list[string],
"avg_node_degree": float,
"global_max_component_size": int,
"continuous_distribution": {
"<attribute_1>": {
"name": string,
"scale": float,
"properties": list[float, np.array]
},
"<attribute_2>": None,
...
},
"categorical_distribution": {
"<attribute_1>": None,
"<attribute_2>": {
"bin_counts": list[int],
"bin_edges": list[float]
},
...
},
"times": dict[string, float]
samples_used - Nombre d'échantillons de données d'entrée utilisés pour générer ce profilcolumn_count - Le nombre de colonnes contenues dans l'ensemble de données d'entréerow_count - Le nombre de lignes contenues dans l'ensemble de données d'entréerow_has_null_ratio - la proportion de lignes qui contiennent au moins une valeur nulle au nombre total de lignesrow_is_null_ratio - la proportion de lignes qui sont entièrement composées de valeurs nulles (lignes nulles) au nombre total de lignesunique_row_ratio - La proportion de lignes distinctes dans l'ensemble de données d'entrée au nombre total de lignesduplicate_row_count - le nombre de lignes qui se produisent plus d'une fois dans l'ensemble de données d'entréefile_type - le format du fichier contenant le jeu de données d'entrée (ex: .csv)encoding - Encodage du fichier contenant l'ensemble de données d'entrée (Ex: UTF-8)correlation_matrix - Matrice de forme column_count x column_count contenant les coefficients de corrélation entre chaque colonne de l'ensemble de donnéeschi2_matrix - Matrice de forme column_count x column_count contenant les statistiques du chi carré entre chaque colonne de l'ensemble de donnéesprofile_schema - Une description du format de l'ensemble de données d'entrée étiquetant chaque colonne et son index dans l'ensemble de donnéesstring - L'étiquette de la colonne en question et son index dans le schéma de profiltimes - La durée du temps qu'il a fallu pour générer les statistiques mondiales de cet ensemble de données en millisecondes column_name - l'étiquette / titre de cette colonne dans l'ensemble de données d'entréedata_type - le type de données Python primitif contenu dans cette colonnedata_label - L'étiquette / entité des données de cette colonne telle que déterminée par le composant d'étiquetercategorical - «vrai» si cette colonne contient des données catégoriquesorder - La façon dont les données de cette colonne sont commandées, le cas échéant, sinon «aléatoire»samples - Un petit sous-ensemble d'entrées de données de cette colonnestatistics - Informations statistiques sur la colonnesample_size - Nombre d'échantillons de données d'entrée utilisés pour générer ce profilnull_count - Le nombre d'entrées nulles dans l'échantillonnull_types - Une liste des différents types nuls présents dans cet échantillonnull_types_index - un dict contenant chaque type nul et une liste respective des indices qu'il est présent dans cet échantillondata_type_representation - le pourcentage d'échantillons utilisés en identifiant comme chaque Data_Typemin - valeur minimale dans l'échantillonmax - valeur maximale dans l'échantillonmode - Mode des entrées dans l'échantillonmedian - médiane des entrées dans l'échantillonmedian_absolute_deviation - La déviation absolue médiane des entrées dans l'échantillonsum - le total de toutes les valeurs échantillonnées de la colonnemean - la moyenne de toutes les entrées de l'échantillonvariance - la variance de toutes les entrées de l'échantillonstddev - L'écart type de toutes les entrées de l'échantillonskewness - l'asymétrie statistique de toutes les entrées de l'échantillonkurtosis - le kurtosis statistique de toutes les entrées de l'échantillonnum_zeros - le nombre d'entrées dans cet échantillon qui ont la valeur 0num_negatives - le nombre d'entrées dans cet échantillon qui ont une valeur inférieure à 0histogram - Contient des informations pertinentes sur l'histogrammebin_counts - le nombre d'entrées dans chaque bacbin_edges - les seuils de chaque bacquantiles - La valeur à chaque centile de l'ordre, ils sont répertoriés en fonction des entrées de l'échantillonvocab - Une liste des personnages utilisés dans les entrées de cet échantillonavg_predictions - Moyenne des confidences de prédiction de l'étiquette de données sur tous les points de données échantillonnéscategories - Une liste de chaque catégorie distincte dans l'échantillon si categorial = 'true'unique_count - Le nombre d'entrées distinctes dans l'échantillonunique_ratio - La proportion du nombre d'entrées distinctes dans l'échantillon au nombre total d'entrées dans l'échantilloncategorical_count - Nombre d'entrées échantillonnées pour chaque catégorie si categorical = 'true'gini_impurity - mesure de la fréquence à laquelle un élément choisi au hasard de l'ensemble serait incorrectement étiqueté s'il était étiqueté au hasard en fonction de la distribution des étiquettes dans le sous-ensembleunalikeability - Une valeur indiquant la fréquence des entrées diffèrent les unes des autres dans l'échantillonprecision - un dict de statistiques en ce qui concerne le nombre de chiffres dans un nombre pour chaque échantillontimes - La durée qu'il a fallu pour générer des statistiques de cet échantillon en millisecondesformat - Liste des formats DateTime possiblesnull_replication_metrics - Statistiques des données partitionnées en fonction de la question de savoir si la valeur de la colonne est nul (index 1 des listes référencées par les clés du dict) ou non (index 0)class_prior - une liste contenant la probabilité d'une valeur de colonne étant nul et non nulclass_sum - une liste contenant une somme de toutes les autres lignes en fonction de la question de savoir si la valeur de la colonne est nul ou nonclass_mean - une liste contenant la moyenne de toutes les autres lignes en fonction de la question de savoir si la valeur de la colonne est nul ou nonsamples_used - Nombre d'échantillons de données d'entrée utilisés pour générer ce profilempty_line_count - Le nombre de lignes vides dans les données d'entréefile_type - le type de fichier des données d'entrée (ex: .txt)encoding - Encodage de fichiers du fichier de données d'entrée (Ex: UTF-8)memory_size - Taille des données d'entrée dans MBtimes - durée du temps qu'il a fallu pour générer ce profil en millisecondes data_label - Étiquettes et statistiques sur les étiquettes des données d'entréeentity_counts - Le nombre de fois qu'une étiquette ou une entité spécifique apparaît à l'intérieur des données d'entréeword_level - le nombre de mots comptés dans chaque étiquette ou entitétrue_char_level - le nombre de caractères comptés dans chaque étiquette ou entité tel que déterminé par le modèlepostprocess_char_level - Le nombre de caractères comptés dans chaque étiquette ou entité tel que déterminé par le postprocesseurentity_percentages - Les pourcentages de chaque étiquette ou entité dans les données d'entréeword_level - le pourcentage de mots dans les données d'entrée qui sont contenues dans chaque étiquette ou entitétrue_char_level - le pourcentage de caractères dans les données d'entrée qui sont contenus dans chaque étiquette ou entité tel que déterminé par le modèlepostprocess_char_level - le pourcentage de caractères dans les données d'entrée qui sont contenus dans chaque étiquette ou entité tel que déterminé par le post-processeurtimes - La durée du temps qu'il a fallu à l'étiqueteur de données pour prédire les donnéesstatistics - Statistiques des données d'entréevocab - Une liste de chaque caractère dans les données d'entréevocab_count - Le nombre d'occurrences de chaque caractère distinct dans les données d'entréewords - une liste de chaque mot dans les données d'entréeword_count - Le nombre d'occurrences de chaque mot distinct dans les données d'entréetimes - La durée du temps qu'il a fallu pour générer les statistiques du vocabulaire et des mots en millisecondesnum_nodes - Nombre de nœuds dans le graphiquenum_edges - nombre de bords dans le graphiquecategorical_attributes - liste des attributs de bord catégorielscontinuous_attributes - liste des attributs de bord continuavg_node_degree - degré moyen de nœuds dans le graphiqueglobal_max_component_size : Taille du composant Global Max <attribute_N> : nom de l'attribut n-th edge dans la liste des attributsname - Nom de la distribution pour l'attributscale - vraisemblance négative des logiciels utilisés pour l'échelle et comparer les distributionsproperties - Liste des propriétés statistiques décrivant la distribution <attribute_N> : nom de l'attribut n-th edge dans la liste des attributs
bin_counts : compte dans chaque bac de l'histogramme de distributionbin_edges : bords de chaque bac de l'histogramme de distributionTemps - durée du temps qu'il a fallu pour générer ce profil en millisecondes
Les types de données sont déterminés au niveau de la colonne pour les données structurées
Les étiquettes de données sont déterminées par cellule pour les données structurées (colonne / ligne lorsque le profileur est utilisé) ou au niveau du caractère pour les données non structurées.
Le profileur de données peut profiler les types de données / fichiers suivants:
Le profileur doit identifier automatiquement le type de fichier et charger les données dans une Data Class .
Parallèlement aux autres attributs, la Data class permet d'accéder aux données via un Pandas DataFrame valide.
# Load a csv file, return a CSVData object
csv_data = Data ( 'your_file.csv' )
# Print the first 10 rows of the csv file
print ( csv_data . data . head ( 10 ))
# Load a parquet file, return a ParquetData object
parquet_data = Data ( 'your_file.parquet' )
# Sort the data by the name column
parquet_data . data . sort_values ( by = 'name' , inplace = True )
# Print the sorted first 10 rows of the parquet data
print ( parquet_data . data . head ( 10 ))
# Load a json file from a URL, return a JSONData object
json_data = Data ( 'https://github.com/capitalone/DataProfiler/blob/main/dataprofiler/tests/data/json/iris-utf-8.json' )Si le type de fichier n'est pas automatiquement identifié (rare), vous pouvez les spécifier spécifiquement, voir la section spécifiant un type de filets ou un délimiteur.
L'exemple utilise un fichier CSV par exemple, mais CSV, JSON, AVRO, Parquet ou le texte fonctionnent également.
import json
from dataprofiler import Data , Profiler
# Load file (CSV should be automatically identified)
data = Data ( "your_file.csv" )
# Profile the dataset
profile = Profiler ( data )
# Generate a report and use json to prettify.
report = profile . report ( report_options = { "output_format" : "pretty" })
# Print the report
print ( json . dumps ( report , indent = 4 ))Actuellement, le profileur de données est équipé pour mettre à jour son profil par lots.
import json
from dataprofiler import Data , Profiler
# Load and profile a CSV file
data = Data ( "your_file.csv" )
profile = Profiler ( data )
# Update the profile with new data:
new_data = Data ( "new_data.csv" )
profile . update_profile ( new_data )
# Print the report using json to prettify.
report = profile . report ( report_options = { "output_format" : "pretty" })
print ( json . dumps ( report , indent = 4 ))Notez que si les données avec lesquelles vous mettez à jour le profil contiennent des indices entiers qui chevauchent les indices sur les données initialement profilés, lorsque les lignes nulles sont calculées, les indices seront "décalés" vers des valeurs inhabitées afin que le nombre de nuls et les ratios soient toujours exacts.
Si vous avez deux fichiers avec le même schéma (mais des données différentes), il est possible de fusionner les deux profils via un opérateur d'addition.
Cela permet également de déterminer les profils de manière distribuée.
import json
from dataprofiler import Data , Profiler
# Load a CSV file with a schema
data1 = Data ( "file_a.csv" )
profile1 = Profiler ( data1 )
# Load another CSV file with the same schema
data2 = Data ( "file_b.csv" )
profile2 = Profiler ( data2 )
profile3 = profile1 + profile2
# Print the report using json to prettify.
report = profile3 . report ( report_options = { "output_format" : "pretty" })
print ( json . dumps ( report , indent = 4 ))Notez que si les profils fusionnés avaient des indices entiers qui se chevauchent, lorsque les lignes nulles sont calculées, les indices seront "déplacés" vers des valeurs inhabitées afin que le nombre et les rapports nuls soient encore précis.
Pour trouver le changement entre les profils avec le même schéma, nous pouvons utiliser la fonction diff du profil. Le diff fournira des différences globales de fichiers et d'échantillonnage ainsi que des différences détaillées des statistiques des données. Par exemple, les colonnes numériques ont à la fois un test t pour évaluer la similitude et le PSI (indice de stabilité de la population) pour quantifier le décalage de distribution des colonnes. Plus d'informations sont décrites dans la section Profiler des pages GitHub.
Créez le rapport de différence comme ceci:
import json
import dataprofiler as dp
# Load a CSV file
data1 = dp . Data ( "file_a.csv" )
profile1 = dp . Profiler ( data1 )
# Load another CSV file
data2 = dp . Data ( "file_b.csv" )
profile2 = dp . Profiler ( data2 )
diff_report = profile1 . diff ( profile2 )
print ( json . dumps ( diff_report , indent = 4 )) import pandas as pd
import dataprofiler as dp
import json
my_dataframe = pd . DataFrame ([[ 1 , 2.0 ],[ 1 , 2.2 ],[ - 1 , 3 ]])
profile = dp . Profiler ( my_dataframe )
# print the report using json to prettify.
report = profile . report ( report_options = { "output_format" : "pretty" })
print ( json . dumps ( report , indent = 4 ))
# read a specified column, in this case it is labeled 0:
print ( json . dumps ( report [ "data_stats" ][ 0 ], indent = 4 )) En plus du profileur structuré, DataProfiler fournit un profilage non structuré pour l'objet ou la chaîne TextData. Le profileur non structuré fonctionne également avec List [String], Pd.Series (String) ou PD.DataFrame (String) donné l'option ProFiler_type spécifiée comme unstructured . Vous trouverez ci-dessous un exemple du profileur non structuré avec un fichier texte.
import dataprofiler as dp
import json
my_text = dp . Data ( 'text_file.txt' )
profile = dp . Profiler ( my_text )
# print the report using json to prettify.
report = profile . report ( report_options = { "output_format" : "pretty" })
print ( json . dumps ( report , indent = 4 )) Un autre exemple du profileur non structuré avec des séances de chaînes PD profiler_type='unstructured'
import dataprofiler as dp
import pandas as pd
import json
text_data = pd . Series ([ 'first string' , 'second string' ])
profile = dp . Profiler ( text_data , profiler_type = 'unstructured' )
# print the report using json to prettify.
report = profile . report ( report_options = { "output_format" : "pretty" })
print ( json . dumps ( report , indent = 4 ))DataProfiler offre également la possibilité de profil les données du graphique à partir d'un fichier CSV. Vous trouverez ci-dessous un exemple du profileur de graphiques avec un fichier CSV de données graphiques:
import dataprofiler as dp
import pprint
my_graph = dp . Data ( 'graph_file.csv' )
profile = dp . Profiler ( my_graph )
# print the report using pretty print (json dump does not work on numpy array values inside dict)
report = profile . report ()
printer = pprint . PrettyPrinter ( sort_dicts = False , compact = True )
printer . pprint ( report )Visitez la page de documentation pour des exemples supplémentaires et les détails de l'API
Sensitive Data Detection with High-Throughput Neural Network Models for Financial Institutions
Authors: Anh Truong, Austin Walters, Jeremy Goodsitt
2020 https://arxiv.org/abs/2012.09597
The AAAI-21 Workshop on Knowledge Discovery from Unstructured Data in Financial Services