neo4j – chatgpz.de – KI-Tools & Praxiswissen https://chatgpz.de Unabhängige Tests, Anleitungen und Hintergründe zu KI-Tools. Wed, 22 Oct 2025 15:50:10 +0000 de-DE hourly 1 https://wordpress.org/?v=6.4.2 234900186 Implementierung der DRIFT-Suche mit Neo4j und LlamaIndex https://chatgpz.de/machine-learning/implementierung-der-drift-suche-mit-neo4j-und-llamaindex/ https://chatgpz.de/machine-learning/implementierung-der-drift-suche-mit-neo4j-und-llamaindex/#respond Wed, 22 Oct 2025 15:50:10 +0000 http://chatgpz.de/machine-learning/implementierung-der-drift-suche-mit-neo4j-und-llamaindex/ [ad_1]

Die GraphRAG-Implementierung von Microsoft warfare eines der ersten Systeme und führte viele revolutionary Funktionen ein. Es kombiniert sowohl die Indizierungsphase, in der Entitäten, Beziehungen und hierarchische Gemeinschaften extrahiert und zusammengefasst werden, mit erweiterten Abfragezeitfunktionen. Dieser Ansatz ermöglicht es dem System, umfassende, thematische Fragen zu beantworten, indem es vorberechnete Entitäts-, Beziehungs- und Group-Zusammenfassungen nutzt und so über die herkömmlichen Einschränkungen beim Abrufen von Dokumenten von Commonplace-RAG-Systemen hinausgeht.

Die GraphRAG-Pipeline von Microsoft. Bild von (Edge et al., 2024), lizenziert unter CC BY 4.0.

Ich habe die Indizierungsphase sowie globale und lokale Suchmechanismen in früheren Blogbeiträgen behandelt (Hier Und Hier), daher überspringen wir diese Particulars in dieser Diskussion. Allerdings haben wir es noch nicht erkundet DRIFT-Suchedas im Mittelpunkt dieses Blogbeitrags stehen wird. DRIFT ist ein neuerer Ansatz, der Merkmale sowohl globaler als auch lokaler Suchmethoden kombiniert. Die Technik beginnt mit der Nutzung von Group-Informationen durch Vektorsuche, um einen breiten Ausgangspunkt für Abfragen zu schaffen, und nutzt diese Group-Einblicke dann, um die ursprüngliche Frage in detaillierte Folgeabfragen zu verfeinern. Dadurch kann DRIFT den Wissensgraphen dynamisch durchlaufen, um spezifische Informationen über Entitäten, Beziehungen und andere lokalisierte Particulars abzurufen und so Recheneffizienz mit umfassender Antwortqualität in Einklang zu bringen.

Drift-Suchimplementierung mit LlamaIndex-Workflows und Neo4j. Bild vom Autor.

Die Implementierung verwendet LlamaIndex-Workflows um den DRIFT-Suchprozess durch mehrere Schlüsselschritte zu orchestrieren. Es beginnt mit HyDE-GenerierungErstellen einer hypothetischen Antwort basierend auf einem Beispiel-Group-Bericht, um die Abfragedarstellung zu verbessern.

Der Group-Suchschritt Anschließend wird die Vektorähnlichkeit verwendet, um die relevantesten Group-Berichte zu identifizieren und so einen breiten Kontext für die Abfrage bereitzustellen. Das System analysiert diese Ergebnisse, um eine erste Zwischenantwort und eine Reihe von Folgeabfragen für eine tiefergehende Untersuchung zu generieren.

Diese Folgeabfragen werden während des Prozesses parallel ausgeführt Lokale Suchphaseum gezielte Informationen, einschließlich Textblöcke, Entitäten, Beziehungen und zusätzliche Group-Berichte, aus dem Wissensgraphen abzurufen. Dieser Prozess kann bis zu einer maximalen Tiefe iterieren, wobei jede Runde möglicherweise neue Folgeabfragen hervorbringt.

Schließlich ist die Antwortgenerierungsschritt fasst alle während des Prozesses gesammelten Zwischenantworten zusammen und kombiniert umfassende Erkenntnisse auf Group-Ebene mit detaillierten lokalen Erkenntnissen, um eine umfassende Antwort zu erstellen. Dieser Ansatz gleicht Breite und Tiefe aus, indem er weitestgehend mit dem Group-Kontext beginnt und nach und nach auf Einzelheiten eingeht.

Dies ist meine Implementierung der DRIFT-Suche, angepasst für LlamaIndex-Workflows und Neo4j. Ich habe den Ansatz rückentwickelt, indem ich den GraphRAG-Code von Microsoft untersucht habe, daher kann es einige Unterschiede zur ursprünglichen Implementierung geben.

Der Code ist verfügbar unter GitHub.

Datensatz

Für diesen Blogbeitrag verwenden wir Alices Abenteuer im Wunderland von Lewis Carroll, ein klassischer Textual content, der frei erhältlich ist bei Projekt Gutenberg. Dieser reichhaltige erzählerische Datensatz mit seinen miteinander verbundenen Charakteren, Orten und Ereignissen macht ihn zu einer hervorragenden Wahl für die Demonstration der Fähigkeiten von GraphRAG.

Einnahme

Für den Aufnahmeprozess verwenden wir die wieder Implementierung der Microsoft GraphRAG-Indizierung Ich habe für a entwickelt vorheriger Blogbeitragangepasst an einen LlamaIndex-Workflow.

Indexierungsworkflow. Bild vom Autor.

Die Aufnahmepipeline folgt dem Commonplace-GraphRAG-Ansatz mit drei Hauptphasen:

