Add utils for graph visualization + classification nodes
This commit is contained in:
parent
2cc4ec7a78
commit
ed1b44fd7b
2 changed files with 115 additions and 138 deletions
135
Demo_graph.ipynb
135
Demo_graph.ipynb
|
|
@ -782,13 +782,11 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": 24,
|
"execution_count": null,
|
||||||
"id": "c94056bd-8d32-48e2-9982-e9af06da3333",
|
"id": "c94056bd-8d32-48e2-9982-e9af06da3333",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [],
|
"outputs": [],
|
||||||
"source": [
|
"source": []
|
||||||
"# from cognitive_architecture.modules.cognify.graph.create_semantic_graph import create_semantic_graph"
|
|
||||||
]
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
|
|
@ -877,47 +875,21 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": 50,
|
"execution_count": 83,
|
||||||
"id": "4dab2ff0-0d12-4a00-a4e4-fb901e701bd3",
|
"id": "4dab2ff0-0d12-4a00-a4e4-fb901e701bd3",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [
|
"outputs": [],
|
||||||
{
|
|
||||||
"ename": "NameError",
|
|
||||||
"evalue": "name 'create_user_content_graph' is not defined",
|
|
||||||
"output_type": "error",
|
|
||||||
"traceback": [
|
|
||||||
"\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
|
|
||||||
"\u001b[0;31mNameError\u001b[0m Traceback (most recent call last)",
|
|
||||||
"Cell \u001b[0;32mIn[50], line 1\u001b[0m\n\u001b[0;32m----> 1\u001b[0m B \u001b[38;5;241m=\u001b[39m \u001b[43mcreate_user_content_graph\u001b[49m(user_id, custom_user_properties, transformed_dict_2, existing_graph\u001b[38;5;241m=\u001b[39mG)\n",
|
|
||||||
"\u001b[0;31mNameError\u001b[0m: name 'create_user_content_graph' is not defined"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"source": [
|
"source": [
|
||||||
"# B = create_user_content_graph(user_id, custom_user_properties, transformed_dict_2, existing_graph=G)"
|
"# B = create_user_content_graph(user_id, custom_user_properties, transformed_dict_2, existing_graph=G)"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": 48,
|
"execution_count": null,
|
||||||
"id": "627d42fd-d2ce-4ccd-a2a1-2f7ac2f463cf",
|
"id": "627d42fd-d2ce-4ccd-a2a1-2f7ac2f463cf",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [
|
"outputs": [],
|
||||||
{
|
"source": []
|
||||||
"ename": "NameError",
|
|
||||||
"evalue": "name 'B' is not defined",
|
|
||||||
"output_type": "error",
|
|
||||||
"traceback": [
|
|
||||||
"\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
|
|
||||||
"\u001b[0;31mNameError\u001b[0m Traceback (most recent call last)",
|
|
||||||
"Cell \u001b[0;32mIn[48], line 1\u001b[0m\n\u001b[0;32m----> 1\u001b[0m \u001b[38;5;28mprint\u001b[39m(\u001b[43mB\u001b[49m)\n",
|
|
||||||
"\u001b[0;31mNameError\u001b[0m: name 'B' is not defined"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"source": [
|
|
||||||
"# print(B)"
|
|
||||||
]
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
|
|
@ -1044,45 +1016,19 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": 61,
|
"execution_count": null,
|
||||||
"id": "8d6a9eb5-387e-45a3-9dc9-5f8ac36fdd38",
|
"id": "8d6a9eb5-387e-45a3-9dc9-5f8ac36fdd38",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [
|
"outputs": [],
|
||||||
{
|
"source": []
|
||||||
"data": {
|
|
||||||
"text/plain": [
|
|
||||||
"{'{\"layer\": \"Semantic Layer\"}': KnowledgeGraph(nodes=[Node(id=1, description='Britons have a significant affection for animals and treat pet-keeping as an integral part of life', category='people', color='blue', memory_type='semantic', created_at=None, summarized=None), Node(id=2, description='Keeping pets is considered a serious and passionate activity in Britain, not merely a leisure activity', category='culturalPractice', color='blue', memory_type='semantic', created_at=None, summarized=None), Node(id=3, description='Dogs are particularly treasured in Britain and are seen as outlets for emotions and social interaction', category='animal', color='blue', memory_type='semantic', created_at=None, summarized=None), Node(id=4, description='British society is accommodating of dogs, with public spaces and services being dog-friendly', category='socialNorm', color='blue', memory_type='semantic', created_at=None, summarized=None), Node(id=5, description='The COVID-19 pandemic caused a surge in pet ownership, particularly dogs, leading to increased numbers and issues like dog attacks', category='event', color='blue', memory_type='semantic', created_at=None, summarized=None), Node(id=6, description='Pets, especially dogs, are increasingly being treated as commodities and status symbols, with a focus on aesthetic breeds', category='socialIssue', color='blue', memory_type='semantic', created_at=None, summarized=None), Node(id=7, description='Fashionable dog breeds, such as French bulldogs and American XL bullies, are in high demand regardless of health issues they may face', category='animal', color='blue', memory_type='semantic', created_at=None, summarized=None), Node(id=8, description='Pets are increasingly treated like substitute children or used to project personal identities', category='socialTrend', color='blue', memory_type='semantic', created_at=None, summarized=None), Node(id=9, description='Spending on pets in the UK has doubled in the last decade, with a trend towards non-essential luxury items for pets', category='economicTrend', color='blue', memory_type='semantic', created_at=None, summarized=None), Node(id=10, description='There is a discrepancy between what pets truly need and the human projection of desires onto them', category='animalWelfare', color='blue', memory_type='semantic', created_at=None, summarized=None), Node(id=11, description='Modern lifestyles can conflict with the needs of pets, leading to behavioral issues and insufficient care', category='animalWelfare', color='blue', memory_type='semantic', created_at=None, summarized=None), Node(id=12, description='The relationship with pets should prioritize their wellbeing and recognize their distinct nature', category='ethicalPrinciple', color='blue', memory_type='semantic', created_at=None, summarized=None)], edges=[Edge(source=1, target=2, description='Britons are known for their serious approach to keeping pets', color='green', created_at=None, summarized=None), Edge(source=2, target=3, description='Dogs are a central part of the pet-keeping practice in Britain', color='green', created_at=None, summarized=None), Edge(source=3, target=4, description='Dogs are widely accepted in public spaces and services due to British social norms', color='green', created_at=None, summarized=None), Edge(source=5, target=6, description='The pandemic surge in pet ownership led to an increase in the commodification of pets', color='green', created_at=None, summarized=None), Edge(source=7, target=6, description='Designer dog breeds are part of the trend of pets being commodified', color='green', created_at=None, summarized=None), Edge(source=9, target=8, description='Increased spending on pet luxuries is related to treating pets as substitutes for children or personal identity projections', color='green', created_at=None, summarized=None), Edge(source=10, target=11, description='The conflict between pet needs and human desires is evident in modern pet care', color='green', created_at=None, summarized=None)])}"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"execution_count": 61,
|
|
||||||
"metadata": {},
|
|
||||||
"output_type": "execute_result"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"source": [
|
|
||||||
"layer_1_graph[0]"
|
|
||||||
]
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": 44,
|
"execution_count": null,
|
||||||
"id": "7f1cde10-3d83-4800-9ef4-f8eaa39cf772",
|
"id": "7f1cde10-3d83-4800-9ef4-f8eaa39cf772",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [
|
"outputs": [],
|
||||||
{
|
"source": []
|
||||||
"data": {
|
|
||||||
"text/plain": [
|
|
||||||
"<TextSubclass.NEWS_STORIES: 'News stories and blog posts'>"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"execution_count": 44,
|
|
||||||
"metadata": {},
|
|
||||||
"output_type": "execute_result"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"source": [
|
|
||||||
"required_layers_two.dict()['label']['subclass'][0]"
|
|
||||||
]
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
|
|
@ -1125,34 +1071,23 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": 264,
|
"execution_count": 85,
|
||||||
"id": "d6d602c3-f543-4843-af8d-bfa13009f3e3",
|
"id": "d6d602c3-f543-4843-af8d-bfa13009f3e3",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [],
|
"outputs": [
|
||||||
|
{
|
||||||
|
"data": {
|
||||||
|
"text/plain": [
|
||||||
|
"DefaultContentPrediction(label=TextContent(type='TEXT', subclass=[<TextSubclass.ARTICLES: 'Articles, essays, and reports'>]))"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"execution_count": 85,
|
||||||
|
"metadata": {},
|
||||||
|
"output_type": "execute_result"
|
||||||
|
}
|
||||||
|
],
|
||||||
"source": [
|
"source": [
|
||||||
"# import uuid\n",
|
"required_layers_one"
|
||||||
"\n",
|
|
||||||
"# def append_to_graph(layer_graphs, required_layers, G):\n",
|
|
||||||
"# layer_uuid = uuid.uuid4()\n",
|
|
||||||
" \n",
|
|
||||||
"# # Directly assign 'NEWS_STORIES' as category_name\n",
|
|
||||||
"# category_name = \"NEWS_STORIES\"\n",
|
|
||||||
" \n",
|
|
||||||
"# # Assuming 'required_layers' structure is as provided, extract 'News stories and blog posts' as the only subgroup\n",
|
|
||||||
"# # This assumes there's always at least one subclass and we're taking the first\n",
|
|
||||||
"# subgroup_name = 'News stories and blog posts'\n",
|
|
||||||
"\n",
|
|
||||||
"# for layer_decomposition in layer_graphs:\n",
|
|
||||||
"# print(layer_decomposition)\n",
|
|
||||||
"# layer_decomposition_uuid = uuid.uuid4()\n",
|
|
||||||
"\n",
|
|
||||||
"# # Assuming append_data_to_graph is defined elsewhere and appends data to G\n",
|
|
||||||
"# F = append_data_to_graph(G, category_name, subgroup_name, layer_decomposition, layer_uuid, layer_decomposition_uuid)\n",
|
|
||||||
" \n",
|
|
||||||
"# Print updated graph for verification\n",
|
|
||||||
"# print(\"Updated Nodes:\", F.nodes(data=True)) # Assuming F is a NetworkX Graph and you want to print node data\n",
|
|
||||||
"\n",
|
|
||||||
"# return F"
|
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
@ -1161,21 +1096,7 @@
|
||||||
"id": "66630223-3ba0-4384-95d2-df2995e15271",
|
"id": "66630223-3ba0-4384-95d2-df2995e15271",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [],
|
"outputs": [],
|
||||||
"source": [
|
"source": []
|
||||||
"# def append_to_graph(layer_graphs, required_layers, G):\n",
|
|
||||||
"# layer_uuid = uuid.uuid4()\n",
|
|
||||||
"# category_name = required_layers.dict()['name']\n",
|
|
||||||
"# subgroup_names = [subgroup['name'] for subgroup in required_layers.dict()['cognitive_subgroups']]\n",
|
|
||||||
"# for subgroup in subgroup_names:\n",
|
|
||||||
"\n",
|
|
||||||
"# for layer_decomposition in layer_graphs:\n",
|
|
||||||
"# layer_decomposition_uuid = uuid.uuid4()\n",
|
|
||||||
"# F = append_data_to_graph(G, category_name[0], subgroup, layer_decomposition, layer_uuid, layer_decomposition_uuid)\n",
|
|
||||||
" \n",
|
|
||||||
"# # Print updated graph for verification\n",
|
|
||||||
"# # print(\"Updated Nodes:\", F)\n",
|
|
||||||
"# return F\n"
|
|
||||||
]
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
|
|
|
||||||
|
|
@ -5,18 +5,20 @@ from enum import Enum, auto
|
||||||
from typing import Type, Optional, Any
|
from typing import Type, Optional, Any
|
||||||
from pydantic import BaseModel
|
from pydantic import BaseModel
|
||||||
from cognitive_architecture.infrastructure.databases.graph.get_graph_client import get_graph_client
|
from cognitive_architecture.infrastructure.databases.graph.get_graph_client import get_graph_client
|
||||||
from cognitive_architecture.shared.data_models import GraphDBType, DefaultGraphModel, Document, DocumentType, Category, Relationship, UserProperties, UserLocation
|
from cognitive_architecture.modules.cognify.llm.content_to_propositions import generate_graph
|
||||||
|
from cognitive_architecture.shared.data_models import GraphDBType, DefaultGraphModel, Document, DocumentType, Category, \
|
||||||
|
Relationship, UserProperties, UserLocation, KnowledgeGraph, TextSubclass, TextContent, DefaultContentPrediction
|
||||||
|
|
||||||
|
|
||||||
def add_propositions(G, category_name, subclass_content, layer_description, new_data, layer_uuid,
|
async def add_propositions(G, category_name, subclass_content, layer_description, new_data, layer_uuid,
|
||||||
layer_decomposition_uuid):
|
layer_decomposition_uuid):
|
||||||
""" Add nodes and edges to the graph for the given LLM knowledge graph and the layer"""
|
""" Add nodes and edges to the graph for the given LLM knowledge graph and the layer"""
|
||||||
|
|
||||||
# Find the node ID for the subclass within the category
|
# Find the node ID for the subclass within the category
|
||||||
G.load_graph_from_file()
|
await G.load_graph_from_file()
|
||||||
G = graph_client.graph
|
|
||||||
subclass_node_id = None
|
subclass_node_id = None
|
||||||
for node, data in G.nodes(data=True):
|
for node, data in G.graph.nodes(data=True):
|
||||||
if subclass_content in node:
|
if subclass_content in node:
|
||||||
subclass_node_id = node
|
subclass_node_id = node
|
||||||
|
|
||||||
|
|
@ -33,7 +35,7 @@ def add_propositions(G, category_name, subclass_content, layer_description, new_
|
||||||
for node in new_data.nodes:
|
for node in new_data.nodes:
|
||||||
unique_node_id = uuid.uuid4()
|
unique_node_id = uuid.uuid4()
|
||||||
new_node_id = f"{node.description} - {str(layer_uuid)} - {str(layer_decomposition_uuid)} - {str(unique_node_id)}"
|
new_node_id = f"{node.description} - {str(layer_uuid)} - {str(layer_decomposition_uuid)} - {str(unique_node_id)}"
|
||||||
G.add_node(new_node_id,
|
await G.add_node(new_node_id,
|
||||||
created_at=datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
|
created_at=datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
|
||||||
updated_at=datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
|
updated_at=datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
|
||||||
description=node.description,
|
description=node.description,
|
||||||
|
|
@ -42,9 +44,9 @@ def add_propositions(G, category_name, subclass_content, layer_description, new_
|
||||||
layer_uuid=str(layer_uuid),
|
layer_uuid=str(layer_uuid),
|
||||||
layer_description=str(layer_description),
|
layer_description=str(layer_description),
|
||||||
layer_decomposition_uuid=str(layer_decomposition_uuid),
|
layer_decomposition_uuid=str(layer_decomposition_uuid),
|
||||||
id=str(unique_node_id),
|
unique_id=str(unique_node_id),
|
||||||
type='detail')
|
type='detail')
|
||||||
G.add_edge(subclass_node_id, new_node_id, relationship='detail')
|
await G.add_edge(subclass_node_id, new_node_id, relationship='detail')
|
||||||
|
|
||||||
# Store the mapping from old node ID to new node ID
|
# Store the mapping from old node ID to new node ID
|
||||||
node_id_mapping[node.id] = new_node_id
|
node_id_mapping[node.id] = new_node_id
|
||||||
|
|
@ -56,7 +58,7 @@ def add_propositions(G, category_name, subclass_content, layer_description, new_
|
||||||
target_node_id = node_id_mapping.get(edge.target)
|
target_node_id = node_id_mapping.get(edge.target)
|
||||||
|
|
||||||
if source_node_id and target_node_id:
|
if source_node_id and target_node_id:
|
||||||
G.add_edge(source_node_id, target_node_id, description=edge.description, relationship='relation')
|
await G.add_edge(source_node_id, target_node_id, description=edge.description, relationship='relation')
|
||||||
else:
|
else:
|
||||||
print(f"Could not find mapping for edge from {edge.source} to {edge.target}")
|
print(f"Could not find mapping for edge from {edge.source} to {edge.target}")
|
||||||
|
|
||||||
|
|
@ -68,30 +70,84 @@ def add_propositions(G, category_name, subclass_content, layer_description, new_
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
import asyncio
|
import asyncio
|
||||||
|
|
||||||
# Assuming all necessary imports and GraphDBType, get_graph_client, Document, DocumentType, etc. are defined
|
|
||||||
|
|
||||||
# Initialize the graph client
|
|
||||||
graph_client = get_graph_client(GraphDBType.NETWORKX)
|
|
||||||
G = asyncio.run(add_propositions(graph_client, 'category_name', 'subclass_content', 'layer_description', 'new_data', 'layer_uuid',
|
|
||||||
'layer_decomposition_uuid'))
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
import asyncio
|
|
||||||
|
|
||||||
# Assuming all necessary imports and GraphDBType, get_graph_client, Document, DocumentType, etc. are defined
|
# Assuming all necessary imports and GraphDBType, get_graph_client, Document, DocumentType, etc. are defined
|
||||||
|
|
||||||
# Initialize the graph client
|
# Initialize the graph client
|
||||||
graph_client = get_graph_client(GraphDBType.NETWORKX)
|
graph_client = get_graph_client(GraphDBType.NETWORKX)
|
||||||
|
|
||||||
|
from typing import List, Type
|
||||||
|
|
||||||
|
|
||||||
|
# Assuming generate_graph, KnowledgeGraph, and other necessary components are defined elsewhere
|
||||||
|
|
||||||
|
async def generate_graphs_for_all_layers(text_input: str, layers: List[str], response_model: Type[BaseModel]):
|
||||||
|
tasks = [generate_graph(text_input, "generate_graph_prompt.txt", {'layer': layer}, response_model) for layer in
|
||||||
|
layers]
|
||||||
|
return await asyncio.gather(*tasks)
|
||||||
|
|
||||||
|
|
||||||
|
input_article_one= "The quick brown fox jumps over the lazy dog"
|
||||||
|
|
||||||
|
|
||||||
|
# Execute the async function and print results for each set of layers
|
||||||
|
async def async_graph_per_layer(text_input: str, cognitive_layers: List[str]):
|
||||||
|
graphs = await generate_graphs_for_all_layers(text_input, cognitive_layers, KnowledgeGraph)
|
||||||
|
# for layer, graph in zip(cognitive_layers, graphs):
|
||||||
|
# print(f"{layer}: {graph}")
|
||||||
|
return graphs
|
||||||
|
|
||||||
|
cognitive_layers_one = ['Structural Layer', 'Semantic Layer',
|
||||||
|
'Syntactic Layer',
|
||||||
|
'Discourse Layer',
|
||||||
|
'Pragmatic Layer',
|
||||||
|
'Stylistic Layer',
|
||||||
|
'Referential Layer',
|
||||||
|
'Citation Layer',
|
||||||
|
'Metadata Layer']
|
||||||
|
required_layers_one = DefaultContentPrediction(
|
||||||
|
label=TextContent(
|
||||||
|
type='TEXT',
|
||||||
|
subclass=[TextSubclass.ARTICLES]
|
||||||
|
)
|
||||||
|
)
|
||||||
|
# Run the async function for each set of cognitive layers
|
||||||
|
level_1_graph = asyncio.run( async_graph_per_layer(input_article_one, cognitive_layers_one))
|
||||||
|
import uuid
|
||||||
|
import json
|
||||||
|
|
||||||
|
|
||||||
|
async def append_to_graph(layer_graphs, required_layers, G):
|
||||||
|
# Generate a UUID for the overall layer
|
||||||
|
layer_uuid = uuid.uuid4()
|
||||||
|
|
||||||
|
# Extract category name from required_layers data
|
||||||
|
category_name = required_layers.dict()['label']['type']
|
||||||
|
|
||||||
|
# Extract subgroup name from required_layers data
|
||||||
|
# Assuming there's always at least one subclass and we're taking the first
|
||||||
|
subgroup_name = required_layers.dict()['label']['subclass'][0].value # Access the value of the enum
|
||||||
|
|
||||||
|
for layer_ind in layer_graphs:
|
||||||
|
|
||||||
|
for layer_json, knowledge_graph in layer_ind.items():
|
||||||
|
# Decode the JSON key to get the layer description
|
||||||
|
layer_description = json.loads(layer_json)
|
||||||
|
|
||||||
|
# Generate a UUID for this particular layer decomposition
|
||||||
|
layer_decomposition_uuid = uuid.uuid4()
|
||||||
|
|
||||||
|
# Assuming append_data_to_graph is defined elsewhere and appends data to G
|
||||||
|
# You would pass relevant information from knowledge_graph along with other details to this function
|
||||||
|
F = await add_propositions(G, category_name, subgroup_name, layer_description, knowledge_graph,
|
||||||
|
layer_uuid, layer_decomposition_uuid)
|
||||||
|
|
||||||
|
# Print updated graph for verification (assuming F is the updated NetworkX Graph)
|
||||||
|
print("Updated Nodes:", F.graph.nodes(data=True))
|
||||||
|
|
||||||
|
return F
|
||||||
|
|
||||||
|
G = asyncio.run(append_to_graph(level_1_graph, required_layers_one, graph_client))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue