Mirkan Deniz Günkaya

Projekt 03 · Graph-ML

NetzRadar

Anomalie-Erkennung in Transaktionsnetzwerken

Fallstudie mit vorab berechneten Ergebnissen. Die Fragestellung: Wie viel gewinnt ein Modell, das die Nachbarschaft einer Transaktion einbezieht, gegenüber einer Baseline auf lokalen Merkmalen, bei gleichem Split und gleichen Metriken?

Diese Seite nimmt keine Eingaben und keine Dateien entgegen. Die vorberechneten Ergebnisse sind beim Erstellen der Seite in HTML und JavaScript eingebettet; nach dem Laden werden nur Programmteile (JavaScript und Seitendaten verlinkter Seiten) vom selben Server nachgeladen, keine weiteren Daten und keine Inhalte von Dritten. Es gibt keine Anmeldung, keine Cookies und kein Tracking.

Verfahren2 Baselines, 2 überwachte Verfahren ohne Kanten und 2 Graph Neural Networks
6
ZeitschritteTraining 1–21, Test 22–30
30
Anfragen an DritteErgebnisse vorab berechnet, kein Modell im Browser
0

Auf einen Blick

PR-AUC je Verfahren

Z-Scores
0,1633
nur lokale Merkmale, ohne Labels
Isolation Forest
0,1281
lokale Merkmale und Graphmaße, ohne Labels
Gradient Boosting
0,6087
lokale Merkmale und Graphmaße, mit Labels, ohne Kanten
GCN
0,7897
lokale Merkmale und Graphmaße, mit Labels und Nachbarschaft
GraphSAGE
0,8941
lokale Merkmale und Graphmaße, mit Labels und Nachbarschaft
MLP (ohne Kanten)
0,3765
lokale Merkmale und Graphmaße, mit Labels, ohne Kanten
Zufällige Rangfolge
0,1181
PR-AUC im Erwartungswert, 95 % bleiben unter 0,1420
Konstanter Score
0,1115
PR-AUC, wenn alle Knoten denselben Score haben (Prävalenz)
Testknoten mit Label
852
davon 95 mit Label illegal

Balken: PR-AUC auf der Skala von 0 bis 1. Strich: Erwartungswert einer zufälligen Rangfolge.

Zur Einordnung der Ergebnisse

Stand der Ergebnisse: 28.10.2026. Gemessen sind die Baselines (Z-Scores und Isolation Forest), als starkes überwachtes Verfahren ohne Kanten ein Gradient Boosting, die Graph Neural Networks GCN und GraphSAGE und als Kontrolle ein MLP ohne Kanten, alle mit demselben zeitlichen Split und auf denselben Testknoten. Alle Messungen stammen aus dem Datensatz „Synthetisches Transaktionsnetz“. Offen: Case-Study, Läufe mit gestörter Nachbarschaft, Baseline mit gemittelten Nachbarmerkmalen. Was die Zahlen tragen und was nicht, steht unter „Einordnung der Ergebnisse“ und „Grenzen“.

Daten

Datensatz

Die öffentliche Demo nutzt den Datensatz „Synthetisches Transaktionsnetz“ (Lizenz MIT), ein eigenes, frei veröffentlichbares Netz. Knoten sind Transaktionen, gerichtete Kanten der Geldfluss zwischen ihnen. Der Generator (services/k3-train/src/k3_train/synth.py (externe Seite), Seed 42) legt einen gutartigen Hintergrund nach Preferential Attachment an, in dem einzelne Knoten viele Kanten haben, und baut darin bekannte Geldwäsche-Muster ein: Fan-in, Fan-out, Kreise und Ketten.

Wie bei realen Daten trägt nur ein Teil der Knoten ein Label. Im Generator erhält ein Musterknoten mit Wahrscheinlichkeit 55 % das Label illegal, ein gutartiger Knoten mit Wahrscheinlichkeit 22 % das Label legal. Alle übrigen bleiben ohne Label; unter den Knoten ohne Label stecken also auch Musterknoten.

Die Zahlen gelten nur für dieses Netz. Wie schwer die Aufgabe ist, legen die Annahmen des Generators fest, etwa wie stark sich die meisten lokalen Merkmale der Musterknoten verschieben (localShift = 0,5 Standardabweichungen). Deutlich stärker weicht der größte Ausgangsanteil der Fan-out-Verteiler ab, und runde Beträge sind bei Musterknoten doppelt so häufig. Fan-in-Sammler haben als Summe vieler Zubringer einen höheren Betrag und einen kleineren Variationskoeffizienten der Eingangsbeträge (die Beträge der Zubringer streuen weniger).

Vorgesehen sind zwei weitere Datensätze, beide nur für einen lokalen Methodenvergleich: IBM Transactions for Anti-Money Laundering (synthetisch, Lizenz CDLA-Sharing-1.0) und das Elliptic Bitcoin Dataset (Lizenz CC BY-NC-ND 4.0). Ausgewertet ist bisher keiner von beiden. Die öffentliche Demo auf dieser Seite bleibt das synthetische Netz; aus beiden Datensätzen werden weder Rohdaten noch bearbeitete Fassungen oder Ausschnitte veröffentlicht.

Begriffe auf dieser Seite

Label
illegal, legal oder ohne Label. Das Label steht im Datensatz fest und ist der Maßstab, an dem die Verfahren gemessen werden; es ist keine rechtliche Bewertung realer Vorgänge.
Score
Ausgabe eines Verfahrens je Knoten. Ein hoher Score heißt: weit oben in der Rangfolge dieses Verfahrens. Der Score ist eine Einschätzung des Modells, kein Label.
markiert
Knoten, deren Score eine gewählte Schwelle erreicht, etwa die obersten Test-Scores bei der Accuracy. Ob ein markierter Knoten das Label illegal trägt, zeigen Precision und Recall.
Alle 38 Generator-Parameter
timeSteps
30
nodesPerStep
400
seed
42
illicitShare
0,04
minPatternsPerStep
1
illicitVisibility
0,55
licitVisibility
0,22
attachmentPower
1
extraEdgeRatio
0,15
patternLinkProbability
0,3
fanSizeMin
5
fanSizeMax
12
cycleLengthMin
3
cycleLengthMax
6
chainLengthMin
4
chainLengthMax
8
localShift
0,5
logAmountMean
5,5
logAmountSd
1,5
smurfLogAmountSd
0,5
hopNoiseSd
0,02
cycleFeeRate
0,01
chainRetention
0,97
fanOutConcentration
5
logHoursMean
3
logHoursSd
1,2
logAgeMean
5
logAgeSd
1
roundAmountRate
0,1
changeOutputRate
0,7
feeSlope
0,4
feeIntercept
−2
feeSd
0,6
extraIoRate
1
maxOutputShareAlpha
4
maxOutputShareBeta
1,5
inputCvShape
2
inputCvScale
0,35
Knoten
12.000
Kanten
13.757
Zeitschritte
30
Lokale Merkmale
12
Labels im gesamten Netz
LabelKnotenAnteil
illegal2922,4 %
legal2.58721,6 %
ohne Label9.12176,0 %

Graph-Ansicht

Netzwerk-Ausschnitt

Gezeigt werden zwei Startmengen aus je 50 Testknoten, beide ohne Rücksicht auf das Label ausgewählt: die mit dem höchsten Isolation-Forest-Score und die mit dem höchsten GNN-Score (GraphSAGE). Dazu kommt jeweils die Nachbarschaft bis 2 Kanten Abstand, ungerichtet gezählt. Der Ausschnitt ist die Vereinigung beider Nachbarschaften: 1.695 Knoten und 1.841 Kanten. 1.635 Knoten liegen in der Nachbarschaft der Startknoten nach Isolation-Forest-Score, 102 in der nach GNN-Score, 42 in beiden; 2 Knoten gehören zu beiden Startmengen. Nicht gekürzt: Die Obergrenze liegt bei 2.000 Knoten, gekürzt würde zuerst bei den Knoten mit dem größten Abstand zu den Startknoten, nie bei Startknoten. Die Positionen hat der Export vorab berechnet (Federlayout, Seed 42); der Browser zeichnet nur. Der Ausschnitt besteht aus 13 zusammenhängenden Teilen.

Der GNN-Score stammt von GraphSAGE, dem Graph Neural Network mit der höheren PR-AUC auf dem Validierungsteil (0,9349 gegen 0,7364 bei GCN); der Testteil entscheidet darüber nicht. Der Umschalter über dem Graphen wählt, welche Startmenge die Tabelle zeigt und der Graph groß zeichnet; das Detailfeld nennt für jeden Knoten beide Ränge und Abstände. Der GNN-Score ist eine Differenz zweier Logits ohne feste Ober- und Untergrenze. Ein Wert über 0 heißt nur, dass das Logit für Label illegal das für Label legal übersteigt. Als Schwelle ist 0 nicht kalibriert: Das Training gewichtet Knoten mit Label illegal mit w = 9,2893, und eine Kalibrierung auf Wahrscheinlichkeiten fehlt. Die Seite liest den GNN-Score deshalb nur als Rangfolge.

Von den 50 Startknoten nach Isolation-Forest-Score tragen 2 das Label illegal, 10 das Label legal und 38 kein Label. Von den 50 Startknoten nach GNN-Score (GraphSAGE) tragen 29 das Label illegal, keiner das Label legal und 21 kein Label.

Ziehen verschiebt den Ausschnitt, das Mausrad zoomt; auf Touch-Geräten mit zwei Fingern zoomen und verschieben. Außerhalb des Graphen scrollen Sie die Seite. Ein Klick auf einen Knoten hebt ihn und seine Nachbarn hervor und zeigt die Werte im Detailfeld. Ohne Maus lässt sich jeder Startknoten über die Tabelle auswählen; der Umschalter über dem Graphen wechselt die Startmenge.

Startknoten nach Score

Groß gezeichnet und in der Tabelle: die 50 Testknoten mit dem höchsten Isolation-Forest-Score, kleiner ihre Nachbarn bis 2 Kanten Abstand. 60 Knoten liegen nur in der Nachbarschaft der Startknoten nach GNN-Score (GraphSAGE) und erscheinen am kleinsten.

Tabelle und Graph zeigen die Startknoten nach Isolation-Forest-Score.

Legende: Label im Datensatz (keine rechtliche Bewertung)

  • illegal(gefüllt, mit Goldring)
  • legal(gefüllt, ohne Ring)
  • ohne Label(hohl)
  • großer Kreis: Startknoten der gewählten Startmenge; klein: Nachbar im Abstand 1 oder 2; am kleinsten: nur über die andere Startmenge im Ausschnitt
  • Pfeil: Richtung des Transaktionsflusses

Detailfeld

Ausgewählter Knoten

Kein Knoten ausgewählt

Noch kein Knoten gewählt.

Wählen Sie einen Knoten in der Graph-Ansicht oder in der Tabelle der Startknoten aus. Angezeigt werden dann Label, Zeitschritt, die Scores der Verfahren, Grade und Nachbarn.

Startknoten

Die 50 Testknoten mit dem höchsten Isolation-Forest-Score

Die 50 Startknoten, sortiert nach dem Isolation-Forest-Score. Die letzte Spalte zeigt zum Vergleich den GNN-Score (GraphSAGE), eine Logit-Differenz ohne feste Ober- und Untergrenze. Ein Klick auf eine Zeile oder Enter auf der ID wählt den Knoten im Graph aus.

Startknoten des Netzwerk-Ausschnitts nach Isolation-Forest-Score
RangIDLabelZeitschrittScore Isolation ForestScore robuste Z-ScoresScore GNN (GraphSAGE)
1ohne Label220,74729,4429−19,9567
2ohne Label250,72229,4429−19,1125
3legal290,71454,7214−13,8810
4ohne Label240,71365,3959−15,2083
5ohne Label220,70647,4194−13,8092
6ohne Label270,69966,0704−23,8408
7ohne Label250,69646,7449−5,6600
8ohne Label270,68896,7449−21,2152
9ohne Label300,68766,0704−14,7893
10ohne Label280,68236,0704−14,5122
11legal240,68205,3959−16,9226
12ohne Label260,68198,7684−13,0744
13legal290,67536,0704−13,4901
14ohne Label230,67356,0704−13,4394
15ohne Label270,66924,0469−15,3699
16ohne Label230,66594,7214−9,6891
17ohne Label250,66164,0469−9,9251
18ohne Label300,66044,0469−23,0422
19ohne Label220,65935,3959−10,5118
20ohne Label260,65892,6980−15,9198
21ohne Label290,65574,7214−13,6060
22ohne Label240,65576,0704−11,5483
23legal260,65186,0704−15,5686
24ohne Label240,64946,0704−5,3512
25ohne Label270,64945,3959−12,7075
26ohne Label240,64855,3959−15,1341
27ohne Label240,64724,0469−9,0555
28legal260,64635,3959−13,1160
29ohne Label290,64003,3725−14,7854
30ohne Label230,63985,3959−6,3249
31ohne Label260,63704,0469−14,7273
32ohne Label280,63554,0469−10,4214
33ohne Label250,63256,7449−13,4694
34ohne Label280,63024,7214−11,4349
35legal260,62986,0704−18,3157
36illegal280,62907,419414,6573
37legal250,62883,0724−7,2859
38ohne Label280,62724,0469−15,7604
39ohne Label220,62613,3725−11,0860
40ohne Label230,62294,7214−6,1187
41ohne Label250,62194,0469−12,0545
42ohne Label260,62033,3725−7,3809
43ohne Label250,61593,1001−12,2758
44legal280,61104,0469−11,7018
45legal230,61014,7214−12,7259
46ohne Label250,61003,3725−6,8315
47legal270,60993,3725−12,1630
48ohne Label300,60964,0469−4,3419
49ohne Label250,60855,39599,0962
50illegal240,60856,070412,4518

Ergebnisse

Metriken

Kennzahlen je Verfahren auf den Testknoten mit Label. Hauptmetrik ist die PR-AUC; Accuracy steht nur als Nebenwert daneben.

Testzeitraum Zeitschritte 22 bis 30: 852 Knoten mit Label, davon 95 mit Label illegal und 757 mit Label legal. Knoten ohne Label sind nicht bewertet. Kennzahlen mit Seed 42; zur Spanne über die Seeds siehe den Hinweis unter der Tabelle.

Kennzahlen je Verfahren auf den Testknoten mit Label
VerfahrenPR-AUCSpanne über 5 SeedsPrecision bei Recall ≥ 0,5Recall bei Precision ≥ 0,5Accuracy (Nebenwert)
Robuste Z-Scores (Einzelmerkmale)nur lokale Merkmale, 12 Merkmale, davon 10 wirksam (MAD = 0 bei 2)ohne Labels angepasst0,1633ohne Zufallsanteil0,13240,02110,8744
Isolation Forest (Einzelmerkmale + Graphmaße)lokale Merkmale und Graphmaße, 16 Merkmaleohne Labels angepasst0,1281nur Seed 42 gerechnet0,13400,00000,8744
Gradient Boosting (ohne Kanten)lokale Merkmale und Graphmaße, 16 Merkmalemit Labels trainiert, ohne Kanten0,60870,6087in allen 5 Seeds gleich, kein Zufallsanteil0,64000,57890,9049
GCN (2 Schichten)lokale Merkmale und Graphmaße, 16 Merkmalemit Labels trainiert, Nachbarschaft bis 2 Kanten Abstand0,78970,7897 bis 0,8148Mittel 0,80020,96080,83160,9096
GraphSAGE (2 Schichten)lokale Merkmale und Graphmaße, 16 Merkmalemit Labels trainiert, Nachbarschaft bis 2 Kanten Abstand0,89410,8689 bis 0,8941Mittel 0,88421,00000,94740,9096
MLP ohne Kanten (2 Schichten)lokale Merkmale und Graphmaße, 16 Merkmalemit Labels trainiert, ohne Kanten0,37650,3418 bis 0,4010Mittel 0,37840,28160,22110,8955
Zufällige RangfolgeScore ohne Information0,1181Erwartungswert der PR-AUC; 95 % von 10.000 zufälligen Rangfolgen (Seed 42) bleiben unter 0,1420.
Konstanter ScoreAnteil der Testknoten mit Label illegal (Prävalenz)0,1115PR-AUC, wenn alle Knoten denselben Score haben

Spanne: kleinster bis größter Wert der PR-AUC über die Seeds 42 bis 46 und ihr Mittel, nur bei den gelernten Verfahren. Mit jedem Seed wird nur das Endmodell neu trainiert; Daten, Merkmalssatz, Gewicht und Epochen- bzw. Baumzahl bleiben gleich. Beim Gradient Boosting ist die Spanne 0: Ohne Stichprobe von Zeilen oder Merkmalen und ohne Early Stopping zieht das Verfahren nichts zufällig, jeder Seed liefert dasselbe Modell. Bei GCN, GraphSAGE und MLP (ohne Kanten) zeigt die Spanne, wie stark Startwerte der Gewichte und Dropout die Kennzahl verschieben. Ein Maß für die Unsicherheit durch die Daten ist die Spanne bei keinem Verfahren.

PR-AUC (Average Precision)
Fläche unter der Precision-Recall-Kurve als Treppensumme, Hauptmetrik.
Precision bei Recall ≥ 0,5
Höchste Precision über alle Schwellen, bei denen mindestens die Hälfte der Testknoten mit Label illegal gefunden wird.
Recall bei Precision ≥ 0,5
Höchster Recall über alle Schwellen, bei denen mindestens jeder zweite markierte Knoten das Label illegal trägt; 0, wenn keine Schwelle das erreicht.
Accuracy (Nebenwert)
Schwelle: oberste 2 % der Test-Scores (gelabelte Testknoten) gelten als markiert, Gleichstände an der Schwelle eingeschlossen. Markierte Knoten: Z-Scores 22, davon 5 mit Label illegal; Isolation Forest 18, davon 3 mit Label illegal; Gradient Boosting 18, davon 16 mit Label illegal; GCN 18, davon 18 mit Label illegal; GraphSAGE 18, davon 18 mit Label illegal; MLP (ohne Kanten) 18, davon 12 mit Label illegal. Richtig sind markierte Knoten mit Label illegal und nicht markierte mit Label legal. Zum Vergleich: Ein Modell, das keinen Knoten markiert, erreicht 0,8885.

Abbildung

Precision-Recall-Kurven

  • Z-Scores
  • Isolation Forest
  • Gradient Boosting
  • GCN
  • GraphSAGE
  • MLP (ohne Kanten)
  • Prävalenz (0,1115)
Precision über Recall auf den 852 Testknoten mit Label, als Treppenkurve wie bei der Average Precision. Jede Kurve beginnt bei der höchsten Schwelle; den künstlichen Startpunkt von scikit-learn (Recall 0, Precision 1) enthält der Export nicht. Für die Darstellung ist jede Kurve auf höchstens 101 Punkte ausgedünnt; die Kennzahlen in der Tabelle stammen aus der vollständigen Kurve. Die gestrichelte waagrechte Linie ist die Prävalenz, also die Precision, die ein Score ohne Information bei jedem Recall im Mittel erreicht.

Vorgehen

Methodik

Split, Verfahren, Auswahl und Metrik im Einzelnen, mit den Werten der Läufe auf dieser Seite.

Zeitlicher Split

Trainiert wird auf den Zeitschritten 1–21, getestet auf 22–30. Die Zeitschritte 18–21 am Ende des Trainingszeitraums sind als Validierungsteil reserviert; dort werden Merkmalssatz, Klassengewicht und Epochenzahl der gelernten Verfahren gewählt (beim Gradient Boosting statt der Epochen die Zahl der Bäume und ihre Blattzahl), nie am Testteil. Kein Zeitschritt liegt auf beiden Seiten, und zwischen Trainings- und Testknoten verläuft keine Kante (crossSplitEdges = 0). Median, MAD und der Isolation Forest werden nur auf Trainingsknoten angepasst, ohne Labels. Die gelernten Verfahren sehen Labels nur aus den Trainingszeitschritten.

Robuste Z-Scores

zij = (xij − Medianj) / (1,4826 · MADj),   Scorei = maxj |zij|

Für jedes der 12 lokalen Merkmale j kommen Median und MAD (Median der absoluten Abweichungen vom Median) nur aus den Trainingsknoten. Der Faktor 1,4826 ≈ 1/Φ⁻¹(0,75) macht die MAD bei Normalverteilung mit der Standardabweichung vergleichbar. Merkmale mit MAD = 0 tragen 0 bei; auf den Trainingsknoten dieses Netzes trifft das auf f_round_amount und f_change_output zu, wirksam sind also 10 der 12 Merkmale. Median und MAD reagieren kaum auf einzelne Ausreißer, anders als Mittelwert und Standardabweichung.

Isolation Forest

200 Bäume (scikit-learn, Seed 42) auf den Trainingsknoten ohne Labels. Zufällige Schnitte isolieren einen Punkt; wird er im Mittel nach wenigen Schnitten isoliert, bekommt er einen hohen Score. Der Score ist −score_samples: je früher ein Punkt isoliert wird, desto höher. Merkmale sind die 12 lokalen Merkmale und vier Graphmaße. Der Parameter contamination = 0,02 setzt nur die interne Schwelle von scikit-learn und ändert den Score nicht.

Graphmaße

Eingangs- und Ausgangsgrad, Betweenness-Zentralität auf dem gerichteten Graphen je Zeitschritt und Eigenvektor-Zentralität auf seiner ungerichteten Fassung. Sie beschreiben die Lage eines Knotens im Netz, nicht aber die Merkmale seiner Nachbarn. Genau das ergänzen die Graph Neural Networks. Die Graphmaße stammen zwar aus den Kanten, aber Gradient Boosting und MLP heißen hier trotzdem „ohne Kanten“: Sie rechnen kein Message Passing, und der Score eines Knotens hängt nur von seiner eigenen Zeile ab.

Gradient Boosting ohne Kanten

Gradient Boosting (HistGradientBoostingClassifier aus scikit-learn) baut nacheinander kleine Entscheidungsbäume f1, …, fM. Jeder neue Baum wird an die Gradienten des Log-Loss der bisherigen Summe angepasst und korrigiert so deren Fehler. Der Score eines Knotens ist die Summe aller Bäume, gelesen als Log-Odds für das Label illegal (p ist die geschätzte Wahrscheinlichkeit für dieses Label):

Score(x) = F0 + η · Σm=1M fm(x) = log(p / (1 − p))

mit dem Startwert F0, den Log-Odds des Anteils der Trainingszeilen mit Label illegal, der Lernrate η = 0,1 und M = 128 Bäumen. Für die PR-AUC zählt nur die Rangfolge der Scores. Jeder Baum hat höchstens 7 Blätter und mindestens 20 Knoten je Blatt, ohne L2-Regularisierung; die Merkmale werden vorab in höchstens 255 Intervalle geteilt, nur aus den Trainingszeilen. Gelernt wird auf denselben Merkmalen wie bei den übrigen Verfahren (12 lokale, im gewählten Merkmalssatz zusätzlich 4 Graphmaße), aber ohne Nachbarn. Auf tabellarischen Daten ist Gradient Boosting der übliche starke Vergleich. Auf diesem Netz liegt das Gradient Boosting deutlich über dem MLP (0,6087 gegen 0,3765); der Abstand der Graph Neural Networks zu ihm ist deshalb ein strengerer Vergleich als der zum MLP. Dieser Abstand mischt aber den Wechsel von Bäumen zu neuronalen Netzen mit der Wirkung der Nachbarschaft; allein in den Kanten unterscheiden sich die Graph Neural Networks nur vom MLP.

Die Suche läuft wie bei den Graph Neural Networks nur am Validierungsteil, hier über 8 Kandidaten: nur lokale Merkmale oder zusätzlich Graphmaße, Gewicht der Knoten mit Label illegal als Verhältnis aus den Labels oder fest 1 (also ungewichtet) und höchstens 7 oder 31 Blätter je Baum. Jeder Kandidat lernt bis zu 300 Bäume auf den Zeitschritten 1–17; seine Baumzahl ist die Stelle mit der höchsten PR-AUC auf den Zeitschritten 18–21. Gewählt wurden lokale Merkmale und Graphmaße, w = 1 (fest), 7 Blätter und 128 Bäume (Validierungs-PR-AUC 0,5294). Das Endmodell lernt mit genau dieser Einstellung auf den Zeitschritten 1–21. Ohne Early Stopping und ohne Stichprobe von Zeilen oder Merkmalen zieht das Verfahren nichts zufällig; es rechnet auf einem Thread, damit Gleitkommasummen nicht von der Reihenfolge abhängen.

Graph Neural Networks: Message Passing

Ein Graph Neural Network rechnet in Schichten. In Schicht k fasst jeder Knoten v die Darstellungen h seiner Nachbarn N(v) aus der vorigen Schicht mit einer Aggregation AGG zusammen, etwa einer normierten Summe oder einem Mittelwert. UPDATE verbindet das Ergebnis über gelernte Gewichte mit der eigenen Darstellung des Knotens, danach folgt eine Nichtlinearität σ, in der letzten Schicht ohne σ:

hv(k) = σ(UPDATE(hv(k−1), AGG({hu(k−1) : u ∈ N(v)}))),   hv(0) = xv

Startwert sind die skalierten Merkmale xv des Knotens. Nach 2 Schichten hängt die Ausgabe eines Knotens nur von Knoten ab, die höchstens 2 Kanten entfernt sind. Hier haben die neuronalen Verfahren GCN, GraphSAGE und MLP (ohne Kanten) dieselbe Form: 2 Schichten mit 64 versteckten Einheiten, ReLU und Dropout 0,5 nach der ersten Schicht und zwei Ausgaben, je eine für das Label illegal und das Label legal. Trainiert wird mit Adam (Lernrate 0,01, Weight Decay 0,0005) auf dem ganzen Graphen auf einmal; eine Epoche ist genau ein Optimierungsschritt. Die Kanten zählen in beide Richtungen. Die Richtung des Geldflusses steckt weiter in den Merkmalen: Zahl der Ein- und Ausgänge, im Merkmalssatz mit Graphmaßen auch Ein- und Ausgangsgrad.

Alle Knoten sind im Graphen, auch die Testknoten und die ohne Label. Das ist kein Leck: Zwischen Trainings- und Testknoten verläuft keine Kante (crossSplitEdges = 0), Nachrichten erreichen Trainingsknoten also nur von Trainingsknoten. Damit hängen Ausgaben, Verlust und Gradienten der Trainingsknoten nicht von Testmerkmalen ab. Labels sind nie Eingabe, nur Ziel im Verlust, und Testlabels gehen nie in den Verlust ein.

GCN und GraphSAGE

GCN (Kipf und Welling) bildet eine normierte Summe über die Nachbarn und den Knoten selbst:

hv′ = Σu ∈ N(v) ∪ {v} W hu / √(d̃u d̃v),   d̃ = Grad + 1

Jeder Beitrag wird durch die Wurzel aus beiden Graden geteilt. Nachbarn mit wenigen Kanten zählen dadurch mehr, Knoten mit vielen Kanten weniger. Eigene und fremde Merkmale laufen durch dasselbe Gewicht W. GraphSAGE in der Variante mit Mittelwert hält die eigenen Merkmale getrennt:

hv′ = W1 hv + W2 · (1 / |N(v)|) Σu ∈ N(v) hu

Am Beispiel der Kette A – B – C – D mit Startwerten x = (1, 0, 0, 1), allen Gewichten 1, ohne Bias und ohne Nichtlinearität ergibt eine Schicht:

Eine Schicht Message Passing auf der Kette A bis D
RegelABCD
Startwert x1,00000,00000,00001,0000
Mittelwert über N(v) ∪ {v}0,50000,33330,33330,5000
GCN0,50000,40820,40820,5000
GraphSAGE1,00000,50000,50001,0000
MLP ohne Kanten1,00000,00000,00001,0000

Weil B und C den Wert 0 haben, stammt der Wert von B ganz von A: GCN gibt 0,4082 = 1/√(2 · 3), der einfache Mittelwert 0,3333 = 1/3. A hat weniger Nachbarn als B und zählt bei GCN deshalb mehr. GraphSAGE behält bei A und D den eigenen Wert 1 und addiert den Mittelwert der Nachbarn. Das MLP sieht keine Nachbarn: B und C bleiben 0.

Kontrolle: MLP ohne Kanten

hv′ = W hv

Die Kontrolle hat dieselbe Größe (2 Schichten, 64 Einheiten), dieselben Labels und dasselbe Auswahlverfahren: dieselben Kandidaten für Merkmalssatz und Klassengewicht, Auswahl am selben Validierungsteil. Sie hat aber lineare Schichten statt der Faltungen und damit keine Kanten. Welcher Merkmalssatz, welches Gewicht und wie viele Epochen gewählt werden, entscheidet die Suche für jedes Verfahren getrennt; die Endmodelle stehen unter der Tabelle der Suche. Der Abstand zwischen einem Graph Neural Network und dem MLP misst deshalb, was die Nachbarschaft bei gleicher Überwachung und gleichem Auswahlverfahren bringt. Der Abstand zwischen MLP und Baselines mischt dagegen die Wirkung der Labels mit dem Wechsel des Verfahrens und gegebenenfalls des Merkmalssatzes. Das MLP ist auf diesem Netz aber deutlich schwächer als das Gradient Boosting (0,3765 gegen 0,6087). Gegen das MLP gerechnet fällt der Beitrag der Nachbarschaft größer aus als gegen das Gradient Boosting; die Einordnung rechnet deshalb vorsichtig gegen das stärkste Verfahren ohne Kanten.

Klassengewichtung

Knoten mit Label illegal sind selten. Trainiert wird deshalb mit gewichteter Kreuzentropie:

L = Σi ∈ ℒ wy(i) · (−log pi, y(i)) / Σi ∈ ℒ wy(i),   wy(i) = 1 bei Label legal, w bei Label illegal

Die Summe läuft über die Knoten mit Label in der Verlustmenge ℒ; Knoten ohne Label und Testknoten gehen nie in den Verlust ein. Weil durch die Summe der Gewichte geteilt wird, zählt nur das Verhältnis w. Standard ist w = Zahl der Knoten mit Label legal durch Zahl der Knoten mit Label illegal in der Verlustmenge; dann tragen beide Klassen dasselbe Gesamtgewicht. In der Auswahl ergibt das w = 8,3409, beim Endmodell auf dem ganzen Trainingszeitraum w = 9,2893. Als zweiter Kandidat läuft ein festes Gewicht w = 20 mit. Das Gewicht verschiebt die vorhergesagten Chancen um den Faktor w, ändert im Optimum aber nicht die Rangfolge der Knoten, und nur die Rangfolge zählt für die PR-AUC. Es wirkt über den Trainingsverlauf: wie stark die seltenen Knoten mit Label illegal die Gradienten bestimmen. Deshalb ist auch der GNN-Score keine Wahrscheinlichkeit, sondern die Differenz der beiden Logits. Das Gradient Boosting gewichtet seinen Log-Loss auf dieselbe Weise über Stichprobengewichte; als festes Gewicht läuft dort w = 1 mit, also ungewichtet.

Auswahl am Validierungsteil, Endmodell auf dem Trainingszeitraum

Für die neuronalen Verfahren werden die Merkmale je Spalte robust skaliert: Median und 1,4826 · MAD kommen nur aus den Knoten der jeweiligen Trainingszeitschritte, bei MAD = 0 ersetzt die Standardabweichung die MAD, und Werte jenseits von ±10 werden gekappt. Je Verfahren laufen 4 Kandidaten: nur lokale Merkmale oder zusätzlich Graphmaße, Gewicht als Verhältnis oder fest. Jeder trainiert auf den Zeitschritten 1–17 und wird nach jeder Epoche auf den Knoten mit Label der Zeitschritte 18–21 bewertet. Nach 50 Epochen ohne Verbesserung bricht das Training ab, spätestens nach 300. Gewählt wird der Kandidat mit der höchsten PR-AUC auf dem Validierungsteil, bei Gleichstand der frühere, als Epochenzahl seine beste Epoche.

Danach wird das Endmodell neu auf den Zeitschritten 1–21 trainiert, mit Skalierung und Gewicht aus diesen Zeitschritten und genau der gewählten Zahl an Epochen, und einmal auf dem Testteil bewertet, mit denselben Funktionen wie die Baselines. Der Testteil entscheidet weder über Merkmale noch über Gewicht oder Epochen.

Versuchsaufbau

Zeitlicher Split

Training, Zeitschritte 1–21davon Validierung, Zeitschritte 18–21Test, Zeitschritte 22–30
Seed
42
Kanten über den Split
0
Testknoten mit Label
852
Hauptmetrik
PR-AUC

Verfahren: Z-Scores, Isolation Forest, Gradient Boosting, GCN, GraphSAGE und MLP (ohne Kanten).

Suche am Validierungsteil

Alle Kandidaten der Suche, auch die verworfenen: Training auf den Zeitschritten 1–17, PR-AUC auf dem Validierungsteil 18–21. Hervorgehoben ist der gewählte Kandidat je Verfahren. Bei GCN, GraphSAGE und MLP (ohne Kanten) ist die beste Stelle die Epoche mit der höchsten PR-AUC auf dem Validierungsteil und Abbruch die letzte trainierte Epoche. Beim Gradient Boosting nennt die Spalte Blätter die Höchstzahl der Blätter je Baum; die beste Stelle ist die Zahl der Bäume mit der höchsten PR-AUC auf dem Validierungsteil (Kurve bis 300 Bäume, ohne Abbruch).

Suche der gelernten Verfahren am Validierungsteil
VerfahrenMerkmaleGewicht wBlätterPR-AUC Validierungbeste Epoche bzw. BäumeAbbruchAuswahl
Gradient Boostinglokal8,3409 (Verhältnis aus den Labels)70,3403136––
lokal8,3409 (Verhältnis aus den Labels)310,2603281––
lokal1 (fest)70,3730110––
lokal1 (fest)310,280630––
lokal + Graphmaße8,3409 (Verhältnis aus den Labels)70,524772––
lokal + Graphmaße8,3409 (Verhältnis aus den Labels)310,514070––
lokal + Graphmaße1 (fest)70,5294128–gewählt
lokal + Graphmaße1 (fest)310,503468––
GCNlokal8,3409 (Verhältnis aus den Labels)–0,67934191–
lokal20 (fest)–0,651762112–
lokal + Graphmaße8,3409 (Verhältnis aus den Labels)–0,7286137187–
lokal + Graphmaße20 (fest)–0,7364140190gewählt
GraphSAGElokal8,3409 (Verhältnis aus den Labels)–0,805390140–
lokal20 (fest)–0,7724184234–
lokal + Graphmaße8,3409 (Verhältnis aus den Labels)–0,9349300300gewählt
lokal + Graphmaße20 (fest)–0,9270159209–
MLP (ohne Kanten)lokal8,3409 (Verhältnis aus den Labels)–0,27222979–
lokal20 (fest)–0,26421161–
lokal + Graphmaße8,3409 (Verhältnis aus den Labels)–0,4816858–
lokal + Graphmaße20 (fest)–0,49701666gewählt

Endmodelle: Gradient Boosting mit lokalen Merkmalen und Graphmaßen, w = 1 (fest) und 128 Bäumen mit höchstens 7 Blättern; GCN mit lokalen Merkmalen und Graphmaßen, w = 20 (fest) und 140 Epochen; GraphSAGE mit lokalen Merkmalen und Graphmaßen, w = 9,2893 (Verhältnis aus den Labels) und 300 Epochen; MLP (ohne Kanten) mit lokalen Merkmalen und Graphmaßen, w = 20 (fest) und 16 Epochen. Die PR-AUC auf dem Validierungsteil dient nur dem Vergleich der Kandidaten untereinander. Der Validierungsteil ist klein und umfasst andere Zeitschritte als der Testteil (18–21 gegen 22–30); Validierungs- und Testwerte sind deshalb nicht direkt vergleichbar. An der Obergrenze lag die Auswahl bei GraphSAGE (beste Epoche auf der Obergrenze von 300 Epochen); dort hat die Suche nicht vor der Grenze gestoppt, mehr Epochen könnten den Wert ändern.

Warum PR-AUC statt Accuracy

Von den 852 Testknoten mit Label tragen 95 das Label illegal, also 11,15 %. Ein Modell, das keinen Knoten markiert, erreicht damit eine Accuracy von 0,8885, ohne einen einzigen Knoten mit Label illegal zu finden. Die PR-AUC bewertet dagegen, wie weit oben die Knoten mit Label illegal in der Rangfolge der Scores stehen:

AP = Σn (Rn − Rn−1) · Pn

summiert über alle Schwellen n, mit Recall Rn und Precision Pn. Ein konstanter Score, der alle Knoten gleich bewertet, erreicht genau die Prävalenz, hier 0,1115. Eine zufällige Rangfolge liegt im Erwartungswert etwas darüber, bei 0,1181, weil die Average Precision die Precision nur an den Rängen der Knoten mit Label illegal mittelt und ein solcher Knoten auf Rang k sich selbst mitzählt; der Effekt ist bei kleinem k am größten. Wie stark der Zufall streut, zeigen 10.000 zufällige Rangfolgen der Testknoten (Seed 42): 95 % davon bleiben unter 0,1420. Gegen diese Werte sind die Zeilen der Tabelle zu lesen.

Alle Hyperparameter: Z-Scores (Lauf vom 28.10.2026, Seed 42)
center
median
scale
mad
madScale
1,4826
madZeroContribution
0
aggregation
maxAbs
fitOn
train
features
f_log_amount, f_log_fee, f_log_fee_rate, f_num_inputs, f_num_outputs, f_log_size, f_round_amount, f_change_output, f_max_output_share, f_input_amount_cv, f_log_hours_since_last, f_log_address_age_days
zeroMadFeatures
f_round_amount, f_change_output
Alle Hyperparameter: Isolation Forest (Lauf vom 28.10.2026, Seed 42)
nEstimators
200
contamination
0,02
maxSamples
auto
maxFeatures
1
bootstrap
nein
randomState
42
score
-score_samples
fitOn
train
labelsUsed
nein
features
f_log_amount, f_log_fee, f_log_fee_rate, f_num_inputs, f_num_outputs, f_log_size, f_round_amount, f_change_output, f_max_output_share, f_input_amount_cv, f_log_hours_since_last, f_log_address_age_days, g_in_degree, g_out_degree, g_betweenness, g_eigenvector
graphMeasures.exactBetweennessLimit
5000
graphMeasures.betweennessSamples
1000
graphMeasures.betweennessSeed
42
graphMeasures.eigenvectorMaxIter
1000
graphMeasures.eigenvectorTol
1e-06
graphMeasures.sampledSteps
–
graphMeasures.eigenvectorFallbackSteps
–
Alle Hyperparameter: Gradient Boosting (Lauf vom 28.10.2026, Seed 42)
estimator
HistGradientBoostingClassifier
loss
log_loss
score
logOddsIllicit
learningRate
0,1
maxIter
300
maxLeafNodes
7
minSamplesLeaf
20
l2Regularization
0
maxBins
255
maxFeatures
1
earlyStopping
nein
randomState
42
positiveWeight
1
positiveWeightRule
fixed
edges
none
features
f_log_amount, f_log_fee, f_log_fee_rate, f_num_inputs, f_num_outputs, f_log_size, f_round_amount, f_change_output, f_max_output_share, f_input_amount_cv, f_log_hours_since_last, f_log_address_age_days, g_in_degree, g_out_degree, g_betweenness, g_eigenvector
selectedIteration
128
selectionMetric
validationPrAuc
validationPrAuc
0,5294
selectionSteps.from
1
selectionSteps.to
17
validationSteps.from
18
validationSteps.to
21
finalFitSteps.from
1
finalFitSteps.to
21
search[0].featureSet
local
search[0].positiveWeightRule
trainRatio
search[0].positiveWeight
8,3409
search[0].maxLeafNodes
7
search[0].validationPrAuc
0,3403
search[0].bestIteration
136
search[0].selected
nein
search[1].featureSet
local
search[1].positiveWeightRule
trainRatio
search[1].positiveWeight
8,3409
search[1].maxLeafNodes
31
search[1].validationPrAuc
0,2603
search[1].bestIteration
281
search[1].selected
nein
search[2].featureSet
local
search[2].positiveWeightRule
fixed
search[2].positiveWeight
1
search[2].maxLeafNodes
7
search[2].validationPrAuc
0,373
search[2].bestIteration
110
search[2].selected
nein
search[3].featureSet
local
search[3].positiveWeightRule
fixed
search[3].positiveWeight
1
search[3].maxLeafNodes
31
search[3].validationPrAuc
0,2806
search[3].bestIteration
30
search[3].selected
nein
search[4].featureSet
local+graph
search[4].positiveWeightRule
trainRatio
search[4].positiveWeight
8,3409
search[4].maxLeafNodes
7
search[4].validationPrAuc
0,5247
search[4].bestIteration
72
search[4].selected
nein
search[5].featureSet
local+graph
search[5].positiveWeightRule
trainRatio
search[5].positiveWeight
8,3409
search[5].maxLeafNodes
31
search[5].validationPrAuc
0,514
search[5].bestIteration
70
search[5].selected
nein
search[6].featureSet
local+graph
search[6].positiveWeightRule
fixed
search[6].positiveWeight
1
search[6].maxLeafNodes
7
search[6].validationPrAuc
0,5294
search[6].bestIteration
128
search[6].selected
ja
search[7].featureSet
local+graph
search[7].positiveWeightRule
fixed
search[7].positiveWeight
1
search[7].maxLeafNodes
31
search[7].validationPrAuc
0,5034
search[7].bestIteration
68
search[7].selected
nein
seedSpread.seeds
42, 43, 44, 45, 46
seedSpread.reportedSeed
42
seedSpread.prAuc
0,6087, 0,6087, 0,6087, 0,6087, 0,6087
seedSpread.mean
0,6087
seedSpread.min
0,6087
seedSpread.max
0,6087
environment.scikitLearn
1.9.1
environment.python
3.12.15
environment.platform
Windows
environment.threads
1
Alle Hyperparameter: GCN (Lauf vom 28.10.2026, Seed 42)
architecture
GCNConv
layers
2
hidden
64
activation
relu
dropout
0,5
optimizer
adam
learningRate
0,01
weightDecay
0,0005
loss
weightedCrossEntropy
score
logitIllicit - logitLicit
positiveWeight
20
positiveWeightRule
fixed
edges
undirected
dtype
float64
scaling.center
median
scaling.scale
mad
scaling.madScale
1,4826
scaling.fallback
std, one
scaling.clip
10
scaling.fitOn
train
scaling.zeroMadFeatures
f_round_amount, f_change_output, g_betweenness
scaling.unitScaleFeatures
–
features
f_log_amount, f_log_fee, f_log_fee_rate, f_num_inputs, f_num_outputs, f_log_size, f_round_amount, f_change_output, f_max_output_share, f_input_amount_cv, f_log_hours_since_last, f_log_address_age_days, g_in_degree, g_out_degree, g_betweenness, g_eigenvector
maxEpochs
300
patience
50
selectedEpoch
140
selectionMetric
validationPrAuc
validationPrAuc
0,7364
selectionSteps.from
1
selectionSteps.to
17
validationSteps.from
18
validationSteps.to
21
finalFitSteps.from
1
finalFitSteps.to
21
search[0].featureSet
local
search[0].positiveWeightRule
trainRatio
search[0].positiveWeight
8,3409
search[0].validationPrAuc
0,6793
search[0].bestEpoch
41
search[0].stoppedEpoch
91
search[0].selected
nein
search[1].featureSet
local
search[1].positiveWeightRule
fixed
search[1].positiveWeight
20
search[1].validationPrAuc
0,6517
search[1].bestEpoch
62
search[1].stoppedEpoch
112
search[1].selected
nein
search[2].featureSet
local+graph
search[2].positiveWeightRule
trainRatio
search[2].positiveWeight
8,3409
search[2].validationPrAuc
0,7286
search[2].bestEpoch
137
search[2].stoppedEpoch
187
search[2].selected
nein
search[3].featureSet
local+graph
search[3].positiveWeightRule
fixed
search[3].positiveWeight
20
search[3].validationPrAuc
0,7364
search[3].bestEpoch
140
search[3].stoppedEpoch
190
search[3].selected
ja
seedSpread.seeds
42, 43, 44, 45, 46
seedSpread.reportedSeed
42
seedSpread.prAuc
0,7897, 0,8148, 0,8008, 0,7947, 0,8009
seedSpread.mean
0,8002
seedSpread.min
0,7897
seedSpread.max
0,8148
environment.torch
2.13.0+cpu
environment.torchGeometric
2.7.0
environment.python
3.12.15
environment.platform
Windows
environment.threads
1
environment.deterministicAlgorithms
ja
Alle Hyperparameter: GraphSAGE (Lauf vom 28.10.2026, Seed 42)
architecture
SAGEConv(aggr=mean)
layers
2
hidden
64
activation
relu
dropout
0,5
optimizer
adam
learningRate
0,01
weightDecay
0,0005
loss
weightedCrossEntropy
score
logitIllicit - logitLicit
positiveWeight
9,2893
positiveWeightRule
trainRatio
edges
undirected
dtype
float64
scaling.center
median
scaling.scale
mad
scaling.madScale
1,4826
scaling.fallback
std, one
scaling.clip
10
scaling.fitOn
train
scaling.zeroMadFeatures
f_round_amount, f_change_output, g_betweenness
scaling.unitScaleFeatures
–
features
f_log_amount, f_log_fee, f_log_fee_rate, f_num_inputs, f_num_outputs, f_log_size, f_round_amount, f_change_output, f_max_output_share, f_input_amount_cv, f_log_hours_since_last, f_log_address_age_days, g_in_degree, g_out_degree, g_betweenness, g_eigenvector
maxEpochs
300
patience
50
selectedEpoch
300
selectionMetric
validationPrAuc
validationPrAuc
0,9349
selectionSteps.from
1
selectionSteps.to
17
validationSteps.from
18
validationSteps.to
21
finalFitSteps.from
1
finalFitSteps.to
21
search[0].featureSet
local
search[0].positiveWeightRule
trainRatio
search[0].positiveWeight
8,3409
search[0].validationPrAuc
0,8053
search[0].bestEpoch
90
search[0].stoppedEpoch
140
search[0].selected
nein
search[1].featureSet
local
search[1].positiveWeightRule
fixed
search[1].positiveWeight
20
search[1].validationPrAuc
0,7724
search[1].bestEpoch
184
search[1].stoppedEpoch
234
search[1].selected
nein
search[2].featureSet
local+graph
search[2].positiveWeightRule
trainRatio
search[2].positiveWeight
8,3409
search[2].validationPrAuc
0,9349
search[2].bestEpoch
300
search[2].stoppedEpoch
300
search[2].selected
ja
search[3].featureSet
local+graph
search[3].positiveWeightRule
fixed
search[3].positiveWeight
20
search[3].validationPrAuc
0,927
search[3].bestEpoch
159
search[3].stoppedEpoch
209
search[3].selected
nein
seedSpread.seeds
42, 43, 44, 45, 46
seedSpread.reportedSeed
42
seedSpread.prAuc
0,8941, 0,8915, 0,8876, 0,8689, 0,879
seedSpread.mean
0,8842
seedSpread.min
0,8689
seedSpread.max
0,8941
environment.torch
2.13.0+cpu
environment.torchGeometric
2.7.0
environment.python
3.12.15
environment.platform
Windows
environment.threads
1
environment.deterministicAlgorithms
ja
Alle Hyperparameter: MLP (ohne Kanten) (Lauf vom 28.10.2026, Seed 42)
architecture
Linear
layers
2
hidden
64
activation
relu
dropout
0,5
optimizer
adam
learningRate
0,01
weightDecay
0,0005
loss
weightedCrossEntropy
score
logitIllicit - logitLicit
positiveWeight
20
positiveWeightRule
fixed
edges
none
dtype
float64
scaling.center
median
scaling.scale
mad
scaling.madScale
1,4826
scaling.fallback
std, one
scaling.clip
10
scaling.fitOn
train
scaling.zeroMadFeatures
f_round_amount, f_change_output, g_betweenness
scaling.unitScaleFeatures
–
features
f_log_amount, f_log_fee, f_log_fee_rate, f_num_inputs, f_num_outputs, f_log_size, f_round_amount, f_change_output, f_max_output_share, f_input_amount_cv, f_log_hours_since_last, f_log_address_age_days, g_in_degree, g_out_degree, g_betweenness, g_eigenvector
maxEpochs
300
patience
50
selectedEpoch
16
selectionMetric
validationPrAuc
validationPrAuc
0,497
selectionSteps.from
1
selectionSteps.to
17
validationSteps.from
18
validationSteps.to
21
finalFitSteps.from
1
finalFitSteps.to
21
search[0].featureSet
local
search[0].positiveWeightRule
trainRatio
search[0].positiveWeight
8,3409
search[0].validationPrAuc
0,2722
search[0].bestEpoch
29
search[0].stoppedEpoch
79
search[0].selected
nein
search[1].featureSet
local
search[1].positiveWeightRule
fixed
search[1].positiveWeight
20
search[1].validationPrAuc
0,2642
search[1].bestEpoch
11
search[1].stoppedEpoch
61
search[1].selected
nein
search[2].featureSet
local+graph
search[2].positiveWeightRule
trainRatio
search[2].positiveWeight
8,3409
search[2].validationPrAuc
0,4816
search[2].bestEpoch
8
search[2].stoppedEpoch
58
search[2].selected
nein
search[3].featureSet
local+graph
search[3].positiveWeightRule
fixed
search[3].positiveWeight
20
search[3].validationPrAuc
0,497
search[3].bestEpoch
16
search[3].stoppedEpoch
66
search[3].selected
ja
seedSpread.seeds
42, 43, 44, 45, 46
seedSpread.reportedSeed
42
seedSpread.prAuc
0,3765, 0,3792, 0,3418, 0,401, 0,3935
seedSpread.mean
0,3784
seedSpread.min
0,3418
seedSpread.max
0,401
environment.torch
2.13.0+cpu
environment.torchGeometric
2.7.0
environment.python
3.12.15
environment.platform
Windows
environment.threads
1
environment.deterministicAlgorithms
ja

Bewertung

Einordnung der Ergebnisse

  1. Alle Verfahren außer Isolation Forest liegen über dem 95-%-Quantil zufälliger Rangfolgen (0,1420) und ordnen Knoten mit Label illegal damit besser als Zufall. Bei Isolation Forest (0,1281) ist die PR-AUC von der einer zufälligen Rangfolge (Erwartungswert 0,1181) nicht zu unterscheiden.
  2. Als Mindestabstand für einen Vergleich zweier Verfahren gilt hier 0,0239, der Abstand zwischen Erwartungswert und 95-%-Quantil zufälliger Rangfolgen. Das ist eine grobe Schwelle, kein Test: Sie zeigt, wie stark schon zufällige Rangfolgen auf diesen 852 Testknoten streuen. Kleinere Unterschiede werden nicht als Rangfolge gelesen. Alle Werte stammen aus Läufen mit Seed 42.
  3. Der Isolation Forest mit zusätzlichen Graphmaßen liegt um 0,0352 unter den robusten Z-Scores auf lokalen Merkmalen. Da sich Verfahren und Merkmalssatz gleichzeitig unterscheiden, lässt sich daraus nicht ablesen, ob die Graphmaße helfen.
  4. Gegen die bessere Baseline (Z-Scores, PR-AUC 0,1633): GCN 0,7897, um 0,6264 höher; GraphSAGE 0,8941, um 0,7308 höher. Dieser Abstand mischt mehrere Effekte: Die Graph Neural Networks lernen aus Labels, die Baselines nicht; sie nutzen zusätzlich die Graphmaße; und nur sie sehen die Nachbarschaft.
  5. GraphSAGE liegt um 0,1044 vor GCN.
  6. Zwei überwachte Verfahren ohne Kanten trennen die Effekte: Sie lernen aus denselben Labels wie die Graph Neural Networks und wählen am selben Validierungsteil, sehen aber keine Nachbarn. Das Gradient Boosting (übliches starkes Verfahren für tabellarische Daten, eigene Suche über Merkmalssatz, Klassengewicht und Blattzahl) erreicht 0,6087 und das MLP (gleiche Größe und dieselben Kandidaten für Merkmalssatz und Klassengewicht wie die Graph Neural Networks) 0,3765. Das Gradient Boosting liegt um 0,4454 über der besseren Baseline (Z-Scores, 0,1633). Dieser Abstand mischt die Wirkung der Labels mit dem Wechsel des Verfahrens und des Merkmalssatzes (das Gradient Boosting nutzt lokale Merkmale und Graphmaße, die bessere Baseline nur lokale Merkmale). Mit Nachbarschaft: GCN 0,7897 (um 0,1810 über dem Gradient Boosting), GraphSAGE 0,8941 (um 0,2854 über dem Gradient Boosting). Gegenüber dem MLP: GCN um 0,4132 darüber, GraphSAGE um 0,5176 darüber. Merkmalssatz, Gewicht und Epochen- bzw. Baumzahl wählt dabei jedes Verfahren für sich. Die Nachbarschaft bringt gegenüber dem stärksten gemessenen Verfahren ohne Kanten (Gradient Boosting) einen messbaren Vorsprung. Der größere Teil des Abstands zur besseren Baseline entsteht auf diesem Netz aber schon ohne Kanten: 0,4454 von 0,6264 bei GCN und von 0,7308 bei GraphSAGE. Gegenüber dem Gradient Boosting wechselt neben den Kanten auch das Verfahren, Entscheidungsbäume statt neuronaler Netze; allein in den Kanten unterscheiden sich die Graph Neural Networks nur vom MLP. Gegen das MLP gerechnet käme der größere Teil aus der Nachbarschaft; das MLP ist auf diesem Netz aber der schwächere Vergleich ohne Kanten.
  7. Recall bei Precision ≥ 0,5 – Z-Scores 0,0211 (etwa 2 von 95); Isolation Forest 0,0000 (keine Schwelle erreicht diese Precision); Gradient Boosting 0,5789 (etwa 55 von 95); GCN 0,8316 (etwa 79 von 95); GraphSAGE 0,9474 (etwa 90 von 95); MLP (ohne Kanten) 0,2211 (etwa 21 von 95).
  8. Die Accuracy liegt zwischen 0,8744 und 0,9096; ein Modell, das keinen Knoten markiert, erreicht 0,8885. GCN und GraphSAGE markieren je 18 Knoten, alle mit Label illegal. Mehr als 0,9096 ist bei 18 markierten Knoten nicht möglich, und das sind nur 0,0211 mehr als bei „nichts markiert“. Deshalb ist Accuracy hier nur Nebenwert.
  9. Unter den 50 Startknoten mit den höchsten Isolation-Forest-Scores tragen 12 ein Label; davon haben 16,7 % das Label illegal (Prävalenz im Test: 11,15 %). Die Startknoten haben im Mittel einen Gesamtgrad von 13,5, die übrigen Knoten ihrer Nachbarschaft von 2,5. Der Isolation Forest gibt also vor allem Knoten mit vielen Kanten einen hohen Score, und solche Knoten gibt es auch im gutartigen Hintergrund. Unter den 50 Startknoten nach GNN-Score (GraphSAGE) tragen 29 ein Label; davon haben 100,0 % das Label illegal, bei einem mittleren Gesamtgrad von 1,7. Das Graph Neural Network hat dafür die Labels der Trainingszeitschritte gesehen, der Isolation Forest keine. Das ist eine Lesart der exportierten Daten, kein eigener Test.

Vorbehalte

Grenzen

  • Synthetische Daten: Alle Ergebnisse, auch die der Graph Neural Networks, sind auf dem Datensatz „Synthetisches Transaktionsnetz“ gemessen. Sie beschreiben das Verhalten auf einem eigenen Generator und lassen sich nicht auf reale Transaktionsdaten übertragen.
  • Ein Lauf je Verfahren: Alle Kennzahlen stammen aus Läufen mit Seed 42. Für die gelernten Verfahren zeigt die Metriktafel zusätzlich die Spanne über die Seeds 42 bis 46 (Einzelwerte im README (externe Seite) und in docs/runs (externe Seite)). Sie zeigt nur, wie stark der Seed das Endmodell verschiebt, und ist beim Gradient Boosting ohne Zufallsanteil 0; über die Unsicherheit durch die Daten sagt sie nichts. Konfidenzintervalle, etwa per Bootstrap über die Testknoten, und eine Streuung des Gradient Boosting über Bootstrap-Stichproben der Trainingsknoten sind nicht berechnet. Bei 95 Testknoten mit Label illegal können kleine Unterschiede zufällig sein.
  • Nur Knoten mit Label werden bewertet. Knoten ohne Label, darunter auch Musterknoten, gehen nicht in die Kennzahlen ein.
  • Eingebaute Nachbarschaft: Im Generator hängen Musterknoten fast nur an anderen Musterknoten, und Kreise und Ketten tragen entlang der Kanten fast denselben Betrag (hopNoiseSd = 0,02). Von den 847 Kanten zwischen zwei Knoten mit Label verbinden 161 zwei Knoten mit Label illegal, 666 zwei Knoten mit Label legal und nur 20 einen Knoten mit Label illegal und einen mit Label legal. 216 von 292 Knoten mit Label illegal haben einen Nachbarn mit Label illegal, aber nur 19 von 2.587 Knoten mit Label legal. Ein Modell, das die Nachbarschaft einbezieht, bekommt dieses Signal teilweise geschenkt. Der gemessene Vorsprung der Graph Neural Networks ist auf diesem Netz deshalb zum Teil eingebaut und nicht auf andere Daten übertragbar.
  • Überwacht gegen unüberwacht: Die Baselines sehen keine Labels, die gelernten Verfahren schon. Gradient Boosting und MLP trennen die Wirkung der Labels von der der Nachbarschaft; mit dem Gradient Boosting ist ein starkes überwachtes Verfahren ohne Kanten gemessen. Offen bleibt, ob ein anderes Verfahren ohne Kanten näher an die Graph Neural Networks herankommt: Ein Random Forest und ein größerer Suchraum des Gradient Boosting (etwa Lernrate, Blattgröße und L2-Regularisierung) sind nicht gemessen. Auf Elliptic lag bei Weber et al. (2019), gemessen mit dem F1-Wert für das Label illegal, ein Random Forest vor dem GCN. Eine Baseline mit gemittelten Nachbarmerkmalen ohne Labels fehlt noch.
  • Die Auswahl der gelernten Verfahren stützt sich auf einen kleinen Validierungsteil (Zeitschritte 18–21). Unterschiede von wenigen Hundertsteln zwischen Kandidaten sind dort nicht belastbar. Bei GraphSAGE lag die Auswahl auf der Obergrenze; ob mehr Epochen helfen, ist nicht gemessen.
  • Nur 2 Architekturen mit Nachbarschaft und ungerichteten Kanten. GAT, getrennte Ein- und Ausgangsnachrichten und zeitliche Modelle sind nicht gemessen.
  • Der Ausschnitt zeigt nur die Nachbarschaft der 50 höchsten Isolation-Forest-Scores und der 50 höchsten GNN-Scores und ist damit bewusst nicht repräsentativ für das ganze Netz.
  • Accuracy hängt von der gewählten Schwelle ab und ist deshalb nur Nebenwert.

Reproduzierbarkeit

Stand

Ergebnisse vom 29.10.2026 (Export 12:12 UTC), Seed 42, Datensatz „Synthetisches Transaktionsnetz“. Jeder Lauf ist mit Datensatz, Split, Seed, Hyperparametern und Datum protokolliert (Laufprotokolle in docs/runs (externe Seite)). Die Seite bindet beim Erstellen nur die vorab exportierten Dateien nodes.json, edges.json und metrics.json ein. Im Browser läuft kein Modell, und es gehen keine Anfragen an Dritte.

NetzRadar ist eine Methodenstudie zur Anomalie-Erkennung in Transaktionsnetzwerken auf synthetischen beziehungsweise öffentlich zugänglichen Forschungsdatensätzen. Die gezeigten Anomalie-Scores sind Ausgaben statistischer Modelle. Sie sind keine Feststellung, dass eine Transaktion oder ein Konto rechtswidrig ist, und es werden keine realen Konten oder Personen geprüft. Die Inhalte stellen keine Anlage-, Rechts- oder Compliance-Beratung dar und ersetzen keine geldwäscherechtliche Prüfung. Alle Angaben ohne Gewähr.

Mit der Nutzung erkennen Sie die Nutzungsbedingungen an. Einzelheiten zum Datenschutz stehen in der Datenschutzerklärung.