class MSGraphRAGIngestion(Workflow):
    @step
    async def entity_extraction(self, ev: StartEvent) -> EntitySummarization:
        chunks = splitter.split_text(ev.textual content)
        await ms_graph.extract_nodes_and_rels(chunks, ev.allowed_entities)
        return EntitySummarization()

    @step
    async def entity_summarization(
        self, ev: EntitySummarization
    ) -> CommunitySummarization:
        await ms_graph.summarize_nodes_and_rels()
        return CommunitySummarization()

    @step
    async def community_summarization(
        self, ev: CommunitySummarization
    ) -> CommunityEmbeddings:
        await ms_graph.summarize_communities()
        return CommunityEmbeddings()

Der Workflow extrahiert Entitäten und Beziehungen aus Textblöcken, generiert Zusammenfassungen sowohl für Knoten als auch für Beziehungen und erstellt dann hierarchische Group-Zusammenfassungen.

Nach der Zusammenfassung generieren wir Vektoreinbettungen sowohl für Communities als auch für Entitäten, um eine Ähnlichkeitssuche zu ermöglichen. Hier ist der Schritt zur Group-Einbettung:

@step
    async def community_embeddings(self, ev: CommunityEmbeddings) -> EntityEmbeddings:
        # Fetch all communities from the graph database
        communities = ms_graph.question(
            """
    MATCH (c:__Community__)
    WHERE c.abstract IS NOT NULL AND c.score > $min_community_rating
    RETURN coalesce(c.title, "") + " " + c.abstract AS community_description, c.id AS community_id
    """,
            params={"min_community_rating": MIN_COMMUNITY_RATING},
        )
        if communities:
            # Generate vector embeddings from group descriptions
            response = await shopper.embeddings.create(
                enter=(c("community_description") for c in communities),
                mannequin=TEXT_EMBEDDING_MODEL,
            )
            # Retailer embeddings within the graph and create vector index
            embeds = (
                {
                    "community_id": group("community_id"),
                    "embedding": embedding.embedding,
                }
                for group, embedding in zip(communities, response.knowledge)
            )
            ms_graph.question(
                """UNWIND $knowledge as row
            MATCH (c:__Community__ {id: row.community_id})
            CALL db.create.setNodeVectorProperty(c, 'embedding', row.embedding)""",
                params={"knowledge": embeds},
            )
            ms_graph.question(
                "CREATE VECTOR INDEX group IF NOT EXISTS FOR (c:__Community__) ON c.embedding"
            )
        return EntityEmbeddings()

Der gleiche Prozess wird auf Entitätseinbettungen angewendet, um die Vektorindizes zu erstellen, die für den ähnlichkeitsbasierten Abruf der DRIFT-Suche erforderlich sind.

DRIFT-Suche

Die DRIFT-Suche ist ein intuitiver Ansatz zum Abrufen von Informationen: Beginnen Sie damit, das Gesamtbild zu verstehen, und gehen Sie dann bei Bedarf in die Einzelheiten ein. Anstatt sofort nach genauen Übereinstimmungen auf Dokument- oder Entitätsebene zu suchen, konsultiert DRIFT zunächst Group-Zusammenfassungen, bei denen es sich um Übersichten auf hoher Ebene handelt, die die Hauptthemen und Themen innerhalb des Wissensgraphen erfassen.

Sobald DRIFT relevante Informationen auf höherer Ebene identifiziert, generiert es auf intelligente Weise Folgeabfragen, um genaue Informationen zu bestimmten Entitäten, Beziehungen und Quelldokumenten abzurufen. Dieser zweiphasige Ansatz spiegelt die natürliche Informationssuche des Menschen wider: Wir orientieren uns zunächst mit einem allgemeinen Überblick und stellen dann gezielte Fragen, um die Particulars zu ergänzen. Durch die Kombination der umfassenden Abdeckung der globalen Suche mit der Präzision der lokalen Suche erreicht DRIFT sowohl Breite als auch Tiefe, ohne dass der Rechenaufwand für die Verarbeitung jedes Group-Berichts oder Dokuments anfällt.

Lassen Sie uns jede Section der Implementierung durchgehen.

Der Code ist verfügbar unter GitHub.

Group-Suche

DRIFT verwendet HyDE (Hypothetical Doc Embeddings), um die Genauigkeit der Vektorsuche zu verbessern. Anstatt die Anfrage des Benutzers direkt einzubetten, generiert HyDE zunächst eine hypothetische Antwort und verwendet diese dann für die Ähnlichkeitssuche. Dies funktioniert, weil hypothetische Antworten semantisch näher an tatsächlichen Group-Zusammenfassungen liegen als reine Abfragen.

@step
async def hyde_generation(self, ev: StartEvent) -> CommunitySearch:
    # Fetch a random group report to make use of as a template for HyDE era
    random_community_report = driver.execute_query(
        """
    MATCH (c:__Community__)
    WHERE c.abstract IS NOT NULL
    RETURN coalesce(c.title, "") + " " + c.abstract AS community_description""",
        result_transformer_=lambda r: r.knowledge(),
    )
    # Generate a hypothetical reply to enhance question illustration
    hyde = HYDE_PROMPT.format(
        question=ev.question, template=random_community_report(0)("community_description")
    )
    hyde_response = await shopper.responses.create(
        mannequin="gpt-5-mini",
        enter=({"function": "person", "content material": hyde}),
        reasoning={"effort": "low"},
    )
    return CommunitySearch(question=ev.question, hyde_query=hyde_response.output_text)

Als nächstes betten wir die HyDE-Abfrage ein und rufen die fünf relevantesten Group-Berichte über Vektorähnlichkeit ab. Anschließend wird das LLM aufgefordert, aus diesen Berichten eine Zwischenantwort zu generieren und Folgefragen für eine tiefergehende Untersuchung zu identifizieren. Die Zwischenantwort wird gespeichert und alle Folgeanfragen werden parallel für die lokale Suchphase versendet.

