AD2000X commited on
Commit
81c27b5
·
verified ·
1 Parent(s): 1ab873b

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +216 -189
app.py CHANGED
@@ -27,17 +27,18 @@ def main():
27
  ["RAG comparison demonstration", "Knowledge graph visualization", "Ontology structure analysis", "Entity exploration", "Semantic path visualization", "Inference tracking", "Detailed comparative analysis"]
28
  )
29
 
30
- if page == "RAG Comparison Demo":
 
31
  run_rag_demo()
32
- elif page == "Knowledge Graph Visualization":
33
  run_knowledge_graph_visualization()
34
- elif page == "Ontology Structure Analysis":
35
  run_ontology_structure_analysis()
36
- elif page == "Entity Exploration":
37
  run_entity_exploration()
38
- elif page == "Semantic Path Visualization":
39
  run_semantic_path_visualization()
40
- elif page == "Inference Tracking":
41
  run_reasoning_trace()
42
  elif page == "Detailed comparative analysis":
43
  run_detailed_comparison()
@@ -69,15 +70,15 @@ def run_rag_demo():
69
  )
70
  vector_answer = vector_response.choices[0].message.content
71
 
72
- st.markdown("#### answer")
73
  st.write(vector_answer)
74
 
75
- st.markdown("#### retrieval context")
76
  for i, doc in enumerate(vector_docs):
77
  with st.expander(f"Source {i+1}"):
78
  st.code(doc.page_content)
79
 
80
- # # Ontology RAG
81
  with col2:
82
  st.subheader("Ontology RAG")
83
  result = semantic_retriever.retrieve_with_paths(query, k=k_val)
@@ -93,18 +94,18 @@ def run_rag_demo():
93
  )
94
  enhanced_answer = enhanced_response.choices[0].message.content
95
 
96
- st.markdown("#### answer")
97
  st.write(enhanced_answer)
98
 
99
- st.markdown("#### Search context")
100
  for i, doc in enumerate(retrieved_docs):
101
  source = doc.metadata.get("source", "unknown")
102
  label = {
103
- "ontology": "Ontology context",
104
- "text": "Text context",
105
- "ontology_context": "Semantic context",
106
- "semantic_path": "Relationship path"
107
- }.get(source, f"source")
108
  with st.expander(f"{label} {i+1}"):
109
  st.markdown(doc.page_content)
110
 
@@ -120,38 +121,38 @@ def run_rag_demo():
120
  st.markdown("""
121
  The above comparison demonstrates several key advantages of ontology-enhanced RAG:
122
 
123
- 1. **Structure-aware**: Ontology-augmented methods understand the relationships between entities, not just their textual similarities.
124
 
125
- 2. **Multi-hop reasoning**: By using the knowledge graph structure, the enhancement method can connect information across multiple relational jumps.
126
 
127
- 3. **Context enrichment**: Ontologies provide additional context about entity types, attributes, and relationships that are not explicit in the text.
128
 
129
- 4. Reasoning ability: Structured knowledge allows for logical reasoning that vector similarity alone cannot achieve.
130
 
131
- Try more complex queries that require understanding of relationships to see the differences more clearly!
132
  """)
133
 
134
  def run_knowledge_graph_visualization():
135
  st.title("Knowledge Graph Visualization")
136
 
137
- # Check if there is a center entity selected
138
  central_entity = st.session_state.get('central_entity', None)
139
 
140
- # Check if there is a center entity selected
141
  display_graph_visualization(knowledge_graph, central_entity=central_entity, max_distance=2)
142
 
143
- # Get and display graphical statistics
144
  graph_stats = knowledge_graph.get_graph_statistics()
145
  if graph_stats:
146
- st.subheader("Graphical Statistics")
147
 
148
  col1, col2, col3, col4 = st.columns(4)
149
- col1.metric("Total number of nodes", graph_stats.get("node_count", 0))
150
- col2.metric("Total number of edges", graph_stats.get("edge_count", 0))
151
- col3.metric("total number of classes", graph_stats.get("class_count", 0))
152
- col4.metric("Total number of instances", graph_stats.get("instance_count", 0))
153
 
154
- # Display the central node
155
  if "central_nodes" in graph_stats and graph_stats["central_nodes"]:
156
  st.subheader("Central Nodes (by Betweenness Centrality)")
157
  central_nodes = graph_stats["central_nodes"]["betweenness"]
@@ -167,7 +168,7 @@ def run_knowledge_graph_visualization():
167
  nodes_df.append({
168
  "ID": node_id,
169
  "Name": name,
170
- "type": node_class,
171
  "Centrality": node_info["centrality"]
172
  })
173
 
@@ -176,11 +177,11 @@ def run_knowledge_graph_visualization():
176
  def run_ontology_structure_analysis():
177
  st.title("Ontology Structure Analysis")
178
 
179
- # Use the existing ontology statistics display function
180
  display_ontology_stats(ontology_manager)
181
 
182
- # Add additional class hierarchy visualization
183
- st.subheader("class hierarchy")
184
 
185
  # Get class hierarchy data
186
  class_hierarchy = ontology_manager.get_class_hierarchy()
@@ -196,19 +197,41 @@ def run_ontology_structure_analysis():
196
  G.add_node(child)
197
  G.add_edge(parent, child)
198
 
