Подробное руководство по графу знаний, включающему обучение и оценку
Прежде чем вы начнете читать эту статью, я предполагаю, что у вас есть краткое представление о вложениях графов знаний. Если нет, я предлагаю вам ознакомиться со следующей статьей, которая дает вам хорошее представление об этой концепции:
Теперь, когда это не так, в этой статье я покажу, как вы можете создавать вложения графов знаний, интерпретировать их, а также оценивать их производительность в задачах на основе графов.
Граф знаний
Рассмотрим граф знаний страны. На этом графике у нас есть названия стран и регионов как объектов. Отношения представлены двумя свойствами, а именно сосед и расположен в.
График представляет собой встроенный набор данных библиотеки PyKEEN Python.
Посмотрите на следующий снимок экрана с тройками графа знаний, показанными в виде фрейма данных:
Тройки имеют вид (croatia, neighbor, serbia)
и (denmark, locatedin, europe).
Ниже приведена полная визуализация графика с использованием библиотеки NetworkX Python:
График большой, поэтому визуализация не слишком четкая. Давайте проверим подграф этого графа знаний.
Подграф выше ясно иллюстрирует триплеты, показывая как сущности, так и отношения.
Теперь у нас есть граф знаний. Давайте разберемся, как генерировать вложения графа знаний с помощью библиотеки Python PyKEEN.
Встраивание графа знаний
Выше показано визуализация вложений графа знаний, обученных с использованием алгоритма TransR
. Обратите внимание, как страны сгруппированы вместе. В верхней части визуализации мы видим Боснию, Черногорию и Албанию близко друг к другу. Это указывает на то, что алгоритм встраивания смог объединить страны с похожими свойствами вместе.
Визуализация выполнена с использованием PCA, где размер встраивания 128 уменьшен до размера 2-х измерений. Это может повлиять на точность группировки стран. Кроме того, алгоритм встраивания можно настроить для повышения производительности.
Вот код для создания вложений:
Предпосылки
pip install pykeen -q # install PyKEEN library
Прочитать данные
from pykeen.datasets import Countries import pandas as pd # read data from pykeen dataset method df = pd.DataFrame(Countries().training.triples) df.columns = ['h', 'r', 't'] df.sample(10)
Создание вложений
from pykeen.triples import TriplesFactory from pykeen.pipeline import pipeline # Generate triples from the graph data tf = TriplesFactory.from_labeled_triples(df.values) # split triples into train and test training, testing = tf.split([0.8, 0.2], random_state=42) # generate embeddings using PyKEEN's pipeline method result = pipeline( training=training, testing=testing, model = "TransR", model_kwargs=dict(embedding_dim=128), training_kwargs=dict(num_epochs=200), random_seed=42)
В приведенном выше коде класс TriplesFactory
обеспечивает стандартизированное представление троек в графе знаний. В PyKEEN есть разные методы для чтения троек и управления ими. Кроме того, чтобы разделить данные на обучающие, проверочные и тестовые наборы. Здесь я просто разделяю данные на обучающие и тестовые наборы, так как не выполняю настройку гиперпараметров.
Я выбрал модель TransR
и установил размер внедрения на 128 и эпохи на 200.
График Loss vs. Epochs выглядит следующим образом:
Потери уменьшаются до 100 эпох, а затем остаются почти постоянными. 100 эпох было бы достаточно для этого тренировочного процесса. Ну что ж!
Получить вложения
Процесс обучения завершен, и теперь мы можем получить вложения из объекта result
функции pipeline()
PyKEEN. Мы изучаем вложения как для сущностей, так и для отношений. Эти вложения можно визуализировать с помощью любых методов уменьшения размерности, таких как PCA или t-SNE (такие же, как визуализация, показанная в разделе выше).
Ниже приведен код для получения вложений после завершения процесса обучения:
Вложения сущностей
# get entity labels from training set entity_labels = training.entity_labeling.all_labels() # convert entities to ids entity_ids = torch.as_tensor(training.entities_to_ids(entity_labels)) # retrieve the embeddings using entity ids entity_embeddings = result.model.entity_representations[0](indices=entity_ids) # create a dictionary of entity labels and embeddings entity_embeddings_dict = dict(zip(entity_labels, entity_embeddings.detach().numpy()))
Вложения отношений
# get relation labels from training set relation_labels = training.relation_labeling.all_labels() # convert relations to ids relation_ids = torch.as_tensor(training.relations_to_ids(relation_labels)) # retrieve the embeddings using relation ids relation_embeddings = result.model.relation_representations[0](indices=relation_ids) # create a dictionary of relation labels and embeddings relation_embeddings_dict = dict(zip(relation_labels, relation_embeddings.detach().numpy()))
Оценка вложений
Мы видели генерацию вложений, а также то, как их извлекать. Теперь давайте проверим их производительность при прогнозировании ссылок. Прогнозирование ссылок — это задача на основе графа, которая включает прогнозирование отсутствующих или будущих связей между узлами в графе.
Посмотрите мою статью, в которой подробно описываются задачи на основе графа, такие как предсказание ссылок и классификация узлов.
PyKEEN предоставляет простой способ выполнить оценку задачи прогнозирования ссылок.
Я создам фрейм данных для обучающих и тестовых наборов, чтобы было легче понять процесс оценки.
# create a train df df_train = pd.DataFrame(training.triples) df_train.columns = ['h','r','t'] # create a test df df_test = pd.DataFrame(testing.triples) df_test.columns = ['h','r','t']
Я буду использовать оценку на основе скоринга для выполнения задачи предсказания хвоста (вариант предсказания ссылки). Модель должна предсказать хвостовую сущность из тестового набора. Я рассматриваю 3 случая, чтобы продемонстрировать работу этого процесса оценки.
Случай 1: Мексика
На изображении выше мы видим, что модель обучена трем тройкам, включающим Mexico
в качестве головного объекта. Тестовый набор имеет один экземпляр с отношением neighbor.
Наша цель — правильно предсказать хвостовую сущность тестового набора, т. е. предсказать united_states
из тройки (mexico, neighbor, united_states).
from pykeen import predict # tail prediction predict.predict_target(model=result.model, head="mexico", relation="neighbor", triples_factory=result.training).df.head(20)
Приведенный выше кодовый блок выполняет предсказание хвоста для «отсутствующей» тройки (mexico, neighbor, ?).
.
В приведенном выше выводе мы видим, что модель оценивает belize
, guatemala
и united_states
как лучшие прогнозы на основе метода оценки. belize
и guatemala
уже присутствовали в тренировочном наборе, и модель правильно предсказала united_states
. Обратите внимание, как прогнозы с самым высоким рейтингом имеют лучший результат.
Это один из вариантов использования задачи предсказания ссылок.
Случай 2: Сенегал
Здесь мы предсказываем хвост тестовой тройки (senegal, locatedin, ?).
В тестовом наборе есть только один экземпляр. Прогноз следующий:
Случай 3: Бутан
Здесь есть два экземпляра в тестовом наборе. Посмотрим прогнозы:
Модель правильно оценивает первый экземпляр предсказания хвоста (india
), но не может оценить второй экземпляр (china
) в верхних рядах. Он успешно предсказывает хвостовую метку, но с низкой достоверностью.
Это связано с тем, что модель не смогла точно отразить сетевые отношения во вложениях. Помните, что я не выполнял оптимизацию гиперпараметров при обучении модели, что могло снизить производительность.
Метрики оценки
В предыдущем разделе я показал базовый процесс оценки. У нас есть методы оценки на основе рангов, которые количественно определяют производительность модели. Ранговые методы имеют несколько метрик, и одной из важных метрик является средний ранг.
Средний ранг — это средний ранг правильного предсказания по всем тройкам тестов. В приведенных выше 3 случаях средний ранг можно рассчитать следующим образом:
Случай 1: Ранг = 4
Случай 2: Ранг = 2
Случай 3: Ранг = 2 (первый случай)
Случай 3: Ранг = 13 (второй случай)
Следовательно, средний ранг равен (4+2+2+13)/4
= 5,25.
Средний ранг для всего набора тестов выглядит следующим образом:
rank_metrics = result.metric_results.to_df() rank_metrics[rank_metrics.Metric=='arithmetic_mean_rank']
Мы выполнили предсказание хвоста в вышеупомянутых 3 случаях. Для всего набора тестов средний ранг предсказания хвоста составляет около 7,2, что не так уж и плохо.
Мы обучили достойную модель встраивания графа знаний!
Спасибо за чтение, и ура!
Хотите присоединиться?
Свяжитесь со мной в LinkedIn, Twitter, GitHub или Website!