@step
async def community_search(self, ctx: Context, ev: CommunitySearch) -> LocalSearch:
    # Create embedding from the HyDE-enhanced question
    embedding_response = await shopper.embeddings.create(
        enter=ev.hyde_query, mannequin=TEXT_EMBEDDING_MODEL
    )
    embedding = embedding_response.knowledge(0).embedding
    
    # Discover high 5 most related group studies by way of vector similarity
    community_reports = driver.execute_query(
        """
    CALL db.index.vector.queryNodes('group', 5, $embedding) YIELD node, rating
    RETURN 'community-' + node.id AS source_id, node.abstract AS community_summary
    """,
        result_transformer_=lambda r: r.knowledge(),
        embedding=embedding,
    )
    
    # Generate preliminary reply and establish what additional information is required
    initial_prompt = DRIFT_PRIMER_PROMPT.format(
        question=ev.question, community_reports=community_reports
    )
    initial_response = await shopper.responses.create(
        mannequin="gpt-5-mini",
        enter=({"function": "person", "content material": initial_prompt}),
        reasoning={"effort": "low"},
    )
    response_json = json_repair.hundreds(initial_response.output_text)
    print(f"Preliminary intermediate response: {response_json('intermediate_answer')}")
    
    # Retailer the preliminary reply and put together for parallel native searches
    async with ctx.retailer.edit_state() as ctx_state:
        ctx_state("intermediate_answers") = (
            {
                "intermediate_answer": response_json("intermediate_answer"),
                "rating": response_json("rating"),
            }
        )
        ctx_state("local_search_num") = len(response_json("follow_up_queries"))
    
    # Dispatch follow-up queries to run in parallel
    for local_query in response_json("follow_up_queries"):
        ctx.send_event(LocalSearch(question=ev.question, local_query=local_query))
    return None

Dies legt den Kernansatz von DRIFT fest: Beginnen Sie breit mit der durch HyDE erweiterten Group-Suche und gehen Sie dann mit gezielten Folgeabfragen weiter in die Tiefe.

Lokale Suche

In der lokalen Suchphase werden parallel Folgeabfragen ausgeführt, um einen Drilldown zu bestimmten Particulars durchzuführen. Jede Abfrage ruft den Zielkontext über eine entitätsbasierte Vektorsuche ab und generiert dann eine Zwischenantwort und möglicherweise weitere Folgeabfragen.

@step(num_workers=5)
async def local_search(self, ev: LocalSearch) -> LocalSearchResults:
    print(f"Operating native question: {ev.local_query}")
    
    # Create embedding for the native question
    response = await shopper.embeddings.create(
        enter=ev.local_query, mannequin=TEXT_EMBEDDING_MODEL
    )
    embedding = response.knowledge(0).embedding
    
    # Retrieve related entities and collect their related context:
    # - Textual content chunks the place entities are talked about
    # - Group studies the entities belong to
    # - Relationships between the retrieved entities
    # - Entity descriptions
    local_reports = driver.execute_query(
        """
CALL db.index.vector.queryNodes('entity', 5, $embedding) YIELD node, rating
WITH acquire(node) AS nodes
WITH
acquire {
  UNWIND nodes as n
  MATCH (n)<-(:MENTIONS)->(c:__Chunk__)
  WITH c, rely(distinct n) as freq
  RETURN {chunkText: c.textual content, source_id: 'chunk-' + c.id}
  ORDER BY freq DESC
  LIMIT 3
} AS text_mapping,
acquire {
  UNWIND nodes as n
  MATCH (n)-(:IN_COMMUNITY*)->(c:__Community__)
  WHERE c.abstract IS NOT NULL
  WITH c, c.score as rank
  RETURN {abstract: c.abstract, source_id: 'community-' + c.id}
  ORDER BY rank DESC
  LIMIT 3
} AS report_mapping,
acquire {
  UNWIND nodes as n
  MATCH (n)-(r:SUMMARIZED_RELATIONSHIP)-(m)
  WHERE m IN nodes
  RETURN {descriptionText: r.abstract, source_id: 'relationship-' + n.identify + '-' + m.identify}
  LIMIT 3
} as insideRels,
acquire {
  UNWIND nodes as n
  RETURN {descriptionText: n.abstract, source_id: 'node-' + n.identify}
} as entities
RETURN {Chunks: text_mapping, Experiences: report_mapping,
   Relationships: insideRels,
   Entities: entities} AS output
""",
        result_transformer_=lambda r: r.knowledge(),
        embedding=embedding,
    )
    
    # Generate reply based mostly on the retrieved context
    local_prompt = DRIFT_LOCAL_SYSTEM_PROMPT.format(
        response_type=DEFAULT_RESPONSE_TYPE,
        context_data=local_reports,
        global_query=ev.question,
    )
    local_response = await shopper.responses.create(
        mannequin="gpt-5-mini",
        enter=({"function": "person", "content material": local_prompt}),
        reasoning={"effort": "low"},
    )
    response_json = json_repair.hundreds(local_response.output_text)
    
    # Restrict follow-up queries to forestall exponential progress
    response_json("follow_up_queries") = response_json("follow_up_queries")(:LOCAL_TOP_K)
    
    return LocalSearchResults(outcomes=response_json, question=ev.question)

Der nächste Schritt orchestriert den iterativen Vertiefungsprozess. Es wartet darauf, dass alle parallelen Suchvorgänge mit abgeschlossen werden collect_eventsund entscheidet dann, ob der Drilldown fortgesetzt werden soll. Wenn die aktuelle Tiefe nicht das Most erreicht hat (wir verwenden maximale Tiefe = 2), werden Folgeabfragen aus allen Ergebnissen extrahiert, die Zwischenantworten gespeichert und die nächste Runde paralleler Suchvorgänge gestartet.