199
- # Check if there are enough nodes to create the visualization
200
  if len(G.nodes) > 1:
201
  # Generate HTML visualization using knowledge graph class
202
  kg = KnowledgeGraph(ontology_manager)
 
 
203
  html = kg.generate_html_visualization(
204
  include_classes=True,
205
  include_instances=False,
206
  max_distance=5,
207
- layout_algorithm="hierarchical"
208
  )
209
 
210
- # Rendering HTML
211
  render_html_in_streamlit(html)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
212
 
213
  def run_entity_exploration():
214
  st.title("Entity Exploration")
@@ -221,8 +244,8 @@ def run_entity_exploration():
221
  # Remove duplicates and sort
222
  entities = sorted(set(entities))
223
 
224
- # Create a drop-down selection box
225
- selected_entity = st.selectbox("Select entity", entities)
226
 
227
  if selected_entity:
228
  # Get entity information
@@ -232,13 +255,13 @@ def run_entity_exploration():
232
  display_entity_details(entity_info, ontology_manager)
233
 
234
  # Set this entity as the central entity (for knowledge graph visualization)
235
- if st.button("View this entity in the knowledge graph"):
236
  st.session_state.central_entity = selected_entity
237
  st.rerun()
238
 
239
  # Get and display entity neighbors
240
  st.subheader("Entity Neighborhood")
241
- max_distance = st.slider("Maximum neighborhood distance", 1, 3, 1)
242
 
