Methodology · Mobile Money

What Dataset Foundry's Mobile Money line actually does

This page is meant to be citable directly in a methodology chapter. Everything below is a design decision, not a discovery — Dataset Foundry does not model real Ghanaian telco or transaction data, it encodes a documented set of assumptions about how Mobile Money fraud-signal factors should relate to fraud outcomes and, optionally, recovery outcomes, so the relationships can be recovered and used to teach or test fraud-detection methods. This is the first non-insurance line on the platform, and it still doesn't mirror the motor, life, health, or Home & Property lines' two-stage frequency/severity model exactly — its own two stages are fraud probability and loss given fraud, not claim frequency and claim severity, and the split across them is asymmetric (four hypotheses on one stage, two on the other) rather than even — see section 1 for why. Like Micro-Credit & Susu Scoring, which stage count to generate (single vs. two-stage) is itself a runtime choice, not a fixed shape.

1. Toggleable one- or two-stage model

Every record starts from the same first stage: one simulated Mobile Money transaction, generated identically regardless of which mode you choose on the generator page. What happens after depends on stage_mode — the same "did it happen" / "how bad was it" split every other two-stage line on this platform uses:

  1. Fraud probability — whether a transaction is fraudulent is a logistic (log-odds) model over four independent risk factors that combine additively, closer to motor's from-scratch logistic frequency model than to life's or health's table-rated approach — table-rating doesn't fit here because there's no single natural ordinal axis, like age, to band against. How much money moved is a property of the transaction itself, not of the fraud outcome, so transaction_amount_ghs is drawn independently of is_fraudulent rather than conditioned on it. This logic is identical in both stage modes and is computed before stage_mode is even consulted — single-stage's entire output, and stage one of two-stage.
  2. Loss given fraud (two-stage only, computed only for transactions already flagged fraudulent) — the fraction of the transaction's own amount the provider fails to recover is a log-normal draw, susu's "multiple of a principal/amount field" technique, capped at 1.0x transaction_amount_ghs the same way susu's loss is capped at 1.0x loan principal. Cash-Out status is the primary driver — physical cash disbursed at an agent till can't be reversed, the classic "point of no return" in Mobile Money fraud response, whereas a transaction that stays inside the digital rails (P2P Transfer, Merchant Payment, Bill Payment, Airtime Top-up, Cash-In, Bulk Disbursement) leaves the receiving wallet freezable and the funds clawable-back. Agent cash-out channel, scoped to Cash-Out rows only, is the second core driver — Bank Partner Cash-Out inherits the bank's own KYC/reversal machinery (best recovery); ATM Cash-Out is fully anonymous (worst recovery). Transaction velocity applies a decorative multiplier on top, regardless of transaction type — the same structuring/smurfing signal read a second time.

Single-stage produces the fraud-probability columns only — loss_given_fraud_ghs is entirely absent from the output in this mode, not null-filled. Two-stage is the default — same "default the richer shape, allow opting down" reasoning every other two-stage line on this platform uses. Whichever mode you pick is recorded in the dataset's manifest and citation — two downloads of this line in different modes are, citation-wise, two different datasets, since a single-stage download simply has no loss-given-fraud column at all.

Unlike susu (two hypotheses on each stage, an even split) or motor/life/health (every hypothesis on one stage), momo puts four of its six hypotheses on the frequency side and two on the severity side — an asymmetric split, not a parity move for its own sake. Each hypothesis sits on whichever stage its own underlying question actually belongs to: "is this transaction fraudulent" has four independently-documented risk factors behind it; "how much is actually lost once fraud is confirmed" has two.

2. The six hypotheses

Four hypotheses act on fraud probability directly and hold in both stage modes, since stage-one logic doesn't change based on the toggle; two more act on loss given fraud for transactions already flagged fraudulent, and only exist — and are only verified — in two-stage mode, scoped to records where is_fraudulent === 1. Each row below is independently documented against publicly-known Mobile Money fraud typologies (Bank of Ghana and GSMA mobile-money fraud advisories), not invented to hit a target fraud or loss rate. Tracked separately below rather than in one undifferentiated table, since which mode a factor actually applies in is the thing a reader needs disambiguated.

