
Vor einigen Jahren hatten mein Team (Compliance bei einer der Schweizer Banken) und ich eine interessante Aufgabe zu implementieren - wir mussten ein riesiges zufälliges Diagramm der Finanztransaktionen zwischen Kunden, Unternehmen und Geldautomaten erstellen. Darüber hinaus wollten wir, dass dieses Diagramm neben der Beschreibung der Knoten wie Namen, Adressen, Währungen usw. auch einige Muster der Geldwäsche und anderer Finanzkriminalität enthält. Offensichtlich sollten alle Daten zufällig von Grund auf neu generiert werden, solange wir aus offensichtlichen Gründen keine echten Daten verwenden konnten.
Als Lösung haben wir einen Generator geschrieben, den ich gerne mit Ihnen teilen würde. In diesem Artikel wird erklärt, warum wir ihn benötigt haben und wie dieser Generator funktioniert. Wenn Sie ihn jedoch nicht lesen und selbst ausprobieren möchten, finden Sie hier den Code:
https://github.com/MGrin/transactions-graph- Generator . Ich hoffe, dass unsere Erfahrung für jeden von Ihnen hilfreich sein wird.
Warum haben wir uns für einen solchen Generator interessiert?
Unser Team hat beschlossen, das
LauzHack- Hackaton zu sponsern. Eine der Bedingungen für Sponsoren war die Bereitstellung einer echten Geschäftsaufgabe für die Teilnehmer, und zufällig hatten wir gleichzeitig ein interessantes Projekt im Zusammenhang mit der Entdeckung von Geldwäsche in der Grafik der Transaktion. Natürlich haben wir uns entschlossen, Hackaton-Teilnehmern die gleiche Aufgabe zu übertragen.
Wie ich bereits sagte, konnten wir keine realen Daten verwenden, daher mussten wir sie erstellen. Um die Aufgabe so realitätsnah wie möglich zu gestalten, haben wir einige Statistiken aus unseren Daten erstellt und versucht, generierte Daten so zu erstellen, dass sie ähnlichen Verteilungen folgen. Außerdem wollten wir kein kleines Diagramm haben - wir arbeiten täglich mit Milliarden von Transaktionen zwischen Millionen von Knoten und wollten den Teilnehmern die Möglichkeit geben, ihre Ideen im gleichen Maßstab auszuprobieren.
Was haben wir als Ergebnis bekommen?
Wir könnten einen ziemlich schnellen, interessanten und konfigurierbaren Graphgenerator bauen! Sehen wir uns das genauer an:
Knotentypen
Teilnehmer unseres generierten Finanzsystems:
- Kunde - ein Konto eines abstrakten Bankkunden. Enthält Felder wie Name, E-Mail, Alter, Beruf, Ausbildung, Nationalität und Adresse.
- Unternehmen - eine Geschäftseinheit in unserem Finanzsystem. Enthält Felder wie Typ, Name und Land.
- Geldautomat - ein Ausgangspunkt für das Geld aus unserem Finanzdiagramm nach draußen, wo es nicht mehr verfolgt werden kann. Enthält GPS-Koordinaten.
- Transaktion - Aufzeichnung des Geldtransfers zwischen 2 Grafikknoten. Enthält Zeiger auf Quell- und Zielknoten, Betrag, Währung sowie Datum und Uhrzeit der Ausführung.
Um diese Daten zu generieren, haben wir
Mimesis verwendet , eine großartige Bibliothek zur Erzeugung gefälschter Daten.
Graphgenerierung: grundlegende Entitäten
Der Generator beginnt mit der Erstellung grundlegender Einheiten - Kunden, Unternehmen und Geldautomaten. Das Skript verwendet eine gewünschte Anzahl von Clients als Eingabe und berechnet basierend auf dieser Anzahl die Anzahl der zu generierenden Unternehmen und Geldautomaten. Wir haben festgestellt, dass die Anzahl der Unternehmen 2,5% der Gesamtzahl der Kunden und die Anzahl der Geldautomaten 0,05% entspricht. Diese Parameter sind ziemlich gemittelt und im Generator selbst fest codiert.
Alle generierten Informationen werden in CSV-Dateien gespeichert. Das Schreiben in diese Dateien erfolgt durch Stapel von k Zeilen, wobei k ein konfigurierbarer Parameter ist. Außerdem wird jeder Knotentyp parallel generiert, um den gesamten Prozess zu beschleunigen.
Diagrammgenerierung: Kanten zwischen Objekten
Nach der Erstellung der Basisentitäten beginnen wir, diese miteinander zu verbinden. Derzeit generieren wir noch keine Transaktionen, sondern nur die Tatsache, dass zwei Knoten verbunden sind. Wir haben dies auf diese Weise getan, um den Prozess zu beschleunigen, und es funktioniert wie folgt: Wenn zwischen zwei Knoten eine Kante vorhanden ist, werden einige Transaktionen zeitlich getrennt. Kein Vorteil - überhaupt keine Transaktionen.
Die Wahrscheinlichkeit, ob und Kante zwischen zwei Knoten und mögliche Kantentypen sind:
- Kunde -> Kunde, p = 0,4%
- Kunde -> Unternehmen, p = 1%
- Kunde -> Geldautomat, p = 3%
- Firma -> Kunde, p = 0,5%
Diese Wahrscheinlichkeiten können mithilfe von Generatorparametern konfiguriert werden.
Genau wie bei Knoten werden alle Kantentypen parallel generiert und stapelweise in Dateien geschrieben.
Graphgenerierung: Transaktionen
Wenn Knoten und Kanten eine gewünschte Verteilung haben, können wir mit der Generierung von Transaktionen beginnen. Der Prozess ist einfach zu implementieren, lässt sich jedoch nur schwer parallelisieren. Aus diesem Grund arbeiten derzeit nur zwei Threads - einer für die Generierung von Client-Sourcing-Transaktionen und einer für die Generierung von Transaktionen für Unternehmen. Die Anzahl der Transaktionen für eine Kante ist zufällig und zeitlich zufällig getrennt.
Wie oben beschrieben, werden generierte Transaktionen stapelweise in CSV-Dateien geschrieben.
Graphgenerierung: Muster
Hier wird es interessant. Wir haben drei Muster definiert, die wir in unserem Diagramm haben wollten:
- Fluss - Ein großer Geldbetrag wird vom Quellknoten an N Knoten gesendet, und jeder dieser N Knoten sendet Geld an andere K Knoten usw. bis die letzte Schicht dieses Netzwerks das gesamte empfangene Geld an einen Zielknoten sendet.
- Rundschreiben - Ein großer Geldbetrag fließt durch verschiedene Knoten und kehrt zum Quellknoten zurück.
- Zeit - Ein Teil wird mehrmals von Knoten A zu Knoten B übertragen, getrennt durch eine pseudozufällige Zeit.
Lassen Sie uns diese Muster einzeln entdecken.
Flow
Wir beginnen mit der Auswahl einer Reihe von Schichten des Netzwerks. In unserer Erkenntnis ist es eine Zufallszahl zwischen 2 und 6, und diese Werte sind nicht konfigurierbar. Dann wählen wir zufällig 2 Knoten aus - Quelle und Ziel. Auch der Betrag, der von einem Quellknoten ausgegeben wird, wird zufällig als 50000 * random () + 50000 * random () generiert.
Jeder Teilnehmer dieses Netzwerks nimmt eine Zahlung für seinen Dienst entgegen. Nach unserer Erkenntnis wird die Gesamtzahlung für die gesamte Netzwerknutzung 10% des Quellbetrags nicht überschreiten.
Alle generierten Transaktionen werden zeitlich von einer Schicht zur anderen verzögert. Die Verzögerungen sind zufällig und betragen höchstens 5 Tage.
Rundschreiben
Ist dem Flussmuster ähnlich, außer dass der Quell- und der Zielknoten identisch sind und es nur einen Knoten pro Zwischenschicht gibt.
Zeit
Das einfachste Muster. Ein zufälliger Betrag wird mehrmals von Knoten A an Knoten B gesendet (Zufallszahl zwischen 5 und 50, nicht konfigurierbar) mit pseudozufälligen Verzögerungen zwischen Transaktionen.
Randomisierung der endgültigen Transaktionen
Zu diesem Zeitpunkt haben wir eine Reihe von CSV-Dateien:
- 3 Dateien mit Knoteninformationen (Kunden, Unternehmen, Geldautomaten)
- 4 Dateien mit Transaktionen: eine für normale Transaktionen und 3 für Transaktionen aus generierten Mustern.
Es gibt ein anderes Skript, das alle Transaktionen zufällig sortiert und in einer Transaktionsdatei zusammenfasst.
Was tun mit der Leistung dieses Generators?
Am Ende des Tages haben wir 4 wunderschöne CSV-Dateien mit Diagrammknoten und Transaktionen. Wir können dieses Diagramm in Neo4J importieren oder über die REST-API bereitstellen - im Grunde können wir alles damit machen! Die Größe des Diagramms kann beliebig groß sein (wir haben schließlich ein Diagramm mit 2 Milliarden Clients erstellt und es hat auf meinem MacBook 2014 ungefähr 8 Stunden gedauert).
Wir haben viele positive Rückmeldungen von Hackaton-Teilnehmern sowie einige wirklich gute Lösungen für Mustererkennungsprobleme in großen Graphen.
Vielen Dank für Ihre Zeit und hier ist der Link zum Generator:
https://github.com/MGrin/transactions-graph-generator