243
  neighborhood = knowledge_graph.get_entity_neighborhood(
244
  selected_entity,
@@ -252,7 +275,7 @@ def run_entity_exploration():
252
  neighbors_at_distance = [n for n in neighborhood["neighbors"] if n["distance"] == distance]
253
 
254
  if neighbors_at_distance:
255
- with st.expander(f"Neighbors at distance {distance} ({len(neighbors_at_distance)})"):
256
  for neighbor in neighbors_at_distance:
257
  st.markdown(f"**{neighbor['id']}** ({neighbor.get('class_type', 'unknown')})")
258
 
@@ -278,16 +301,16 @@ def run_semantic_path_visualization():
278
  col1, col2 = st.columns(2)
279
 
280
  with col1:
281
- source_entity = st.selectbox("Select source entity", entities, key="source")
282
 
283
  with col2:
284
- target_entity = st.selectbox("Select target entity", entities, key="target")
285
 
286
  if source_entity and target_entity and source_entity != target_entity:
287
  # Provide a maximum path length option
288
- max_length = st.slider("Maximum path length", 1, 5, 3)
289
 
290
- # Find the path
291
  paths = knowledge_graph.find_paths_between_entities(
292
  source_entity,
293
  target_entity,
@@ -295,15 +318,15 @@ def run_semantic_path_visualization():
295
  )
296
 
297
  if paths:
298
- st.success(f"Found {len(paths)} paths")
299
 
300
  # Create expanders for each path
301
  for i, path in enumerate(paths):
302
- # Calculate path length and relationship type
303
  path_length = len(path)
304
  rel_types = [edge["type"] for edge in path]
305
 
306
- with st.expander(f"path {i+1} (length: {path_length}, relation: {', '.join(rel_types)})", expanded=(i==0)):
307
  # Create a text description of the path
308
  path_text = []
309
  entities_in_path = []
@@ -316,7 +339,7 @@ def run_semantic_path_visualization():
316
  entities_in_path.append(source)
317
  entities_in_path.append(target)
318
 
319
- # Get entity information to get a human-readable name
320
  source_info = ontology_manager.get_entity_info(source)
321
  target_info = ontology_manager.get_entity_info(target)
322
 
@@ -344,13 +367,13 @@ def run_semantic_path_visualization():
344
  # Display path visualization
345
  visualize_path(path_info, ontology_manager)
346
  else:
347
- st.warning(f"No path of length {max_length} or shorter was found between these entities.")
348
 
349
  def run_reasoning_trace():
350
- st.title("Inference Tracking Visualization")
351
 
352
  if not st.session_state.get("query") or not st.session_state.get("retrieved_docs") or not st.session_state.get("answer"):
353
- st.warning("Please run a query on the RAG comparison page first to generate inference trace data.")
354
  return
355
 
356
  # Get data from session state
@@ -358,11 +381,11 @@ def run_reasoning_trace():
358
  retrieved_docs = st.session_state.retrieved_docs
359
  answer = st.session_state.answer
360
 
361
- # Show inference trace
362
  display_reasoning_trace(query, retrieved_docs, answer, ontology_manager)
363
 
364
  def run_detailed_comparison():
365
- st.title("Detailed comparison of RAG methods")
366
 
367
  # Add comparison query options
368
  comparison_queries = [
@@ -374,7 +397,7 @@ def run_detailed_comparison():
374
  ]
375
 
376
  selected_query = st.selectbox(
377
- "Select Compare Query",
378
  comparison_queries,
379
  index=0
380
  )
@@ -386,8 +409,8 @@ def run_detailed_comparison():
386
  else:
387
  query = selected_query
388
 
389
- if st.button("Compare RAG methods"):
390
- with st.spinner("Run detailed comparison..."):
391
  # Start timing
392
  import time
393
  start_time = time.time()
@@ -406,10 +429,10 @@ def run_detailed_comparison():
406
  vector_answer = vector_response.choices[0].message.content
407
  vector_time = time.time() - start_time
408
 
409
- # Reset the timer
410
  start_time = time.time()
411
 
412
- # Run the enhanced RAG
413
  result = semantic_retriever.retrieve_with_paths(query, k=k_val)
414
  retrieved_docs = result["documents"]
415
  enhanced_context = "\n\n".join([doc.page_content for doc in retrieved_docs])
@@ -424,59 +447,59 @@ def run_detailed_comparison():
424
  enhanced_answer = enhanced_response.choices[0].message.content
425
  enhanced_time = time.time() - start_time
426
 
427
- # Save the results for visualization
428
  st.session_state.query = query
429
  st.session_state.retrieved_docs = retrieved_docs
430
  st.session_state.answer = enhanced_answer
431
 
432
- # Display the comparison results
433
- st.subheader("Comparison results")
434
 
435
- # Use tabs to show comparisons in different aspects
436
- tab1, tab2, tab3, tab4 = st.tabs(["Answer Comparison", "Performance Indicators", "Retrieval Source Comparison", "Context Quality"])
437
 
438
  with tab1:
439
  col1, col2 = st.columns(2)
440
 
441
  with col1:
442
- st.markdown("#### Traditional RAG answer")
443
  st.write(vector_answer)
444
 
445
  with col2:
446
- st.markdown("#### Ontology Enhanced RAG Answer")
447
  st.write(enhanced_answer)
448
 
449
  with tab2:
450
- # Performance Indicators
451
  col1, col2 = st.columns(2)
452
 
453
  with col1:
454
- st.metric("Traditional RAG response time", f"{vector_time:.2f}")
455
 
456
- # Calculate text related indicators
457
  vector_tokens = len(vector_context.split())
458
- st.metric("Number of retrieved context tokens", vector_tokens)
459
 
460
- st.metric("Number of retrieved documents", len(vector_docs))
461
 
462
  with col2:
463
- st.metric("Ontology enhanced RAG response time", f"{enhanced_time:.2f}")
464
 
465
- # Calculate text related indicators
466
  enhanced_tokens = len(enhanced_context.split())
467
- st.metric("Number of retrieved context tokens", enhanced_tokens)
468
 
469
- st.metric("Number of retrieved documents", len(retrieved_docs))
470
 
471
- # Add a chart
472
  import pandas as pd
473
  import plotly.express as px
474
 
475
  # Performance comparison chart
476
  performance_data = {
477
- "Metrics": ["Response time (seconds)", "Number of context tags", "Number of retrieved documents"],
478
  "Traditional RAG": [vector_time, vector_tokens, len(vector_docs)],
479
- "Ontology Enhanced RAG": [enhanced_time, enhanced_tokens, len(retrieved_docs)]
480
  }
481
 
482
  df = pd.DataFrame(performance_data)
@@ -484,31 +507,31 @@ def run_detailed_comparison():
484
  # Plotly bar chart
485
  fig = px.bar(
486
  df,
487
- x="Indicator",
488
- y=["Traditional RAG", "Ontology Enhanced RAG"],
489
  barmode="group",
490
- title="Performance Index Comparison",
491
- labels={"value": "Numerical value", "variable": "RAG method"}
492
  )
493
 
494
- st.plotly_chart(fig)
495
 
496
  with tab3:
497
- # Search source comparison
498
- traditional_sources = ["Traditional vector retrieval"] * len(vector_docs)
499
 
500
  enhanced_sources = []
501
  for doc in retrieved_docs:
502
  source = doc.metadata.get("source", "unknown")
503
  label = {
504
- "ontology": "Ontology context",
505
- "text": "Text context",
506
- "ontology_context": "Semantic context",
507
- "semantic_path": "Relationship path"
508
- }.get(source, "unknown source")
509
  enhanced_sources.append(label)
510
 
511
- # Create a source distribution chart
512
  source_counts = {}
513
  for source in enhanced_sources:
514
  if source in source_counts:
@@ -517,32 +540,32 @@ def run_detailed_comparison():
517
  source_counts[source] = 1
518
 
519
  source_df = pd.DataFrame({
520
- "Source type": list(source_counts.keys()),
521
- "Number of documents": list(source_counts.values())
522
  })
523
 
524
  fig = px.pie(
525
  source_df,
526
- values="Number of documents",
527
- names="Source type",
528
- title="Ontology-enhanced RAG retrieval source distribution"
529
  )
530
 
531
- st.plotly_chart(fig)
532
 
533
- # Show the relationship between the source and the answer
534
- st.subheader("Relationship between source and answer")
535
  st.markdown("""
536
  Ontology-enhanced methods leverage multiple sources of knowledge to construct more comprehensive answers. The figure above shows the distribution of different sources.
537
 
538
- In particular, semantic context and relation paths provide knowledge that cannot be captured by traditional vector retrieval, enabling the system to connect concepts and perform multi-hop reasoning.
539
  """)
540
 
541
  with tab4:
542
- # Contextual quality assessment
543
- st.subheader("Contextual Quality Assessment")
544
 
545
- # Create an evaluation function (simplified version)
546
  def evaluate_context(docs):
547
  metrics = {
548
  "Direct Relevance": 0,
@@ -556,18 +579,18 @@ def run_detailed_comparison():
556
 
557
  # Direct Relevance - Based on Keywords
558
  if any(kw in content.lower() for kw in query.lower().split()):
559
- metrics["direct relevance"] += 1
560
 
561
  # Semantic richness - based on text length
562
- metrics["semantic richness"] += min(1, len(content.split()) / 50)
563
 
564
- # Structural information - from the body
565
  if hasattr(doc, "metadata") and doc.metadata.get("source") in ["ontology", "ontology_context"]:
566
  metrics["Structure Information"] += 1
567
 
568
  # Relationship information - from path
569
  if hasattr(doc, "metadata") and doc.metadata.get("source") == "semantic_path":
570
- metrics["relationship information"] += 1
571
 
572
  # Standardization
573
  for key in metrics:
@@ -575,109 +598,113 @@ def run_detailed_comparison():
575
 
576
  return metrics
577
 
578
- # Evaluate the two methods
579
  vector_metrics = evaluate_context(vector_docs)
580
  enhanced_metrics = evaluate_context(retrieved_docs)
581
 
582
- # Create a comparative radar chart
583
  metrics_df = pd.DataFrame({
584
  "metrics": list(vector_metrics.keys()),
585
  "Traditional RAG": list(vector_metrics.values()),
586
- "Ontology Enhanced RAG": list(enhanced_metrics.values())
587
  })
588
 
589
  # Convert data to Plotly radar chart format
590
  fig = px.line_polar(
591
  metrics_df,
592
- r=["Traditional RAG", "Ontology Enhanced RAG"],
593
- theta="Indicator",
594
  line_close=True,
595
  range_r=[0, 10],
596
- title="Contextual Quality Comparison"
597
  )
598
 
599
- st.plotly_chart(fig)
600
 
601
  st.markdown("""
602
- The figure above shows the comparison of the two RAG methods in terms of contextual quality. Ontology-enhanced RAG performs better in multiple dimensions:
 
 
 
 
 
 
 
 
 
 
 
 
 
 
603
 
604
- 1. **Direct relevance**: the degree of relevance between the search content and the query
605
- 2. **Semantic Richness**: Information density and richness of the retrieval context
606
- 3. **Structural information**: structured knowledge of entity types, attributes, and relationships
607
- 4. **Relationship information**: explicit relationships and connection paths between entities
 
 
 
 
 
 
 
 
 
 
608
 
609
- The advantage of ontology-enhanced RAG is that it can retrieve structured knowledge and relational information, which are missing in traditional RAG methods.
610
- """)
611
-
612
- # Display detailed analysis section
613
- st.subheader("Method Effect Analysis")
614
-
615
- with st.expander("Comparison of advantages and disadvantages", expanded=True):
616
- col1, col2 = st.columns(2)
 
 
 
 
 
 
 
617
 
618
- with col1:
619
- st.markdown("#### Traditional RAG")
620
  st.markdown("""
621
- **Advantages**:
622
- - Simple implementation and light computational burden
623
- - Works well with unstructured text
624
- - Response times are usually faster
625
-
626
- **Disadvantages**:
627
- - Unable to capture relationships between entities
628
- - Lack of context for structured knowledge
629
- - Difficult to perform multi-hop reasoning
630
- - Retrieval is mainly based on text similarity
 
 
 
 
 
631
  """)
632
-
633
- with col2:
634
- st.markdown("#### Ontology Enhanced RAG")
635
  st.markdown("""
636
- **Advantages**:
637
- - Ability to understand relationships and connections between entities
638
- - Provides rich structured knowledge context
639
- - Support multi-hop reasoning and path discovery
640
- - Combining vector similarity and semantic relationship
641
-
642
- **Disadvantages**:
643
- - Higher implementation complexity
644
- - Need to maintain the ontology model
645
- - The computational overhead is relatively high
646
- - Retrieval and inference times may be longer
647
  """)
648
-
649
- # Add usage scenario suggestions
650
- with st.expander("Applicable scenarios"):
651
- st.markdown("""
652
- ### Traditional RAG applicable scenarios
653
-
654
- - Simple fact-finding
655
- - Unstructured document retrieval
656
- - Applications with high response time requirements
657
- - When the document content is clear and direct
658
-
659
- ### Applicable scenarios for Ontology Enhanced RAG
660
-
661
- - Complex knowledge association query
662
- - Problems that require understanding of relationships between entities
663
- - Applications that require cross-domain reasoning
664
- - Enterprise Knowledge Management System
665
- - Reasoning scenarios that require high accuracy and consistency
666
- - Applications that require implicit knowledge discovery
667
- """)
668
 
669
- # Add practical application examples
670
- with st.expander("Actual Application Case"):
671
- st.markdown("""
672
- ### Enterprise Knowledge Management
673
- Ontology-enhanced RAG systems can help enterprises effectively organize and access their knowledge assets, connect information in different departments and systems, and provide more comprehensive business insights.
674
-
675
- ### Product development decision support
676
- By understanding the relationship between customer feedback, product features, and market data, the system can provide more valuable support for product development decisions.
677
-
678
- ### Complex compliance query
679
- In compliance problems that require consideration of multiple rules and relationships, ontology-enhanced RAG can provide rule-based reasoning, ensuring that recommendations comply with all applicable policies and regulations.
680
-
681
- ### Diagnostics and Troubleshooting
682
- In technical support and troubleshooting scenarios, the system can connect symptoms, causes, and solutions to provide more accurate diagnoses through multi-hop reasoning.
683
- """)
 
27
  ["RAG comparison demonstration", "Knowledge graph visualization", "Ontology structure analysis", "Entity exploration", "Semantic path visualization", "Inference tracking", "Detailed comparative analysis"]
28
  )
29
 
30
+ # 修正條件判斷,使其與選項名稱一致
31
+ if page == "RAG comparison demonstration":
32
  run_rag_demo()
33
+ elif page == "Knowledge graph visualization":
34
  run_knowledge_graph_visualization()
35
+ elif page == "Ontology structure analysis":
36
  run_ontology_structure_analysis()
37
+ elif page == "Entity exploration":
38
  run_entity_exploration()
39
+ elif page == "Semantic path visualization":
40
  run_semantic_path_visualization()
41
+ elif page == "Inference tracking":
42
  run_reasoning_trace()
43
  elif page == "Detailed comparative analysis":
44
  run_detailed_comparison()
 
70
  )
