Kapitel 4. Studieren von Startup-Investitionen

Diese Arbeit wurde mithilfe von KI übersetzt. Wir freuen uns über dein Feedback und deine Kommentare: translation-feedback@oreilly.com

In diesem Kapitel tauchen wir in die Welt der Startup-Investitionen ein. Dieser reale Anwendungsfall zeigt uns, wie drei der sechs Graphenfähigkeiten uns dabei helfen, vielversprechende Investitionsmöglichkeiten zu erkennen. Mit der ersten Graphenkraft, der Verbindung der Punkte, können wir sehen, wie die verschiedenen Akteure in der Investitionslandschaft miteinander verbunden sind. Die zweite Graphenkraft, der Blick in die Tiefe, bietet Investoren eine Methode, um verknüpfte Informationen über diese Akteure in unsere Analyse einzubeziehen. Die dritte Kraft der Grafik, das Abwägen und Vorhersagen, ermöglicht es uns, vergangene Finanzierungsereignisse und Investitionsportfolios zu nutzen, um die Erfolgsquote zukünftiger Investitionen vorherzusagen.

Nach Abschluss dieses Kapitels solltest du in der Lage sein:

  • Erläutern, wie das Verbinden von Punkten, der Blick in die Tiefe und das Abwägen und Vorhersagen den Such- und Analysebedarf decken

  • Modellieren und Analysieren von Investitionsmöglichkeiten für Start-ups

  • Durchquere Multihop-Beziehungen, um tiefer liegende Informationen zu filtern

  • Lies und verstehe fortgeschrittene GSQL-Abfragen

Ziel: Vielversprechende Startups finden

Die Investition in ein Start-up ist eine aufregende und lukrative Möglichkeit, Vermögen aufzubauen. Im Jahr 2020 haben Investoren über 156 Milliarden Dollar in US-Startups gesteckt. Diese Startups haben über 290 Milliarden Dollar an Liquidität generiert.1 Allerdings werden 9 von 10 Startups fehlschlagen, und nur 40 % werden profitabel, so dass es eine Herausforderung ist, auf das richtige Pferd zu setzen.2

Startups beginnen mit einem Gründungsteam, das nur aus wenigen Mitgliedern besteht. Im Laufe der Zeit durchläuft ein Startup verschiedene Entwicklungsphasen, sein Produkt wird verbessert und das Team wächst. Um diese Entwicklungen zu finanzieren, braucht das Startup Geld von Investoren. Eine Möglichkeit, um zu erkennen, welches Startup ein geeigneter Kandidat für eine Finanzierung ist, besteht darin, die Zusammensetzung des Startup-Teams und die Organisation des Unternehmens zu betrachten. Startups, die die richtigen Leute an den richtigen Stellen in ihrem Unternehmen haben, haben in der Regel höhere Erfolgschancen. Startups, die von Gründern geleitet werden, die eine positive Erfolgsbilanz beim Aufbau von Unternehmen vorweisen können, haben daher eine höhere Wahrscheinlichkeit, auch in anderen Unternehmen erfolgreich zu sein. Eine weitere Möglichkeit, die Investitionsmöglichkeiten zu beurteilen, ist ein Blick auf die bestehenden Investoren des Startups. Investoren mit einer hohen Rendite auf ihr Investitionsportfolio zeigen, dass sie das Potenzial von Start-ups in der Anfangsphase erkennen und ihnen helfen, zu profitableren Unternehmen zu wachsen.

In Startups zu investieren ist eine riskante und komplexe Einschätzung, die ein Verständnis des Produkts und des Marktes, den es erobern will, sowie der Menschen und Organisationen, die es vorantreiben, erfordert. Investoren müssen einen Überblick über die Beziehungen zwischen diesen Aspekten haben, um das Potenzial eines Startups besser einschätzen zu können.

Lösung: Ein Startup-Investitionsdiagramm

Die Daten auf, die die Bewertung von Investitionen unterstützen, sind größtenteils unstrukturiert, da sie aus verschiedenen Quellen gesammelt werden. Ein Beispiel für eine solche Quelle ist der Crunchbase-Datensatz. Dieser Datensatz enthält Informationen zu Investitionsrunden, Gründern, Unternehmen, Investoren und Investitionsportfolios. Der Datensatz liegt jedoch im Rohformat vor, d. h. die Daten sind nicht so strukturiert, dass sie die Fragen beantworten, die wir zu den mit Startups verbundenen Unternehmen für Investitionszwecke haben. Daten über Startups und die Unternehmen, die zum aktuellen Stand beitragen, bleiben uns verborgen, es sei denn, wir fragen die Daten explizit ab. Mit Diagrammen können wir ein Schema erstellen, das sich auf ein bestimmtes Startup konzentriert, das wir untersuchen möchten, und die Auswirkungen anderer Unternehmen auf das Startup anzeigen.

Investitionen in Start-ups erfolgen in einer Reihe von Finanzierungsrunden, wie in Abbildung 4-1 dargestellt. In der Regel wollen Start-ups in jeder späteren Finanzierungsphase mehr Geld von einer größeren Anzahl von Investoren aufnehmen. Die Kenntnis des Zeitpunkts und der Abfolge der Ereignisse in diesen Finanzierungsphasen ist entscheidend für die Validierung erfolgreicher Investitionsinteraktionen. Graphen können einen vollständigen Überblick über ein Investitionsnetzwerk geben, indem sie nach Multihop-Ereignisketten suchen. Auf diese Weise können wir Angel-Investoren und Risikokapitalgeber über verschiedene Finanzierungsphasen hinweg miteinander verbinden und die Erfolgsquoten ihrer Investitionsportfolios im Laufe der Zeit aufzeigen.

Startup funding stages and types of investors per stage
Abbildung 4-1. Phasen der Startup-Finanzierung und Arten von Investoren pro Phase

