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",
"execution_count": 24,
"execution_count": null,
"id": "c94056bd-8d32-48e2-9982-e9af06da3333",
"metadata": {},
"outputs": [],
"source": [
"# from cognitive_architecture.modules.cognify.graph.create_semantic_graph import create_semantic_graph"
]
"source": []
},
{
"cell_type": "code",
@ -877,47 +875,21 @@
},
{
"cell_type": "code",
"execution_count": 50,
"execution_count": 83,
"id": "4dab2ff0-0d12-4a00-a4e4-fb901e701bd3",
"metadata": {},
"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"
]
}
],
"outputs": [],
"source": [
"# B = create_user_content_graph(user_id, custom_user_properties, transformed_dict_2, existing_graph=G)"
]
},
{
"cell_type": "code",
"execution_count": 48,
"execution_count": null,
"id": "627d42fd-d2ce-4ccd-a2a1-2f7ac2f463cf",
"metadata": {},
"outputs": [
{
"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)"
]
"outputs": [],
"source": []
},
{
"cell_type": "code",
@ -1044,45 +1016,19 @@
},
{
"cell_type": "code",
"execution_count": 61,
"execution_count": null,
"id": "8d6a9eb5-387e-45a3-9dc9-5f8ac36fdd38",
"metadata": {},
"outputs": [
{
"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]"
]
"outputs": [],
"source": []
},
{
"cell_type": "code",
"execution_count": 44,
"execution_count": null,
"id": "7f1cde10-3d83-4800-9ef4-f8eaa39cf772",
"metadata": {},
"outputs": [
{
"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]"
]
"outputs": [],
"source": []
},
{
"cell_type": "code",
@ -1125,34 +1071,23 @@
},
{
"cell_type": "code",
"execution_count": 264,
"execution_count": 85,
"id": "d6d602c3-f543-4843-af8d-bfa13009f3e3",
"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": [
"# import uuid\n",
"\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"
"required_layers_one"
]
},
{
@ -1161,21 +1096,7 @@
"id": "66630223-3ba0-4384-95d2-df2995e15271",
"metadata": {},
"outputs": [],
"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"
]
"source": []
},
{
"cell_type": "code",

View file

@ -5,18 +5,20 @@ from enum import Enum, auto
from typing import Type, Optional, Any
from pydantic import BaseModel
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):
""" 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
G.load_graph_from_file()
G = graph_client.graph
await G.load_graph_from_file()
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:
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:
unique_node_id = uuid.uuid4()
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"),
updated_at=datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
description=node.description,
@ -42,9 +44,9 @@ def add_propositions(G, category_name, subclass_content, layer_description, new_
layer_uuid=str(layer_uuid),
layer_description=str(layer_description),
layer_decomposition_uuid=str(layer_decomposition_uuid),
id=str(unique_node_id),
unique_id=str(unique_node_id),
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
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)
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:
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__":
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
# Initialize the graph client
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))