@step
async def local_search_results(
    self, ctx: Context, ev: LocalSearchResults
) -> LocalSearch | FinalAnswer:
    local_search_num = await ctx.retailer.get("local_search_num")
    
    # Await all parallel searches to finish
    outcomes = ctx.collect_events(ev, (LocalSearchResults) * local_search_num)
    if outcomes is None:
        return None
        
    intermediate_results = (
        {
            "intermediate_answer": occasion.outcomes("response"),
            "rating": occasion.outcomes("rating"),
        }
        for occasion in outcomes
    )
    current_depth = await ctx.retailer.get("local_search_depth", default=1)
    question = (ev.question for ev in outcomes)(0)

    # Proceed drilling down if we have not reached max depth
    if current_depth < MAX_LOCAL_SEARCH_DEPTH:
        await ctx.retailer.set("local_search_depth", current_depth + 1)
        follow_up_queries = (
            question
            for occasion in outcomes
            for question in occasion.outcomes("follow_up_queries")
        )
        
        # Retailer intermediate solutions and dispatch subsequent spherical of searches
        async with ctx.retailer.edit_state() as ctx_state:
            ctx_state("intermediate_answers").lengthen(intermediate_results)
            ctx_state("local_search_num") = len(follow_up_queries)

        for local_query in follow_up_queries:
            ctx.send_event(LocalSearch(question=question, local_query=local_query))
        return None
    else:
        return FinalAnswer(question=question)

Dadurch entsteht eine iterative Verfeinerungsschleife, in der jede Tiefenebene auf früheren Erkenntnissen aufbaut. Sobald die maximale Tiefe erreicht ist, wird die endgültige Antwortgenerierung ausgelöst.

Endgültige Antwort

Im letzten Schritt werden alle während des DRIFT-Suchprozesses gesammelten Zwischenantworten zu einer umfassenden Antwort zusammengefasst. Dazu gehören die erste Antwort aus der Group-Suche und alle Antworten, die während der lokalen Suchiterationen generiert wurden.

@step
async def final_answer_generation(self, ctx: Context, ev: FinalAnswer) -> StopEvent:
    # Retrieve all intermediate solutions collected all through the search course of
    intermediate_answers = await ctx.retailer.get("intermediate_answers")
    
    # Synthesize all findings right into a complete ultimate response
    answer_prompt = DRIFT_REDUCE_PROMPT.format(
        response_type=DEFAULT_RESPONSE_TYPE,
        context_data=intermediate_answers,
        global_query=ev.question,
    )
    answer_response = await shopper.responses.create(
        mannequin="gpt-5-mini",
        enter=(
            {"function": "developer", "content material": answer_prompt},
            {"function": "person", "content material": ev.question},
        ),
        reasoning={"effort": "low"},
    )

    return StopEvent(outcome=answer_response.output_text)

Zusammenfassung

Die DRIFT-Suche stellt eine interessante Strategie dar, um die Breite der globalen Suche mit der Präzision der lokalen Suche in Einklang zu bringen. Indem mit dem Kontext auf Group-Ebene begonnen und schrittweise iterative Folgeabfragen durchgeführt werden, wird der Rechenaufwand für die Verarbeitung aller Group-Berichte vermieden und gleichzeitig eine umfassende Abdeckung gewährleistet.

Es gibt jedoch Raum für mehrere Verbesserungen. Die aktuelle Implementierung behandelt alle Zwischenantworten gleich, aber eine Filterung basierend auf ihren Konfidenzwerten könnte die Qualität der endgültigen Antworten verbessern und Rauschen reduzieren. Ebenso könnten Folgeanfragen vor der Ausführung nach Relevanz oder potenziellem Informationsgewinn geordnet werden, um sicherzustellen, dass die vielversprechendsten Leads zuerst verfolgt werden.

Eine weitere vielversprechende Verbesserung wäre die Einführung eines Abfrageverfeinerungsschritts, der mithilfe eines LLM alle generierten Folgeabfragen analysiert, ähnliche gruppiert, um redundante Suchvorgänge zu vermeiden, und Abfragen herausfiltert, die wahrscheinlich keine nützlichen Informationen liefern. Dies könnte die Anzahl lokaler Suchen erheblich reduzieren und gleichzeitig die Antwortqualität beibehalten.

Die vollständige Implementierung ist verfügbar unter GitHub für diejenigen, die daran interessiert sind, mit diesen Verbesserungen zu experimentieren oder DRIFT für ihre eigenen Anwendungsfälle anzupassen.

[ad_2]

]]>
https://chatgpz.de/machine-learning/implementierung-der-drift-suche-mit-neo4j-und-llamaindex/feed/ 0 13378
Erste Schritte mit NEO4J: Installations- und Setup -Handbuch https://chatgpz.de/data-analytics/erste-schritte-mit-neo4j-installations-und-setup-handbuch/ https://chatgpz.de/data-analytics/erste-schritte-mit-neo4j-installations-und-setup-handbuch/#respond Wed, 13 Aug 2025 06:17:07 +0000 http://chatgpz.de/data-analytics/erste-schritte-mit-neo4j-installations-und-setup-handbuch/ [ad_1]

Erste Schritte mit NEO4J: Installations- und Setup -HandbuchErste Schritte mit NEO4J: Installations- und Setup -Handbuch
Bild von Editor | Chatgpt

# Einführung

Neo4j ist eine leistungsstarke Datenbank, die mit verbundenen Daten funktioniert. Im Gegensatz zu herkömmlichen Datenbanken, die Tabellen verwenden, verwendet NEO4J Knoten und Beziehungen. Mit diesem Setup können komplexe Hyperlinks in Daten leicht erforscht werden. NEO4J ist für Projekte wie soziale Netzwerke, Empfehlungssysteme und Netzwerkanalysen beliebt.

