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


Руководство. Обнаружение связей в наборе данных Synthea с помощью семантической ссылки

В этом руководстве показано, как обнаруживать связи в общедоступном наборе данных Synthea с помощью семантической ссылки.

При работе с новыми данными или без существующей модели данных может быть полезно автоматически обнаруживать связи. Это обнаружение связей поможет вам:

  • понимание модели на высоком уровне
  • получите больше аналитических сведений во время анализа аналитических данных,
  • проверка обновленных данных или новых, входящих данных и
  • очистка данных.

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

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

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

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

Необходимые компоненты

  • Получение подписки Microsoft Fabric. Или зарегистрируйте бесплатную пробную версию Microsoft Fabric.

  • Войдите в Microsoft Fabric.

  • Используйте переключатель интерфейса в левой части домашней страницы, чтобы перейти на интерфейс Synapse Обработка и анализ данных.

    Снимок экрана: меню переключателя интерфейса, в котором показано, где выбрать Обработка и анализ данных.

  • Выберите рабочие области в области навигации слева, чтобы найти и выбрать рабочую область. Эта рабочая область становится текущей рабочей областью.

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

Записная книжка relationships_detection_tutorial.ipynb сопровождает это руководство.

Чтобы открыть сопровождающую записную книжку для этого руководства, следуйте инструкциям в статье "Подготовка системы для обработки и анализа данных", чтобы импортировать записную книжку в рабочую область.

Если вы хотите скопировать и вставить код на этой странице, можно создать новую записную книжку.

Перед запуском кода обязательно подключите lakehouse к записной книжке .

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

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

  1. Установите из PyPI с помощью %pip встроенной возможности установки SemPy в записной книжке:

    %pip install semantic-link
    
  2. Выполните необходимые импорты модулей SemPy, которые потребуются позже:

    import pandas as pd
    
    from sempy.samples import download_synthea
    from sempy.relationships import (
        find_relationships,
        list_relationship_violations,
        plot_relationship_metadata
    )
    
  3. Импорт pandas для применения параметра конфигурации, который помогает с форматированием выходных данных:

    import pandas as pd
    pd.set_option('display.max_colwidth', None)
    
  4. Извлеките примеры данных. В этом руководстве вы используете набор данных Synthea синтетических медицинских записей (небольшая версия для простоты):

    download_synthea(which='small')
    

Обнаружение связей в небольшом подмножестве таблиц Synthea

  1. Выберите три таблицы из большего набора:

    • patients указывает сведения о пациенте
    • encounters указывает пациентов, которые имели медицинские встречи (например, медицинская встреча, процедура)
    • providers указывает, какие медицинские поставщики присутствовали у пациентов

    Таблица encounters разрешает связь "многие ко многим" между patients и providers может быть описана как ассоциативная сущность:

    patients = pd.read_csv('synthea/csv/patients.csv')
    providers = pd.read_csv('synthea/csv/providers.csv')
    encounters = pd.read_csv('synthea/csv/encounters.csv')
    
  2. Поиск связей между таблицами с помощью функции SemPy find_relationships :

    suggested_relationships = find_relationships([patients, providers, encounters])
    suggested_relationships
    
  3. Визуализировать отношения DataFrame в виде графа с помощью функции SemPy plot_relationship_metadata .

    plot_relationship_metadata(suggested_relationships)
    

    Снимок экрана: связи между таблицами в наборе данных.

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

    По умолчанию связи создаются как "m:1" (не как "1:m") или "1:1". Связи "1:1" могут быть созданы одним или обоими способами в зависимости от того, превышает coverage_threshold ли соотношение сопоставленных значений со всеми значениями только в одном или обоих направлениях. Далее в этом руководстве описаны менее частые случаи связей m:m.

Устранение неполадок обнаружения связей

В базовом примере показано успешное обнаружение связей при очистке данных Synthea . На практике данные редко очищается, что предотвращает успешное обнаружение. Существует несколько методов, которые могут быть полезны, если данные не очищаются.

В этом разделе этого руководства рассматривается обнаружение связей, когда семантическая модель содержит данные грязное.

  1. Начните с управления исходными кадрами данных для получения данных грязное и печати размера грязное данных.

    # create a dirty 'patients' dataframe by dropping some rows using head() and duplicating some rows using concat()
    patients_dirty = pd.concat([patients.head(1000), patients.head(50)], axis=0)
    
    # create a dirty 'providers' dataframe by dropping some rows using head()
    providers_dirty = providers.head(5000)
    
    # the dirty dataframes have fewer records than the clean ones
    print(len(patients_dirty))
    print(len(providers_dirty))
    
    
  2. Для сравнения размеры печати исходных таблиц:

    print(len(patients))
    print(len(providers))
    
  3. Поиск связей между таблицами с помощью функции SemPy find_relationships :

    find_relationships([patients_dirty, providers_dirty, encounters])
    

    В выходных данных кода показано, что связи не обнаружены из-за ошибок, введенных ранее для создания семантической модели "грязное".

