Как построить граф знаний из текста?

Из предыдущих историй мы знаем, что такое граф знаний, и получаем необходимую информацию, чтобы извлекать информацию для создания графа знаний. В этой истории мы объединим эти две части информации и создадим наш собственный граф знаний!

Введение

О Балканах слышали даже люди, не интересующиеся географией или историей. Вот страница Википедии:

Как видите, там много информации не только в виде текста, но и в виде гиперссылок и изображений.

Большая часть информации актуальна и полезна для исследования Балкан. Однако мы не можем напрямую использовать этот источник данных в наших программах. Чтобы сделать эти данные доступными для чтения для наших машин, а также для интерпретации нами, мы преобразуем их в граф знаний!

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

Если мы напрямую сопоставим первое предложение на странице Википедии о Балканах, которое называется «Балканы, известные как Балканский полуостров», на нашем графике, мы получим следующий простой график:

Этот пример сделан нашими руками, однако для нас невозможно или масштабируемо вручную построить весь граф знаний, поэтому нам нужно извлекать сущности и отношения с помощью машин! Однако здесь возникает проблема: Машины не могут интерпретировать естественный язык. Чтобы наши машины могли понимать наши тексты, мы будем использовать методы обработки естественного языка, а именно НЛП, такие как сегментация предложений, синтаксический анализ зависимостей, тегирование частей речи и распознавание сущностей. Мы обсудили и испытали эти методы в предыдущей истории. Давайте воспользуемся этим здесь!

Создание сети знаний

Граф знаний состоит из фактов, основанных на связи, соединяющей сущности. Факты имеют форму троек, субъект-объект-предикат. Например;

«Балканы известны как Балканский полуостров».

В тройном виде вышеуказанный факт может быть представлен как isKnownAs ( Балканы , Балканский полуостров ) где,

  • Тема: Балканы
  • Предикат: isKnownAs
  • Объект: Балканский полуостров.

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

import spacy
nlp = spacy.load('en_core_web_sm')
doc = nlp(u"The Balkans, also known as the Balkan Peninsula, \
            is a geographic area in Southeast Europe with \                                                                                           
            various definitions and meanings, including \ 
            geopolitical and historical. The region takes its name \ 
            from the Balkan Mountains that stretch throughout the \ 
            whole of Bulgaria from the Serbian–Bulgarian border \ 
            to the Black Sea coast..."

Теперь мы можем использовать эти предложения, созданные spaCy, в textpipeliner, который обеспечивает простой способ извлечения частей предложений в виде структурированных кортежей из неструктурированного текста. textpipeliner состоит из двух основных частей: Pipes и PipelineEngine. Из каналов вы можете создать структуру, которая будет использоваться для извлечения частей из каждого предложения в документе. Движок будет использовать эту структуру каналов и применять ее обработку для каждого предложения в предоставленном документе и возвращать список извлеченных кортежей.

pipes_structure = [
              SequencePipe([
                 FindTokensPipe("VERB/nsubj/*"),
                 NamedEntityFilterPipe(),
                 NamedEntityExtractorPipe()]),
                 FindTokensPipe("VERB"),
                       
              AnyPipe([
                 SequencePipe([FindTokensPipe("VBD/dobj/NNP"),     
                    AggregatePipe([NamedEntityFilterPipe("GPE"), 
                    NamedEntityFilterPipe("PERSON")]),
                    NamedEntityExtractorPipe()]),                          
              
                 SequencePipe([FindTokensPipe("VBD/**/*/pobj/NNP"),                                         
                    AggregatePipe([NamedEntityFilterPipe("LOC"), 
                    NamedEntityFilterPipe("PERSON")]),
                    NamedEntityExtractorPipe()])])]
engine = PipelineEngine(pipes_structure, Context(doc), [0, 1, 2]) process = engine.process()

Извлеченные кортежи:

[([The, Achaemenid, Persian, Empire], [incorporated], [Macedonia]),
 ([Romans], [considered], [[the, Peninsula, of, Haemus], [Greek]]),
 ([Bulgars], [arrived], [the, Bulgarian, Empire])]

Мы можем изменять параметры в соответствии с типами сущностей, перечисленными в spaCy. Давайте используем эти извлеченные кортежи для создания нашего графа знаний. Для этого сначала нам нужно определить, каковы исходные узлы, целевые узлы и отношения. Используя простые операции Python, вы можете напрямую получить следующие списки и сохранить их в DataFrame:

source = ['The Achaemenid Persian Empire', 'Romans', 'Bulgars'] target = ['Macedonia', 'the Peninsula of Haemus Greek', 'the Bulgarian Empire']
edge = ['incorporated ', 'considered ', 'arrived ']
kg_df = pd.DataFrame({'source':source, 'target':target, 'edge':edge})

После извлечения списков и создания DataFrame мы можем использовать этот DataFrame в пакете NetworkX для построения нашего графа знаний:

G=nx.from_pandas_edgelist(kg_df, "source", "target", edge_attr=True, create_using=nx.MultiDiGraph())
plt.figure(figsize=(12,12))
pos = nx.spring_layout(G)
nx.draw(G, with_labels=True, node_color='skyblue', edge_cmap=plt.cm.Blues, pos = pos)
nx.draw_networkx_edge_labels(G, pos=pos)
plt.show()

И в итоге мы видим итоговый график:

Здесь наш результирующий граф настолько мал, поскольку мы использовали только один тип конвейера, который учитывает только названные объекты типа location и людей. Если вы обогатите свой конвейер, а также необработанный текст, вы получите больший график, на котором вы также сможете выполнять логический вывод!

В конце концов…

В этой серии рассказов мы узнали, как использовать методы НЛП для извлечения информации из заданного текста в форме троек, а затем построения из нее графа знаний. Несмотря на то, что мы используем только небольшой набор данных и создаем очень ограниченный граф знаний, мы можем построить довольно информативные графы знаний с нашим текущим опытом. Графы знаний - одна из самых интересных концепций в области науки о данных. Я рекомендую вам больше исследовать эту область извлечения информации.

использованная литература