In diesem Artikel wird angezeigt, wie Sie NEO4J installieren und einrichten. Wir beginnen mit den grundlegenden Dingen, die Sie vor der Set up benötigen. Als nächstes werden wir die verschiedenen Möglichkeiten zur Set up von NEO4J wie Neo4j -Desktop oder Docker überprüfen. Schließlich führen wir Sie durch die ersten Schritte der Verwendung von Neo4j. Am Ende dieses Artikels haben Sie NEO4J vollständig eingerichtet und bereit zu verwenden. Sie werden auch wissen, wie Sie einige grundlegende Befehle verwenden, um loszulegen.

# Voraussetzungen

Stellen Sie vor der Set up von NEO4J sicher, dass Sie Folgendes haben:

  • Betriebssystem: NEO4J unterstützt MacOS, Linux und Home windows
  • Java: Neo4j erfordert Java 11 oder höher (Java 17 wird empfohlen)
  • Speicher- und Festplattenraum: Ziehen Sie mindestens 2 GB RAM und genügend Speicherplatz für den Datenbankspeicher zu

# Installieren von Neo4j

Abhängig von Ihren Anforderungen gibt es verschiedene Möglichkeiten, Neo4J zu installieren:

  1. NEO4J Desktop (für die Entwicklung empfohlen)
  2. NEO4J Neighborhood Server (für leichte Installationen)
  3. Docker (für Containerumgebungen)

// Neo4j Desktop

Der NEO4J-Desktop ist perfekt für Entwickler, die eine benutzerfreundliche Umgebung mit integrierten Administration-Instruments benötigen. Es enthält Visualisierungstools, den NEO4J -Browser und die Datenbankverwaltung.

  1. Obtain Neo4j Desktop: Besuchen Sie die NEO4J -Obtain -Seite und wählen Sie NEO4J -Desktop für Ihr Betriebssystem.
  2. Installieren Sie den NEO4J -Desktop: Führen Sie den heruntergeladenen Installateur aus und befolgen Sie die Anweisungen auf dem Bildschirm.
  3. Starten Sie den NEO4J -Desktop: Öffnen Sie NEO4J Desktop. Sie werden aufgefordert, ein neues Projekt zu erstellen, mit dem Sie Ihre Datenbanken organisieren können.

Der NEO4J -Desktop enthält auch Plugins wie APOC (eine leistungsstarke Prozedures Library) und Graph Information Science (GDS), die für erweiterte Analyse- und Graph -Algorithmen nützlich sind.

// NEO4J Neighborhood Server

NEO4J Neighborhood Server ist eine kostenlose Open-Supply-Model, die Kernfunktionen ohne zusätzliche GUI- oder Administration-Instruments bietet. Diese Model ist leicht und passt intestine, wenn Sie NEO4J als eigenständigen Server ausführen möchten.

  1. Obtain Neo4J Neighborhood Server: Besuchen Sie das NEO4J -Obtain -Heart und laden Sie die Neighborhood Server -Model herunter
  2. Extrahieren Sie die Dateien: Entpacken Sie die heruntergeladene Datei in einen Ordner, in dem Sie die NEO4J -Dateien behalten möchten
  3. Starten Sie den Server: Öffnen Sie unter Linux oder MacOS ein Terminal, navigieren Sie zum extrahierten Verzeichnis und starten Sie den Server mit ./bin/neo4j Konsole. Öffnen Sie unter Home windows eine Eingabeaufforderung, navigieren Sie zum extrahierten Verzeichnis und laufen Sie aus binneo4j.bat Konsole
  4. Zugriff auf den Server: Nach dem Begin des Servers können Sie über darauf zugreifen http://localhost:7474

// Verwenden von Docker

Die Set up von Neo4j über Docker ist für diejenigen, die mit Docker vertraut sind, bequem und eine Container -Instanz von NEO4J bereitgestellt.

1. Ziehen Sie das NEO4J -Bild:

2. Führen Sie Neo4j in einem Behälter aus:

docker run 
    --name neo4j 
    -p7474:7474 -p7687:7687 
    -d 
    -e NEO4J_AUTH=neo4j/password 
    neo4j

3.. Zugriff auf Neo4j:

Öffnen Sie Ihren Browser und gehen Sie zu http://localhost:7474Melden Sie sich dann mit NEO4J als Benutzername und dem Passwort an, das Sie im Befehl Docker festlegen.

# Erstes Einrichtung und Konfiguration

Nach der Set up ist eine gewisse Erstkonfiguration erforderlich, um sicherzustellen, dass NEO4J sicher ist und auf Ihre Spezifikationen eingerichtet ist.

  1. Legen Sie ein starkes Passwort fest: Wenn Sie es noch nicht getan haben, ändern Sie das Commonplace -NEO4J -Passwort, indem Sie sich im NEO4J -Browser anmelden
  2. Bearbeiten Sie die Konfigurationsdatei: Offen neo4j.conf im NEO4J -Installationsverzeichnis und passen Sie die Einstellungen nach Bedarf an
  3. Plugins aktivieren/deaktivieren: Im NEO4J -Desktop können Sie Plugins wie APOC (großartige Prozeduren auf CYPHER) und Graph Information Science aktivieren

# Zugriff auf den NEO4J -Browser