FactorStageDirectionVerification n
Transaction velocity (trailing 24h) Fraud probability both modes Positive 20,000
SIM-swap recency Fraud probability both modes Positive 20,000
Wallet tenure Fraud probability both modes Positive (inverse — newer wallets carry more risk) 20,000
Agent cash-out channel Fraud probability both modes Positive (Cash-Out rows only) 20,000
Cash-Out status Loss given fraud two-stage only Positive 200,000
Agent cash-out channel (recoverability) Loss given fraud two-stage only Positive (Cash-Out AND fraudulent rows only) 200,000

Transaction velocity — a rapidly rising count of transactions in the trailing 24 hours is the structuring/"smurfing" signal: splitting or cycling funds through many small transactions to move stolen money before a victim or the telco can freeze the wallet, or to stay under a reporting threshold. SIM-swap recency is by far the largest single loading in the model — a fresh SIM swap (within the last 24 hours) is widely documented as the strongest individual fraud signal in the Mobile Money literature this line is anchored against, and the loading decays as the swap ages out of that highest-risk window. Wallet tenure works inversely: a wallet opened within the last month has no established legitimate transaction history to compare against and is disproportionately the vehicle a fraud ring picks, so the loading is highest for the newest band and actually goes slightly negative for the oldest ("3+ years") band, rather than just flattening at zero. Agent cash-out channel (fraud probability) only applies to Cash-Out rows (about 8% of all transactions) — an unmanned ATM cash-out carries the largest loading of the four channels since it leaves the weakest human trail, while a Bank Partner Cash-Out sits below the reference band, since it inherits the bank's own KYC checks.

Cash-Out status (loss given fraud) — once cash is disbursed at an agent, it can't be reversed: the classic "point of no return" in Mobile Money fraud response. A transaction that stays inside the digital rails is more often freezable and clawable-back before the money moves again, so Cash-Out transactions carry a far higher loss-given-fraud fraction than any other transaction type. Agent cash-out channel (loss given fraud) reads the same field the frequency-side hypothesis above does, but asks a different question — not "is this transaction more likely to be fraudulent," but "given a Cash-Out transaction is already fraudulent, how much of it is actually recovered." Bank Partner Cash-Out inherits the bank's own KYC and reversal machinery — the best-recovery channel, the same reason it's also the lowest-fraud-probability channel. ATM Cash-Out is fully anonymous with no attendant able to intervene once cash is dispensed — the worst-recovery channel, for the same underlying reason it's also the highest-fraud-probability one.

The four frequency-side hypotheses are verified at n=20,000, not the n=5,000 the motor/life/health/property lines default to — driven specifically by the agent cash-out channel hypothesis (unchanged from before this phase: at n=5,000 the weak, Cash-Out-only channel effect flips sign for at least one regression seed). The two severity-side hypotheses need considerably more, n=200,000: each is scoped to fraudulent rows, and one of the two further scopes to Cash-Out rows on top of that — a fraction of a fraction of all records — so the qualifying subpopulation per seed is small enough that a smaller n lets sampling noise flip the sign, the same "real-but-thin-population effect, not a broken hypothesis" conclusion the frequency-side agent-channel hypothesis already reached at a smaller n.

3. Coefficients

Fraud probability is modeled as p = clip(sigmoid(intercept + velocity_band_loading + agent_channel_loading + sim_swap_loading + wallet_tenure_loading), min_probability, max_probability), where each loading is a named log-odds term keyed off the transaction's own velocity band, agent cash-out channel (only applied on Cash-Out rows — zero everywhere else), SIM-swap recency band, and wallet tenure band. The intercept is tuned so the realized fraud rate across a generated dataset lands in the low single-digit percent range, consistent with Mobile Money fraud-detection literature treating fraud as a rare-event classification problem, not a guess to hit an arbitrary target. anomaly_score is derived from that same logit plus independent normal noise (anomaly_score_noise_sd), then passed back through the sigmoid and clipped to [0, 1] — it is correlated with, but not a deterministic function of, is_fraudulent, by construction, and is computed identically in both stage modes.

