From d91619f191db6cf7ae624bcd42b2416efbf3e272 Mon Sep 17 00:00:00 2001 From: KaifAhmad1 Date: Tue, 20 Jan 2026 01:51:29 +0530 Subject: [PATCH] Fix earnings call analysis notebook: attribute access and export logic --- .../finance/03_Earnings_Call_Analysis.ipynb | 103 ++++++++++++++---- 1 file changed, 79 insertions(+), 24 deletions(-) diff --git a/cookbook/use_cases/finance/03_Earnings_Call_Analysis.ipynb b/cookbook/use_cases/finance/03_Earnings_Call_Analysis.ipynb index bc8a51e5..44182be3 100644 --- a/cookbook/use_cases/finance/03_Earnings_Call_Analysis.ipynb +++ b/cookbook/use_cases/finance/03_Earnings_Call_Analysis.ipynb @@ -1105,7 +1105,7 @@ }, { "cell_type": "code", - "execution_count": 4, + "execution_count": null, "metadata": {}, "outputs": [ { @@ -1133,7 +1133,7 @@ ")\n", "\n", "memory_id = agent_context.store(\n", - " content=parsed_doc[\"full_text\"][:1000],\n", + " content=chunks,\n", " metadata={\"source\": \"earnings_call\", \"date\": \"2024-Q1\"},\n", " extract_entities=True,\n", " extract_relationships=True,\n", @@ -1177,32 +1177,71 @@ "\n", "generated_answers = []\n", "\n", + "print(\"--- Generating Enhanced Answers ---\\n\")\n", + "\n", + "def format_context(retrieved_contexts):\n", + " \"\"\"Formats retrieved context with graph information.\"\"\"\n", + " formatted_parts = []\n", + " \n", + " for i, ctx in enumerate(retrieved_contexts):\n", + " content = getattr(ctx, \"content\", \"\")\n", + " source = getattr(ctx, \"source\", \"unknown\")\n", + " \n", + " # Format related entities from the graph\n", + " related_entities = getattr(ctx, \"related_entities\", [])\n", + " entities_str = \", \".join([\n", + " f\"{e.get('name', 'Unknown')} ({e.get('type', 'Entity')})\" \n", + " for e in related_entities[:5] # Limit to top 5 per chunk\n", + " ])\n", + " \n", + " # Format related relationships\n", + " related_rels = getattr(ctx, \"related_relationships\", [])\n", + " rels_str = \"; \".join([\n", + " f\"{r.get('source', '')} -> {r.get('type', '')} -> {r.get('target', '')}\"\n", + " for r in related_rels[:3] # Limit to top 3 per chunk\n", + " ])\n", + " \n", + " part = f\"Source {i+1} ({source}):\\n{content}\\n\"\n", + " if entities_str:\n", + " part += f\"Related Entities: {entities_str}\\n\"\n", + " if rels_str:\n", + " part += f\"Graph Connections: {rels_str}\\n\"\n", + " \n", + " formatted_parts.append(part)\n", + " \n", + " return \"\\n---\\n\".join(formatted_parts)\n", + "\n", "for question in financial_questions:\n", + " print(f\"Question: {question}\")\n", + " \n", + " # Retrieve with graph expansion enabled and higher limits\n", " retrieved_contexts = context_retriever.retrieve(\n", " query=question,\n", - " max_results=3,\n", + " max_results=10, # Increased from 3\n", " min_relevance_score=0.2,\n", + " use_graph_expansion=True, # Explicitly enable graph expansion\n", + " max_hops=2 # Traverse up to 2 hops in the graph\n", " )\n", "\n", - " context_text = \"\\n\\n\".join(\n", - " ctx.get(\"content\", ctx.get(\"text\", \"\"))\n", - " for ctx in retrieved_contexts\n", - " )[:1000]\n", + " # Use the rich formatter\n", + " context_text = format_context(retrieved_contexts)\n", "\n", - " entity_names = [\n", - " entity.get(\"name\", \"\")\n", - " for entity in knowledge_graph.get(\"entities\", [])[:5]\n", + " # Get global key entities (optional, but good for high-level context)\n", + " global_entities = [\n", + " f\"{e.get('name', '')} ({e.get('type', '')})\"\n", + " for e in knowledge_graph.get(\"entities\", [])[:10]\n", " ]\n", - " entities_text = \", \".join(entity_names) or \"N/A\"\n", + " global_entities_text = \", \".join(global_entities)\n", "\n", " prompt = f\"\"\"\n", - "Answer the question using only the context below.\n", + "Answer the question comprehensively using the provided context.\n", + "The context includes text chunks and knowledge graph connections (entities and relationships).\n", "If the answer is not present, say so.\n", "\n", "Context:\n", "{context_text}\n", "\n", - "Key entities: {entities_text}\n", + "Global Key Entities: {global_entities_text}\n", "\n", "Question:\n", "{question}\n", @@ -1213,16 +1252,18 @@ " try:\n", " answer = groq_llm.generate(\n", " prompt,\n", - " temperature=0.7,\n", - " max_tokens=400,\n", + " temperature=0.3, # Lower temperature for more factual answers\n", + " max_tokens=1000, # Allow longer answers\n", " )\n", " except Exception as error:\n", " answer = f\"Answer generation failed: {error}\"\n", "\n", " generated_answers.append(answer)\n", + " print(f\"Answer: {answer}\\n\")\n", + " print(\"-\" * 50 + \"\\n\")\n", "\n", "print(\"Answer generation completed\")\n", - "print(\"Questions answered:\", len(generated_answers))\n" + "print(\"Questions answered:\", len(generated_answers))" ] }, { @@ -1241,27 +1282,41 @@ "outputs": [], "source": [ "from semantica.export import JSONExporter, RDFExporter\n", + "import json\n", "\n", + "# Initialize exporters\n", "json_exporter = JSONExporter()\n", "rdf_exporter = RDFExporter()\n", "\n", - "kg_json = json_exporter.export(knowledge_graph, format=\"json\")\n", - "kg_rdf = rdf_exporter.export_to_rdf(knowledge_graph, format=\"turtle\")\n", + "# Define output file paths\n", + "json_output_path = \"knowledge_graph.json\"\n", + "rdf_output_path = \"knowledge_graph.ttl\"\n", "\n", + "# Export to files (required by the API)\n", + "json_exporter.export(knowledge_graph, file_path=json_output_path, format=\"json\")\n", + "\n", + "# FIXED: Use .export() instead of .export_to_rdf() to write to disk\n", + "rdf_exporter.export(knowledge_graph, file_path=rdf_output_path, format=\"turtle\")\n", + "\n", + "# Load the RDF file content to check its size\n", + "with open(rdf_output_path, \"r\", encoding=\"utf-8\") as f:\n", + " kg_rdf_content = f.read()\n", + "\n", + "# Create analysis summary\n", "analysis_summary = {\n", " \"entities\": len(knowledge_graph.get(\"entities\", [])),\n", " \"relationships\": len(knowledge_graph.get(\"relationships\", [])),\n", - " \"entity_conflicts_resolved\": len(resolved_entity_value_conflicts),\n", - " \"relationship_conflicts_resolved\": len(resolved_relationship_conflicts),\n", - " \"deduplicated_entities\": len(deduplicated_entities),\n", - " \"communities\": num_communities,\n", + " \"entity_conflicts_resolved\": len(locals().get(\"resolved_entity_value_conflicts\", [])),\n", + " \"relationship_conflicts_resolved\": len(locals().get(\"resolved_relationship_conflicts\", [])),\n", + " \"deduplicated_entities\": len(locals().get(\"deduplicated_entities\", [])),\n", + " \"communities\": locals().get(\"num_communities\", 0),\n", " \"questions_answered\": len(generated_answers),\n", - " \"llm_model\": groq_llm.model,\n", + " \"llm_model\": getattr(groq_llm, \"model\", \"unknown\"),\n", "}\n", "\n", "print(\"Export completed\")\n", "print(\"KG JSON entities:\", analysis_summary[\"entities\"])\n", - "print(\"KG RDF size (chars):\", len(kg_rdf))\n", + "print(\"KG RDF size (chars):\", len(kg_rdf_content))\n", "print(\"Questions answered:\", analysis_summary[\"questions_answered\"])\n", "print(\"LLM model:\", analysis_summary[\"llm_model\"])\n", "print(\"Conflicts resolved:\", analysis_summary[\"entity_conflicts_resolved\"] + analysis_summary[\"relationship_conflicts_resolved\"])"