Der NEO4J -Browser ist eine interaktive Konsole, mit der Sie Cypher -Abfragen ausführen und Daten als Grafiken visualisieren können. Zu darauf zugreifen:

  1. Öffnen Sie Ihren Browser: Gehen zu http://localhost:7474
  2. Einloggen: Geben Sie den Benutzernamen und das Passwort ein
  3. Anfragen ausführen: Verwenden Sie grundlegende Cypher -Befehle wie Übereinstimmung, Erstellen und Rückkehr, um Daten abzufragen und zu erkunden
  4. Konfiguration und Einstellungen: Passen Sie die Anzeigeoptionen, Abfragegrenzen und andere Einstellungen an, um Ihre Erfahrung zu personalisieren

# Grundlegende Cypher -Befehle

Hier finden Sie eine kurze Einführung in einige grundlegende Cypher -Befehle, um mit Neo4J zu beginnen:

Knoten erstellen: Erstellen Sie einen Knoten, der eine Particular person darstellt

CREATE (n:Particular person {identify: 'Alice', age: 30})

Beziehungen schaffen: Schließen Sie zwei Knoten mit einer Beziehung an

MATCH (a:Particular person {identify: 'Alice'}), (b:Particular person {identify: 'Bob'})
CREATE (a)-(:FRIENDS_WITH)->(b)

Knoten abrufen: Abrufen Sie alle Knoten mit der Label Particular person ab

MATCH (n:Particular person) RETURN n

Eigenschaften aktualisieren: Aktualisieren Sie eine Eigenschaft auf einem Knoten

MATCH (n:Particular person {identify: 'Alice'})
SET n.age = 31

Knoten und Beziehungen löschen: Löschen Sie einen Knoten und alle seine Beziehungen

MATCH (n:Particular person {identify: 'Alice'})
DETACH DELETE n

# Nächste Schritte

Jetzt sind Sie bereit, Ihre ersten Diagrammprojekte zu starten. Hier sind einige einfache Möglichkeiten, um weiter zu lernen:

  • Experimentieren Sie mit NEO4J -Plugins: Plugins wie APOC und Graph Information Science verbessern die Funktionalität und erleichtern die Ausführung komplexer Vorgänge
  • Erforschen Sie Cypher: Erfahren Sie mehr über die leistungsstarken Abfragemöglichkeiten von Cypher in der Cypher -Dokumentation von Neo4J
  • Erstellen Sie reale Anwendungen: Betrachten Sie Anwendungsfälle wie Empfehlungssysteme, Netzwerkanalyse und Betrugserkennung, um die wahre Kraft von NEO4J zu erleben

# Abschluss

NEO4J ist eine robuste Diagrammdatenbank für verbundene Daten. Das Datenmodell und die Cypher -Abfragesprache machen komplexe Beziehungen einfach zu verwalten. NEO4J ist perfekt für soziale Netzwerke, Empfehlungen und Netzwerkanalysen. Mit Neo4J Setup und grundlegenden Cypher-Fähigkeiten können Sie Graph-Datenbanken erkunden und datengesteuerte Anwendungen erstellen.

Jayita Gulati ist ein Fanatic und technische Schriftsteller für maschinelles Lernen, der von ihrer Leidenschaft für den Aufbau maschineller Lernmodelle angetrieben wird. Sie hat einen Grasp -Abschluss in Informatik an der Universität von Liverpool.

[ad_2]

]]>
https://chatgpz.de/data-analytics/erste-schritte-mit-neo4j-installations-und-setup-handbuch/feed/ 0 11550
Krebsarten mit neo4j erforschen | von David Wells | August 2024 https://chatgpz.de/artificial-intelligence/krebsarten-mit-neo4j-erforschen-von-david-wells-august-2024/ https://chatgpz.de/artificial-intelligence/krebsarten-mit-neo4j-erforschen-von-david-wells-august-2024/#respond Sun, 18 Aug 2024 13:42:21 +0000 https://chatgpz.de/artificial-intelligence/krebsarten-mit-neo4j-erforschen-von-david-wells-august-2024/ [ad_1]

So identifizieren und visualisieren Sie Cluster in Wissensgraphen

In diesem Beitrag identifizieren und visualisieren wir verschiedene Cluster von Krebsarten durch die Analyse Krankheitsontologie als Wissensgraph. Konkret werden wir neo4j in einem Docker-Container einrichten, die Ontologie importieren, Graphcluster und -einbettungen generieren, bevor wir diese Cluster mithilfe der Dimensionsreduktion darstellen und einige Erkenntnisse daraus ableiten. Obwohl wir `disease_ontology` als Beispiel verwenden, können dieselben Schritte verwendet werden, um jede Ontologie oder Graphdatenbank zu untersuchen.

Krebsarten als Einbettungen angezeigt und nach Cluster eingefärbt, Bild vom Autor

In einer Graphdatenbank werden Daten nicht als Zeilen gespeichert (wie in einer Tabellenkalkulation oder relationalen Datenbank), sondern als Knoten und Beziehungen zwischen Knoten. In der folgenden Abbildung sehen wir beispielsweise, dass Melanom und Karzinom Unterkategorien des Zelltyps Krebstumor sind (dargestellt durch die SCO-Beziehung). Anhand dieser Artwork von Daten können wir deutlich erkennen, dass Melanom und Karzinom verwandt sind, auch wenn dies in den Daten nicht explizit angegeben ist.

Beispiel einer Graphdatenbank, Bild vom Autor

Ontologien sind eine formalisierte Reihe von Konzepten und Beziehungen zwischen diesen Konzepten. Sie sind für Pc viel einfacher zu analysieren als freier Textual content und daher leichter zu verstehen. Ontologien werden in den Biowissenschaften häufig verwendet und Sie finden möglicherweise eine Ontologie, die Sie interessiert, unter https://obofoundry.org/. Hier konzentrieren wir uns auf die Krankheitsontologie, die zeigt, wie verschiedene Arten von Krankheiten miteinander in Beziehung stehen.