71
  vector_answer = vector_response.choices[0].message.content
72
 
73
+ st.markdown("#### Answer")
74
  st.write(vector_answer)
75
 
76
+ st.markdown("#### Retrieved Context")
77
  for i, doc in enumerate(vector_docs):
78
  with st.expander(f"Source {i+1}"):
79
  st.code(doc.page_content)
80
 
81
+ # Ontology RAG
82
  with col2:
83
  st.subheader("Ontology RAG")
84
  result = semantic_retriever.retrieve_with_paths(query, k=k_val)
 
94
  )
95
  enhanced_answer = enhanced_response.choices[0].message.content
96
 
97
+ st.markdown("#### Answer")
98
  st.write(enhanced_answer)
99
 
100
+ st.markdown("#### Retrieved Context")
101
  for i, doc in enumerate(retrieved_docs):
102
  source = doc.metadata.get("source", "unknown")
103
  label = {
104
+ "ontology": "Ontology Context",
105
+ "text": "Text Context",
106
+ "ontology_context": "Semantic Context",
107
+ "semantic_path": "Relationship Path"
108
+ }.get(source, f"Source")
109
  with st.expander(f"{label} {i+1}"):
110
  st.markdown(doc.page_content)
111
 
 
121
  st.markdown("""
122
  The above comparison demonstrates several key advantages of ontology-enhanced RAG:
123
 
124
+ 1. **Structural Awareness**: The ontology-enhanced approach understands the relationships between entities, not just their textual similarity.
125
 
126
+ 2. **Multi-hop Reasoning**: By using the knowledge graph structure, the enhanced approach can connect information across multiple relationship hops.
127
 
128
+ 3. **Context Enrichment**: The ontology provides additional context about entity types, properties, and relationships that isn't explicit in the text.
129
 
130
+ 4. **Inference Capabilities**: The structured knowledge allows for logical inferences that vector similarity alone cannot achieve.
131
 
132
+ Try more complex queries that require understanding relationships to see the differences more clearly!
133
  """)