Herkömmliche relationale Datenbankabfragen liefern uns eine Momentaufnahme eines Ereignisses und des Zustands jeder Entität zu einem einzigen Zeitpunkt. Bei der Bewertung von Investitionsportfolios müssen wir jedoch die Beziehungen zwischen Investoren und den Unternehmen, in die sie investiert haben, verstehen und wie sich diese Beziehungen entwickelt haben. Diagramme lösen dieses Problem, indem sie das Investitionsportfolio als eine Reihe von Ereignissen mit Hilfe von Multihop-Abfragen darstellen. Wir können auch mehrere Hops verwenden, um komplexe Such- und Filterfunktionen auszuführen, wie z. B. "Finde Unternehmen, deren Vorstandsmitglieder von einer hochrangigen VC-Firma kommen und zuvor im Vorstand von Startups saßen, die erfolgreiche Exits hatten."

Wir wollen zum Beispiel wissen, in welche Startups die Kollegen eines erfolgreichen Investors jetzt investieren. Auf diese Weise können wir das Fachwissen und das Netzwerk erfolgreicher Investoren nutzen, das auf ihren früheren Investitionen basiert. Eine Multihop-Abfrage kann dies realisieren, indem wir zunächst einen oder mehrere erfolgreiche Investoren auswählen. Vielleicht haben wir schon einige im Kopf, oder wir können sie finden, indem wir die Anzahl der erfolgreichen Investoren pro Investor zählen; das wäre dann ein Sprung. Der zweite Schritt wählt alle Finanzunternehmen aus, in denen die Investoren arbeiten. Die dritte Abfrage wählt die Kolleginnen und Kollegen in diesen Finanzorganisationen aus und die vierte Abfrage wählt andere Finanzierungsveranstaltungen aus, an denen diese Kollegen teilnehmen.

Implementierung eines Startup-Investitionsdiagramms und Abfragen

TigerGraph Cloud bietet ein Starterkit für die Analyse von Startup-Investitionen. Im weiteren Verlauf dieses Kapitels beschreiben wir, wie wir Startups und ihre Finanzierung mit einem Graphschema modellieren. Dann sehen wir uns vier verschiedene Graphanalysen an, die einem Investor bei der Auswahl vielversprechender Startups helfen können.

Das Crunchbase Starter Kit

Verwende das TigerGraph Cloud-Konto, das du in Kapitel 3 erstellt hast, um einen neuen Anwendungsfall einzurichten und wähle "Enterprise Knowledge Graph (Crunchbase)". Sobald dieses Starterkit installiert ist, befolge die Schritte im Abschnitt "Daten laden und Abfragen für ein Starterkit installieren" in Kapitel 3.

Graph Schema

Das Starter-Kit enthält aktuelle Daten von Investitionen in Startups im Jahr 2013, die von Crunchbase gesammelt wurden. Es hat mehr als 575K Eckpunkte und über 664K Kanten, mit 10 Eckpunkttypen und 24 Kantentypen. Abbildung 4-2 zeigt das Graphschema dieses Starterkits. Wir können sofort erkennen, dass Company ein Vertex-Typ ist, der als Knotenpunkt fungiert, weil er mit vielen anderen Vertex-Typen verbunden ist.