Neo4j ist ein Software zum Verwalten, Abfragen und Analysieren von Graphdatenbanken. Um die Einrichtung zu vereinfachen, verwenden wir einen Docker-Container.

docker run 
-it - rm
- publish=7474:7474 - publish=7687:7687
- env NEO4J_AUTH=neo4j/123456789
- env NEO4J_PLUGINS='("graph-data-science","apoc","n10s")'
neo4j:5.17.0

Im obigen Befehl setzen die Flags `-publish` Ports, damit Python die Datenbank direkt abfragen und uns über einen Browser darauf zugreifen kann. Das Argument `NEO4J_PLUGINS` gibt an, welche Plugins installiert werden sollen. Leider scheint das Home windows-Docker-Picture die Set up nicht bewältigen zu können, daher müssen Sie Neo4j Desktop manuell installieren, um weitermachen zu können. Aber keine Sorge, die anderen Schritte sollten alle trotzdem für Sie funktionieren.

Während neo4j läuft, können Sie auf Ihre Datenbank zugreifen, indem Sie in Ihrem Browser http://localhost:7474/ aufrufen, oder Sie können den Python-Treiber verwenden, um eine Verbindung wie unten beschrieben herzustellen. Beachten Sie, dass wir den Port verwenden, den wir oben mit unserem Docker-Befehl veröffentlicht haben, und dass wir uns mit dem Benutzernamen und dem Passwort authentifizieren, die wir ebenfalls oben definiert haben.

URI = "bolt://localhost:7687"
AUTH = ("neo4j", "123456789")
driver = GraphDatabase.driver(URI, auth=AUTH)
driver.verify_connectivity()

Sobald Sie Ihre Neo4j-Datenbank eingerichtet haben, ist es an der Zeit, einige Daten abzurufen. Das Neo4j-Plug-in n10s ist für den Import und die Handhabung von Ontologien konzipiert. Sie können es verwenden, um Ihre Daten in eine vorhandene Ontologie einzubetten oder die Ontologie selbst zu erkunden. Mit den folgenden Cypher-Befehlen legen wir zunächst einige Konfigurationen fest, um die Ergebnisse sauberer zu gestalten, dann richten wir eine Eindeutigkeitsbeschränkung ein und schließlich importieren wir tatsächlich die Krankheitsontologie.