134
 
135
  def run_knowledge_graph_visualization():
136
  st.title("Knowledge Graph Visualization")
137
 
138
+ # Check if there is a central entity selected
139
  central_entity = st.session_state.get('central_entity', None)
140
 
141
+ # Call visualization function
142
  display_graph_visualization(knowledge_graph, central_entity=central_entity, max_distance=2)
143
 
144
+ # Get and display graph statistics
145
  graph_stats = knowledge_graph.get_graph_statistics()
146
  if graph_stats:
147
+ st.subheader("Graph Statistics")
148
 
149
  col1, col2, col3, col4 = st.columns(4)
150
+ col1.metric("Nodes", graph_stats.get("node_count", 0))
151
+ col2.metric("Edges", graph_stats.get("edge_count", 0))
152
+ col3.metric("Classes", graph_stats.get("class_count", 0))
153
+ col4.metric("Instances", graph_stats.get("instance_count", 0))
154
 
155
+ # Display central nodes
156
  if "central_nodes" in graph_stats and graph_stats["central_nodes"]:
157
  st.subheader("Central Nodes (by Betweenness Centrality)")
158
  central_nodes = graph_stats["central_nodes"]["betweenness"]
 
168
  nodes_df.append({
169
  "ID": node_id,
170
  "Name": name,
171
+ "Type": node_class,
172
  "Centrality": node_info["centrality"]
173
  })
174
 
 
177
  def run_ontology_structure_analysis():
178
  st.title("Ontology Structure Analysis")
179
 
180
+ # Use ontology statistics display function
181
  display_ontology_stats(ontology_manager)
182
 
183
+ # Add class hierarchy visualization
184
+ st.subheader("Class Hierarchy")
185
 
186
  # Get class hierarchy data
187
  class_hierarchy = ontology_manager.get_class_hierarchy()
 
197
  G.add_node(child)
198
  G.add_edge(parent, child)
199
 
200
+ # Check if there are enough nodes to create visualization
201
  if len(G.nodes) > 1:
202
  # Generate HTML visualization using knowledge graph class
203
  kg = KnowledgeGraph(ontology_manager)
204
+
205
+ # Use built-in layout algorithm
206
  html = kg.generate_html_visualization(
207
  include_classes=True,
208
  include_instances=False,
209
  max_distance=5,
210
+ layout_algorithm="hierarchical" # Use the built-in hierarchical layout
211
  )
