Add utils for graph visualization + classification nodes

This commit is contained in:
Vasilije 2024-03-10 13:18:28 +01:00
parent 2cc4ec7a78
commit ed1b44fd7b
2 changed files with 115 additions and 138 deletions

View file

@ -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",

View file

@ -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))