CALL n10s.graphconfig.init({ handleVocabUris: "IGNORE" });
CREATE CONSTRAINT n10s_unique_uri FOR (r:Useful resource) REQUIRE r.uri IS UNIQUE;
CALL n10s.onto.import.fetch(http://purl.obolibrary.org/obo/doid.owl, RDF/XML);

Um zu sehen, wie dies mit dem Python-Treiber gemacht werden kann, sehen Sie sich hier den vollständigen Code an https://github.com/DAWells/do_onto/blob/foremost/import_ontology.py

Nachdem wir die Ontologie importiert haben, können Sie sie erkunden, indem Sie http://localhost:7474/ in Ihrem Webbrowser öffnen. Auf diese Weise können Sie Ihre Ontologie ein wenig manuell erkunden, aber wir sind am Gesamtbild interessiert, additionally führen wir eine Analyse durch. Insbesondere werden wir Louvain-Clustering durchführen und schnelle zufällige Projektionseinbettungen generieren.

Louvain-Clustering ist ein Clustering-Algorithmus für Netzwerke wie dieses. Kurz gesagt, es identifiziert Knotensätze, die stärker miteinander verbunden sind als mit dem größeren Knotensatz; dieser Satz wird dann als Cluster definiert. Bei Anwendung auf eine Ontologie ist es eine schnelle Möglichkeit, einen Satz verwandter Konzepte zu identifizieren. Die schnelle Zufallsprojektion hingegen erzeugt eine Einbettung für jeden Knoten, d. h. einen numerischen Vektor, bei dem mehr ähnliche Knoten mehr ähnliche Vektoren haben. Mit diesen Instruments können wir identifizieren, welche Krankheiten ähnlich sind, und diese Ähnlichkeit quantifizieren.

Um Einbettungen und Cluster zu generieren, müssen wir die Teile unseres Graphen „projizieren“, die uns interessieren. Da Ontologien normalerweise sehr groß sind, ist diese Teilmenge eine einfache Möglichkeit, die Berechnung zu beschleunigen und Speicherfehler zu vermeiden. In diesem Beispiel sind wir nur an Krebs und nicht an anderen Krankheitsarten interessiert. Wir tun dies mit der folgenden Cypher-Abfrage; wir gleichen den Knoten mit der Bezeichnung „Krebs“ und jeden Knoten ab, der durch eine oder mehrere SCO- oder SCO_RESTRICTION-Beziehungen damit verbunden ist. Da wir die Beziehungen zwischen Krebsarten einbeziehen möchten, haben wir eine zweite MATCH-Abfrage, die die verbundenen Krebsknoten und ihre Beziehungen zurückgibt.

MATCH (most cancers:Class {label:"most cancers"})<-(:SCO|SCO_RESTRICTION *1..)-(n:Class)
WITH n
MATCH (n)-(:SCO|SCO_RESTRICTION)->(m:Class)
WITH gds.graph.mission(
"proj", n, m, {}, {undirectedRelationshipTypes: ('*')}
) AS g
RETURN g.graphName AS graph, g.nodeCount AS nodes, g.relationshipCount AS rels

Sobald wir die Projektion haben (die wir „proj“ genannt haben), können wir die Cluster und Einbettungen berechnen und sie in das ursprüngliche Diagramm zurückschreiben. Schließlich können wir durch Abfragen des Diagramms die neuen Einbettungen und Cluster für jeden Krebstyp abrufen, die wir in eine CSV-Datei exportieren können.

CALL gds.fastRP.write(
'proj',
{embeddingDimension: 128, randomSeed: 42, writeProperty: 'embedding'}
) YIELD nodePropertiesWritten

CALL gds.louvain.write(
"proj",
{writeProperty: "louvain"}
) YIELD communityCount

MATCH (most cancers:Class {label:"most cancers"})<-(:SCO|SCO_RESTRICTION *0..)-(n)
RETURN DISTINCT
n.label as label,
n.embedding as embedding,
n.louvain as louvain

Schauen wir uns einige dieser Cluster an, um zu sehen, welche Krebsarten zusammengefasst sind. Nachdem wir die exportierten Daten in einen Pandas-Datenrahmen in Python geladen haben, können wir einzelne Cluster untersuchen.

Cluster 2168 ist eine Gruppe von Bauchspeicheldrüsenkrebserkrankungen.

nodes(nodes.louvain == 2168)("label").tolist()
#array(('"islet cell tumor"',
# '"non-functioning pancreatic endocrine tumor"',
# '"pancreatic ACTH hormone producing tumor"',
# '"pancreatic somatostatinoma"',
# '"pancreatic vasoactive intestinal peptide producing tumor"',
# '"pancreatic gastrinoma"', '"pancreatic delta cell neoplasm"',
# '"pancreatic endocrine carcinoma"',
# '"pancreatic non-functioning delta cell tumor"'), dtype=object)

Cluster 174 ist eine größere Gruppe von Krebserkrankungen, hauptsächlich jedoch Karzinome.

nodes(nodes.louvain == 174)("label")
#array(('"head and neck most cancers"', '"glottis carcinoma"',
# '"head and neck carcinoma"', '"squamous cell carcinoma"',
#...
# '"pancreatic squamous cell carcinoma"',
# '"pancreatic adenosquamous carcinoma"',
#...
# '"blended epithelial/mesenchymal metaplastic breast carcinoma"',
# '"breast mucoepidermoid carcinoma"'), dtype=object)p

Dies sind sinnvolle Gruppierungen, die entweder auf Organen oder Krebsarten basieren und für die Visualisierung nützlich sind. Die Einbettungen hingegen sind immer noch zu hochdimensional, um sinnvoll visualisiert zu werden. Glücklicherweise ist TSNE eine sehr nützliche Methode zur Dimensionsreduzierung. Hier verwenden wir TSNE, um die Einbettung von 128 Dimensionen auf 2 zu reduzieren, während eng verwandte Knoten weiterhin nahe beieinander bleiben. Wir können überprüfen, ob dies funktioniert hat, indem wir diese beiden Dimensionen als Streudiagramm darstellen und nach den Louvain-Clustern einfärben. Wenn diese beiden Methoden übereinstimmen, sollten wir Knoten sehen, die nach Farbe gruppiert sind.

from sklearn.manifold import TSNE

nodes = pd.read_csv("export.csv")
nodes('louvain') = pd.Categorical(nodes.louvain)

embedding = nodes.embedding.apply(lambda x: ast.literal_eval(x))
embedding = embedding.tolist()
embedding = pd.DataFrame(embedding)

tsne = TSNE()
X = tsne.fit_transform(embedding)

fig, axes = plt.subplots()
axes.scatter(
X(:,0),
X(:,1),
c = cm.tab20(Normalize()(nodes('louvain').cat.codes))
)
plt.present()

TSNE-Projektion von Krebseinbettungen, farblich nach Clustern sortiert, Bild vom Autor

Und genau das sehen wir: Ähnliche Krebsarten werden gruppiert und als Cluster einer einzigen Farbe angezeigt. Beachten Sie, dass einige Knoten einer einzigen Farbe sehr weit voneinander entfernt sind. Dies liegt daran, dass wir einige Farben wiederverwenden müssen, da es 29 Cluster und nur 20 Farben gibt. Dies gibt uns einen guten Überblick über die Struktur unseres Wissensgraphen, aber wir können auch unsere eigenen Daten hinzufügen.

Nachfolgend stellen wir die Häufigkeit der Krebsart als Knotengröße und die Sterblichkeitsrate als Opazität dar (Bray et al 2024). Ich hatte nur für einige Krebsarten Zugriff auf diese Daten, daher habe ich nur diese Knotenpunkte dargestellt. Unten können wir sehen, dass Leberkrebs insgesamt keine besonders hohe Inzidenz aufweist. Die Inzidenzraten von Leberkrebs sind jedoch viel höher als bei anderen Krebsarten innerhalb seines Clusters (violett dargestellt) wie Oropharynx, Larynx und Nasopharynx.

Häufigkeit und Mortalität von Krebserkrankungen, eingefärbt nach Cluster, Bild vom Autor

Hier haben wir die Krankheitsontologie verwendet, um verschiedene Krebsarten in Cluster zu gruppieren, was uns den Kontext gibt, um diese Krankheiten zu vergleichen. Hoffentlich hat Ihnen dieses kleine Projekt gezeigt, wie Sie eine Ontologie visuell erkunden und diese Informationen Ihren eigenen Daten hinzufügen können.

Den vollständigen Code für dieses Projekt finden Sie unter https://github.com/DAWells/do_onto.

Bray, F., Laversanne, M., Sung, H., Ferlay, J., Siegel, RL, Soerjomataram, I., & Jemal, A. (2024). Globale Krebsstatistik 2022: GLOBOCAN-Schätzungen der Inzidenz und Mortalität weltweit für 36 Krebsarten in 185 Ländern. CA: eine Krebszeitschrift für Kliniker, 74(3), 229–263.

[ad_2]

]]>
https://chatgpz.de/artificial-intelligence/krebsarten-mit-neo4j-erforschen-von-david-wells-august-2024/feed/ 0 3272