212
 
213
+ # Render HTML
214
  render_html_in_streamlit(html)
215
+
216
+ # Add extra tree view for each root node
217
+ with st.expander("Node Tree View", expanded=False):
218
+ # Find root nodes (nodes without parent nodes)
219
+ roots = [n for n in G.nodes() if G.in_degree(n) == 0]
220
+
221
+ # Display tree structure for each root node
222
+ for root in roots:
223
+ st.markdown(f"### Root Node: {root}")
224
+
225
+ # Recursively display child nodes
226
+ def display_tree(node, depth=0):
227
+ children = list(G.successors(node))
228
+ if children:
229
+ for child in sorted(children):
230
+ st.markdown(" " * depth * 4 + f"- {child}")
231
+ display_tree(child, depth + 1)
232
+
233
+ display_tree(root)
234
+ st.markdown("---")
235
 
236
  def run_entity_exploration():
237
  st.title("Entity Exploration")
 
244
  # Remove duplicates and sort
245
  entities = sorted(set(entities))
246
 
247
+ # Create a dropdown selection box
248
+ selected_entity = st.selectbox("Select Entity", entities)
249
 
250
  if selected_entity:
251
  # Get entity information
 
255
  display_entity_details(entity_info, ontology_manager)
256
 
257
  # Set this entity as the central entity (for knowledge graph visualization)
258
+ if st.button("View this Entity in the Knowledge Graph"):
259
  st.session_state.central_entity = selected_entity
260
  st.rerun()
261
 
262
  # Get and display entity neighbors
263
  st.subheader("Entity Neighborhood")
264
+ max_distance = st.slider("Maximum Neighborhood Distance", 1, 3, 1)
265
 
