Partilhar via


Tutorial: Limpar dados com dependências funcionais

Neste tutorial, você usa dependências funcionais para limpeza de dados. Existe uma dependência funcional quando uma coluna em um modelo semântico (um conjunto de dados do Power BI) é uma função de outra coluna. Por exemplo, uma coluna de código postal pode determinar os valores em uma coluna de cidade . Uma dependência funcional se manifesta como uma relação um-para-muitos entre os valores em duas ou mais colunas dentro de um DataFrame. Este tutorial usa o conjunto de dados Synthea para mostrar como as relações funcionais podem ajudar a detetar problemas de qualidade de dados.

Neste tutorial, irá aprender a:

  • Aplicar conhecimento de domínio para formular hipóteses sobre dependências funcionais em um modelo semântico.
  • Familiarize-se com os componentes da biblioteca Python (SemPy) do link semântico que ajudam a automatizar a análise da qualidade dos dados. Esses componentes incluem:
    • FabricDataFrame - uma estrutura semelhante a pandas aprimorada com informações semânticas adicionais.
    • Funções úteis que automatizam a avaliação de hipóteses sobre dependências funcionais e que identificam violações de relações em seus modelos semânticos.

Pré-requisitos

  • Obtenha uma assinatura do Microsoft Fabric. Ou inscreva-se para uma avaliação gratuita do Microsoft Fabric.

  • Entre no Microsoft Fabric.

  • Use o seletor de experiência no lado esquerdo da sua página inicial para alternar para a experiência Synapse Data Science.

    Captura de tela do menu do seletor de experiência, mostrando onde selecionar Ciência de Dados.

  • Selecione Espaços de trabalho no painel de navegação esquerdo para localizar e selecionar seu espaço de trabalho. Este espaço de trabalho torna-se o seu espaço de trabalho atual.

Acompanhe no caderno

O notebook data_cleaning_functional_dependencies_tutorial.ipynb acompanha este tutorial.

Para abrir o bloco de anotações que acompanha este tutorial, siga as instruções em Preparar seu sistema para tutoriais de ciência de dados, para importar o bloco de anotações para seu espaço de trabalho.

Se preferir copiar e colar o código desta página, pode criar um novo bloco de notas.

Certifique-se de anexar um lakehouse ao bloco de anotações antes de começar a executar o código.

Configurar o bloco de notas

Nesta seção, você configura um ambiente de notebook com os módulos e dados necessários.

  1. Para o Spark 3.4 e superior, o link semântico está disponível no tempo de execução padrão ao usar o Fabric e não há necessidade de instalá-lo. Se você estiver usando o Spark 3.3 ou inferior, ou se quiser atualizar para a versão mais recente do Link Semântico, poderá executar o comando:

python %pip install -U semantic-link  

  1. Execute as importações necessárias de módulos que você precisará mais tarde:

    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. Puxe os dados de exemplo. Para este tutorial, você usa o conjunto de dados Synthea de registros médicos sintéticos (versão pequena para simplificar):

    download_synthea(which='small')
    

Explorar os dados

  1. Inicialize um FabricDataFrame com o conteúdo do arquivo providers.csv:

    providers = FabricDataFrame(pd.read_csv("synthea/csv/providers.csv"))
    providers.head()
    
  2. Verifique se há problemas de qualidade de dados com a função do SemPy plotando um gráfico de dependências find_dependencies funcionais detetadas automaticamente:

    deps = providers.find_dependencies()
    plot_dependency_metadata(deps)
    

    Captura de tela mostrando o gráfico de dependências funcionais.

    O gráfico de dependências funcionais mostra que determina NAME e ORGANIZATION (indicado pelas setas sólidas), o que é esperado, uma vez Id que Id é único:

  3. Confirme que Id é único:

    providers.Id.is_unique
    

    O código retorna True para confirmar que Id é exclusivo.

Analise as dependências funcionais em profundidade

O gráfico de dependências funcionais também mostra que ORGANIZATION determina ADDRESS e ZIP, conforme esperado. No entanto, você pode esperar ZIP também determinar CITY, mas a seta tracejada indica que a dependência é apenas aproximada, apontando para um problema de qualidade de dados.