When stage mode is two-stage, loss given fraud, for transactions already flagged fraudulent, is modeled as loss_given_fraud = min(transaction_amount_ghs · exp(log_base + cash_out_loading + log(agent_channel_multiplier) + log(velocity_band_multiplier) + ε), transaction_amount_ghs), where cash_out_loading applies only when the transaction is Cash-Out (else 0), agent_channel_multiplier is a named term keyed off cash-out channel and applies only on Cash-Out rows (1.0 everywhere else), velocity_band_multiplier is a named term keyed off velocity band and applies to every row, and ε is normal noise. The min(..., transaction_amount_ghs) term is this line's loss cap — a fraudulent transaction can't lose more than its own amount by construction, susu's identical indemnity-cap reasoning. These coefficients are illustrative, chosen to produce a clearly recoverable signal, anchored against general Mobile Money fraud-recovery practice (cash-out as the point at which reversal becomes impossible; structuring as an evasion tactic used by organized fraud rings to move funds before detection), not derived from any real Ghanaian telco's own recovery data. Exact magnitudes aren't published on this page — see the current defaults, and change them, in the Advanced: customize the model panel on the Mobile Money generator if your thesis calls for weaker or stronger effects, and note in your write-up which values you changed from the defaults.

4. Determinism

Generation runs server-side using a seeded generator (numpy's default_rng, PCG64) rather than an unseeded source of randomness — same mechanism as every other line on the platform. The same seed, record count, and generator version (stamped in every citation and manifest — see the Cite section on the generator page) will always reproduce byte-identical output. Report the seed and record count alongside your dataset — that pair, together with the generator version, is sufficient for anyone to regenerate exactly what you analyzed.

5. What's decorative vs. load-bearing

Region and transaction amount exist to make records look like real Ghanaian Mobile Money transactions and are internally consistent with each other, but they are not the object of the hypotheses above — transaction_amount_ghs is drawn from a per-transaction-type range independently of the fraud outcome (section 1), not as a driver of it — though it is what loss given fraud is drawn as a fraction of, once a transaction is already fraudulent. Transaction velocity's severity-side multiplier is decorative in the same sense loan purpose's severity-side multiplier is on susu's own page — its frequency-side role is load-bearing; only its severity-side role is decorative. Unlike every insurance line and susu, momo records carry no subscriber name field at all: a Mobile Money fraud log is keyed off a wallet/MSISDN identifier, not a name, so there is no name-inclusion toggle to disable here (contrast the other lines' name fields, gated by the name-inclusion toggle).

6. Known limitations

  • This is synthetic data. It should never be presented as, or mistaken for, real telco or transaction data in a publication.
  • The four frequency-side risk factors combine additively in log-odds space, with no interaction effects between transaction velocity, SIM-swap recency, wallet tenure, and agent cash-out channel modeled beyond that simple addition, unless you add them yourself downstream.
  • Loss given fraud is capped at 1.0x transaction amount regardless of how Cash-Out status, agent channel, and transaction velocity stack — this line's loss cap, a harder constraint than it might look, since it follows directly from a fraudulent transaction not being able to lose more than it was worth, not from a chosen sanity limit.
  • The agent cash-out channel hypotheses (both stages) are only measurable on Cash-Out rows (about 8% of all transactions), and the severity-side one further narrows to Cash-Out rows that are also fraudulent — generating fewer than a few thousand records will make the frequency-side comparison look noisy, and fewer than roughly 200,000 will make the severity-side one look noisy, even though the other hypotheses hold up at smaller n.
  • If your thesis needs a different balance between the six hypotheses, adjust the relevant loadings in the Advanced: customize the model panel on the Mobile Money generator and say so in your write-up.

7. Citing this tool

Something like: "Synthetic data generated using Dataset Foundry (seed = 42, n = 20,000), a deterministic Mobile Money fraud-signal data generator built for this thesis in the absence of accessible real-world MoMo transaction data." Include the seed and record count so the exact dataset is reproducible from the tool alone — or use the auto-generated citation block on the generator page, which also includes the generator version and any advanced-config changes.