Graph schema for Enterprise Knowledge Graph (Crunchbase)
Abbildung 4-2. Graphenschema für den Enterprise Knowledge Graph (Crunchbase) (siehe eine größere Version dieser Abbildung unter https://oreil.ly/gpam0402)

Außerdem gibt es zwei Arten von Selbstkanten. A Company kann acquire eine andere Company, und ein Company kann auch invest in einem anderen Company. A Person Typ Vertex hingegen hat keine eigenen Kanten, was bedeutet, dass eine soziale Verbindung immer über einen anderen Vertex-Typ wie University, Financial_Org, Fund⁠ing_Rounds, oder Company. Wenn zum Beispiel ein Person für ein Unternehmen arbeitet, wird diese Art der Beziehung mit dem Kantentyp work_for_company.

In Tabelle 4-1 beschreiben wir die 10 Scheitelpunkttypen des Starterkits. Aus der Beschreibung können wir ersehen, dass Company Scheitelpunkte potenzielle Beziehungen zu vielen anderen Scheitelpunkttypen haben. Einige von ihnen haben sogar mehrere Beziehungstypen, die sich mit Company. Zum Beispiel kann ein Person kann in a investieren Companyinvestieren, aber es kann auch für einen Company.

Tabelle 4-1. Vertex Typen in das Crunchbase Starter Kit
Scheitelpunkt Typ Beschreibung
Company Ein Unternehmen
Funding_Rounds Ein Investitionsereignis, bei dem ein Company Gelder investiert oder erhält
Person Eine natürliche Person, die für ein Unternehmen arbeitet Company oder in ein Unternehmen investiert Company
University Eine universitäre Einrichtung
Financial_Org Ein Finanzinstitut, das in ein Unternehmen investiert Company
Funds Eine finanzielle Investition
Office Ein physisches Büro einer Company
IPO Ein Börsengang einer Company
Product Ein Produkt oder eine Dienstleistung eines Company
Milestone Ein Meilenstein, den ein Company erreicht hat

Abfragen und Analysen

Schauen wir uns unter die Abfragen im Enterprise Knowledge Graph (Crunchbase) Starter Kit an. Es gibt vier Abfragen in diesem Starter Kit. Jede Abfrage ist darauf ausgelegt, Fragen zu beantworten, die ein potenzieller Investor oder Arbeitgeber stellen könnte.

Entdeckung der Schlüsselrolle
Diese Abfrage findet alle Personen, die eine Schlüsselrolle in einem bestimmten Company und seinen Muttergesellschaften. Eine Schlüsselrolle für ein Person ist definiert als Gründer, CEO, CTO, Direktor oder Führungskraft für die Company wo sie arbeiten.
Erfolgreiche Exits von Investoren
Bei einem bestimmten Investor findet diese Abfrage die Startups, die innerhalb einer bestimmten Anzahl von Jahren nach der Investition des Investors einen erfolgreichen Exit hatten. Ein erfolgreicher Exit liegt vor, wenn ein Unternehmen an die Börse geht oder von einem anderen Unternehmen übernommen wird. Die visuelle Ausgabe der Abfrage ist der Subgraph des gegebenen Investors mit all seinen Beziehungen zu IPO und aufnehmenden Company Elementen. Ein Investor kann ein beliebiges Element des Typs Person, Financial_Org, oder Company.
Top-Startups basierend auf dem Vorstand
Diese Abfrage listet Startups nach der Anzahl der Fälle auf, in denen ein aktuelles Vorstandsmitglied, das für eine Top-Investmentfirma (Financial_Org) tätig ist, auch Vorstandsmitglied eines früheren Start-ups war, das einen erfolgreichen Exit hatte. Die Investmentfirmen werden nach der Höhe der in den letzten N Jahren investierten Mittel eingestuft. Die Vorstandsmitglieder werden nach der Anzahl ihrer erfolgreichen Exits bewertet. Darüber hinaus filtert die Abfrage Start-ups heraus, die eine bestimmte Finanzierungsrunde hinter sich haben.
Top-Startups basierend auf Leader
Diese Abfrage ordnet Startups danach, wie oft einer ihrer Gründer zuvor in einem anderen Unternehmen gearbeitet hat. Companyin einer frühen Phase des Unternehmens gearbeitet hat und dieses dann erfolgreich verlassen hat. Die Suche wird so gefiltert, dass sie nur einen bestimmten Wirtschaftszweig berücksichtigt.

Entdeckung der Schlüsselrolle

Die Abfrage key_role_discovery hat zwei Argumente. Das erste Argument, com⁠pany​_​name, ist unser Ziel Company für das wir die Personen finden wollen, die entweder dort oder in einer Muttergesellschaft eine Schlüsselrolle gespielt haben. Das zweite Argument, k, legt fest, wie viele Sprünge von unserem Startpunkt company_name aus wir nach Mutterunternehmen suchen wollen. Diese Abfrage passt aufgrund des Parameters k hops sehr gut zu einem Graphenmodell. Abbildung 4-3 zeigt einen Teil des Graphen-Traversals für zwei Sprünge. Ausgehend vom Unternehmen Com A könnten wir Verbindungen zu einem Mutterunternehmen Com B und zwei Schlüsselpersonen, Ben und Adam, finden. Dann sehen wir nach, ob Com B Schlüsselpersonen oder eine andere Muttergesellschaft hat.

Wir werden dich jetzt durch die GSQL-Implementierung führen. Suche in deinem Starterkit nach der Abfrage key_role_discovery. Wähle sie aus, damit du den Code sehen kannst.

Zuerst deklarieren wir einige Akkumulatoren3 in denen wir unsere Ausgabeobjekte, @@output_vertices und @@output_edges, sammeln. Außerdem deklarieren wir visited , um Eckpunkte zu markieren, auf die die Abfrage bereits gestoßen ist, um Doppelzählungen oder Suchen im Kreis zu vermeiden. Wenn in diesem Datensatz eine Zeitvariable keinen echten Wert hat, wird sie auf den Code 0 gesetzt, was dem 1. Januar 1970 entspricht. Wir deklarieren TNULL als einen anschaulicheren Namen für diese Situation:

    OrAccum @visited; 
    SetAccum<VERTEX> @@output_vertices;
    SetAccum<EDGE> @@output_edges;
    DATETIME TNULL = to_datetime("1970-01-01 00:00:00");
Graph traversal pattern to find employees who have a key role at a company and its parent companies
Abbildung 4-3. Graphen-Traversal-Muster, um Mitarbeiter zu finden, die eine Schlüsselrolle in einem Unternehmen und seinen Muttergesellschaften haben

Als nächstes wählen wir alle Unternehmenselemente aus, deren name Attribut mit dem Eingabeparameter company_name übereinstimmt. Die Funktionen lower(trim()) entfernen alle führenden oder nachfolgenden Leerzeichen und wandeln alle Buchstaben in Kleinbuchstaben um, damit Unterschiede in der Großschreibung keine Rolle spielen. Jeder Eckpunkt, dessen Name übereinstimmt, wird der Menge @@output_vertices hinzugefügt und außerdem als @visited markiert:

    Linked_companies (ANY) = SELECT tgt 
        FROM Company:tgt
        WHERE lower(trim(tgt.name)) == lower(trim(company_name))
        ACCUM @@output_vertices += tgt
        POST-ACCUM tgt.@visited = TRUE;

Jetzt starten wir eine WHILE Schleife, um nach Schlüsselpersonen und Muttergesellschaften bis zu k Ebenen tief zu suchen. Bei jeder Iteration wählen wir alle Company Elemente aus, die ein invested_by_company, acquired_by, oder work_for_company Kante zu einem Company oder Person. Dies ist ein gutes Beispiel dafür, wie wichtig es ist, beschreibende Namen für deine Eckpunkte und Kanten zu wählen:

    WHILE TRUE LIMIT k DO 
        Linked_companies = SELECT tgt
            FROM Linked_companies:s
                - ((invested_by_company> | acquired_by> | work_for_company):e) 
                - (Company | Person):tgt

Dieser SELECT Block hat noch mehr zu bieten. Seine WHERE-Klausel führt zusätzliche Filterungen der ausgewählten Unternehmen und Personen durch. Um sicherzustellen, dass wir die Kanten von Unternehmen zu Personen in der richtigen Richtung durchlaufen, müssen wir zunächst sicherstellen, dass der Quellknoten (mit dem Alias s) ein Unternehmen ist. Außerdem müssen wir sicherstellen, dass wir den Zielknoten noch nicht besucht haben (NOT tgt.@visited). Wenn der Kantentyp dann work_for_companyist, muss die Berufsbezeichnung "Gründer", "CEO", "CTO", "[b]oard [of] directors" oder "[e]xecutive" enthalten:

            WHERE s.type == "Company" AND tgt.@visited == FALSE AND
              (e.type == "work_for_company" AND
                (e.title LIKE "%founder%" OR e.title LIKE "%Founder%" OR
                 e.title LIKE "%CEO%" OR e.title LIKE "% ceo%" OR
                 e.title LIKE "%CTO%" OR e.title LIKE "% cto%" OR
                 ((e.title LIKE "%oard%irectors%" OR e.title LIKE "%xecutive%")
                   AND datetime_diff(e.end_at, TNULL) == 0))
                ) OR
                 e.type != "work_for_company"

Dann fügen wir die ausgewählten Eckpunkte und Kanten zu unseren Akkumulatoren @@output_vertices und @@output_edges hinzu und markieren die Eckpunkte als visited.

Schließlich zeigen wir die ausgewählten Unternehmen und Personen mit ihren verbindenden Kanten sowohl grafisch als auch als JSON-Daten an. Die Zeile Results = {@@output_vertices} erstellt einen Scheitelpunktsatz aus SetAccum<VERTEX>. Wenn wir direkt @@output_vertex drucken würden, würden wir nur die IDs der Scheitelpunkte sehen. Wenn wir ein Vertex-Set wie Results ausdrucken, werden alle Eigenschaften der Scheitelpunkte angezeigt:

IF @@output_vertices.size() != 0 THEN
    Results = {@@output_vertices}; // conversion to output more that just id
    PRINT Results;
    PRINT @@output_edges;
ELSE
    PRINT "No parties with key relations to the company found within ", k,
        " steps" AS msg;

GSQL: Vertices drucken

Aus Gründen der Effizienz werden in den Akkumulatoren , die Scheitelpunkte enthalten, nur deren IDs gespeichert. Um Scheitelpunkteigenschaften auszudrucken, kopierst du den Akkumulator in eine reguläre Scheitelpunktmenge und druckst die Scheitelpunktmenge aus.

In Abbildung 4-4 zeigen wir die Ausgabe von company_name = LuckyCal and k = 3 . Obwohl der Name des Unternehmens in der Mitte fehlt, können wir anhand der Liste der Gründer, darunter Mark Zuckerberg, erkennen, dass es sich um Facebook handelt.

Key role discovery when company_name = LuckyCal and k = 3
Abbildung 4-4. Entdeckung der Schlüsselrolle, wenn company_name = LuckyCal und k = 3 (siehe eine größere Version dieser Abbildung unter https://oreil.ly/gpam0404)

Erfolgreiche Exits von Investoren

Die Abfrage investor_successful_exits findet den Erfolg eines bestimmten Investors, wobei der Erfolg an der Anzahl der Investitionen gemessen wird, die zu Börsengängen und Übernahmen führen. Die Abfrage benötigt drei Argumente. investor_name ist der Name des Zielinvestors, dessen Erfolge wir wissen wollen, und investor_type ist der Typ des Investors, der sein kann Company, Person, oder Financial_Org. Wir verwenden year, um zu prüfen, ob ein Ausstieg früh genug nach der Finanzierung erfolgt ist. Wir können diese Abfrage beantworten, indem wir das folgende Graph-Traversal-Muster verwenden, wie in Abbildung 4-5 dargestellt. Beginne mit dem ausgewählten Investor-Vertex (investor_name):

  1. Springe zu den Finanzierungsrunden, an denen der Investor beteiligt war.

  2. Spring zu den Unternehmen, die durch diese Runden finanziert wurden.

  3. Springe zu den Ausstiegsereignissen (acquired_by oder company_ipo Kanten).

Graph traversal pattern to find investors with successful exits
Abbildung 4-5. Graph-Traversal-Muster, um Investoren mit erfolgreichen Exits zu finden (siehe eine größere Version dieser Abbildung unter https://oreil.ly/gpam0405)

Wir führen dich durch die wichtigsten Teile des GSQL-Codes für die Abfrage investor_successful_exits.

Wir beginnen damit, mehrere Variablen zu deklarieren. Wir wollen die Wege vom Investor zum erfolgreichen Ausstieg aufzeigen. Während wir uns durch den Graphen bewegen, funktionieren @parent_vertex_set und @parent_edge_set wie Brotkrumen. An jedem neu besuchten Knotenpunkt halten wir mit ihnen fest, wie wir dorthin gekommen sind. Wenn wir das Ende erreicht haben, benutzen wir diese Akkumulatoren, um den Weg zurück zu finden. Während des Rückwegs sammeln wir alle Knoten und Kanten auf diesen Pfaden in den globalen Akkumulatoren @@result_vertex_set und @@result_edge_set:

    SetAccum<VERTEX> @parent_vertex_set;
    SetAccum<EDGE> @parent_edge_set;
    SetAccum<VERTEX> @@result_vertex_set;
    SetAccum<EDGE> @@result_edge_set;

Als Nächstes erstellen wir den Start Satz von Scheitelpunkten, indem wir eine CASE Anweisung und den Parameter investor_type verwenden, um den vom Benutzer angegebenen Anlegertyp auszuwählen:

    Start (ANY) = {}; 
    CASE lower(trim(investor_type))
        WHEN "person"    THEN Start = {Person.*};
        WHEN "company"    THEN Start = {Company.*};
        WHEN "financialorg"  THEN Start = {Financial_Org.*};
    END;

Wir schließen die Vorbereitungen ab, indem wir den einzelnen Investor finden, der investor_name hat. Wenn der Anleger ein Personist, überprüfen wir das Attribut fullname; andernfalls überprüfen wir das Attribut name:

     Investor (ANY) = SELECT inv
        FROM Start:inv
        WHERE ( inv.type == "Person"
              AND lower(trim(inv.fullname)) == lower(trim(investor_name))
         ) OR lower(trim(inv.name)) == lower(trim(investor_name));

Jetzt beginnen wir mit unseren Graphenhüpfungen. Zuerst wählen wir alle Funding_Rounds die mit dem Investor verbunden sind. Bei jedem ausgewählten Funding_Rounds Knoten speichern wir die Identität des Knotens und der Kante, die wir überquert haben, um dorthin zu gelangen. Die Zielknoten dieses Sprungs werden in einer Variablen namens Funding_rounds gespeichert:

    Funding_rounds = SELECT tgt
        FROM Investor:s - ((investment_from_company | investment_from_person | 
            investment_from_financialORG):e) - Funding_Rounds:tgt
        ACCUM
            tgt.@parent_vertex_set += s, 
            tgt.@parent_edge_set += e;

Jetzt machen wir einen weiteren Sprung von den ausgewählten Finanzierungsrunden zu den Unternehmen, die sie finanziert haben. Ein Investor kann in ein Unternehmen in mehr als einer Finanzierungsrunde investieren. In Abbildung 4-6 sehen wir zum Beispiel, dass Ted Leonsis sowohl in Runde B als auch in Runde C in Revolution Money investiert hat. Der Erfolg eines Investors sollte ab dem Zeitpunkt seiner ersten Investition beurteilt werden. Jeder Funding_Rounds vertex sendet seinen funded_at Parameterwert an eine MinAccum @min_invested_time, die sich an den Mindestwert erinnert, der ihr gegeben wurde:

    Invested_companies = SELECT tgt
        FROM Funding_rounds:s - ((company_funding_rounds):e) - Company:tgt
        ACCUM
            tgt.@parent_vertex_set += s,
            tgt.@parent_edge_set += e,
            tgt.@min_invested_time += s.funded_at;

Schließlich prüfen wir für jedes Unternehmen, das eine Investitionsfinanzierung erhalten hat, ob es innerhalb des vorgeschriebenen Zeitfensters einen erfolgreichen Exit hatte. A company_ipo oder acquired_by Kante zeigt einen Exit an. Wenn es sich um einen Börsengang handelte, prüfen wir, ob das Datum des Börsengangs (das Attribut public_at ) nach dem Investitionsdatum liegt, aber nicht mehr als der Wert von years später. Eine analoge Prüfung wird für das Attribut acquired_at durchgeführt, wenn es sich um eine Übernahme handelt:

    IPO_acquired_companies = SELECT tgt 
        FROM Invested_companies:s - ((company_ipo | acquired_by>):e) -:tgt
        ACCUM
            tgt.@parent_vertex_set += s,
            tgt.@parent_edge_set += e,
            // See if IPO occurred within `years` after Investor's investment
            IF (e.type == "company_ipo"
                AND datetime_diff(tgt.public_at, s.@min_invested_time) > 0
                AND datetime_diff(
                tgt.public_at, s.@min_invested_time) <= years * SECS_PER_YR)
            // See if Acquisition occurred within `years` of investment
            OR (e.type == "acquired_by"
                AND datetime_diff(e.acquired_at, s.@min_invested_time) > 0
                AND datetime_diff(
                e.acquired_at, s.@min_invested_time) <= years * SECS_PER_YR)
            THEN @@result_vertex_set += tgt
            END;
Investor Successful Exits when investor_name = Ted Leonsis and years = 3
Abbildung 4-6. Erfolgreiche Ausstiege von Investoren, wenn investor_name = Ted Leonsis und years = 3 (siehe eine größere Version dieser Abbildung unter https://oreil.ly/gpam0406)

Wenn wir nur wissen wollten, wie viele erfolgreiche Exits unser Investor hatte, oder die Unternehmensdetails dieser Exits, wären wir schon fertig. Es ist jedoch interessant, die Pfade von Investor → Finanzierung → Unternehmen → Exit grafisch darzustellen, wie in Abbildung 4-6. Um diese Informationen zu sammeln, gehen wir von den Exit-Eckpunkten zurück zum Investor, indem wir die Breadcrumbs (@parent_vertex_set und @parent_edge_set) verwenden, die wir zuvor auf gesetzt haben:

    Children = {@@result_vertex_set};
    PRINT Children.size() as Num_Successful_Exits;
    WHILE(Children.size() > 0) DO
        Start = SELECT s
            FROM Children:s
            ACCUM
                @@parents += s.@parent_vertex_set,
                @@result_edge_set += s.@parent_edge_set;

        @@result_vertex_set += @@parents;
        Children = {@@parents};
        @@parents.clear();

Top-Startups basierend auf dem Vorstand

Die Abfrage top_startups_based_on_board macht die Sache etwas komplizierter, indem sie zwei Formen des Rankings hinzufügt: die leistungsstärksten Investmentgesellschaften und die leistungsstärksten Führungskräfte in diesen Investmentgesellschaften. Zunächst werden die Unternehmen ermittelt, die Financial_Org Unternehmen, die in den letzten Jahren das meiste Geld investiert haben. Dann erstellen wir ein Ranking Persons wir diese Unternehmen danach, wie oft sie im Vorstand eines Start-ups saßen und Company und es zu einem erfolgreichen Exit geführt haben. Dann zeigen wir alle Pre-Exits Companies die derzeit eine dieser erfolgreichen Führungskräfte als Vorstandsmitglied haben.

Die Abfrage top_startups_based_on_board hat vier Eingabeparameter:

k_orgs
Die Anzahl der Top-Finanzinstitute, die wir in unseren Auswahlbereich aufnehmen wollen
num_persons
Die Anzahl der zu wählenden Top-Vorstandsmitglieder
max_funding_round
Filtert die endgültige Liste der vielversprechenden Start-ups, um diejenigen auszuschließen, die erst zu einem späteren Zeitpunkt Investitionsmittel erhalten haben als max_funding_round
past_n_years
Legt das Zeitfenster für Geld fest, das von Financial_Org

Wir können diese Abfrage anhand der folgenden Schritte implementieren, von denen die meisten einem Graphensprung entsprechen; diese Schritte sind in Abbildung 4-7 dargestellt:

  1. Berechne, wie viel Funding_Rounds Investition jeder Financial_Org in den letzten N Jahren getätigt hat [Hop 1].

  2. Ordnen Sie die Financial_Org nach der Investitionssumme und nimm den besten k_orgs.

  3. Finde Persons die für einen Top-K arbeiten Financial_Org (aus Schritt 2) [Hop 2].

  4. Finde Unternehmen, bei denen die Persons (aus Schritt 3) als Vorstandsmitglieder tätig waren [Hop 3].

  5. Ordne diese Persons (aus Schritt 3) nach der Anzahl der Male, die sie auf dem Brett eines Company (aus Schritt 4) vor seinem erfolgreichen Abgang [Hop 4].

  6. Finde Pre-Exit Company Eckpunkte, die ein oberes Vorstandsmitglied haben Person (aus Schritt 5). Filtere diese Unternehmen nach dem Cutoff der Finanzierungsrunde [Hop 5].

Diese Abfrage deklariert mehrere Akkumulatoren und andere Variablen, die bei dieser Berechnung helfen. Es gibt auch zwei interessante Datenvorbereitungsschritte. Einer speichert einige Wechselkurse in einer Nachschlagetabelle. Ein anderer erstellt eine Liste aller Finanzierungsrundencodes @@allowed_funding_rounds bis hin zu unserer max_cutoff_round.

Graph traversal pattern to find promising startups based on successful board members from top financial organizations
Abbildung 4-7. Graphen-Traversal-Muster, um vielversprechende Startups auf der Grundlage erfolgreicher Vorstandsmitglieder von Top-Finanzorganisationen zu finden

Unser erster Graph Hop ist auch ein Schritt der Datenaufbereitung. Unser Crunchbase-Graphschema speichert das Datum des Börsengangs oder der Übernahme eines Unternehmens an einer Kante. Kopiere diese Daten, damit sie auch bei den Unternehmen selbst verfügbar sind:

    Comp = SELECT c
        FROM (Company):c - ((company_ipo|acquired_by>):e) - (IPO|Company):x
        ACCUM
            CASE WHEN
              e.type == "company_ipo" AND datetime_diff(x.public_at, T0) != 0
            THEN
              c.@t_exit += x.public_at
            END,
            CASE WHEN
              e.type == "acquired_by" AND datetime_diff(e.acquired_at,T0) != 0
            THEN
              c.@t_exit += e.acquired_at
            END;

Im nächsten Schritt verbinden wir Financial_Org Eckpunkte mit ihren Investitionen Funds um die Investitionen der past_n_years zu summieren und dann die besten k Organisationen auszuwählen. Die WHERE Klausel filtert nach dem gewünschten Zeitbereich. Um die Top k zu ermitteln, bietet GSQL wie in SQL die Klauseln ORDER BY und LIMIT:

    Top_orgs = SELECT org 
        FROM (Financial_Org):org - (financial_funds:e) - Funds:f
        WHERE datetime_diff(END_2013, f.funded_at) <= past_n_years*SECS_PER_YR
        ACCUM org.@amount +=
            (f.raised_amount / @@currency2USD.get(f.raised_currency_code)),
            f.@visited = TRUE
        ORDER BY org.@amount DESC 
        LIMIT k_orgs;

Fortgeschrittene GSQL-Benutzer entscheiden sich manchmal dafür, HeapAccum anstelle von ORDER BY/LIMIT zu verwenden, weil das Sortieren eines kleinen Heaps weniger Arbeitsspeicher benötigt als die globale Sortierung, die ORDER BY durchführt.

Als nächstes wählen wir alle Mitarbeiter (Person die work_for_fOrg) bei diesen Top-Finanzorganisationen (die Top_org Eckpunkte aus dem vorherigen Schritt):

  Persons_at_top_orgs = SELECT p
      FROM Top_orgs:o - (work_for_fOrg:e) - Person:p;

Aus diesen Persons_at_top_orgs wollen wir diejenigen auswählen, die die folgenden Kriterien erfüllen, um zu einem erfolgreichen Ausstieg beizutragen:

  • Ihre Berufsbezeichnung lautete "Vorstand".

  • Das Unternehmen hat einen Exit (c.@t_exit.size() != 0).

  • Die Person hat ein gültiges Datum für den Arbeitsbeginn (datetime_diff(w.start_at, T0) != 0).

  • Der Ausstieg des Unternehmens erfolgte nach dem Eintritt des Vorstandsmitglieds.

Der folgende Code führt diese Auswahl durch:

    Top_board_members = SELECT p
        FROM Persons_at_top_orgs:p - (work_for_company:w) - Company:c
        WHERE (w.title LIKE "%Board%" OR w.title LIKE "%board%")
            AND c.@t_exit.size() != 0 AND datetime_diff(w.start_at, T0) != 0
            AND datetime_diff(c.@t_exit.get(0), w.start_at) > 0

Nachdem wir diese erfolgreichen Startup-Vorstandsmitglieder gefunden haben, erstellen wir eine Liste dieser erfolgreichen Startup-Unternehmen (@@comp_set). Wir lassen auch jedes dieser Company Vorstandsmitglied aufzeichnen (c@board_set), und wir zählen die erfolgreichen Exits jeder Schlüsselperson auf (p.@amount += 1). Schließlich nehmen wir die produktivsten Vorstandsmitglieder (ORDER BY und LIMIT):

        ACCUM
            @@comp_set += c,
            c.@board_set += p,
            p.@amount += 1
        ORDER BY p.@amount DESC 
        LIMIT num_persons;

Dann finden wir alle Pre-Exit Company Entitäten, die eine top_board_member haben:

    Top_startups = SELECT c 
        FROM Top_board_members:s - (work_for_company:w) - Company:c
        WHERE (w.title LIKE "%Board%" OR w.title LIKE "%board%")
            AND w.start_at != T0
            AND c.status == "operating" AND c.@t_exit.size() == 0;

Schließlich berücksichtigen wir nur die Unternehmen, die vor dem Ausstieg Funding_Rounds früh genug waren, um die max_cutoff_round Grenze zu erfüllen:

    Top_early_startups = SELECT r
        FROM Top_startups:s - (company_funding_rounds:e) - Funding_Rounds:r
        ACCUM 
            s.@visited += TRUE,
            IF @allowed_funding_rounds.contains(r.funding_round_code) THEN
                r.@visited = TRUE
            ELSE
                s.@early += FALSE
            END;

Der Rest der Abfrage wird verwendet, um von den Top-Vorstandsmitgliedern zurückzugehen und die Unternehmen, für die sie gearbeitet haben, sowie ihre erfolgreichen Exits anzuzeigen.

Abbildung 4-8 zeigt die Ergebnisse, wenn wir k_orgs = 10, num_persons = 2, max_funding_round = b, und past_n_years = 10 setzen. Die beiden wichtigsten Vorstandsmitglieder sind Jim Goetz und Jim Breyer, die beide für Accel Partners arbeiten. Goetz hatte vier erfolgreiche Exits, während Breyer drei hatte. Die empfohlenen Startups sind Unternehmen, die mit Goetz oder Breyer verbunden sind und noch keinen Exit haben: Nimble Storage, Ruckus Wireless, HubSpot, Booyah und Etsy.4

Graph output for top startups based on board members
Abbildung 4-8. Grafische Darstellung der Top-Startups nach Vorstandsmitgliedern (eine größere Version dieser Abbildung findest du unter https://oreil.ly/gpam0408)

Top-Startups basierend auf Leader

Unsere letzte Abfrage in diesem Starterkit ähnelt der vorherigen, nur dass wir nicht nach Top-Vorstandsmitgliedern, sondern nach Gründern suchen. Diese Abfrage hat drei Argumente. max_funding_round ist der Grenzwert für die Finanzierungsrunde, d.h. wir wählen nur Startups aus, deren Investitionsrunden nicht länger als max_funding_round zurückliegen. Das Argument return_size ist die Anzahl der Top-Startups, die wir aus unserer Abfrage abrufen wollen, und sector ist die Branche, aus der wir das Ergebnis herausfiltern wollen.

Abbildung 4-9 zeigt, wie wir diese Abfrage als eine Reihe von Graphen-Sprüngen konstruieren:

  1. Finde alle Unternehmen, die an die Börse gegangen sind oder übernommen wurden [Hop 1].

  2. Finde Arbeitnehmer, die in Schritt 1 [Hop 2] zu den Unternehmen beigetragen haben.

  3. Finde Startups, deren Gründer auch ein Schlüsselmitarbeiter aus Schritt 2 war [Hop 3]. Filtere die Startups anhand der Cutoff-Runde und des Sektors.

  4. Finde Unternehmen, deren Gründer die erfolgreichsten Verbindungen haben.

Graph traversal pattern to find promising startups based on successful founders
Abbildung 4-9. Graph-Traversal-Muster, um vielversprechende Startups auf der Grundlage erfolgreicher Gründer zu finden

Diese Abfrage führt einige Datenstrukturen ein, die wir bisher noch nicht gesehen haben: ein TUPIL und ein HeapAccum. Ein GSQL-Tupel ist ein benutzerdefinierter Datentyp, der aus einer Reihe von bestehenden Grundtypen besteht. Ein Company_Score Tupel besteht aus einem Company Scheitelpunkt gefolgt von einer ganzen Zahl. Ein HeapAccum verwaltet eine sortierte Liste von Tupeln bis zu einer benutzerdefinierten maximalen Anzahl von Elementen. Unser HeapAccum @@top_companies_heap enthält Company_Score Tupel, die nach ihren Punktwerten sortiert sind. Der Heap kann bis zu return_size Unternehmen enthalten:

    TYPEDEF TUPLE<VERTEX<Company> company, INT score> Company_Score;
    HeapAccum<Score_Results>(return_size, score DESC) @@top_companies_heap;

Wir definieren auch zwei verschachtelte MapAccums. Eine Karte ist wie eine Nachschlagetabelle. Bei der strukturellen Definition von @@person_company_leave_date_map bedeutet dies, dass wir für eine bestimmte Person aufzeichnen, wann diese Person ein bestimmtes Unternehmen verlassen hat. Für @@person_company_employment_map erfassen wir das Beschäftigungsverhältnis zwischen einer Person und a Company:

    // Declare map to store when an employee left which company
    MapAccum<VERTEX<Person>,
        MapAccum<VERTEX<Company>, DATETIME>> @@person_company_leave_date_map;
    MapAccum<VERTEX<person>,
        MapAccum<VERTEX<Company>, EDGE>> @@person_company_employment_map;

Jetzt finden wir alle Unternehmen, die an die Börse gegangen sind oder die von einem anderen Unternehmen übernommen wurden. Um den Code übersichtlicher zu gestalten, findet ein Codeblock Unternehmen, die an die Börse gegangen sind, ein anderer konzentriert sich auf Übernahmen, und dann führen wir die beiden Gruppen von Unternehmen zusammen. Für die IPOs gehen wir von IPO Eckpunkten zu Company Vertices. Wir prüfen, ob das IPO ein gültiges public_at Attribut hat. Sobald er ausgewählt ist, markieren wir jeden Company mit dem Pfad zurück zum IPO Vertex und mit dem public_at Datum. Wir kennzeichnen das Unternehmen als nicht mehr in der Startup-Phase:

    IPO_companies = SELECT c
        FROM IPO:i - (company_ipo:e) - Company:c
        //Filter out companies with null acquisition time (not yet acquired)
        WHERE datetime_diff(i.public_at, TNULL) != 0
        ACCUM
            c.@parent_vertex_set += i,
            c.@parent_edge_set += e,
            c.@min_public_date = i.public_at,
            c.@is_still_startup += FALSE;

Ein ähnlicher Codeblock findet die acquired_companies. Der Typ der Kanten ist anders (acquire anstelle von company_ipo) und das effektive Datenattribut ist anders (acquired_at statt public_at).

Dann fügen wir die Ausgabesätze aus diesen beiden Blöcken zusammen:

    IPO_acquired_companies = IPO_companies UNION Acquired_companies;

Als Nächstes wählen wir alle Personen aus, die vor dem Ausstiegsereignis für ein erfolgreich ausgeschiedenes Unternehmen gearbeitet haben. Für jede dieser Personen speichern wir die relevanten Informationen in den verschachtelten Maps, die wir zuvor beschrieben haben. Beachte den -> Operator, der verwendet wird, um das key -> value Paar einer Karte zu bestimmen:

Startup_employees = SELECT p
     FROM IPO_acquired_companies:c - (work_for_company:e) - Person:p
      WHERE datetime_diff(e.start_at, TNULL) != 0
        AND datetime_diff(e.end_at, TNULL) != 0
        AND datetime_diff(e.start_at, c.@min_public_date) < 0
      ACCUM
            @@person_company_employment_map += (p -> (c -> e)),
            @@person_company_leave_date_map += (p -> (c -> e.end_at));

Jetzt finden wir die Startups, bei denen diese erfolgreich ausgeschiedenen Mitarbeiter derzeit Gründer sind, gefiltert nach Branche. Die Prüfungen für den Startup-Status und den Gründerstatus werden in der WHERE Klausel durchgeführt:

    New_startups = SELECT c
        FROM startup_employees :p - (work_for_company :e) - Company :c
        WHERE c.@is_still_startup 
            AND c.@early_startup
            AND c.status != "acquired"
            AND c.status != "ipo"
            AND e.title LIKE "%ounder%"
            AND lower(trim(c.category_code)) == lower(trim(sector))
            AND datetime_diff(e.start_at, TNULL) != 0
            AND datetime_diff(e.end_at, TNULL) != 0

Nachdem wir diese Startups ausgewählt haben, zählen wir die bisherigen Erfolge der Gründerinnen und Gründer:

        ACCUM
        // Tally the founder:past-success relationships per new company
            FOREACH (past_company, leave_date)
            IN @@person_company_leave_date_map.get(p) DO
                IF datetime_diff(e.start_at, leave_date) > 0 THEN
                    p.@parent_edge_set +=
                      @@person_company_employment_map.get(p).get(past_company),
                    p.@company_list += past_company,
                    c.@parent_vertex_set += p,
                    c.@parent_edge_set += e,
                    c.@sum_ipo_acquire += 1
                END
            END
        HAVING c.@sum_ipo_acquire > 0;

Wähle die Unternehmen aus, bei denen die Gründer die meisten Beziehungen zu erfolgreichen Exit-Unternehmen haben. Wir verwenden die zuvor beschriebene HeapAccum, um die Unternehmen nach der Anzahl der erfolgreichen Exits ihrer Gründer/innen zu bewerten:

    Top_companies = SELECT c
        FROM Startups_from_employees:c
        ACCUM @@top_score_results_heap += Score_Results(c, c.@sum_ipo_acquire);
    PRINT @@top_score_results_heap;

    FOREACH item IN @@top_score_results_heap DO
        @@output_vertex_set += item.company;
    END;

Abbildung 4-10 zeigt die Ergebnisse, wenn die Eingangsargumente max_funding_round = c, return_size = 5 und sector = Software sind. Die fünf ausgewählten Startups sind auf der rechten Seite aufgelistet. Wenn wir das zweite Unternehmen von oben betrachten, lesen wir von rechts nach links: Packet Trap Networks wurde ausgewählt, weil der Gründer Steve Goodman Gründer/CEO von Lasso Logic war, das von SonicWALL übernommen wurde.

Graph output of top startups based on leader
Abbildung 4-10. Graphische Ausgabe der Top-Startups basierend auf dem Leader (eine größere Version dieser Abbildung findest du unter https://oreil.ly/gpam0410)

Kapitel Zusammenfassung

In diesem Kapitel haben wir gesehen, wie wir Graph-Analysen nutzen können, um wichtige Fragen zu beantworten und wertvolle Erkenntnisse über Startup-Investitionen zu gewinnen. Anhand des Graphenschemas für Crunchbase-Daten haben wir gesehen, dass solche Daten stark miteinander verknüpft sind. Bei der Anlageberatung schauen wir oft auf die vergangene Leistung als Indikator für mögliche zukünftige Ergebnisse. Wir suchen also nach einem Muster (Erfolg in der Vergangenheit) und schauen, ob sich dieses Muster möglicherweise wiederholt. Diese Art der Mustersuche oder Ähnlichkeitssuche ist typisch für die Graph-Analytik.

Wir haben in diesem Kapitel vier Abfragen besprochen, um die Muster zu identifizieren, die uns bei der Untersuchung von Investitionsmöglichkeiten helfen können. Die erste Abfrage identifiziert alle Personen mit Schlüsselrollen in einem Unternehmen. Die zweite Abfrage identifiziert erfolgreiche Exits von Startups durch einen Investor. Die dritte Abfrage zeigt uns eine Rangliste der Startups mit erfolgreichen Vorstandsmitgliedern. Die vierte Abfrage zeigt uns eine Rangliste der Startups mit erfolgreichen Gründern. Jede Abfrage zeigt, wie wir Multihops für unsere Analysen nutzen können.

In diesem Kapitel wurden verschiedene Funktionen und Techniken der GSQL-Sprache vorgestellt, wie z.B.:

  • Eine WHILE Schleife verwenden, um mehrere Ebenen tief zu suchen

  • Markierung von Eckpunkten mit einem booleschen Akkumulator, um zu kennzeichnen, dass sie besucht wurden

  • Während der mehrstufigen Durchquerung markieren wir die Eckpunkte mit parent_vertex und parent_edge, damit wir unsere Pfade später wiederfinden können.

  • Die Klauseln ORDER BY und LIMIT in einem SELECT Block verwenden, um die bestplatzierten Eckpunkte zu finden, ähnlich wie die Auswahl der bestplatzierten Datensätze in SQL

1 Alex Wilhelm, "In 2020, VCs Invested $428M into US-Based Startups Every Day", TechCrunch, 19. Januar 2021, https://techcrunch.com/2021/01/19/in-2020-vcs-invested-428m-into-us-based-startups-every-day.

2 Sandeep Babu, "STARTUP STATISTICS-The Numbers You Need to Know", Small Business Trends, 28. März 2023, https://smallbiztrends.com/2022/12/startup-statistics.html.

3 Die Akkumulatoren wurden in Kapitel 3 beschrieben.

4 Wir analysieren die Daten von Crunchbase aus dem Jahr 2013. Einige dieser Start-ups waren erfolgreich, andere nicht.

Get Graphengestützte Analysen und maschinelles Lernen mit TigerGraph now with the O’Reilly learning platform.

O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.