Как построить граф знаний из текста?
Из предыдущих историй мы знаем, что такое граф знаний, и получаем необходимую информацию, чтобы извлекать информацию для создания графа знаний. В этой истории мы объединим эти две части информации и создадим наш собственный граф знаний!
Введение
О Балканах слышали даже люди, не интересующиеся географией или историей. Вот страница Википедии:
Как видите, там много информации не только в виде текста, но и в виде гиперссылок и изображений.
Большая часть информации актуальна и полезна для исследования Балкан. Однако мы не можем напрямую использовать этот источник данных в наших программах. Чтобы сделать эти данные доступными для чтения для наших машин, а также для интерпретации нами, мы преобразуем их в граф знаний!
Прежде чем приступить к построению нашего графа знаний, давайте посмотрим, как мы встраиваем информацию в эти графики. Как и в большинстве графов, у нас есть объекты, представленные как узлы, и связи между ними, а именно ребра.
Если мы напрямую сопоставим первое предложение на странице Википедии о Балканах, которое называется «Балканы, известные как Балканский полуостров», на нашем графике, мы получим следующий простой график:
Этот пример сделан нашими руками, однако для нас невозможно или масштабируемо вручную построить весь граф знаний, поэтому нам нужно извлекать сущности и отношения с помощью машин! Однако здесь возникает проблема: Машины не могут интерпретировать естественный язык. Чтобы наши машины могли понимать наши тексты, мы будем использовать методы обработки естественного языка, а именно НЛП, такие как сегментация предложений, синтаксический анализ зависимостей, тегирование частей речи и распознавание сущностей. Мы обсудили и испытали эти методы в предыдущей истории. Давайте воспользуемся этим здесь!
Создание сети знаний
Граф знаний состоит из фактов, основанных на связи, соединяющей сущности. Факты имеют форму троек, субъект-объект-предикат. Например;
«Балканы известны как Балканский полуостров».
В тройном виде вышеуказанный факт может быть представлен как 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 и людей. Если вы обогатите свой конвейер, а также необработанный текст, вы получите больший график, на котором вы также сможете выполнять логический вывод!
В конце концов…
В этой серии рассказов мы узнали, как использовать методы НЛП для извлечения информации из заданного текста в форме троек, а затем построения из нее графа знаний. Несмотря на то, что мы используем только небольшой набор данных и создаем очень ограниченный граф знаний, мы можем построить довольно информативные графы знаний с нашим текущим опытом. Графы знаний - одна из самых интересных концепций в области науки о данных. Я рекомендую вам больше исследовать эту область извлечения информации.