Поделиться через


Руководство. Очистка данных с помощью функциональных зависимостей

В этом руководстве вы используете функциональные зависимости для очистки данных. Функциональная зависимость существует, если один столбец в семантической модели (набор данных Power BI) является функцией другого столбца. For example, a zip code column might determine the values in a city column. Функциональная зависимость проявляется в виде связи типа "один ко многим" между значениями в двух или нескольких столбцах в DataFrame. В этом руководстве используется набор данных Synthea, чтобы показать, как функциональные связи могут помочь обнаружить проблемы с качеством данных.

В этом руководстве описано, как:

  • Применение знаний домена для формирования гипотез о функциональных зависимостях в семантической модели.
  • Ознакомьтесь с компонентами библиотеки Python семантической связи (SemPy), которые помогают автоматизировать анализ качества данных. К этим компонентам относятся:
    • FabricDataFrame — структура, подобная pandas, с дополнительной семантической информацией.
    • Полезные функции, которые автоматизируют оценку гипотез о функциональных зависимостях и определяют нарушения связей в семантических моделях.

Необходимые условия

  • Select Workspaces from the left navigation pane to find and select your workspace. This workspace becomes your current workspace.

Следуйте инструкциям в записной книжке

The data_cleaning_functional_dependencies_tutorial.ipynb notebook accompanies this tutorial.

Настройка записной книжки

В этом разделе описана настройка среды записной книжки с необходимыми модулями и данными.

  1. Для Spark 3.4 и более поздних версий семантическая ссылка доступна в среде выполнения по умолчанию при использовании Fabric и не требуется устанавливать ее. Если вы используете Spark 3.3 или ниже или хотите обновить до последней версии семантической ссылки, можно выполнить следующую команду:

python %pip install -U semantic-link  

  1. Выполните необходимые импорты модулей, которые потребуются вам позже:

    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. Pull the sample data. For this tutorial, you use the Synthea dataset of synthetic medical records (small version for simplicity):

    download_synthea(which='small')
    

Изучение данных

  1. Initialize a FabricDataFrame with the content of the providers.csv file:

    providers = FabricDataFrame(pd.read_csv("synthea/csv/providers.csv"))
    providers.head()
    
  2. Проверьте наличие проблем с качеством данных в функции find_dependencies SemPy, настроив граф автоопределенных функциональных зависимостей:

    deps = providers.find_dependencies()
    plot_dependency_metadata(deps)
    

    снимок экрана: граф функциональных зависимостей.

    График функциональных зависимостей показывает, что Id определяет NAME и ORGANIZATION (указанные сплошными стрелками), что ожидается, так как Id является уникальным:

  3. Убедитесь, что Id является уникальным:

    providers.Id.is_unique
    

    Код возвращает True для подтверждения уникальности Id.

Подробный анализ функциональных зависимостей

График функциональных зависимостей также показывает, что ORGANIZATION определяет ADDRESS и ZIP, как ожидалось. Однако вы можете ожидать, что ZIP также определяет CITY, но пунктирная стрелка указывает, что зависимость является только приблизительной, указывая на проблему качества данных.