Использование проверки

Проверка — это лучший инструмент для устранения ошибок обнаружения связей, так как:

  • Он ясно сообщает, почему определенная связь не соответствует правилам внешнего ключа и поэтому не может быть обнаружена.
  • Он работает быстро с большими семантических моделями, так как он фокусируется только на объявленных отношениях и не выполняет поиск.

Проверка может использовать любой кадр данных с столбцами, аналогичными столбцам, созданным с помощью find_relationshipsпроверки. В следующем коде suggested_relationships кадр данных ссылается patients на нее patients_dirty, но вы можете псевдонимировать кадры данных с помощью словаря:

dirty_tables = {
    "patients": patients_dirty,
    "providers" : providers_dirty,
    "encounters": encounters
}

errors = list_relationship_violations(dirty_tables, suggested_relationships)
errors

Критерии свободного поиска

В более мрачных сценариях вы можете попробовать освободить критерии поиска. Этот метод повышает вероятность ложных срабатываний.

  1. Задайте include_many_to_many=True и оцените, помогает ли она:

    find_relationships(dirty_tables, include_many_to_many=True, coverage_threshold=1)
    

    Результаты показывают, что связь из encounters нее patients обнаружена, но есть две проблемы:

    • Связь указывает направление от patients encounters, которое является обратной ожидаемой связью. Это связано с тем, что все patients , что было охвачено encounters (Coverage From 1,0) в то время как encounters только частично охвачены patients (Coverage To = 0,85), так как строки пациентов отсутствуют.
    • Существует случайное совпадение в столбце низкой карта inalityGENDER, который соответствует по имени и значению в обеих таблицах, но это не отношение "m:1" интереса. Низкая карта inality обозначается столбцами и Unique Count To столбцамиUnique Count From.
  2. Повторно выполните поиск find_relationships только связей "m:1", но с более низким coverage_threshold=0.5:

    find_relationships(dirty_tables, include_many_to_many=False, coverage_threshold=0.5)
    

    Результат показывает правильное направление связей от encounters providers. Однако связь от encounters patients не обнаруживается, так как patients не является уникальной, поэтому она не может находиться на стороне "Один" отношения "m:1".

  3. Освободить оба include_many_to_many=True и coverage_threshold=0.5:

    find_relationships(dirty_tables, include_many_to_many=True, coverage_threshold=0.5)
    

    Теперь оба отношения интереса видны, но есть гораздо больше шума:

    • Присутствует низкое карта инальностьGENDER.
    • Появляется более высокая карта нальность "m:m"ORGANIZATION, что делает его очевидным, что, скорее всего, ORGANIZATION столбец не нормализован для обеих таблиц.

Сопоставление имен столбцов

По умолчанию SemPy рассматривает как совпадения только атрибутов, которые показывают сходство имен, используя тот факт, что конструкторы баз данных обычно называют связанные столбцы таким же образом. Это поведение помогает избежать спрогнозных связей, которые чаще всего происходят с низкими карта целочисленными ключами. Например, если существуют 1,2,3,...,10 категории продуктов и 1,2,3,...,10 код состояния заказа, они будут путаться друг с другом только при просмотре сопоставлений значений без учета имен столбцов. Спрогнозные связи не должны быть проблемой с такими ключами, как GUID.

SemPy смотрит на сходство между именами столбцов и именами таблиц. Сопоставление является приблизительным и не учитывает регистр. Он игнорирует наиболее часто встречающиеся подстроки "декоратора", такие как "id", "code", "name", "key", "pk", "fk". В результате наиболее типичные варианты соответствия:

  • Атрибут , называемый "column" в сущности foo, совпадает с атрибутом "column" (также "COLUMN" или "Column") в сущности "bar".
  • Атрибут с именем column в сущности foo совпадает с атрибутом с именем "column_id" в строке.
  • Атрибут с именем "bar" в сущности foo соответствует атрибуту с атрибутом", который называется "code" в строке.

