From faf7e6ae5954bc1f6a747c98f60b3883af6c77d1 Mon Sep 17 00:00:00 2001 From: Vasilije <8619304+Vasilije1990@users.noreply.github.com> Date: Sun, 10 Mar 2024 23:27:56 +0100 Subject: [PATCH] Add utils for graph visualization + classification nodes --- Demo_graph.ipynb | 921 ++++++++---------- .../api/v1/cognify/cognify.py | 144 ++- .../databases/vector/qdrant/adapter.py | 51 +- .../databases/vector/vector_db_interface.py | 15 +- .../infrastructure/llm/openai/adapter.py | 19 +- .../modules/cognify/graph/add_propositions.py | 62 +- .../graph/add_semantic_search_connection.py | 101 ++ .../modules/cognify/graph/create.py | 2 +- .../modules/cognify/vector/batch_search.py | 29 + .../cognify/vector/load_propositions.py | 33 + .../graph/find_proposition_categories.py | 1 + .../graph/find_proposition_neighbourhood.py | 13 + .../search/vector/search_propositions.py | 15 + 13 files changed, 781 insertions(+), 625 deletions(-) create mode 100644 cognitive_architecture/modules/cognify/graph/add_semantic_search_connection.py create mode 100644 cognitive_architecture/modules/cognify/vector/batch_search.py create mode 100644 cognitive_architecture/modules/cognify/vector/load_propositions.py create mode 100644 cognitive_architecture/modules/search/graph/find_proposition_categories.py create mode 100644 cognitive_architecture/modules/search/graph/find_proposition_neighbourhood.py create mode 100644 cognitive_architecture/modules/search/vector/search_propositions.py diff --git a/Demo_graph.ipynb b/Demo_graph.ipynb index 01f36b8ac..d99d81349 100644 --- a/Demo_graph.ipynb +++ b/Demo_graph.ipynb @@ -102,7 +102,7 @@ }, { "cell_type": "code", - "execution_count": 1, + "execution_count": 14, "id": "8a8942b5-91d6-4746-b35d-00f58bc16d7b", "metadata": {}, "outputs": [], @@ -140,7 +140,7 @@ }, { "cell_type": "code", - "execution_count": 2, + "execution_count": 46, "id": "14484e25-fae8-4306-b03f-dae91fe5d0aa", "metadata": {}, "outputs": [], @@ -153,27 +153,6 @@ "\n", "As with so many latent traits in the national psyche, it all came unleashed with the pandemic, when many people thought they might as well make the most of all that time at home and in local parks with a dog. Between 2019 and 2022, the number of pet dogs in the UK rose from about nine million to 13 million. But there’s long been a seasonal surge around this time of year, substantial enough for the Dogs Trust charity to coin its famous slogan back in 1978: “A dog is for life, not just for Christmas.”\n", "\n", - "Green spaces, meanwhile, have been steadily declining, and now many of us have returned to the office, just as those “pandemic dogs” are entering their troublesome teens. It’s a combustible combination and we are already seeing the results: the number of dog attacks recorded by police in England and Wales rose by more than a third between 2018 and 2022.\n", - "\n", - "At the same time, sites such as Pets4Homes.co.uk are replete with listings for dogs that, their owners accept “with deep regret”, are no longer suited to their lifestyles now that lockdown is over. It may have felt as if it would go on for ever, but was there ever any suggestion it was going to last the average dog’s lifespan of a decade?\n", - "\n", - "Living beings are being downgraded to mere commodities. You can see it reflected the “designer” breeds currently in fashion, the French bulldogs and pugs that look cute but spend their entire lives in discomfort. American XL bully dogs, now so controversial, are often sought after as a signifier of masculinity: roping an entire other life in service of our egos. Historically, many of Britain’s most popular breeds evolved to hunt vermin, retrieve game, herd, or otherwise do a specific job alongside humans; these days we are breeding and buying them for their aesthetic appeal.\n", - "\n", - "Underpinning this is a shift to what was long disdained as the “American” approach: treating pets as substitutes for children. In the past in Britain, dogs were treasured on their own terms, for the qualities that made them dogs, and as such, sometimes better than people: their friendliness and trustingness and how they opened up the world for us. They were indulged, certainly – by allowing them on to the sofa or in our beds, for instance, when we’d sworn we never would – but in ways that did not negate or deny their essential otherness.\n", - "\n", - "Now we have more dogs of such ludicrous proportions, they struggle to function as dogs at all – and we treat them accordingly, indulging them as we would ourselves: by buying unnecessary things. The total spend on pets in the UK has more than doubled in the past decade, reaching nearly £10bn last year. That huge rise has not just come from essentials: figures from the marketing agency Mintel suggest that one in five UK owners like their pet to “keep up with the latest trends” in grooming or, heaven forbid, outfits.\n", - "\n", - "These days pet “boutiques” – like the one that recently opened on my street in Norwich, selling “cold-pressed” dog treats, “paw and nose balms” and spa services – are a widespread sign of gentrification. But it’s not just wealthier areas: this summer in Great Yarmouth, one of the most deprived towns in the country, I noticed seaside stalls selling not one but two brands of ice-cream for dogs.\n", - "\n", - "It suggests dog-lovers have become untethered from their companions’ desires, let alone their needs. Let’s be honest: most dogs would be thrilled to bits to be eating a paper bag, or even their own faeces. And although they are certainly delighted by ice-cream, they don’t need it. But the ways we ourselves find solace – in consumption, by indulging our simian “treat brain” with things that we don’t need and/or aren’t good for us – we have simply extended to our pets.\n", - "\n", - "It’s hard not to see the rise in dog-friendly restaurants, cinema screenings and even churches as similar to the ludicrous expenditure: a way to placate the two-legged being on the end of the lead (regardless of the experience of others in the vicinity).\n", - "\n", - "Meanwhile, many dogs suffer daily deprivation, their worlds made small and monotonous by our busy modern schedules. These are social animals: it’s not natural for them to live without other dogs, let alone in an empty house for eight hours a day, Monday to Friday. If we are besieged by badly behaved dogs, the cause isn’t hard to pinpoint. Many behavioural problems can be alleviated and even addressed by sufficient exercise, supervision and consistent routines, but instead of organising our lives so that our pets may thrive, we show our love with a Halloween-themed cookie, or a new outfit for Instagram likes.\n", - "\n", - "It’s easy to forget that we are sharing our homes with a descendant of the wolf when it is dressed in sheep’s clothing; but the more we learn about animals, the clearer it becomes that our treatment of them, simultaneously adoring and alienated, means they are leading strange, unsatisfying simulacra of the lives they ought to lead.\n", - "\n", - "But for as long as we choose to share our lives with pets, the bar should be the same as for any relationship we value: being prepared to make sacrifices for their wellbeing, prioritising quality time and care, and loving them as they are – not for how they reflect on us, or how we’d like them to be.\n", "\n", "\n", "\"\"\"" @@ -181,7 +160,7 @@ }, { "cell_type": "code", - "execution_count": 3, + "execution_count": 16, "id": "50d5afda-418f-436b-b467-004863193d4a", "metadata": {}, "outputs": [], @@ -355,7 +334,7 @@ }, { "cell_type": "code", - "execution_count": 4, + "execution_count": 47, "id": "f97f11f1-4490-49ea-b193-1f858e72893b", "metadata": {}, "outputs": [], @@ -370,7 +349,7 @@ }, { "cell_type": "code", - "execution_count": 5, + "execution_count": 48, "id": "84da594a-459e-4ec5-9a5c-3a6cc3ab98af", "metadata": {}, "outputs": [], @@ -380,7 +359,7 @@ }, { "cell_type": "code", - "execution_count": 6, + "execution_count": 49, "id": "f56ae869-0dce-41f2-9db0-5f8d5eccba52", "metadata": {}, "outputs": [ @@ -388,7 +367,7 @@ "name": "stdout", "output_type": "stream", "text": [ - "{'label': {'type': 'TEXT', 'subclass': []}}\n" + "{'label': {'type': 'TEXT', 'subclass': []}}\n" ] } ], @@ -398,7 +377,7 @@ }, { "cell_type": "code", - "execution_count": 7, + "execution_count": 50, "id": "6e64e72f-d18b-4d21-85d6-55ed3621124a", "metadata": {}, "outputs": [], @@ -409,7 +388,7 @@ }, { "cell_type": "code", - "execution_count": 8, + "execution_count": 51, "id": "cdeb3631-fb55-4580-a5e5-d2a193a44e79", "metadata": {}, "outputs": [ @@ -453,7 +432,7 @@ }, { "cell_type": "code", - "execution_count": 9, + "execution_count": 52, "id": "fad0c4b0-cd61-4c3c-9964-47f019278060", "metadata": {}, "outputs": [], @@ -489,7 +468,7 @@ }, { "cell_type": "code", - "execution_count": 10, + "execution_count": 53, "id": "709ec529-bb91-45cd-82cb-c122eb69fcd7", "metadata": {}, "outputs": [ @@ -498,10 +477,10 @@ "text/plain": [ "{'data_type': 'text',\n", " 'context_name': 'TEXT',\n", - " 'layer_name': 'Articles, essays, and reports'}" + " 'layer_name': 'News stories and blog posts'}" ] }, - "execution_count": 10, + "execution_count": 53, "metadata": {}, "output_type": "execute_result" } @@ -512,7 +491,7 @@ }, { "cell_type": "code", - "execution_count": 11, + "execution_count": 54, "id": "06b483bf-2fa0-414f-8253-27ffe9a2881c", "metadata": {}, "outputs": [], @@ -522,7 +501,7 @@ }, { "cell_type": "code", - "execution_count": 12, + "execution_count": 55, "id": "35461aff-fd80-4eb2-94b2-66c742db8e55", "metadata": {}, "outputs": [], @@ -532,7 +511,7 @@ }, { "cell_type": "code", - "execution_count": 13, + "execution_count": 56, "id": "41d06ecb-83b9-4284-8d88-6a3f710cb457", "metadata": {}, "outputs": [ @@ -540,7 +519,7 @@ "name": "stdout", "output_type": "stream", "text": [ - "Extracted Layer Names: ['Semantic Layer', 'Syntactic Layer', 'Referential Layer', 'Contextual Layer', 'Lexical Layer', 'Narrative Layer', 'Discourse Layer', 'Pragmatic Layer', 'Stylistic Layer']\n" + "Extracted Layer Names: ['Contextual Layer', 'Thematic Layer', 'Sentimental Layer', 'Structural Layer', 'Temporal Layer', 'Interactivity Layer', 'Semantic Layer', 'Network Layer']\n" ] } ], @@ -552,7 +531,7 @@ }, { "cell_type": "code", - "execution_count": 14, + "execution_count": 57, "id": "1a287a2a-2fb5-4ad3-a69e-80ed2e2ffa5a", "metadata": {}, "outputs": [ @@ -560,7 +539,7 @@ "name": "stdout", "output_type": "stream", "text": [ - "Extracted Layer Names: ['Thematic Layer', 'Narrative Layer', 'Sentiment Layer', 'Semantic Layer', 'Temporal Layer', 'Geographic Layer', 'Source Credibility Layer', 'Interaction Layer', 'Multimedia Layer', 'Intertextuality Layer']\n" + "Extracted Layer Names: ['Semantic Content Layer', 'Entity and Relationship Layer', 'Sentiment and Emotion Layer', 'Temporal Layer', 'Geospatial Layer', 'Topical and Thematic Layer']\n" ] } ], @@ -572,7 +551,7 @@ }, { "cell_type": "code", - "execution_count": 15, + "execution_count": 58, "id": "609b1287-e0bf-42a5-856a-f2e0d859ea8b", "metadata": {}, "outputs": [], @@ -582,7 +561,7 @@ }, { "cell_type": "code", - "execution_count": 46, + "execution_count": 59, "id": "42dbf97d-79b9-4627-b307-b64ac22db4f7", "metadata": {}, "outputs": [ @@ -591,10 +570,10 @@ "text/plain": [ "{'data_type': 'text',\n", " 'context_name': 'TEXT',\n", - " 'layer_name': 'Articles, essays, and reports'}" + " 'layer_name': 'News stories and blog posts'}" ] }, - "execution_count": 46, + "execution_count": 59, "metadata": {}, "output_type": "execute_result" } @@ -605,7 +584,7 @@ }, { "cell_type": "code", - "execution_count": 51, + "execution_count": 60, "id": "25adeeb7-cce2-4eac-8fb5-4ff47029d77d", "metadata": {}, "outputs": [], @@ -637,7 +616,7 @@ }, { "cell_type": "code", - "execution_count": 52, + "execution_count": 69, "id": "b59a52d7-d82b-4546-b0b1-a3d0f62a2a65", "metadata": {}, "outputs": [], @@ -647,25 +626,24 @@ }, { "cell_type": "code", - "execution_count": 26, + "execution_count": 70, "id": "3e7b9fde-fcd5-4891-b43c-177d3877559d", "metadata": {}, "outputs": [ { "data": { "text/plain": [ - "['Structural Layer',\n", + "['Contextual Layer',\n", + " 'Thematic Layer',\n", + " 'Sentimental Layer',\n", + " 'Structural Layer',\n", + " 'Temporal Layer',\n", + " 'Interactivity Layer',\n", " 'Semantic Layer',\n", - " 'Syntactic Layer',\n", - " 'Discourse Layer',\n", - " 'Pragmatic Layer',\n", - " 'Stylistic Layer',\n", - " 'Referential Layer',\n", - " 'Citation Layer',\n", - " 'Metadata Layer']" + " 'Network Layer']" ] }, - "execution_count": 26, + "execution_count": 70, "metadata": {}, "output_type": "execute_result" } @@ -676,7 +654,7 @@ }, { "cell_type": "code", - "execution_count": 19, + "execution_count": 72, "id": "f06edd84-c455-4034-a38b-3a7d2f746f42", "metadata": {}, "outputs": [], @@ -702,57 +680,36 @@ "\n", "# Run the async function for each set of cognitive layers\n", "layer_1_graph = await async_graph_per_layer(input_article_one, cognitive_layers_one)\n", - "layer_2_graph = await async_graph_per_layer(input_article_one, cognitive_layers_two)\n" + "# layer_2_graph = await async_graph_per_layer(input_article_one, cognitive_layers_two)\n" ] }, { "cell_type": "code", - "execution_count": 30, + "execution_count": null, "id": "a34971b4-d1fa-4db8-abbc-395bc70b0b49", "metadata": {}, "outputs": [], "source": [ - "import ast \n" + "# import ast \n" ] }, { "cell_type": "code", - "execution_count": 47, + "execution_count": null, "id": "de3bdbb7-0b2b-46fa-a42f-3ca288c4d875", "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": 47, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "layer_1_graph[0]" - ] + "outputs": [], + "source": [] }, { "cell_type": "code", - "execution_count": 31, + "execution_count": null, "id": "088e92a0-06e7-4128-b9b8-eacd9e735cb4", "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Semantic Layer\n" - ] - } - ], + "outputs": [], "source": [ - "for n,y in layer_1_graph[0].items():\n", - " print(ast.literal_eval(n)['layer'])" + "# for n,y in layer_1_graph[0].items():\n", + "# print(ast.literal_eval(n)['layer'])" ] }, { @@ -790,17 +747,17 @@ }, { "cell_type": "code", - "execution_count": 21, + "execution_count": null, "id": "dd3f0e55-9f9d-4804-9ad6-31afd2088ab5", "metadata": {}, "outputs": [], "source": [ "# Example usage\n", - "user_id = 'user123'\n", - "custom_user_properties = {\n", - " 'username': 'exampleUser',\n", - " 'email': 'user@example.com'\n", - "}\n", + "# user_id = 'user123'\n", + "# custom_user_properties = {\n", + "# 'username': 'exampleUser',\n", + "# 'email': 'user@example.com'\n", + "# }\n", "\n", "# additional_categories = {\n", "# \"Natural Language Text\": [\"Articles, essays, and reports\", \"Books and manuscripts\"]\n", @@ -811,50 +768,25 @@ }, { "cell_type": "code", - "execution_count": 233, + "execution_count": null, "id": "2cc7c3bb-7cc0-453b-beab-2983a703ccda", "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "{'data_type': 'text',\n", - " 'context_name': 'TEXT',\n", - " 'layer_name': 'News stories and blog posts'}" - ] - }, - "execution_count": 233, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ - "transformed_dict_1" + "# transformed_dict_1" ] }, { "cell_type": "code", - "execution_count": 23, + "execution_count": null, "id": "b3160a1d-a6ea-40ce-a521-37ad26d31ffb", "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Nodes in the graph:\n", - "[('user123', {'created_at': '2024-03-08 14:41:03', 'updated_at': '2024-03-08 14:41:03', 'username': 'exampleUser', 'email': 'user@example.com', 'exist': True}), ('Temporal', {'created_at': '2024-03-08 14:41:03', 'updated_at': '2024-03-08 14:41:03', 'type': 'category', 'exist': True}), ('Temporal:Historical events', {'created_at': '2024-03-08 14:41:03', 'updated_at': '2024-03-08 14:41:03', 'type': 'subclass', 'content': 'Historical events', 'exist': True}), ('Temporal:Schedules and timelines', {'created_at': '2024-03-08 14:41:03', 'updated_at': '2024-03-08 14:41:03', 'type': 'subclass', 'content': 'Schedules and timelines', 'exist': True}), ('Positional', {'created_at': '2024-03-08 14:41:03', 'updated_at': '2024-03-08 14:41:03', 'type': 'category', 'exist': True}), ('Positional:Geographical locations', {'created_at': '2024-03-08 14:41:03', 'updated_at': '2024-03-08 14:41:03', 'type': 'subclass', 'content': 'Geographical locations', 'exist': True}), ('Positional:Spatial data', {'created_at': '2024-03-08 14:41:03', 'updated_at': '2024-03-08 14:41:03', 'type': 'subclass', 'content': 'Spatial data', 'exist': True}), ('Propositions', {'created_at': '2024-03-08 14:41:03', 'updated_at': '2024-03-08 14:41:03', 'type': 'category', 'exist': True}), ('Propositions:Hypotheses and theories', {'created_at': '2024-03-08 14:41:03', 'updated_at': '2024-03-08 14:41:03', 'type': 'subclass', 'content': 'Hypotheses and theories', 'exist': True}), ('Propositions:Claims and arguments', {'created_at': '2024-03-08 14:41:03', 'updated_at': '2024-03-08 14:41:03', 'type': 'subclass', 'content': 'Claims and arguments', 'exist': True}), ('Personalization', {'created_at': '2024-03-08 14:41:03', 'updated_at': '2024-03-08 14:41:03', 'type': 'category', 'exist': True}), ('Personalization:User preferences', {'created_at': '2024-03-08 14:41:03', 'updated_at': '2024-03-08 14:41:03', 'type': 'subclass', 'content': 'User preferences', 'exist': True}), ('Personalization:User information', {'created_at': '2024-03-08 14:41:03', 'updated_at': '2024-03-08 14:41:03', 'type': 'subclass', 'content': 'User information', 'exist': True}), ('News Stories', {'created_at': '2024-03-08 14:41:03', 'updated_at': '2024-03-08 14:41:03', 'type': 'category', 'exist': True}), ('News Stories:News stories and blog posts', {'created_at': '2024-03-08 14:41:03', 'updated_at': '2024-03-08 14:41:03', 'type': 'subclass', 'content': 'News stories and blog posts', 'exist': True})]\n", - "\n", - "Edges in the graph:\n", - "[('user123', 'Temporal', {'relationship': 'created'}), ('user123', 'Positional', {'relationship': 'created'}), ('user123', 'Propositions', {'relationship': 'created'}), ('user123', 'Personalization', {'relationship': 'created'}), ('user123', 'News Stories', {'relationship': 'created'}), ('Temporal', 'Temporal:Historical events', {'relationship': 'includes'}), ('Temporal', 'Temporal:Schedules and timelines', {'relationship': 'includes'}), ('Positional', 'Positional:Geographical locations', {'relationship': 'includes'}), ('Positional', 'Positional:Spatial data', {'relationship': 'includes'}), ('Propositions', 'Propositions:Hypotheses and theories', {'relationship': 'includes'}), ('Propositions', 'Propositions:Claims and arguments', {'relationship': 'includes'}), ('Personalization', 'Personalization:User preferences', {'relationship': 'includes'}), ('Personalization', 'Personalization:User information', {'relationship': 'includes'}), ('News Stories', 'News Stories:News stories and blog posts', {'relationship': 'includes'})]\n" - ] - } - ], + "outputs": [], "source": [ - "print(\"Nodes in the graph:\")\n", - "print(G.nodes(data=True))\n", - "print(\"\\nEdges in the graph:\")\n", - "print(G.edges(data=True))" + "# print(\"Nodes in the graph:\")\n", + "# print(G.nodes(data=True))\n", + "# print(\"\\nEdges in the graph:\")\n", + "# print(G.edges(data=True))" ] }, { @@ -875,7 +807,7 @@ }, { "cell_type": "code", - "execution_count": 83, + "execution_count": null, "id": "4dab2ff0-0d12-4a00-a4e4-fb901e701bd3", "metadata": {}, "outputs": [], @@ -893,7 +825,7 @@ }, { "cell_type": "code", - "execution_count": 53, + "execution_count": 73, "id": "512f15be-0114-4c8c-9754-e82f2fa16344", "metadata": {}, "outputs": [ @@ -901,7 +833,7 @@ "data": { "text/html": [ "\n", - "