Knowledge_Graph_in_NLP / knowledge_Graph.py
EddyGiusepe's picture
Gráfico de conhecimentos
3c15751
Raw
History Blame Contribute Delete
5.08 kB
"""
Data Scientist.: Dr.Eddy Giusepe Chirinos Isidro
"""
"""Importando Bibliotecas:"""
import requests
from bs4 import BeautifulSoup
import spacy
import networkx as nx
import matplotlib.pyplot as plt
import pandas as pd
"""coleta e pré-processamento de dados (usamos a página da Wikipedia):"""
url = "https://pt.wikipedia.org/wiki/William_Shakespeare"
# Envie uma solicitação HTTP para o URL e recupere o conteúdo HTML:
response = requests.get(url)
# Analise o conteúdo HTML usando BeautifulSoup:
soup = BeautifulSoup(response.text, "html.parser")
# Extraia o conteúdo do texto de um elemento HTML específico com o id "mw-content-text":
text = soup.find("div", id="mw-content-text").text
# Substitua caracteres de nova linha por espaços e limite o texto aos primeiros 1.000 caracteres:
text = text.replace("\n", " ")
text = text[:1500]
print(text)
"""Usamos Reconhecimento de Entidade Nomeada (NER) - usamos um modelo pré-treinado para o português:"""
nlp = spacy.load("pt_core_news_lg")
# Processe o texto com o pipeline de NLP do spaCy:
doc = nlp(text)
# Inicialize listas vazias para armazenar entidades reconhecidas e seus rótulos:
entities = []
labels = []
# Extraia entidades nomeadas e seus rótulos:
for ent in doc.ents:
entities.append(ent.text)
labels.append(ent.label_)
print("\n")
print('Entidades:', entities)
print("")
print('Labels:', labels)
"""Extraindo Relações entre Entidades:"""
# Inicialize uma lista vazia para armazenar relações:
relations = []
# Iterar através de frases no texto processado:
for sent in doc.sents:
sent_doc = nlp(sent.text)
subject = None
object = None
predicate = None
# Iterar através de tokens na frase para identificar sujeito, objeto e predicado:
for token in sent_doc:
if token.dep_ == "nsubj":
subject = token.text
if token.dep_ == "pobj":
object = token.text
if token.dep_ == "ROOT":
predicate = token.text
# Se sujeito, objeto e predicado forem encontrados, armazene a relação:
if subject and object and predicate:
relation = (subject, predicate, object)
relations.append(relation)
print('Relações:', relations)
"""Criando um DataFrame:"""
# Crie pares de entidades consecutivas:
entity_pairs = list(zip(entities, entities[1:]))
# Certifique-se de que as relações e os pares de entidades tenham o mesmo comprimento:
relations = relations[:len(entity_pairs)]
# Extraia a source e target de pares de entidades:
source = [i[0] for i in entity_pairs]
target = [i[1] for i in entity_pairs]
# Certifique-se de que as relações tenham o mesmo comprimento que a source e o target:
missing_relations = ["N/A"] * (len(entity_pairs) - len(relations))
relations += missing_relations
# Crie um DataFrame para representar o 'knowledge graph':
kg_df = pd.DataFrame({'source': source, 'target': target, 'edge': relations})
print(kg_df)
"""Construindo o Gráfico de Conhecimento:"""
# Crie um gráfico direcionado do DataFrame usando NetworkX:
G = nx.from_pandas_edgelist(kg_df, "source", "target", edge_attr=True, create_using=nx.MultiDiGraph())
"""Visualizando o Gráfico de Conhecimento:"""
# Calcule o comprimento máximo da palavra nos rótulos de cada nó:
max_word_lengths = [max(len(word) for word in node.split()) for node in G.nodes()]
# Calculate adaptive node sizes based on the maximum word length in each label
node_sizes = [max_word_length * 400 for max_word_length in max_word_lengths]
# Create a figure for the graph visualization
plt.figure(figsize=(12, 12))
fig = plt.figure(figsize=(12, 12))
# Define the layout for the graph using a spring layout with a seed for reproducibility
pos = nx.spring_layout(G, seed=42)
# Define the node colors for different types of entities
node_colors = []
for node in G.nodes():
if node in ["William Shakespeare", "English", "Stratford-upon-Avon", "London", "England"]:
node_colors.append("#ff7f0e") # Laranja para localizações
else:
node_colors.append("#1f77b4") # Blue for people
# Draw nodes and edges with improved aesthetics and adaptive node sizes
nx.draw(G, pos, node_color=node_colors, edge_color="#888888", node_size=node_sizes, font_size=10,
font_color="white", font_weight="bold", alpha=0.9, linewidths=0.5, width=1.0, cmap=plt.cm.viridis)
# Create a dictionary to store node labels with line breaks for long labels
node_labels = {}
for node in G.nodes():
label = node
if len(node) > 2: # Add line break for labels with more than two words
label = '\n'.join(node.split())
node_labels[node] = label
# Draw node labels with automatic placement and text wrapping
nx.draw_networkx_labels(G, pos, labels=node_labels, font_size=10, font_color="white", font_weight="bold", alpha=0.9,
verticalalignment="center", horizontalalignment="center")
# Set the title for the graph
plt.title("William Shakespeare Knowledge Graph", fontsize=16)
fig.set_facecolor("#00000F")
# Turn off the axis
plt.axis('off')
# Display the knowledge graph
plt.show()