При первом сопоставлении имен столбцов обнаружение выполняется быстрее.

  1. Совпадают с именами столбцов:

    • Чтобы понять, какие столбцы выбраны для дальнейшей оценки, используйте verbose=2 параметр (verbose=1 перечисляет только обрабатываемые сущности).
    • Параметр name_similarity_threshold определяет, как сравниваются столбцы. Пороговое значение 1 указывает, что вам нужно только 100 % совпадений.
    find_relationships(dirty_tables, verbose=2, name_similarity_threshold=1.0);
    

    Выполнение при 100% сходстве не может учитывать небольшие различия между именами. В примере таблицы имеют форму множественного числа с суффиксом "s", что приводит к отсутствии точного совпадения. Это хорошо обрабатывается по умолчанию name_similarity_threshold=0.8.

  2. Повторное выполнение с параметром по умолчанию name_similarity_threshold=0.8:

    find_relationships(dirty_tables, verbose=2, name_similarity_threshold=0.8);
    

    Обратите внимание, что идентификатор для формы patients plural теперь сравнивается с сингулярным patient , не добавляя слишком много других спрогнозированных сравнений во время выполнения.

  3. Повторное выполнение с параметром по умолчанию name_similarity_threshold=0:

    find_relationships(dirty_tables, verbose=2, name_similarity_threshold=0);
    

    Изменение name_similarity_threshold на 0 — это другая крайняя, и это означает, что вы хотите сравнить все столбцы. Это редко необходимо и приводит к увеличению времени выполнения и спрогнозным совпадениям, которые необходимо проверить. Просмотрите количество сравнений в подробных выходных данных.

Сводка по устранению неполадок

  1. Начиная с точного соответствия для связей "m:1" (то есть по умолчанию include_many_to_many=False и coverage_threshold=1.0). Обычно это то, что вы хотите.
  2. Используйте узкий фокус на небольших подмножествах таблиц.
  3. Используйте проверку для обнаружения проблем с качеством данных.
  4. Используйте, verbose=2 если вы хотите понять, какие столбцы считаются для связи. Это может привести к большому количеству выходных данных.
  5. Помните о компромиссах аргументов поиска. include_many_to_many=True и coverage_threshold<1.0 может привести к спрогнозным отношениям, которые могут быть сложнее анализировать и должны быть отфильтрованы.

Обнаружение связей в полном наборе данных Synthea

Простой базовый пример — это удобное средство обучения и устранения неполадок. На практике вы можете начать с семантической модели, например полный набор данных Synthea , который имеет гораздо больше таблиц. Изучите полный набор данных synthea следующим образом.

  1. Чтение всех файлов из каталога synthea/csv :

    all_tables = {
        "allergies": pd.read_csv('synthea/csv/allergies.csv'),
        "careplans": pd.read_csv('synthea/csv/careplans.csv'),
        "conditions": pd.read_csv('synthea/csv/conditions.csv'),
        "devices": pd.read_csv('synthea/csv/devices.csv'),
        "encounters": pd.read_csv('synthea/csv/encounters.csv'),
        "imaging_studies": pd.read_csv('synthea/csv/imaging_studies.csv'),
        "immunizations": pd.read_csv('synthea/csv/immunizations.csv'),
        "medications": pd.read_csv('synthea/csv/medications.csv'),
        "observations": pd.read_csv('synthea/csv/observations.csv'),
        "organizations": pd.read_csv('synthea/csv/organizations.csv'),
        "patients": pd.read_csv('synthea/csv/patients.csv'),
        "payer_transitions": pd.read_csv('synthea/csv/payer_transitions.csv'),
        "payers": pd.read_csv('synthea/csv/payers.csv'),
        "procedures": pd.read_csv('synthea/csv/procedures.csv'),
        "providers": pd.read_csv('synthea/csv/providers.csv'),
        "supplies": pd.read_csv('synthea/csv/supplies.csv'),
    }
    
  2. Поиск связей между таблицами с помощью функции SemPy find_relationships :

    suggested_relationships = find_relationships(all_tables)
    suggested_relationships
    
  3. Визуализировать связи:

    plot_relationship_metadata(suggested_relationships)
    

    Снимок экрана: связи между таблицами.

  4. Подсчитывайте, сколько новых связей "m:m" будет обнаружено.include_many_to_many=True Эти связи в дополнение к ранее показанным отношениям "m:1"; Таким образом, необходимо отфильтровать следующие multiplicityпараметры:

    suggested_relationships = find_relationships(all_tables, coverage_threshold=1.0, include_many_to_many=True) 
    suggested_relationships[suggested_relationships['Multiplicity']=='m:m']
    
  5. Вы можете сортировать данные связи по различным столбцам, чтобы получить более глубокое представление о своей природе. Например, вы можете упорядочить выходные данные Row Count From по и Row Count To, которые помогут определить самые большие таблицы.

    suggested_relationships.sort_values(['Row Count From', 'Row Count To'], ascending=False)
    

    В другой семантической модели, возможно, важно сосредоточиться на количестве значений NULL Null Count From или Coverage To.

    Этот анализ поможет вам понять, может ли какая-либо из связей быть недопустимыми, и если необходимо удалить их из списка кандидатов.

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