266
  neighborhood = knowledge_graph.get_entity_neighborhood(
267
  selected_entity,
 
275
  neighbors_at_distance = [n for n in neighborhood["neighbors"] if n["distance"] == distance]
276
 
277
  if neighbors_at_distance:
278
+ with st.expander(f"Neighbors at Distance {distance} ({len(neighbors_at_distance)})"):
279
  for neighbor in neighbors_at_distance:
280
  st.markdown(f"**{neighbor['id']}** ({neighbor.get('class_type', 'unknown')})")
281
 
 
301
  col1, col2 = st.columns(2)
302
 
303
  with col1:
304
+ source_entity = st.selectbox("Select Source Entity", entities, key="source")
305
 
306
  with col2:
307
+ target_entity = st.selectbox("Select Target Entity", entities, key="target")
308
 
309
  if source_entity and target_entity and source_entity != target_entity:
310
  # Provide a maximum path length option
311
+ max_length = st.slider("Maximum Path Length", 1, 5, 3)
312
 
313
+ # Find paths
314
  paths = knowledge_graph.find_paths_between_entities(
315
  source_entity,
316
  target_entity,
 
318
  )
319
 
320
  if paths:
321
+ st.success(f"Found {len(paths)} paths!")
322
 
323
  # Create expanders for each path
324
  for i, path in enumerate(paths):
325
+ # Calculate path length and relationship types
326
  path_length = len(path)
327
  rel_types = [edge["type"] for edge in path]
328
 
329
+ with st.expander(f"Path {i+1} (Length: {path_length}, Relations: {', '.join(rel_types)})", expanded=(i==0)):
330
  # Create a text description of the path
331
  path_text = []
332
  entities_in_path = []
 
339
  entities_in_path.append(source)
340
  entities_in_path.append(target)
341
 
342
+ # Get entity information to get a readable name
343
  source_info = ontology_manager.get_entity_info(source)
344
  target_info = ontology_manager.get_entity_info(target)
345
 
 
367
  # Display path visualization
368
  visualize_path(path_info, ontology_manager)
369
  else:
370
+ st.warning(f"No paths of length {max_length} or shorter were found between these entities.")
371
 
372
  def run_reasoning_trace():
373
+ st.title("Reasoning Trace Visualization")
374
 
375
  if not st.session_state.get("query") or not st.session_state.get("retrieved_docs") or not st.session_state.get("answer"):
376
+ st.warning("Please run a query on the RAG comparison page first to generate reasoning trace data.")
377
  return
378
 
379
  # Get data from session state
 
381
  retrieved_docs = st.session_state.retrieved_docs
382
  answer = st.session_state.answer
383
 
384
+ # Show reasoning trace
385
  display_reasoning_trace(query, retrieved_docs, answer, ontology_manager)
386
 
387
  def run_detailed_comparison():
388
+ st.title("Detailed Comparison of RAG Methods")
389
 
390
  # Add comparison query options
391
  comparison_queries = [
 
397
  ]
398
 
399
  selected_query = st.selectbox(
400
+ "Select Comparison Query",
401
  comparison_queries,
402
  index=0
403
  )
 
409
  else:
410
  query = selected_query
411
 
412
+ if st.button("Compare RAG Methods"):
413
+ with st.spinner("Running detailed comparison..."):
414
  # Start timing
415
  import time
416
  start_time = time.time()
 
429
  vector_answer = vector_response.choices[0].message.content
430
  vector_time = time.time() - start_time
431
 
432
+ # Reset timer
433
  start_time = time.time()
434
 
435
+ # Run ontology-enhanced RAG
436
  result = semantic_retriever.retrieve_with_paths(query, k=k_val)
437
  retrieved_docs = result["documents"]
438
  enhanced_context = "\n\n".join([doc.page_content for doc in retrieved_docs])
 
447
  enhanced_answer = enhanced_response.choices[0].message.content
448
  enhanced_time = time.time() - start_time
449
 
450
+ # Save results for visualization
451
  st.session_state.query = query
452
  st.session_state.retrieved_docs = retrieved_docs
453
  st.session_state.answer = enhanced_answer
454
 
455
+ # Display comparison results
456
+ st.subheader("Comparison Results")
457
 
458
+ # Use tabs to show different aspects of comparison
459
+ tab1, tab2, tab3, tab4 = st.tabs(["Answer Comparison", "Performance Metrics", "Retrieval Source Comparison", "Context Quality"])
460
 
461
  with tab1:
462
  col1, col2 = st.columns(2)
463
 
464
  with col1:
465
+ st.markdown("#### Traditional RAG Answer")
466
  st.write(vector_answer)
467
 
468
  with col2:
469
+ st.markdown("#### Ontology-Enhanced RAG Answer")
470
  st.write(enhanced_answer)
471
 
472
  with tab2:
473
+ # Performance metrics
474
  col1, col2 = st.columns(2)
475
 
476
  with col1:
477
+ st.metric("Traditional RAG Response Time", f"{vector_time:.2f} seconds")
478
 
479
+ # Calculate text metrics
480
  vector_tokens = len(vector_context.split())
481
+ st.metric("Retrieved Context Tokens", vector_tokens)
482
 
483
+ st.metric("Retrieved Documents", len(vector_docs))
484
 
485
  with col2:
486
+ st.metric("Ontology-Enhanced RAG Response Time", f"{enhanced_time:.2f} seconds")
487
 
488
+ # Calculate text metrics
489
  enhanced_tokens = len(enhanced_context.split())
490
+ st.metric("Retrieved Context Tokens", enhanced_tokens)
491
 
492
+ st.metric("Retrieved Documents", len(retrieved_docs))
493
 
494
+ # Add chart
495
  import pandas as pd
496
  import plotly.express as px
497
 
498
  # Performance comparison chart
499
  performance_data = {
500
+ "Metrics": ["Response Time (seconds)", "Context Tokens", "Retrieved Documents"],
501
  "Traditional RAG": [vector_time, vector_tokens, len(vector_docs)],
502
+ "Ontology-Enhanced RAG": [enhanced_time, enhanced_tokens, len(retrieved_docs)]
503
  }
504
 
505
  df = pd.DataFrame(performance_data)
 
507
  # Plotly bar chart
508
  fig = px.bar(
509
  df,
510
+ x="Metrics", # Fixed column name
511
+ y=["Traditional RAG", "Ontology-Enhanced RAG"],
512
  barmode="group",
513
+ title="Performance Metrics Comparison",
514
+ labels={"value": "Value", "variable": "RAG Method"}
515
  )
516
 
517
+ st.plotly_chart(fig, use_container_width=True)
518
 
519
  with tab3:
520
+ # Retrieval source comparison
521
+ traditional_sources = ["Traditional Vector Retrieval"] * len(vector_docs)
522
 
523
  enhanced_sources = []
524
  for doc in retrieved_docs:
525
  source = doc.metadata.get("source", "unknown")
526
  label = {
527
+ "ontology": "Ontology Context",
528
+ "text": "Text Context",
529
+ "ontology_context": "Semantic Context",
530
+ "semantic_path": "Relationship Path"
531
+ }.get(source, "Unknown Source")
532
  enhanced_sources.append(label)
533
 
534
+ # Create source distribution chart
535
  source_counts = {}
536
  for source in enhanced_sources:
537
  if source in source_counts:
 
540
  source_counts[source] = 1
541
 
542
  source_df = pd.DataFrame({
543
+ "Source Type": list(source_counts.keys()),
544
+ "Document Count": list(source_counts.values())
545
  })
546
 
547
  fig = px.pie(
548
  source_df,
549
+ values="Document Count",
550
+ names="Source Type",
551
+ title="Ontology-Enhanced RAG Retrieval Source Distribution"
552
  )
553
 
554
+ st.plotly_chart(fig, use_container_width=True)
555
 
556
+ # Show source-answer relationship
557
+ st.subheader("Relationship Between Sources and Answer")
558
  st.markdown("""
559
  Ontology-enhanced methods leverage multiple sources of knowledge to construct more comprehensive answers. The figure above shows the distribution of different sources.
560
 
561
+ In particular, semantic context and relationship paths provide knowledge that cannot be captured by traditional vector retrieval, enabling the system to connect concepts and perform multi-hop reasoning.
562
  """)
563
 
564
  with tab4:
565
+ # Context quality assessment
566
+ st.subheader("Context Quality Assessment")
567
 
568
+ # Create evaluation function (simplified)
569
  def evaluate_context(docs):
570
  metrics = {
571
  "Direct Relevance": 0,
 
579
 
580
  # Direct Relevance - Based on Keywords
581
  if any(kw in content.lower() for kw in query.lower().split()):
582
+ metrics["Direct Relevance"] += 1 # Fixed key name
583
 
584
  # Semantic richness - based on text length
585
+ metrics["Semantic Richness"] += min(1, len(content.split()) / 50) # Fixed key name
586
 
587
+ # Structural information - from ontology
588
  if hasattr(doc, "metadata") and doc.metadata.get("source") in ["ontology", "ontology_context"]:
589
  metrics["Structure Information"] += 1
590
 
591
  # Relationship information - from path
592
  if hasattr(doc, "metadata") and doc.metadata.get("source") == "semantic_path":
593
+ metrics["Relationship Information"] += 1 # Fixed key name
594
 
595
  # Standardization
596
  for key in metrics:
 
598
 
599
  return metrics
600
 
601
+ # Evaluate both methods
602
  vector_metrics = evaluate_context(vector_docs)
603
  enhanced_metrics = evaluate_context(retrieved_docs)
604
 
605
+ # Create comparative radar chart
606
  metrics_df = pd.DataFrame({
607
  "metrics": list(vector_metrics.keys()),
608
  "Traditional RAG": list(vector_metrics.values()),
609
+ "Ontology-Enhanced RAG": list(enhanced_metrics.values())
610
  })
611
 
612
  # Convert data to Plotly radar chart format
613
  fig = px.line_polar(
614
  metrics_df,
615
+ r=["Traditional RAG", "Ontology-Enhanced RAG"],
616
+ theta="metrics", # Fixed column name
617
  line_close=True,
618
  range_r=[0, 10],
619
+ title="Context Quality Comparison"
620
  )
621
 
622
+ st.plotly_chart(fig, use_container_width=True)
623
 
624
  st.markdown("""
625
+ The figure above shows a comparison of the two RAG methods in terms of context quality. Ontology-enhanced RAG performs better in multiple dimensions:
626
+
627
+ 1. **Direct Relevance**: The degree of relevance between the retrieved content and the query
628
+ 2. **Semantic Richness**: Information density and richness of the retrieval context
629
+ 3. **Structural Information**: Structured knowledge of entity types, attributes, and relationships
630
+ 4. **Relationship Information**: Explicit relationships and connection paths between entities
631
+
632
+ The advantage of ontology-enhanced RAG is that it can retrieve structured knowledge and relational information, which are missing in traditional RAG methods.
633
+ """)
634
+
635
+ # Display detailed analysis section
636
+ st.subheader("Method Effectiveness Analysis")
637
+
638
+ with st.expander("Comparison of Advantages and Disadvantages", expanded=True):
639
+ col1, col2 = st.columns(2)
640
 
641
+ with col1:
642
+ st.markdown("#### Traditional RAG")
643
+ st.markdown("""
644
+ **Advantages**:
645
+ - Simple implementation and light computational burden
646
+ - Works well with unstructured text
647
+ - Response times are usually faster
648
+
649
+ **Disadvantages**:
650
+ - Unable to capture relationships between entities
651
+ - Lack of context for structured knowledge
652
+ - Difficult to perform multi-hop reasoning
653
+ - Retrieval is mainly based on text similarity
654
+ """)
655
 
656
+ with col2:
657
+ st.markdown("#### Ontology Enhanced RAG")
658
+ st.markdown("""
659
+ **Advantages**:
660
+ - Ability to understand relationships and connections between entities
661
+ - Provides rich structured knowledge context
662
+ - Support multi-hop reasoning and path discovery
663
+ - Combining vector similarity and semantic relationship
664
+
665
+ **Disadvantages**:
666
+ - Higher implementation complexity
667
+ - Need to maintain the ontology model
668
+ - The computational overhead is relatively high
669
+ - Retrieval and inference times may be longer
670
+ """)
671
 
672
+ # Add usage scenario suggestions
673
+ with st.expander("Applicable Scenarios"):
674
  st.markdown("""
675
+ ### Traditional RAG Applicable Scenarios
676
+
677
+ - Simple fact-finding
678
+ - Unstructured document retrieval
679
+ - Applications with high response time requirements
680
+ - When the document content is clear and direct
681
+
682
+ ### Applicable Scenarios for Ontology Enhanced RAG
683
+
684
+ - Complex knowledge association query
685
+ - Problems that require understanding of relationships between entities
686
+ - Applications that require cross-domain reasoning
687
+ - Enterprise Knowledge Management System
688
+ - Reasoning scenarios that require high accuracy and consistency
689
+ - Applications that require implicit knowledge discovery
690
  """)
691
+
692
+ # Add practical application examples
693
+ with st.expander("Application Case Studies"):
694
  st.markdown("""
695
+ ### Enterprise Knowledge Management
696
+ Ontology-enhanced RAG systems can help enterprises effectively organize and access their knowledge assets, connect information in different departments and systems, and provide more comprehensive business insights.
697
+
698
+ ### Product Development Decision Support
699
+ By understanding the relationship between customer feedback, product features, and market data, the system can provide more valuable support for product development decisions.
700
+
701
+ ### Complex Compliance Queries
702
+ In compliance problems that require consideration of multiple rules and relationships, ontology-enhanced RAG can provide rule-based reasoning, ensuring that recommendations comply with all applicable policies and regulations.
703
+
704
+ ### Diagnostics and Troubleshooting
705
+ In technical support and troubleshooting scenarios, the system can connect symptoms, causes, and solutions to provide more accurate diagnoses through multi-hop reasoning.
706
  """)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
707
 
708
+ if __name__ == "__main__":
709
+ main()
710
+