In dit artikel gaan we aan de slag met deze data-analyse. Het is in feite een hele simpele analyse, die je ook in Excel kan doen, maar wel een belangrijke en vaak gebruikte controle. Door deze analyse uit te voeren kun je immers:
- Dubbele betalingen of ongeautoriseerde bankrekeningen sneller opsporen
- Inconsistenties in stamdata (leveranciers, medewerkers, klanten) identificeren
Wanneer deze analyse automatisch wordt uitgevoerd op basis van bankdata (bijvoorbeeld via een CAMT-export), kan dit handmatig controlewerk flink verminderen en mogelijke fouten op tijd signaleren.
CAMT-bestand
Ik zei dat het een vrij makkelijke analyse is, maar soms maakt het bronbestand het nog wel wat lastiger. Zeker in Europa worden tegenwoordig vaak CAMT bestanden gebruikt. CAMT-bestanden zijn XML-bestanden die door banken worden gebruikt om transacties te rapporteren. Dat is heel fijn, want daarmee is er standaardisatie, maar het omzetten van de CAMT-bestanden kan soms een puzzel zijn.
Meer uitleg over het formaat vind je hier en in een ander artikel vind je een coverter naar Excel.
Batchdetails
Helaas zitten in veel CAMT-exports nog geen batchdetails. Wanneer een organisatie daar gebruik van maakt (bijvoorbeeld bij salarissen), dan mis je die informatie. Deze informatie zit soms nog wel in het ERP systeem van de klant. Als je die er los uit kunt trekken, dan zou je die nog kunnen combineren met het resultaat van de CAMT-converter.
Data-analyse in Python
Goed, dan duiken we de techniek in. Voor de analyse gebruiken we dus python. Deze scripts zijn goed te volgen en kunnen veel data aan. Daarvoor gebruiken we nog wel een los package:
pandas
voor datamanipulatie
Meer informatie over pandas in de audit vind je ook op deze website.
1. CAMT-bestand inlezen
Allereerst lezen we het CAMT bestand in. In het script hieronder heb ik dat redelijk kort door de bocht gedaan. Meer informatie over deze CAMT-converter vind je in het andere artikel.
import xml.etree.ElementTree as ET
import pandas as pd
def parse_camt053(file_path):
tree = ET.parse(file_path)
root = tree.getroot()
ns = {'ns': 'urn:iso:std:iso:20022:tech:xsd:camt.053.001.02'}
transactions = []
for entry in root.findall('.//ns:Ntry', ns):
try:
amount = float(entry.find('ns:Amt', ns).text)
except:
amount = 0.0
currency = entry.find('ns:Amt', ns).attrib.get('Ccy', 'N/A')
date = entry.find('.//ns:BookgDt/ns:Dt', ns).text
debtor = entry.find('.//ns:Dbtr/ns:Nm', ns).text
debtor_iban = entry.find('.//ns:DbtrAcct/ns:Id/ns:IBAN', ns).text
creditor = entry.find('.//ns:Cdtr/ns:Nm', ns).text
creditor_iban = entry.find('.//ns:CdtrAcct/ns:Id/ns:IBAN', ns).text
transactions.append({
"Datum": date,
"Debiteur": debtor,
"Debiteur IBAN": debtor_iban,
"Crediteur": creditor,
"Crediteur IBAN": creditor_iban,
"Bedrag": amount,
"Munteenheid": currency
})
return pd.DataFrame(transactions)
file_path = "camt053_dummy.xml"
df = parse_camt053(file_path)
print(df.head())
2. Duplicaten analyseren
Als we de CAMT hebben omgezet, is de daadwerkelijke analyse eigenlijk niet meer dan het maken van een draaitabel. Met python kunnen we 'groupby' en nunique() gebruiken om te tellen hoeveel unieke IBAN's iedere crediteursnaam heeft.
# Groeperen en tellen van unieke IBANs per begunstigde
duplicates = df.groupby('Crediteur')['Crediteur IBAN'].nunique().reset_index()
duplicates = duplicates[duplicates['Crediteur IBAN'] > 1] # Filter alleen begunstigden met meerdere IBANs
print("Begunstigden met meerdere IBANs:")
print(duplicates)
Het resultaat zou er zo uit kunnen komen te zien:
Crediteur | Crediteur IBAN |
---|---|
Durban Inc. | 3 |
City Escapes BV | 2 |
Math Engines Inc. | 2 |
In dat geval weet je dat je voor deze drie moet controleren of deze dubbele rekeningen legitiem zijn.
2.1 IBAN’s gekoppeld aan meerdere begunstigden
Naast het identificeren van begunstigden met meerdere IBANs, kunnen we ook analyseren of een IBAN aan meerdere begunstigden is gekoppeld. Dit kan wijzen op gezamenlijke rekeningen of verdachte transacties.
# Groeperen en tellen van unieke begunstigden per IBAN
iban_duplicates = df.groupby('Crediteur IBAN')['Crediteur'].nunique().reset_index()
iban_duplicates = iban_duplicates[iban_duplicates['Crediteur'] > 1] # Filter alleen IBANs met meerdere begunstigden
print("IBANs die aan meerdere begunstigden zijn gekoppeld:")
print(iban_duplicates)
Het resultaat zou er zo uit kunnen komen te zien:
Crediteur IBAN | Crediteur |
---|---|
DE12DEUT123456789 | 3 |
9876543123 | 2 |
NL98ABNA987654321 | 2 |
In dit geval worden deze rekeningen gebruikt met meerdere namen. Dit kan simpelweg een spatie of punt zijn, maar het kan ook een bewuste invoering zijn.
3. Exporteren van resultaten
Na deze analyses kunnen we het het beste exporteren naar Excel, zodat je het kan opnemen in je dossier en je eventuele bijzonderheden kan toelichten.
duplicates.to_excel("liquide_middelen_dubbele_iban.xlsx", index=False)
iban_duplicates.to_excel("liquide_middelen_dubbele_begunstigden.xlsx", index=False)
Fuzzy logica
Deze analyse is heel strict; wat goed is, maar ook voor extra werk kan zorgen. Wanneer je bijvoorbeeld als begunstigde 'Brood B.V.' invoert en later 'Brood BV', dan heb je het over hetzelfde bedrijf. Echter, de tekst is anders en daarom wordt het een bevinding in deze analyse.
Je kunt ook werken met Fuzzy Logic. Fuzzy logic (of 'fuzzy matching') is een techniek die niet zoekt naar exacte overeenkomsten, maar naar de waarschijnlijkheid van een overeenkomst. In plaats van te zeggen "deze twee teksten zijn 100% identiek of 0% identiek", berekent het een gelijkenisscore (bijvoorbeeld 95%). Dit is uitermate geschikt voor het opsporen van dubbele betalingen of leveranciers, omdat data in de praktijk zelden perfect is.
Denk aan variaties zoals:
- Typfouten: "Jansen" vs. "Janssen".
- Volgorde: "Jan de Vries" vs. "Vries, Jan de".
Een strikte analyse zou deze allemaal als uniek zien. Een analyse met fuzzy logic kan deze echter groeperen als "waarschijnlijk dezelfde entiteit" of "waarschijnlijk een dubbele betaling".
Fuzzy Logic in de Praktijk
Het implementeren van een betrouwbaar fuzzy matching model vereist specialistische Python-bibliotheken (zoals thefuzz
of recordlinkage
) en een zorgvuldige afweging van welke velden je vergelijkt en welke drempelwaarde je voor een 'match' hanteert.
Om je te helpen deze geavanceerde techniek direct en effectief toe te passen, bevat de CAMT Analytics Toolkit een kant-en-klaar script. Deze voert zowel de traditionele manier uit als de fuzzy logic. Hiermee overbrug je de beperkingen van een strikte analyse en spoor je veel slimmer en sneller verdachte dubbelingen op.