From 74e955aa592a9ba436293004be3d1e2bbdd1f88e Mon Sep 17 00:00:00 2001 From: yuxz Date: Fri, 26 Sep 2025 11:10:04 +0800 Subject: [PATCH] fix: update documentation for hypergraph visualization --- docs/examples/basic-usage.md | 119 +++++++++++++++-------------- docs/getting-started/quickstart.md | 23 +++--- docs/index.md | 14 ++-- 3 files changed, 78 insertions(+), 78 deletions(-) diff --git a/docs/examples/basic-usage.md b/docs/examples/basic-usage.md index fa926b5..d279ddd 100644 --- a/docs/examples/basic-usage.md +++ b/docs/examples/basic-usage.md @@ -133,25 +133,25 @@ def find_frequently_bought_together(product_id, min_frequency=2): """Find products frequently bought together with the given product.""" # Find all shopping sessions containing this product sessions_with_product = hg.nbr_e_of_v(product_id) - + # Count co-occurrences co_occurrence = defaultdict(int) for session in sessions_with_product: other_products = hg.nbr_v_of_e(session) - {product_id} for other_product in other_products: co_occurrence[other_product] += 1 - + # Filter by minimum frequency - recommendations = {product: count for product, count in co_occurrence.items() - if count >= min_frequency} - + recommendations = {product: count for product, count in co_occurrence.items() if count >= min_frequency} + return sorted(recommendations.items(), key=lambda x: x[1], reverse=True) + # Generate recommendations laptop_recommendations = find_frequently_bought_together("laptop_1") print("Products frequently bought with Gaming Laptop:") for product, frequency in laptop_recommendations: - product_name = hg.v[product]["name"] + product_name = hg.v(product)["name"] print(f" {product_name}: {frequency} times") # Find most popular product categories @@ -159,12 +159,14 @@ category_popularity = defaultdict(int) for edge in hg.all_e: products_in_session = hg.nbr_v_of_e(edge) for product in products_in_session: - category = hg.v[product]["category"] + category = hg.v(product)["category"] category_popularity[category] += 1 print("\nCategory popularity:") for category, count in sorted(category_popularity.items(), key=lambda x: x[1], reverse=True): print(f" {category}: {count} purchases") + +hg.draw() ``` ## Example 3: Social Network Group Analysis @@ -173,6 +175,7 @@ Analyze group dynamics in social networks: ```python from hyperdb import HypergraphDB +from collections import defaultdict # Create social network hg = HypergraphDB() @@ -186,7 +189,7 @@ people = { 5: {"name": "Eve", "age": 27, "city": "Austin", "interests": ["art", "food"]}, 6: {"name": "Frank", "age": 35, "city": "Chicago", "interests": ["sports", "food"]}, 7: {"name": "Grace", "age": 29, "city": "Portland", "interests": ["travel", "music"]}, - 8: {"name": "Henry", "age": 31, "city": "Denver", "interests": ["tech", "art"]} + 8: {"name": "Henry", "age": 31, "city": "Denver", "interests": ["tech", "art"]}, } for person_id, info in people.items(): @@ -197,69 +200,70 @@ activities = [ # Small groups ((1, 2), {"type": "coffee_meeting", "location": "Cafe Central", "date": "2024-01-10"}), ((3, 5), {"type": "art_gallery", "location": "MoMA", "date": "2024-01-12"}), - - # Medium groups + # Medium groups ((1, 2, 4), {"type": "tech_meetup", "location": "TechHub", "date": "2024-01-15"}), ((3, 5, 7), {"type": "music_concert", "location": "Music Hall", "date": "2024-01-18"}), ((2, 6), {"type": "sports_game", "location": "Stadium", "date": "2024-01-20"}), - # Large groups ((1, 2, 3, 4, 5), {"type": "birthday_party", "location": "Alice's House", "date": "2024-01-25"}), ((4, 6, 7, 8), {"type": "travel_planning", "location": "Online", "date": "2024-01-28"}), - # Very large group - ((1, 2, 3, 4, 5, 6, 7, 8), {"type": "company_picnic", "location": "Central Park", "date": "2024-02-01"}) + ((1, 2, 3, 4, 5, 6, 7, 8), {"type": "company_picnic", "location": "Central Park", "date": "2024-02-01"}), ] for participants, activity_info in activities: hg.add_e(participants, activity_info) + # Social network analysis def analyze_social_network(hg): """Analyze the social network structure.""" - + # Find most social person (highest degree) most_social = max(hg.all_v, key=lambda v: hg.degree_v(v)) - print(f"Most social person: {hg.v(most_social)['name']} " - f"(participates in {hg.degree_v(most_social)} activities)") - + print( + f"Most social person: {hg.v(most_social)['name']} " f"(participates in {hg.degree_v(most_social)} activities)" + ) + # Analyze group sizes group_sizes = [hg.degree_e(e) for e in hg.all_e] avg_group_size = sum(group_sizes) / len(group_sizes) print(f"Average group size: {avg_group_size:.1f}") print(f"Largest group: {max(group_sizes)} people") print(f"Smallest group: {min(group_sizes)} people") - + # Find common interest groups interest_groups = defaultdict(set) for edge in hg.all_e: participants = hg.nbr_v_of_e(edge) # Find common interests if len(participants) >= 2: - common_interests = set(hg.v[list(participants)[0]]["interests"]) + common_interests = set(hg.v(list(participants)[0])["interests"]) for person in participants: - common_interests &= set(hg.v[person]["interests"]) - + common_interests &= set(hg.v(person)["interests"]) + for interest in common_interests: interest_groups[interest].update(participants) - + print("\nInterest-based communities:") for interest, community in interest_groups.items(): if len(community) >= 3: # Only show communities with 3+ people - names = [hg.v[person]["name"] for person in community] + names = [hg.v(person)["name"] for person in community] print(f" {interest}: {', '.join(names)}") + analyze_social_network(hg) + # Find bridges (people who connect different groups) def find_bridges(hg): """Find people who act as bridges between groups.""" bridges = [] - + for person in hg.all_v: # Get all groups this person participates in person_groups = hg.nbr_e_of_v(person) - + if len(person_groups) >= 2: # Person is in multiple groups # Check if removing this person would disconnect the groups other_connections = 0 @@ -267,21 +271,22 @@ def find_bridges(hg): for group2 in person_groups: if group1 != group2: # Check if groups share other members - group1_members = hg.N_v_of_e(group1) - {person} - group2_members = hg.N_v_of_e(group2) - {person} + group1_members = set(hg.nbr_v_of_e(group1)) - {person} + group2_members = set(hg.nbr_v_of_e(group2)) - {person} if group1_members & group2_members: other_connections += 1 break - + if other_connections < len(person_groups) - 1: bridges.append(person) - + return bridges + bridges = find_bridges(hg) print(f"\nBridge people (connect different groups):") for bridge in bridges: - name = hg.v[bridge]["name"] + name = hg.v(bridge)["name"] num_groups = hg.degree_v(bridge) print(f" {name} (connects {num_groups} groups)") @@ -305,19 +310,16 @@ entities = { "einstein": {"type": "person", "name": "Albert Einstein", "birth": 1879, "death": 1955}, "curie": {"type": "person", "name": "Marie Curie", "birth": 1867, "death": 1934}, "newton": {"type": "person", "name": "Isaac Newton", "birth": 1642, "death": 1727}, - # Concepts "relativity": {"type": "theory", "name": "Theory of Relativity", "year": 1915}, "radioactivity": {"type": "phenomenon", "name": "Radioactivity", "discovered": 1896}, "gravity": {"type": "force", "name": "Gravitational Force", "discovered": 1687}, - # Institutions "princeton": {"type": "university", "name": "Princeton University", "founded": 1746}, "sorbonne": {"type": "university", "name": "University of Paris", "founded": 1150}, - # Awards "nobel_physics": {"type": "award", "name": "Nobel Prize in Physics"}, - "nobel_chemistry": {"type": "award", "name": "Nobel Prize in Chemistry"} + "nobel_chemistry": {"type": "award", "name": "Nobel Prize in Chemistry"}, } for entity_id, info in entities.items(): @@ -329,78 +331,76 @@ relationships = [ (("einstein", "relativity"), {"relation": "developed", "year": 1915}), (("curie", "radioactivity"), {"relation": "studied", "significance": "pioneering"}), (("newton", "gravity"), {"relation": "discovered", "year": 1687}), - - # Person-Institution relationships + # Person-Institution relationships (("einstein", "princeton"), {"relation": "worked_at", "period": "1933-1955"}), (("curie", "sorbonne"), {"relation": "studied_at", "degree": "PhD"}), - # Award relationships (("einstein", "nobel_physics"), {"relation": "won", "year": 1921, "for": "photoelectric effect"}), (("curie", "nobel_physics"), {"relation": "won", "year": 1903, "shared_with": "Pierre Curie"}), (("curie", "nobel_chemistry"), {"relation": "won", "year": 1911, "first_woman": True}), - # Complex multi-way relationships - (("einstein", "curie", "nobel_physics"), { - "relation": "both_won", - "significance": "two great physicists" - }), - (("relativity", "gravity", "newton", "einstein"), { - "relation": "theory_evolution", - "description": "Newton's gravity evolved into Einstein's relativity" - }) + (("einstein", "curie", "nobel_physics"), {"relation": "both_won", "significance": "two great physicists"}), + ( + ("relativity", "gravity", "newton", "einstein"), + {"relation": "theory_evolution", "description": "Newton's gravity evolved into Einstein's relativity"}, + ), ] for entities_in_rel, rel_info in relationships: kg.add_e(entities_in_rel, rel_info) + # Knowledge graph queries def find_related_entities(entity_id, relation_type=None): """Find all entities related to the given entity.""" related = set() - + # Get all relationships involving this entity - for edge in kg.N_e(entity_id): - edge_info = kg.e[edge] - + for edge in kg.nbr_e_of_v(entity_id): + edge_info = kg.e(edge) + # Filter by relation type if specified if relation_type and edge_info.get("relation") != relation_type: continue - + # Add all other entities in this relationship - other_entities = kg.N_v_of_e(edge) - {entity_id} + other_entities = kg.nbr_v_of_e(edge) - {entity_id} related.update(other_entities) - + return related + # Find entities related to Einstein einstein_related = find_related_entities("einstein") print("Entities related to Einstein:") for entity in einstein_related: - entity_info = kg.v[entity] + entity_info = kg.v(entity) print(f" {entity_info['name']} ({entity_info['type']})") # Find award winners award_winners = find_related_entities("nobel_physics", "won") print(f"\nNobel Physics winners in our graph:") for winner in award_winners: - winner_info = kg.v[winner] + winner_info = kg.v(winner) print(f" {winner_info['name']}") # Find theory developers print(f"\nTheory developers:") for theory in ["relativity", "radioactivity"]: developers = find_related_entities(theory, "developed") | find_related_entities(theory, "studied") - theory_name = kg.v[theory]["name"] - developer_names = [kg.v[dev]["name"] for dev in developers] + theory_name = kg.v(theory)["name"] + developer_names = [kg.v(dev)["name"] for dev in developers] print(f" {theory_name}: {', '.join(developer_names)}") # Visualize the knowledge graph kg.draw() + ``` ## Tips for Effective Usage ### 1. Choose Meaningful IDs + ```python # Good: descriptive IDs hg.add_v("user_123", {"name": "Alice"}) @@ -412,6 +412,7 @@ hg.add_v(2, {"name": "Gaming Laptop"}) ``` ### 2. Use Rich Attributes + ```python # Rich attributes provide more analysis possibilities hg.add_v("paper_001", { @@ -426,10 +427,11 @@ hg.add_v("paper_001", { ``` ### 3. Leverage Hypergraph Structure + ```python # Instead of multiple binary edges: hg.add_e((1, 2), {"type": "collaboration"}) -hg.add_e((1, 3), {"type": "collaboration"}) +hg.add_e((1, 3), {"type": "collaboration"}) hg.add_e((2, 3), {"type": "collaboration"}) # Use a single hyperedge for group relationships: @@ -437,6 +439,7 @@ hg.add_e((1, 2, 3), {"type": "collaboration", "project": "AI Research"}) ``` ### 4. Plan for Analysis + ```python # Add metadata that supports your analysis goals hg.add_e((author1, author2, author3), { diff --git a/docs/getting-started/quickstart.md b/docs/getting-started/quickstart.md index dd73dd2..1eabfcd 100644 --- a/docs/getting-started/quickstart.md +++ b/docs/getting-started/quickstart.md @@ -105,10 +105,11 @@ Visualize your hypergraph in a web browser: ```python # This opens an interactive visualization in your default browser -hg.show() +hg.draw() ``` The visualization will show: + - **Vertices** as nodes with their attributes - **Hyperedges** connecting multiple vertices - **Interactive features** for exploring the structure @@ -122,9 +123,9 @@ from hyperdb import HypergraphDB def create_research_collaboration_network(): """Create a hypergraph representing research collaborations.""" - + hg = HypergraphDB() - + # Add researchers researchers = { 1: {"name": "Dr. Alice", "field": "ML", "university": "MIT"}, @@ -133,10 +134,10 @@ def create_research_collaboration_network(): 4: {"name": "Dr. Diana", "field": "Robotics", "university": "Berkeley"}, 5: {"name": "Dr. Eve", "field": "Theory", "university": "Princeton"} } - + for id, info in researchers.items(): hg.add_v(id, info) - + # Add research papers (as hyperedges connecting collaborators) papers = [ ((1, 2), {"title": "Deep Learning for NLP", "year": 2023, "venue": "ICML"}), @@ -144,10 +145,10 @@ def create_research_collaboration_network(): ((2, 3, 4), {"title": "Multimodal AI", "year": 2024, "venue": "NeurIPS"}), ((1, 2, 3, 5), {"title": "AI Theory and Practice", "year": 2024, "venue": "JMLR"}) ] - + for authors, paper_info in papers: hg.add_e(authors, paper_info) - + return hg # Create the network @@ -166,7 +167,7 @@ collab_size = research_hg.d_e(largest_collab) print(f"Largest collaboration has {collab_size} authors") # Visualize the research network -research_hg.show() +research_hg.draw() ``` ## Next Steps @@ -204,8 +205,4 @@ hg.add_e((1, 2, 3), {"type": "collaboration", "start": "2023-07", "end": "2024-0 hg.add_e((1, 2, 3), {"type": "project", "weight": 0.8, "importance": "high"}) ``` -!!! tip "Performance Tips" - - Use meaningful vertex and edge IDs for easier debugging - - Batch operations when adding many vertices/edges - - Use `show()` periodically to visualize and understand your data structure - - Save your work frequently with `save()` method +!!! tip "Performance Tips" - Use meaningful vertex and edge IDs for easier debugging - Batch operations when adding many vertices/edges - Use `draw()` periodically to visualize and understand your data structure - Save your work frequently with `save()` method diff --git a/docs/index.md b/docs/index.md index 7551110..d27df82 100644 --- a/docs/index.md +++ b/docs/index.md @@ -31,11 +31,11 @@ Hypergraph-DB is a lightweight, flexible, and Python-based database designed to Hypergraph-DB is designed for efficiency. Here are some performance benchmarks: -| Vertices | Hyperedges | Add Vertices | Add Edges | Query Time | Total Time | -|----------|------------|--------------|-----------|------------|------------| -| 100,000 | 20,000 | 0.12s | 0.17s | 0.04s | 0.58s | -| 500,000 | 100,000 | 0.85s | 1.07s | 0.22s | 3.34s | -| 1,000,000| 200,000 | 1.75s | 1.82s | 0.51s | 6.60s | +| Vertices | Hyperedges | Add Vertices | Add Edges | Query Time | Total Time | +| --------- | ---------- | ------------ | --------- | ---------- | ---------- | +| 100,000 | 20,000 | 0.12s | 0.17s | 0.04s | 0.58s | +| 500,000 | 100,000 | 0.85s | 1.07s | 0.22s | 3.34s | +| 1,000,000 | 200,000 | 1.75s | 1.82s | 0.51s | 6.60s | ## 🚀 Quick Start @@ -67,13 +67,13 @@ print(f"Vertices: {hg.all_v}") print(f"Edges: {hg.all_e}") # Visualize the hypergraph -hg.show() # Opens visualization in web browser +hg.draw() # Opens visualization in web browser ``` ## 📚 Documentation - **[Getting Started](getting-started/installation.md)**: Installation and basic setup -- **[API Reference](api/index.md)**: Complete API documentation +- **[API Reference](api/index.md)**: Complete API documentation - **[Visualization Guide](visualization/index.md)**: Interactive hypergraph visualization - **[Examples](examples/basic-usage.md)**: Practical examples and tutorials