В графе существуют и другие особенности. Например, NAME не определяет GENDER, Id, SPECIALITYили ORGANIZATION. Каждое из этих особенностей может быть стоит исследовать.

  1. Более подробно рассмотрим приблизительную связь между ZIP и CITYс помощью функции list_dependency_violations SemPy для просмотра табличного списка нарушений:

    providers.list_dependency_violations('ZIP', 'CITY')
    
  2. Нарисуйте граф с помощью функции визуализации plot_dependency_violations SemPy. Этот график полезен, если количество нарушений невелико:

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

    снимок экрана: график нарушений зависимостей.

    На графике нарушений зависимостей отображаются значения ZIP на левой стороне и значения для CITY справа. Ребро соединяет zip-код на левой стороне графика с городом на правой стороне, если существует строка, содержащая эти два значения. Края аннотированы с количеством таких строк. Например, есть две строки с почтовым кодом 02747-1242, одна строка с городом "NORTH DARTHMOUTH" и другой с городом "DARTHMOUTH", как показано в предыдущем графике и следующем коде:

  3. Проверьте предыдущие наблюдения, сделанные с помощью графика нарушений зависимостей, выполнив следующий код:

    providers[providers.ZIP == '02747-1242'].CITY.value_counts()
    
  4. На графике также показано, что среди строк, которые имеют CITY как "DARTHMOUTH", девять строк имеют ZIP 02747-1262; одна строка имеет ZIP 02747-1242; и одна строка имеет ZIP 02747-2537. Подтверждает эти наблюдения с помощью следующего кода:

    providers[providers.CITY == 'DARTMOUTH'].ZIP.value_counts()
    
  5. Существуют другие zip-коды, связанные с DARTMOUTH, но эти zip-коды не отображаются в графе нарушений зависимостей, так как они не указывают на проблемы с качеством данных. Например, почтовый индекс "02747-4302" однозначно связан с DARTMOUTH и не отображается в графе нарушений зависимостей. Подтвердите, выполнив следующий код:

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

Сводка проблем с качеством данных, обнаруженных с помощью SemPy

Вернитесь к графу нарушений зависимостей, вы увидите, что в этой семантической модели существует несколько интересных проблем с качеством данных:

  • Некоторые имена городов — это все прописные буквы. Эта проблема легко устранить с помощью строковых методов.
  • Некоторые имена городов имеют квалификаторы (или префиксы), такие как "Север" и "Восток". Например, почтовый индекс "2128" соотносится с "EAST BOSTON" один раз и с "БОСТОН" один раз. A similar issue occurs between "NORTH DARTHMOUTH" and "DARTHMOUTH". You could try to drop these qualifiers or map the zip codes to the city with the most common occurrence.
  • В некоторых городах есть опечатки, такие как "PITTSFIELD" против "PITTSFILED" и "NEWBURGPORT" против "NEWBURYPORT". Для "NEWBURGPORT" эту ошибку можно исправить, выбрав наиболее часто встречающееся написание. For "PITTSFIELD", having only one occurrence each makes it much harder for automatic disambiguation without external knowledge or the use of a language model.
  • Иногда префиксы, такие как "Запад", сокращены до одной буквы "W". This issue could potentially be fixed with a simple replace, if all occurrences of "W" stand for "West".
  • The zip code "02130" maps to "BOSTON" once and "Jamaica Plain" once. This issue isn't easy to fix, but if there was more data, mapping to the most common occurrence could be a potential solution.

Очистка данных

  1. Fix the capitalization issues by changing all capitalization to title case:

    providers['CITY'] = providers.CITY.str.title()
    
  2. Запустите обнаружение нарушений еще раз, чтобы увидеть, что некоторые из неоднозначности исчезли (число нарушений меньше):

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

    На этом этапе можно уточнить данные вручную, но одна из потенциальных задач очистки данных заключается в том, чтобы удалить строки, которые нарушают функциональные ограничения между столбцами в данных, используя функцию SemPy drop_dependency_violations.

    Для каждого значения детерминированной переменной drop_dependency_violations работает путем выбора наиболее распространенного значения зависимой переменной и удаления всех строк с другими значениями. Эту операцию следует применять только в том случае, если вы уверены, что эта статистическая эвристика приведет к правильным результатам для данных. В противном случае необходимо написать собственный код для обработки обнаруженных нарушений по мере необходимости.

  3. Запустите функцию drop_dependency_violations в столбцах ZIP и CITY:

    providers_clean = providers.drop_dependency_violations('ZIP', 'CITY')
    
  4. Перечислить все нарушения зависимостей между ZIP и CITY:

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

    Код возвращает пустой список, указывающий на отсутствие нарушений функционального ограничения CITY -> ZIP-.

Ознакомьтесь с другими руководствами по семантической ссылке / SemPy: