Billing Fraud Detection
A machine learning pipeline that merges a labelled client table with about 4.5 million electricity and gas invoices, engineers features, rebalances the classes and trains three classifiers (Random Forest, Logistic Regression, Keras neural network) to predict a client fraud flag.
By Jawher Ennaceur
View on GitHub- Fraud Detection
- Feature Engineering
- Imbalanced Data Handling
- Scikit-Learn
- Neural Networks
- Exploratory Data Analysis
The Problem
Fraud is a small share of the client base: the mean of the fraud label in the client table is 0.0558, about 5.6% of clients. The project asks whether client attributes and invoice history can be used to flag these clients.
The Approach
I loaded a client table (135,493 clients with a binary fraud label) and an invoice table (4,476,749 rows covering electricity and gas counters) with pandas, then checked for missing values and duplicates and plotted the class balance and the district, region and client-category distributions. I converted district, region and client category to categorical types, mapped the counter type to 0/1, cleaned the counter status codes, parsed the dates, and created the cooperation time in months (relative to 2019), invoice month and invoice year. I merged invoices with clients on client_id (right join, 4,476,749 rows), kept every fraud-labelled invoice row, undersampled non-fraud rows to three times that number, and rescaled each column with StandardScaler. I split the data 75/25 with train_test_split (stratified, random_state=420) and trained three models: a Random Forest (10 trees, entropy criterion), a Logistic Regression (max_iter=2000), and a Keras network with dense layers of 32, 32, 32 and 10 ReLU units and a sigmoid output, compiled with Adam and binary cross-entropy and trained for 12 epochs. The feature list I passed to the models has 20 columns: district, client category, region, cooperation time, tariff type, counter number and code, reading remark, counter coefficient, four consumption levels, old and new index, months number, counter type, invoice month, invoice year, and the fraud label itself.
Results
- Client table: 135,493 clients with a fraud-label mean of 0.0558 (about 5.6% fraud); no duplicated rows in the client table and no missing values in either table.
- Invoice table: 4,476,749 rows and 16 raw columns, merged with the client table to 4,476,749 rows.
- Engineered features used by the models: cooperation time in months, invoice month and invoice year (region group, weekend flag and meter index difference were also computed but are not used).
- Rebalanced to three non-fraud invoice rows per fraud-labelled invoice row, about 1.41 million rows in total (inferred from 33,105 training steps at batch size 32; confirm).
- Random Forest scored an accuracy of 0.999 on the 25% test split, Logistic Regression a training accuracy of 0.9998, and the neural network a validation accuracy of 1.0 from epoch 1 through epoch 12 (final training and validation loss about 2.3e-11).
- These perfect scores come from a run in which the fraud label was one of the 20 input columns, and the split was by invoice row rather than by client. They show that the pipeline runs end to end and are not an estimate of how well it detects fraud.