Há outras peculiaridades no gráfico. Por exemplo, NAME não determina GENDER, Id, SPECIALITY, ou ORGANIZATION. Cada uma dessas peculiaridades pode valer a pena investigar.

  1. Dê uma olhada mais profunda na relação aproximada entre ZIP e CITY, usando a função do list_dependency_violations SemPy para ver uma lista tabular de violações:

    providers.list_dependency_violations('ZIP', 'CITY')
    
  2. Desenhe um gráfico com a função de visualização do plot_dependency_violations SemPy. Este gráfico é útil se o número de violações for pequeno:

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

    Captura de tela mostrando o gráfico de violações de dependência.

    O gráfico de violações de dependência mostra valores para ZIP no lado esquerdo e valores para CITY no lado direito. Uma aresta conecta um CEP no lado esquerdo do gráfico com uma cidade no lado direito se houver uma linha que contenha esses dois valores. As arestas são anotadas com a contagem dessas linhas. Por exemplo, existem duas linhas com o CEP 02747-1242, uma linha com a cidade "NORTH DARTHMOUTH" e outra com a cidade "DARTHMOUTH", como mostrado no gráfico anterior e no seguinte código:

  3. Confirme as observações anteriores feitas com o gráfico de violações de dependência executando o seguinte código:

    providers[providers.ZIP == '02747-1242'].CITY.value_counts()
    
  4. O gráfico também mostra que entre as linhas que têm CITY como "DARTHMOUTH", nove linhas têm um ZIP de 02747-1262, uma linha tem um ZIP de 02747-1242 e uma linha tem um ZIP de 02747-2537. Confirma estas observações com o seguinte código:

    providers[providers.CITY == 'DARTMOUTH'].ZIP.value_counts()
    
  5. Existem outros códigos postais associados a "DARTMOUTH", mas esses códigos postais não são mostrados no gráfico de violações de dependência, pois não sugerem problemas de qualidade de dados. Por exemplo, o CEP "02747-4302" está exclusivamente associado a "DARTMOUTH" e não aparece no gráfico de violações de dependência. Confirme executando o seguinte código:

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

Resumir os problemas de qualidade de dados detetados com o SemPy

Voltando ao gráfico de violações de dependência, você pode ver que há vários problemas interessantes de qualidade de dados presentes neste modelo semântico:

  • Alguns nomes de cidades são todos maiúsculos. Esse problema é fácil de corrigir usando métodos de cadeia de caracteres.
  • Alguns nomes de cidades têm qualificadores (ou prefixos), como "Norte" e "Leste". Por exemplo, o código postal "2128" mapeia para "EAST BOSTON" uma vez e para "BOSTON" uma vez. Um problema semelhante ocorre entre "NORTH DARTHMOUTH" e "DARTHMOUTH". Você pode tentar soltar esses qualificadores ou mapear os CEPs para a cidade com a ocorrência mais comum.
  • Há erros de digitação em algumas cidades, como "PITTSFIELD" vs. "PITTSFILED" e "NEWBURGPORT vs. "NEWBURYPORT". Para "NEWBURGPORT" este erro de digitação pode ser corrigido usando a ocorrência mais comum. Para "PITTSFIELD", ter apenas uma ocorrência cada torna muito mais difícil a desambiguação automática sem conhecimento externo ou o uso de um modelo de linguagem.
  • Às vezes, prefixos como "West" são abreviados para uma única letra "W". Esse problema poderia ser corrigido com uma simples substituição, se todas as ocorrências de "W" representassem "West".
  • O código postal "02130" mapeia para "BOSTON" uma vez e "Jamaica Plain" uma vez. Esse problema não é fácil de corrigir, mas se houvesse mais dados, o mapeamento para a ocorrência mais comum poderia ser uma solução potencial.

Limpar os dados

  1. Corrija os problemas de capitalização alterando todas as maiúsculas para maiúsculas e minúsculas:

    providers['CITY'] = providers.CITY.str.title()
    
  2. Execute a deteção de violação novamente para ver que algumas das ambiguidades desapareceram (o número de violações é menor):

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

    Neste ponto, você pode refinar seus dados mais manualmente, mas uma possível tarefa de limpeza de dados é soltar linhas que violam restrições funcionais entre colunas nos dados, usando a função do drop_dependency_violations SemPy.

    Para cada valor da variável determinante, drop_dependency_violations funciona escolhendo o valor mais comum da variável dependente e soltando todas as linhas com outros valores. Você deve aplicar esta operação somente se estiver confiante de que essa heurística estatística levaria aos resultados corretos para seus dados. Caso contrário, você deve escrever seu próprio código para lidar com as violações detetadas, conforme necessário.

  3. Execute a drop_dependency_violations função nas ZIP colunas e CITY :

    providers_clean = providers.drop_dependency_violations('ZIP', 'CITY')
    
  4. Liste todas as violações de dependência entre ZIP e CITY:

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

    O código retorna uma lista vazia para indicar que não há mais violações da restrição funcional CITY -> ZIP.

Confira outros tutoriais para link semântico / SemPy: