Summary
Every fraud transaction is generated with amount = 9999.00, a hardcoded dataclass default,
while normal transactions draw from a hardcoded uniform(10, 500). Neither Config nor the
CLI exposes any parameter for fraud amounts, class overlap, label noise, or difficulty — so
the fraud/normal separation is total, and a user of the public API has no way to make the
data harder.
Evidence (code locations)
src/gen_fraud_graph/typologies.py:52 — amount: float = 9999.00 (dataclass default used
for injected fraud edges).
src/gen_fraud_graph/generator.py:198 — normal amounts:
round(random.uniform(10, 500), 2).
- The README itself documents the split (
README.md:172): "Transaction amount (10 – 500 for
normal, 9999 for fraud)".
- Grep of
Config and the CLI surface: no amount / overlap / noise / difficulty /
label-contamination parameter of any kind. Our write-up of that check:
findings/results.md L44–L48 ("Not our config").
Why it matters
With max(normal) < min(fraud) by construction, a one-line threshold (amount > 500)
separates the classes with 100% precision and recall — measured on a generated 2,000-account
dataset: F1/AUC/MCC = 1.000 for the threshold rule
(findings/results.md L12–L17, baseline table). Any model
benchmarked on this data saturates instantly, so comparisons between detection methods on it
are not informative. As shipped, the data is a smoke test, not a benchmark — which is at odds
with the README's "benchmarking graph-based fraud detection models" framing.
(The deeper consequence — the label being perfectly recoverable from one feature — is split
into a companion issue filed alongside this one.)
Proposed fix
Expose the amount model in Config (and mirror it in the CLI), keeping current values as
defaults so existing users see no change:
@dataclass
class Config:
...
normal_amount_range: tuple[float, float] = (10.0, 500.0)
fraud_amount_range: tuple[float, float] = (9999.0, 9999.0) # current sentinel behaviour
Overlapping the two ranges (e.g. fraud_amount_range=(300.0, 2000.0)) would immediately give
users a difficulty dial. A fancier option — an explicit overlap/noise fraction — could be
layered on later; the ranges alone remove the hard floor.
Context: this came out of a small independent teardown that wired several SantanderAI tools
into one fraud-decision pipeline: https://github.com/Leonardasvekrikas-source/santander-ai-governance-teardown
Summary
Every fraud transaction is generated with
amount = 9999.00, a hardcoded dataclass default,while normal transactions draw from a hardcoded
uniform(10, 500). NeitherConfignor theCLI exposes any parameter for fraud amounts, class overlap, label noise, or difficulty — so
the fraud/normal separation is total, and a user of the public API has no way to make the
data harder.
Evidence (code locations)
src/gen_fraud_graph/typologies.py:52—amount: float = 9999.00(dataclass default usedfor injected fraud edges).
src/gen_fraud_graph/generator.py:198— normal amounts:round(random.uniform(10, 500), 2).README.md:172): "Transaction amount (10 – 500 fornormal, 9999 for fraud)".
Configand the CLI surface: no amount / overlap / noise / difficulty /label-contamination parameter of any kind. Our write-up of that check:
findings/results.mdL44–L48 ("Not our config").Why it matters
With
max(normal) < min(fraud)by construction, a one-line threshold (amount > 500)separates the classes with 100% precision and recall — measured on a generated 2,000-account
dataset: F1/AUC/MCC = 1.000 for the threshold rule
(
findings/results.mdL12–L17, baseline table). Any modelbenchmarked on this data saturates instantly, so comparisons between detection methods on it
are not informative. As shipped, the data is a smoke test, not a benchmark — which is at odds
with the README's "benchmarking graph-based fraud detection models" framing.
(The deeper consequence — the label being perfectly recoverable from one feature — is split
into a companion issue filed alongside this one.)
Proposed fix
Expose the amount model in
Config(and mirror it in the CLI), keeping current values asdefaults so existing users see no change:
Overlapping the two ranges (e.g.
fraud_amount_range=(300.0, 2000.0)) would immediately giveusers a difficulty dial. A fancier option — an explicit
overlap/noisefraction — could belayered on later; the ranges alone remove the hard floor.
Context: this came out of a small independent teardown that wired several SantanderAI tools
into one fraud-decision pipeline: https://github.com/Leonardasvekrikas-source/santander-ai-governance-teardown