├── fraud-detection-federated ├── docs │ ├── fraud_flowchart.png │ ├── fraud_model_metrics.png │ ├── system_architecture.png │ ├── high_fraud_data_preview.png │ ├── low_fraud_data_preview.png │ ├── synthetic_data_preview.png │ ├── fraud_detection_presentation.pptx │ ├── merchant_pattern_data_preview.png │ ├── project_roadmap.md │ ├── industry_standards.md │ ├── README.md │ └── project_slide_deck.md ├── data │ ├── merchant_pattern_data.csv │ ├── README.md │ ├── low_fraud_data.csv │ ├── synthetic_data.csv │ └── high_fraud_data.csv ├── models │ └── README.md ├── notebooks │ ├── README.md │ ├── model_inference_demo.ipynb │ ├── explore_fraud_data.ipynb │ ├── fraud_detection_demo.ipynb │ └── federated_training_demo.ipynb └── src │ ├── README.md │ ├── test_main.py │ ├── evaluator.py │ ├── federated_train.py │ ├── model_builder.py │ ├── utils.py │ ├── client_simulator.py │ ├── data_loader.py │ ├── model_inference.py │ ├── trainer.py │ ├── preprocessing.py │ ├── main.py │ ├── client_manager.py │ ├── explainability.py │ ├── deployment_utils.py │ ├── data_augmentation.py │ ├── federated_metrics.py │ ├── feature_engineering.py │ ├── visualization_tools.py │ ├── monitoring_dashboard.py │ ├── hyperparameter_tuning.py │ └── synthetic_data_generator.py └── README.md /fraud-detection-federated/docs/fraud_flowchart.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RahulAutade2288/fraud-detection-federated/HEAD/fraud-detection-federated/docs/fraud_flowchart.png -------------------------------------------------------------------------------- /fraud-detection-federated/docs/fraud_model_metrics.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RahulAutade2288/fraud-detection-federated/HEAD/fraud-detection-federated/docs/fraud_model_metrics.png -------------------------------------------------------------------------------- /fraud-detection-federated/docs/system_architecture.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RahulAutade2288/fraud-detection-federated/HEAD/fraud-detection-federated/docs/system_architecture.png -------------------------------------------------------------------------------- /fraud-detection-federated/docs/high_fraud_data_preview.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RahulAutade2288/fraud-detection-federated/HEAD/fraud-detection-federated/docs/high_fraud_data_preview.png -------------------------------------------------------------------------------- /fraud-detection-federated/docs/low_fraud_data_preview.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RahulAutade2288/fraud-detection-federated/HEAD/fraud-detection-federated/docs/low_fraud_data_preview.png -------------------------------------------------------------------------------- /fraud-detection-federated/docs/synthetic_data_preview.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RahulAutade2288/fraud-detection-federated/HEAD/fraud-detection-federated/docs/synthetic_data_preview.png -------------------------------------------------------------------------------- /fraud-detection-federated/docs/fraud_detection_presentation.pptx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RahulAutade2288/fraud-detection-federated/HEAD/fraud-detection-federated/docs/fraud_detection_presentation.pptx -------------------------------------------------------------------------------- /fraud-detection-federated/docs/merchant_pattern_data_preview.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RahulAutade2288/fraud-detection-federated/HEAD/fraud-detection-federated/docs/merchant_pattern_data_preview.png -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # fraud-detection-federated 2 | Federated learning-based fraud detection system enabling secure, privacy-preserving model training across financial institutions without sharing raw data. Supports real-time and batch processing, anomaly detection, and modular integration with external APIs. 3 | -------------------------------------------------------------------------------- /fraud-detection-federated/data/merchant_pattern_data.csv: -------------------------------------------------------------------------------- 1 | transaction_id,amount,merchant_id,timestamp,is_fraud 2 | 1,300.00,M301,2025-01-01 12:00:00,0 3 | 2,850.00,M301,2025-01-01 12:10:00,1 4 | 3,70.00,M302,2025-01-01 12:15:00,0 5 | 4,60.00,M303,2025-01-01 12:20:00,0 6 | 5,1200.00,M301,2025-01-01 12:30:00,1 7 | -------------------------------------------------------------------------------- /fraud-detection-federated/docs/project_roadmap.md: -------------------------------------------------------------------------------- 1 | # 🚧 Project Roadmap 2 | 3 | ## ✅ Completed 4 | - Synthetic data creation 5 | - Initial federated training prototype 6 | - Basic visualization and metrics 7 | - Unit tests and architecture documentation 8 | 9 | ## 🔜 In Progress 10 | - Model benchmarking with real datasets 11 | - Integration with streaming fraud simulation 12 | - Evaluation of precision/recall tradeoffs 13 | 14 | ## 📅 Future Work 15 | - Support for real-time federated updates 16 | - Multi-feature and multi-client deployment 17 | - Deployment on edge devices for in-app detection 18 | -------------------------------------------------------------------------------- /fraud-detection-federated/docs/industry_standards.md: -------------------------------------------------------------------------------- 1 | # 📘 Industry Standards in Fraud Detection 2 | 3 | This document summarizes common techniques and regulatory expectations in financial fraud detection. 4 | 5 | ## 🔍 Techniques 6 | - Rule-based systems (e.g., transaction limits, velocity checks) 7 | - Supervised machine learning (e.g., random forests, gradient boosting) 8 | - Unsupervised learning (e.g., anomaly detection) 9 | - Neural networks and deep learning 10 | - Federated learning for multi-party data without centralization 11 | 12 | ## 🏛️ Compliance Considerations 13 | - GDPR and data minimization 14 | - PCI-DSS standards for transaction handling 15 | - FFIEC guidelines in U.S. banking 16 | - Risk-based authentication strategies 17 | -------------------------------------------------------------------------------- /fraud-detection-federated/data/README.md: -------------------------------------------------------------------------------- 1 | # Readme placeholder for data 2 | 3 | 4 | --- 5 | 6 | ### 📁 `data/` Directory 7 | 8 | This folder contains **synthetic transaction data** used to simulate fraud detection scenarios across federated clients. 9 | 10 | --- 11 | 12 | #### 📄 Files Included: 13 | 14 | * `synthetic_data.csv`: 15 | A sample dataset of anonymized transactions including: 16 | 17 | * `transaction_id` 18 | * `amount` 19 | * `merchant_id` 20 | * `timestamp` 21 | * `is_fraud` (binary label) 22 | 23 | * `schema.md` (optional): 24 | Describes column types and field meanings for consistency and reproducibility. 25 | 26 | --- 27 | 28 | #### ⚠️ Note: 29 | 30 | No real or personally identifiable information (PII) is used. All data is **entirely synthetic**, created for demonstration and testing purposes in this open-source prototype. 31 | 32 | -------------------------------------------------------------------------------- /fraud-detection-federated/docs/README.md: -------------------------------------------------------------------------------- 1 | # Readme placeholder for docs 2 | 3 | 4 | ### 📁 `docs/` Directory 5 | 6 | This folder contains documentation and visual assets related to the architecture, design, and technical implementation of the **Federated Fraud Detection** project. 7 | 8 | --- 9 | 10 | #### 📄 Contents: 11 | 12 | * `system_architecture.png` 13 | A visual overview of the federated learning setup, showing communication flow between the central coordinator and distributed clients. 14 | 15 | * `project_slide_deck.md` 16 | A markdown-formatted slide deck summarizing the project purpose, challenges, architecture, results, and contributions by **Rahul Autade**. 17 | 18 | --- 19 | 20 | #### 📌 Purpose: 21 | 22 | These materials are intended to support: 23 | 24 | * Technical understanding of the system design 25 | * Documentation for contributors 26 | * Evidence for academic, professional, or immigration use (e.g., EB1A petition) 27 | 28 | -------------------------------------------------------------------------------- /fraud-detection-federated/models/README.md: -------------------------------------------------------------------------------- 1 | # Readme placeholder for models 2 | 3 | 4 | ### 📁 `models/` Directory 5 | 6 | This folder contains trained or exported machine learning models generated during the simulation of federated fraud detection. 7 | 8 | --- 9 | 10 | #### 📄 Contents: 11 | 12 | * `federated_model.h5` *(optional)* – Placeholder for a locally trained Keras model 13 | * `federated_model_saved/` – Directory generated by `federated_train.py`, containing the final global model saved in TensorFlow's standard format 14 | 15 | --- 16 | 17 | #### 📌 Purpose: 18 | 19 | These models represent the output of collaborative training across multiple clients in a federated setup. They can be used for: 20 | 21 | * Inference testing 22 | * Performance evaluation 23 | * Future retraining or fine-tuning 24 | 25 | --- 26 | 27 | > ⚠️ All models in this directory are trained on **synthetic data** and are intended for demonstration or research purposes only. 28 | 29 | -------------------------------------------------------------------------------- /fraud-detection-federated/notebooks/README.md: -------------------------------------------------------------------------------- 1 | # Readme placeholder for notebooks 2 | 3 | ### 📁 `notebooks/` Directory 4 | 5 | This folder contains Jupyter notebooks used for visualizing data, testing model outputs, and demonstrating project functionality in an interactive format. 6 | 7 | --- 8 | 9 | #### 📄 Contents: 10 | 11 | * `fraud_detection_demo.ipynb` 12 | A demo notebook that: 13 | 14 | * Loads and explores the synthetic transaction dataset 15 | * Visualizes the distribution of fraudulent vs. legitimate transactions 16 | * Supports visual storytelling for EB1A or academic presentation 17 | 18 | --- 19 | 20 | #### 📌 Purpose: 21 | 22 | These notebooks are intended for: 23 | 24 | * Exploratory data analysis (EDA) 25 | * Demonstrating how fraud is detected 26 | * Supporting reproducibility and transparency for reviewers or collaborators 27 | 28 | --- 29 | 30 | > 🧠 These notebooks can be run locally or in Google Colab for convenient sharing and testing. 31 | 32 | -------------------------------------------------------------------------------- /fraud-detection-federated/src/README.md: -------------------------------------------------------------------------------- 1 | # Readme placeholder for src 2 | 3 | 4 | ### 📁 `src/` Directory 5 | 6 | This folder contains the core source code for the **fraud-detection-federated** project. It includes scripts for preprocessing data, simulating federated learning, evaluating results, and testing. 7 | 8 | --- 9 | 10 | #### 📄 Contents: 11 | 12 | * `main.py` 13 | A simple script that loads the dataset and calculates basic fraud statistics. 14 | 15 | * `federated_train.py` 16 | The main script that sets up and runs a federated learning simulation using TensorFlow Federated across multiple simulated clients. 17 | 18 | * `test_main.py` 19 | A unit test script to ensure data format and labeling are valid before training. 20 | 21 | --- 22 | 23 | #### 📌 Purpose: 24 | 25 | These files represent the technical foundation of the project: 26 | 27 | * Showcasing **original algorithm design** 28 | * Demonstrating **federated architecture implementation** 29 | * Supporting **model evaluation and reproducibility** 30 | 31 | -------------------------------------------------------------------------------- /fraud-detection-federated/notebooks/model_inference_demo.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "id": "910910ff", 6 | "metadata": {}, 7 | "source": [ 8 | "# 🔍 Model Inference\n", 9 | "Run predictions on new transactions using a trained model." 10 | ] 11 | }, 12 | { 13 | "cell_type": "code", 14 | "execution_count": null, 15 | "id": "aeca701b", 16 | "metadata": {}, 17 | "outputs": [], 18 | "source": [ 19 | "import numpy as np\n", 20 | "from tensorflow.keras.models import load_model\n", 21 | "\n", 22 | "# Load model\n", 23 | "model = load_model(\"../models/simple_model.h5\")\n", 24 | "\n", 25 | "# Predict new transactions\n", 26 | "transactions = np.array([[100.0], [2000.0], [50.0]])\n", 27 | "predictions = model.predict(transactions)\n", 28 | "for amount, prob in zip(transactions, predictions):\n", 29 | " print(f\"Amount: ${amount[0]:.2f} → Fraud Probability: {prob[0]:.4f}\")" 30 | ] 31 | } 32 | ], 33 | "metadata": {}, 34 | "nbformat": 4, 35 | "nbformat_minor": 5 36 | } 37 | -------------------------------------------------------------------------------- /fraud-detection-federated/notebooks/explore_fraud_data.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "id": "6c7480b1", 6 | "metadata": {}, 7 | "source": [ 8 | "# 📊 Data Exploration: Fraud Dataset\n", 9 | "This notebook explores the structure and distribution of synthetic transaction data." 10 | ] 11 | }, 12 | { 13 | "cell_type": "code", 14 | "execution_count": null, 15 | "id": "4dac1003", 16 | "metadata": {}, 17 | "outputs": [], 18 | "source": [ 19 | "import pandas as pd\n", 20 | "import matplotlib.pyplot as plt\n", 21 | "\n", 22 | "# Load dataset\n", 23 | "df = pd.read_csv(\"../data/synthetic_data.csv\")\n", 24 | "\n", 25 | "# Summary\n", 26 | "print(df.describe())\n", 27 | "\n", 28 | "# Fraud distribution\n", 29 | "df['is_fraud'].value_counts().plot(kind='bar', color=['blue', 'orange'])\n", 30 | "plt.title(\"Fraud vs Legit Transactions\")\n", 31 | "plt.xticks([0, 1], ['Legit', 'Fraud'])\n", 32 | "plt.show()" 33 | ] 34 | } 35 | ], 36 | "metadata": {}, 37 | "nbformat": 4, 38 | "nbformat_minor": 5 39 | } 40 | -------------------------------------------------------------------------------- /fraud-detection-federated/notebooks/fraud_detection_demo.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "id": "6cdcd7ca", 6 | "metadata": {}, 7 | "source": [ 8 | "# 📊 Federated Fraud Detection Visualization\n", 9 | "This notebook visualizes fraud distribution using synthetic data." 10 | ] 11 | }, 12 | { 13 | "cell_type": "code", 14 | "execution_count": null, 15 | "id": "a5f237c4", 16 | "metadata": {}, 17 | "outputs": [], 18 | "source": [ 19 | "import pandas as pd\n", 20 | "import matplotlib.pyplot as plt\n", 21 | "\n", 22 | "# Load dataset\n", 23 | "df = pd.read_csv(\"../data/synthetic_data.csv\")\n", 24 | "\n", 25 | "# Plot fraud distribution\n", 26 | "plt.figure(figsize=(6, 4))\n", 27 | "df[\"is_fraud\"].value_counts().plot(kind='bar', color=['green', 'red'])\n", 28 | "plt.title(\"Fraud vs Legitimate Transactions\")\n", 29 | "plt.xticks([0, 1], ['Legit', 'Fraud'], rotation=0)\n", 30 | "plt.ylabel(\"Count\")\n", 31 | "plt.grid(True)\n", 32 | "plt.tight_layout()\n", 33 | "plt.show()" 34 | ] 35 | } 36 | ], 37 | "metadata": {}, 38 | "nbformat": 4, 39 | "nbformat_minor": 5 40 | } 41 | -------------------------------------------------------------------------------- /fraud-detection-federated/docs/project_slide_deck.md: -------------------------------------------------------------------------------- 1 | # Slide Deck: fraud-detection-federated 2 | 3 | --- 4 | 5 | ## Slide 1: Project Overview 6 | - Title: Federated Fraud Detection Engine 7 | - Developer: Rahul Autade 8 | - Purpose: Privacy-preserving, AI-based fraud detection across banks 9 | 10 | --- 11 | 12 | ## Slide 2: Key Challenges Addressed 13 | - Data privacy laws (e.g., GDPR) 14 | - Fraud detection accuracy. 15 | - Cross-institution collaboration. 16 | 17 | --- 18 | 19 | ## Slide 3: Architecture 20 | - Federated learning setup with 3 simulated clients 21 | - Central coordinator trains global model 22 | - Clients retain sensitive data locally 23 | 24 | --- 25 | 26 | ## Slide 4: Technical Stack 27 | - Python, Pandas, TensorFlow Federated 28 | - GitHub for version control and open access 29 | - Jupyter for visualization 30 | 31 | --- 32 | 33 | ## Slide 5: Results and Impact 34 | - Demonstrates feasibility of cross-bank fraud detection 35 | - Fraud rate analysis and federated learning loop 36 | - Potential for real-world integration and research extension 37 | 38 | --- 39 | 40 | ## Slide 6: Author Contributions 41 | - Designed architecture and model 42 | - Developed code and dataset 43 | - Wrote tests and documentation 44 | - Created this GitHub repo for EB1A evidence 45 | 46 | --- 47 | 48 | ## Slide 7: Contact 49 | - Rahul Autade | rahul.autade@ieee.org 50 | - GitHub: https://github.com/rahul2287/fraud-detection-federated 51 | -------------------------------------------------------------------------------- /fraud-detection-federated/notebooks/federated_training_demo.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "id": "f12ed621", 6 | "metadata": {}, 7 | "source": [ 8 | "# 🤖 Federated Learning: Basic Simulation\n", 9 | "Simulates federated learning using a simple dataset." 10 | ] 11 | }, 12 | { 13 | "cell_type": "code", 14 | "execution_count": null, 15 | "id": "f8fe750f", 16 | "metadata": {}, 17 | "outputs": [], 18 | "source": [ 19 | "import pandas as pd\n", 20 | "import numpy as np\n", 21 | "import tensorflow as tf\n", 22 | "import tensorflow_federated as tff\n", 23 | "\n", 24 | "# Load data\n", 25 | "df = pd.read_csv(\"../data/synthetic_data.csv\")\n", 26 | "X, y = df[['amount']].values.astype(np.float32), df['is_fraud'].values.astype(np.int32)\n", 27 | "client_1 = (X[:3], y[:3])\n", 28 | "client_2 = (X[3:], y[3:])\n", 29 | "\n", 30 | "def create_tf_dataset(X, y):\n", 31 | " return tf.data.Dataset.from_tensor_slices((X, y)).batch(2)\n", 32 | "\n", 33 | "train_data = [create_tf_dataset(*client_1), create_tf_dataset(*client_2)]\n", 34 | "\n", 35 | "def model_fn():\n", 36 | " model = tf.keras.Sequential([\n", 37 | " tf.keras.layers.Input(shape=(1,)),\n", 38 | " tf.keras.layers.Dense(1, activation='sigmoid')\n", 39 | " ])\n", 40 | " return tff.learning.models.from_keras_model(\n", 41 | " model,\n", 42 | " input_spec=train_data[0].element_spec,\n", 43 | " loss=tf.keras.losses.BinaryCrossentropy(),\n", 44 | " metrics=[tf.keras.metrics.BinaryAccuracy()]\n", 45 | " )\n", 46 | "\n", 47 | "fed_avg = tff.learning.algorithms.build_weighted_fed_avg(model_fn)\n", 48 | "state = fed_avg.initialize()\n", 49 | "for round_num in range(1, 4):\n", 50 | " result = fed_avg.next(state, train_data)\n", 51 | " state = result.state\n", 52 | " print(f\"Round {round_num}: {result.metrics}\")" 53 | ] 54 | } 55 | ], 56 | "metadata": {}, 57 | "nbformat": 4, 58 | "nbformat_minor": 5 59 | } 60 | -------------------------------------------------------------------------------- /fraud-detection-federated/src/test_main.py: -------------------------------------------------------------------------------- 1 | 2 | import unittest 3 | import pandas as pd 4 | import os 5 | import subprocess 6 | 7 | DATA_PATH = "../data/synthetic_data.csv" 8 | 9 | class TestDataIntegrity(unittest.TestCase): 10 | def setUp(self): 11 | self.df = pd.read_csv(DATA_PATH) 12 | 13 | def test_required_columns_exist(self): 14 | required_columns = [ 15 | "transaction_id", "user_id", "amount", "transaction_type", 16 | "location", "timestamp", "device_type", "merchant_id", 17 | "is_international", "is_fraud" 18 | ] 19 | for col in required_columns: 20 | self.assertIn(col, self.df.columns) 21 | 22 | def test_fraud_column_binary(self): 23 | self.assertTrue(self.df["is_fraud"].isin([0, 1]).all()) 24 | 25 | def test_no_missing_values(self): 26 | self.assertEqual(self.df.isnull().sum().sum(), 0) 27 | 28 | def test_row_count_and_column_count(self): 29 | self.assertGreaterEqual(len(self.df), 50) 30 | self.assertGreaterEqual(len(self.df.columns), 7) 31 | 32 | def test_valid_transaction_types(self): 33 | valid_types = {"online", "instore", "transfer"} 34 | self.assertTrue(set(self.df["transaction_type"]).issubset(valid_types)) 35 | 36 | def test_valid_locations(self): 37 | self.assertGreaterEqual(self.df["location"].nunique(), 3) 38 | 39 | def test_timestamp_format(self): 40 | try: 41 | pd.to_datetime(self.df["timestamp"]) 42 | success = True 43 | except Exception: 44 | success = False 45 | self.assertTrue(success) 46 | 47 | def test_fraud_distribution(self): 48 | fraud_count = self.df["is_fraud"].sum() 49 | total = len(self.df) 50 | fraud_rate = fraud_count / total 51 | self.assertGreaterEqual(fraud_rate, 0.01) 52 | self.assertLessEqual(fraud_rate, 0.5) 53 | 54 | class TestMainCLI(unittest.TestCase): 55 | def run_script_with_arg(self, arg): 56 | result = subprocess.run( 57 | ["python3", "../src/main.py", arg], 58 | capture_output=True, text=True 59 | ) 60 | return result.stdout, result.stderr 61 | 62 | def test_summary_flag(self): 63 | out, err = self.run_script_with_arg("--summary") 64 | self.assertIn("Summary Statistics", out) 65 | 66 | def test_fraud_flag(self): 67 | out, err = self.run_script_with_arg("--fraud") 68 | self.assertIn("Fraudulent Transactions", out) 69 | 70 | if __name__ == "__main__": 71 | unittest.main() 72 | -------------------------------------------------------------------------------- /fraud-detection-federated/src/evaluator.py: -------------------------------------------------------------------------------- 1 | """ 2 | Evaluates model performance on test data using multiple metrics and visualizations. 3 | """ 4 | 5 | import numpy as np 6 | import matplotlib.pyplot as plt 7 | from sklearn.metrics import ( 8 | accuracy_score, 9 | precision_score, 10 | recall_score, 11 | f1_score, 12 | confusion_matrix, 13 | classification_report, 14 | roc_curve, 15 | auc, 16 | precision_recall_curve 17 | ) 18 | import seaborn as sns 19 | 20 | def evaluate_model(model, X_test, y_test, model_type='keras', plot=True): 21 | """ 22 | Evaluates a model and prints metrics. 23 | 24 | Args: 25 | model: Trained model (Keras or scikit-learn). 26 | X_test (array-like): Test features. 27 | y_test (array-like): True labels. 28 | model_type (str): 'keras' or 'sklearn'. 29 | plot (bool): Show plots (ROC, confusion matrix, PR). 30 | 31 | Returns: 32 | dict: Metric scores. 33 | """ 34 | # Get predictions 35 | if model_type == 'keras': 36 | y_pred_probs = model.predict(X_test).ravel() 37 | y_pred = (y_pred_probs >= 0.5).astype(int) 38 | else: # sklearn 39 | y_pred = model.predict(X_test) 40 | y_pred_probs = model.predict_proba(X_test)[:, 1] 41 | 42 | # Metrics 43 | acc = accuracy_score(y_test, y_pred) 44 | prec = precision_score(y_test, y_pred, zero_division=0) 45 | rec = recall_score(y_test, y_pred, zero_division=0) 46 | f1 = f1_score(y_test, y_pred, zero_division=0) 47 | 48 | print("=== Classification Report ===") 49 | print(classification_report(y_test, y_pred)) 50 | 51 | # Confusion Matrix 52 | cm = confusion_matrix(y_test, y_pred) 53 | if plot: 54 | plt.figure(figsize=(5, 4)) 55 | sns.heatmap(cm, annot=True, fmt='d', cmap='Blues', xticklabels=["Legit", "Fraud"], yticklabels=["Legit", "Fraud"]) 56 | plt.xlabel("Predicted") 57 | plt.ylabel("Actual") 58 | plt.title("Confusion Matrix") 59 | plt.tight_layout() 60 | plt.show() 61 | 62 | # ROC Curve 63 | fpr, tpr, _ = roc_curve(y_test, y_pred_probs) 64 | roc_auc = auc(fpr, tpr) 65 | 66 | if plot: 67 | plt.figure(figsize=(6, 4)) 68 | plt.plot(fpr, tpr, label=f'ROC curve (AUC = {roc_auc:.2f})') 69 | plt.plot([0, 1], [0, 1], 'k--') 70 | plt.xlabel("False Positive Rate") 71 | plt.ylabel("True Positive Rate") 72 | plt.title("ROC Curve") 73 | plt.legend(loc="lower right") 74 | plt.tight_layout() 75 | plt.show() 76 | 77 | # Precision-R 78 | -------------------------------------------------------------------------------- /fraud-detection-federated/src/federated_train.py: -------------------------------------------------------------------------------- 1 | 2 | import pandas as pd 3 | import numpy as np 4 | import tensorflow as tf 5 | import tensorflow_federated as tff 6 | 7 | # Load dataset 8 | df = pd.read_csv("../data/synthetic_data.csv") 9 | features = ["amount", "is_international", "merchant_id"] 10 | target = "is_fraud" 11 | 12 | X = df[features].values.astype(np.float32) 13 | y = df[target].values.astype(np.int32) 14 | 15 | # Simulate 3 clients evenly 16 | def split_clients(X, y, num_clients=3): 17 | split_X = np.array_split(X, num_clients) 18 | split_y = np.array_split(y, num_clients) 19 | return list(zip(split_X, split_y)) 20 | 21 | client_data = split_clients(X, y, num_clients=3) 22 | 23 | def create_tf_dataset(X, y): 24 | return tf.data.Dataset.from_tensor_slices((X, y)).shuffle(buffer_size=10).batch(4) 25 | 26 | federated_train_data = [create_tf_dataset(x, y) for x, y in client_data] 27 | 28 | # === Model Builder === 29 | def create_keras_model(): 30 | model = tf.keras.models.Sequential([ 31 | tf.keras.layers.Input(shape=(len(features),)), 32 | tf.keras.layers.Dense(8, activation='relu'), 33 | tf.keras.layers.Dense(4, activation='relu'), 34 | tf.keras.layers.Dense(1, activation='sigmoid') 35 | ]) 36 | return model 37 | 38 | def model_fn(): 39 | keras_model = create_keras_model() 40 | return tff.learning.models.from_keras_model( 41 | keras_model, 42 | input_spec=federated_train_data[0].element_spec, 43 | loss=tf.keras.losses.BinaryCrossentropy(), 44 | metrics=[tf.keras.metrics.BinaryAccuracy()] 45 | ) 46 | 47 | # === Federated Process === 48 | iterative_process = tff.learning.algorithms.build_weighted_fed_avg( 49 | model_fn=model_fn, 50 | client_optimizer_fn=lambda: tf.keras.optimizers.SGD(learning_rate=0.05), 51 | server_optimizer_fn=lambda: tf.keras.optimizers.Adam() 52 | ) 53 | 54 | state = iterative_process.initialize() 55 | 56 | # Train for several rounds 57 | NUM_ROUNDS = 10 58 | for round_num in range(1, NUM_ROUNDS + 1): 59 | state, metrics = iterative_process.next(state, federated_train_data) 60 | print(f"Round {round_num}: {metrics}") 61 | 62 | # Evaluate global model 63 | def evaluate_model(state, dataset): 64 | keras_model = create_keras_model() 65 | model_weights = state.model.trainable 66 | tff.learning.models.assign_weights_to_keras_model(keras_model, model_weights) 67 | keras_model.compile(optimizer='adam', loss='binary_crossentropy', metrics=['accuracy']) 68 | result = keras_model.evaluate(dataset.batch(8), verbose=0) 69 | print(f"\nGlobal Model Evaluation: Loss={result[0]:.4f}, Accuracy={result[1]:.4f}") 70 | 71 | # Combine all client data for evaluation 72 | full_X = np.vstack([x for x, _ in client_data]) 73 | full_y = np.hstack([y for _, y in client_data]) 74 | full_dataset = tf.data.Dataset.from_tensor_slices((full_X, full_y)) 75 | 76 | evaluate_model(state, full_dataset) 77 | -------------------------------------------------------------------------------- /fraud-detection-federated/src/model_builder.py: -------------------------------------------------------------------------------- 1 | """ 2 | Builds configurable Keras models for binary classification. 3 | Supports different architectures and training configurations. 4 | """ 5 | 6 | from tensorflow.keras.models import Sequential 7 | from tensorflow.keras.layers import Dense, Input, Dropout, BatchNormalization 8 | from tensorflow.keras.optimizers import Adam, SGD, RMSprop 9 | import tensorflow as tf 10 | 11 | def build_model(input_shape=1, 12 | architecture='simple', 13 | optimizer='adam', 14 | loss='binary_crossentropy', 15 | metrics=['accuracy'], 16 | dropout_rate=0.2, 17 | show_summary=True): 18 | """ 19 | Builds and compiles a Keras Sequential model. 20 | 21 | Args: 22 | input_shape (int): Number of input features. 23 | architecture (str): One of ['simple', 'wide', 'deep']. 24 | optimizer (str or tf.keras.optimizers.Optimizer): Optimizer to use. 25 | loss (str): Loss function. 26 | metrics (list): List of metrics to evaluate. 27 | dropout_rate (float): Dropout rate if applicable. 28 | show_summary (bool): If True, prints the model summary. 29 | 30 | Returns: 31 | Compiled Keras model. 32 | """ 33 | model = Sequential() 34 | model.add(Input(shape=(input_shape,))) 35 | 36 | if architecture == 'simple': 37 | model.add(Dense(16, activation='relu')) 38 | elif architecture == 'wide': 39 | model.add(Dense(64, activation='relu')) 40 | model.add(Dense(64, activation='relu')) 41 | elif architecture == 'deep': 42 | model.add(Dense(64, activation='relu')) 43 | model.add(BatchNormalization()) 44 | model.add(Dropout(dropout_rate)) 45 | model.add(Dense(32, activation='relu')) 46 | model.add(Dropout(dropout_rate)) 47 | model.add(Dense(16, activation='relu')) 48 | else: 49 | raise ValueError("Invalid architecture. Choose from 'simple', 'wide', or 'deep'.") 50 | 51 | model.add(Dense(1, activation='sigmoid')) 52 | 53 | # Optimizer selection 54 | if isinstance(optimizer, str): 55 | if optimizer == 'adam': 56 | optimizer = Adam() 57 | elif optimizer == 'sgd': 58 | optimizer = SGD() 59 | elif optimizer == 'rmsprop': 60 | optimizer = RMSprop() 61 | else: 62 | raise ValueError("Unsupported optimizer name.") 63 | 64 | model.compile(optimizer=optimizer, loss=loss, metrics=metrics) 65 | 66 | if show_summary: 67 | model.summary() 68 | 69 | return model 70 | 71 | # Example usage 72 | if __name__ == "__main__": 73 | # Dummy data to test compilation 74 | import numpy as np 75 | 76 | X_dummy = np.random.rand(100, 5) 77 | y_dummy = np.random.randint(0, 2, 100) 78 | 79 | print("Building and training 'deep' model with 5 inputs...") 80 | model = build_model(input_shape=5, architecture='deep', optimizer='ada 81 | -------------------------------------------------------------------------------- /fraud-detection-federated/src/utils.py: -------------------------------------------------------------------------------- 1 | """ 2 | Utility functions for logging metrics, visualizing results, and exporting reports. 3 | """ 4 | 5 | import json 6 | import csv 7 | import os 8 | from sklearn.metrics import classification_report, confusion_matrix 9 | import matplotlib.pyplot as plt 10 | import seaborn as sns 11 | 12 | def log_metrics(metrics_dict, prefix=""): 13 | """ 14 | Logs training or evaluation metrics in formatted output. 15 | 16 | Args: 17 | metrics_dict (dict): Dictionary of metric name to value. 18 | prefix (str): Optional text to prefix logs. 19 | """ 20 | print(f"{prefix} Metrics:") 21 | for key, val in metrics_dict.items(): 22 | print(f" {key}: {val:.4f}") 23 | 24 | def save_metrics(metrics_dict, filepath, fmt='json'): 25 | """ 26 | Saves metrics to a file in JSON or CSV format. 27 | 28 | Args: 29 | metrics_dict (dict): Dictionary of metrics. 30 | filepath (str): Output file path. 31 | fmt (str): Format ('json' or 'csv'). 32 | """ 33 | os.makedirs(os.path.dirname(filepath), exist_ok=True) 34 | 35 | if fmt == 'json': 36 | with open(filepath, 'w') as f: 37 | json.dump(metrics_dict, f, indent=4) 38 | elif fmt == 'csv': 39 | with open(filepath, 'w', newline='') as f: 40 | writer = csv.writer(f) 41 | writer.writerow(["Metric", "Value"]) 42 | for k, v in metrics_dict.items(): 43 | writer.writerow([k, v]) 44 | else: 45 | raise ValueError("Unsupported format. Use 'json' or 'csv'.") 46 | 47 | print(f"Metrics saved to {filepath}") 48 | 49 | def display_classification_report(y_true, y_pred): 50 | """ 51 | Prints classification report. 52 | """ 53 | print("\n=== Classification Report ===") 54 | print(classification_report(y_true, y_pred)) 55 | 56 | def plot_confusion_matrix(y_true, y_pred, labels=None, title="Confusion Matrix"): 57 | """ 58 | Plots a confusion matrix heatmap. 59 | """ 60 | cm = confusion_matrix(y_true, y_pred) 61 | plt.figure(figsize=(5, 4)) 62 | sns.heatmap(cm, annot=True, fmt='d', cmap='Blues', xticklabels=labels, yticklabels=labels) 63 | plt.xlabel("Predicted") 64 | plt.ylabel("Actual") 65 | plt.title(title) 66 | plt.tight_layout() 67 | plt.show() 68 | 69 | # Example usage for standalone testing 70 | if __name__ == "__main__": 71 | # Mock metrics 72 | mock_metrics = { 73 | "loss": 0.356, 74 | "accuracy": 0.894, 75 | "precision": 0.774, 76 | "recall": 0.620, 77 | "f1_score": 0.687 78 | } 79 | 80 | log_metrics(mock_metrics, prefix="Test") 81 | save_metrics(mock_metrics, "outputs/metrics.json", fmt='json') 82 | save_metrics(mock_metrics, "outputs/metrics.csv", fmt='csv') 83 | 84 | # Mock classification data 85 | y_true = [0, 0, 1, 1, 0, 1, 0, 1] 86 | y_pred = [0, 0, 1, 0, 0, 1, 1, 1] 87 | 88 | display_classification_report(y_true, y_pred) 89 | plot_confusion_matrix(y_true, y_pred, labels=["Legit", "Fraud"]) 90 | -------------------------------------------------------------------------------- /fraud-detection-federated/src/client_simulator.py: -------------------------------------------------------------------------------- 1 | """ 2 | Simulates multiple clients by splitting dataset. 3 | Enhanced for edge case handling, analysis, and reproducibility. 4 | """ 5 | 6 | import numpy as np 7 | import pandas as pd 8 | import matplotlib.pyplot as plt 9 | import logging 10 | from collections import Counter 11 | 12 | logging.basicConfig(level=logging.INFO) 13 | 14 | def ensure_numpy(X, y): 15 | """ 16 | Converts pandas DataFrames or Series to numpy arrays. 17 | """ 18 | if isinstance(X, pd.DataFrame) or isinstance(X, pd.Series): 19 | X = X.values 20 | if isinstance(y, pd.DataFrame) or isinstance(y, pd.Series): 21 | y = y.values 22 | return X, y 23 | 24 | def stratified_split(X, y, num_clients): 25 | """ 26 | Attempts a stratified split to preserve label proportions across clients. 27 | """ 28 | from sklearn.model_selection import StratifiedKFold 29 | skf = StratifiedKFold(n_splits=num_clients, shuffle=True, random_state=42) 30 | client_data = [] 31 | for _, idx in skf.split(X, y): 32 | client_data.append((X[idx], y[idx])) 33 | return client_data 34 | 35 | def analyze_distribution(y, title="Label Distribution"): 36 | """ 37 | Plots the distribution of labels in a pie chart. 38 | """ 39 | counter = Counter(y) 40 | labels = list(counter.keys()) 41 | sizes = list(counter.values()) 42 | plt.figure(figsize=(5, 5)) 43 | plt.pie(sizes, labels=labels, autopct='%1.1f%%', startangle=140) 44 | plt.title(title) 45 | plt.show() 46 | 47 | def split_clients(X, y, num_clients=3, shuffle=True, seed=None, stratify=False, analyze=False): 48 | """ 49 | Splits dataset into federated clients. 50 | 51 | Args: 52 | X (array-like): Features. 53 | y (array-like): Labels. 54 | num_clients (int): Number of clients. 55 | shuffle (bool): Shuffle before split. 56 | seed (int): Random seed. 57 | stratify (bool): Enable stratified splitting. 58 | analyze (bool): Plot label distribution for each client. 59 | 60 | Returns: 61 | List of (X_i, y_i) tuples for each simulated client. 62 | """ 63 | X, y = ensure_numpy(X, y) 64 | 65 | if shuffle and not stratify: 66 | if seed is not None: 67 | np.random.seed(seed) 68 | indices = np.arange(len(X)) 69 | np.random.shuffle(indices) 70 | X = X[indices] 71 | y = y[indices] 72 | 73 | if stratify: 74 | logging.info("Performing stratified split...") 75 | client_data = stratified_split(X, y, num_clients) 76 | else: 77 | X_split = np.array_split(X, num_clients) 78 | y_split = np.array_split(y, num_clients) 79 | client_data = list(zip(X_split, y_split)) 80 | 81 | for i, (Xi, yi) in enumerate(client_data): 82 | logging.info(f"Client {i+1}: {Xi.shape[0]} samples, fraud rate: {np.mean(yi):.2f}") 83 | if analyze: 84 | analyze_distribution(yi, title=f"Client {i+1} Label Distribution") 85 | 86 | return client_data 87 | 88 | # Example usage 89 | if __name__ == "__main__": 90 | from sklearn.datasets imp 91 | -------------------------------------------------------------------------------- /fraud-detection-federated/src/data_loader.py: -------------------------------------------------------------------------------- 1 | """ 2 | Loads and preprocesses transaction data for fraud detection and federated learning. 3 | """ 4 | 5 | import pandas as pd 6 | import numpy as np 7 | from sklearn.model_selection import train_test_split 8 | from sklearn.preprocessing import StandardScaler, LabelEncoder 9 | import logging 10 | 11 | logging.basicConfig(level=logging.INFO) 12 | 13 | def load_raw_data(file_path): 14 | """ 15 | Loads raw transaction data from a CSV file. 16 | """ 17 | try: 18 | df = pd.read_csv(file_path) 19 | logging.info(f"Data loaded successfully. Shape: {df.shape}") 20 | return df 21 | except Exception as e: 22 | logging.error(f"Error loading data: {e}") 23 | raise 24 | 25 | def validate_columns(df, required_cols): 26 | """ 27 | Validates that the required columns exist in the dataset. 28 | """ 29 | missing = [col for col in required_cols if col not in df.columns] 30 | if missing: 31 | raise ValueError(f"Missing columns: {missing}") 32 | 33 | def preprocess_data(df, features, target='is_fraud'): 34 | """ 35 | Selects features, encodes categoricals, scales numerics. 36 | """ 37 | validate_columns(df, features + [target]) 38 | df = df.copy() 39 | 40 | # Encode categorical features 41 | for col in df[features].select_dtypes(include='object').columns: 42 | le = LabelEncoder() 43 | df[col] = le.fit_transform(df[col]) 44 | logging.info(f"Encoded column: {col}") 45 | 46 | X = df[features].values 47 | y = df[target].values 48 | 49 | # Scale features 50 | scaler = StandardScaler() 51 | X_scaled = scaler.fit_transform(X) 52 | logging.info("Features scaled.") 53 | 54 | return X_scaled, y 55 | 56 | def load_and_preprocess(file_path, features, target='is_fraud'): 57 | df = load_raw_data(file_path) 58 | return preprocess_data(df, features, target) 59 | 60 | def split_data(X, y, test_size=0.2, random_state=42): 61 | """ 62 | Splits data into train and test sets. 63 | """ 64 | return train_test_split(X, y, test_size=test_size, random_state=random_state) 65 | 66 | def split_clients(X, y, num_clients=3): 67 | """ 68 | Splits data for simulated federated learning clients. 69 | """ 70 | client_data = [] 71 | X_split = np.array_split(X, num_clients) 72 | y_split = np.array_split(y, num_clients) 73 | for i in range(num_clients): 74 | client_data.append((X_split[i], y_split[i])) 75 | logging.info(f"Client {i+1} data size: {len(X_split[i])}") 76 | return client_data 77 | 78 | # Example usage for testing 79 | if __name__ == "__main__": 80 | file = "../data/synthetic_data.csv" 81 | features = ['amount', 'is_international', 'merchant_id'] 82 | 83 | try: 84 | X, y = load_and_preprocess(file, features) 85 | X_train, X_test, y_train, y_test = split_data(X, y) 86 | clients = split_clients(X_train, y_train, num_clients=3) 87 | 88 | print("Data preprocessing complete.") 89 | print(f"Train set: {X_train.shape}, Test set: {X_test.shape}") 90 | except Exception as ex: 91 | logging.error(f"Execution failed: {ex}") 92 | -------------------------------------------------------------------------------- /fraud-detection-federated/src/model_inference.py: -------------------------------------------------------------------------------- 1 | """ 2 | Model Inference Script for fraud-detection-federated 3 | Loads a trained model and performs inference on sample transactions. 4 | """ 5 | 6 | import numpy as np 7 | import pandas as pd 8 | import argparse 9 | import os 10 | from tensorflow.keras.models import load_model 11 | 12 | def load_sample_data(from_csv=False, csv_path=None): 13 | """ 14 | Loads input data for prediction. 15 | 16 | Args: 17 | from_csv (bool): If True, loads from a CSV file. 18 | csv_path (str): Path to CSV file (must have numerical features). 19 | 20 | Returns: 21 | np.ndarray: Input features. 22 | """ 23 | if from_csv and csv_path: 24 | df = pd.read_csv(csv_path) 25 | print(f"Loaded {len(df)} samples from CSV.") 26 | return df.values 27 | else: 28 | print("Using sample transaction amounts.") 29 | return np.array([ 30 | [120.0, 0, 531], 31 | [5000.0, 1, 544], 32 | [75.5, 0, 510] 33 | ]) 34 | 35 | def load_model_for_inference(model_path): 36 | """ 37 | Loads a trained Keras model. 38 | """ 39 | if not os.path.exists(model_path): 40 | raise FileNotFoundError(f"Model not found at {model_path}") 41 | model = load_model(model_path) 42 | model.summary() 43 | return model 44 | 45 | def run_inference(model, data, threshold=0.5, save_output=False, output_path="predictions.csv"): 46 | """ 47 | Runs model inference on input data. 48 | 49 | Args: 50 | model: Trained Keras model. 51 | data (np.ndarray): Input features. 52 | threshold (float): Classification threshold. 53 | save_output (bool): Whether to save results to CSV. 54 | output_path (str): Output file path if saving. 55 | """ 56 | predictions = model.predict(data) 57 | print("\n=== Inference Results ===") 58 | results = [] 59 | for i, row in enumerate(data): 60 | prob = predictions[i][0] 61 | is_fraud = int(prob >= threshold) 62 | print(f"Input: {row} -> Fraud Probability: {prob:.4f} -> Classified as: {'FRAUD' if is_fraud else 'LEGIT'}") 63 | results.append(list(row) + [prob, is_fraud]) 64 | 65 | if save_output: 66 | col_names = [f"feature_{i+1}" for i in range(data.shape[1])] + ["fraud_prob", "is_fraud"] 67 | df = pd.DataFrame(results, columns=col_names) 68 | df.to_csv(output_path, index=False) 69 | print(f"Results saved to {output_path}") 70 | 71 | def main(): 72 | parser = argparse.ArgumentParser(description="Fraud Detection Inference Script") 73 | parser.add_argument("--model", type=str, default="../models/simple_model.h5", help="Path to trained model") 74 | parser.add_argument("--csv", type=str, help="Path to input CSV file (optional)") 75 | parser.add_argument("--threshold", type=float, default=0.5, help="Classification threshold") 76 | parser.add_argument("--save", action='store_true', help="Save predictions to CSV") 77 | args = parser.parse_args() 78 | 79 | input_data = load_sample_data(from_csv=bool(args.csv), csv_path=args.csv) 80 | model = load_model_for_inference(args.model) 81 | run_inference(model, input_data, threshold=args.threshold, save_output=args.save) 82 | 83 | if __name__ == "__main__": 84 | main() 85 | -------------------------------------------------------------------------------- /fraud-detection-federated/src/trainer.py: -------------------------------------------------------------------------------- 1 | """ 2 | Trains a Keras model on local client data. 3 | Supports early stopping, validation, and history visualization. 4 | """ 5 | 6 | import matplotlib.pyplot as plt 7 | from tensorflow.keras.callbacks import EarlyStopping, ModelCheckpoint 8 | 9 | def train_model(model, X, y, 10 | epochs=10, 11 | batch_size=8, 12 | validation_split=0.2, 13 | patience=3, 14 | save_path=None, 15 | verbose=1, 16 | plot_history=True): 17 | """ 18 | Trains the model on local data. 19 | 20 | Args: 21 | model: Compiled Keras model. 22 | X (np.ndarray): Features. 23 | y (np.ndarray): Labels. 24 | epochs (int): Number of epochs. 25 | batch_size (int): Batch size. 26 | validation_split (float): Portion of training data used for validation. 27 | patience (int): Early stopping patience. 28 | save_path (str): Optional path to save best model. 29 | verbose (int): Verbosity level. 30 | plot_history (bool): Plot training/validation loss. 31 | 32 | Returns: 33 | model: Trained model. 34 | history: Training history object. 35 | """ 36 | callbacks = [] 37 | if patience > 0: 38 | callbacks.append(EarlyStopping(monitor='val_loss', patience=patience, restore_best_weights=True)) 39 | if save_path: 40 | callbacks.append(ModelCheckpoint(filepath=save_path, monitor='val_loss', save_best_only=True)) 41 | 42 | history = model.fit( 43 | X, y, 44 | validation_split=validation_split, 45 | epochs=epochs, 46 | batch_size=batch_size, 47 | verbose=verbose, 48 | callbacks=callbacks 49 | ) 50 | 51 | if plot_history: 52 | plot_training_history(history) 53 | 54 | return model, history 55 | 56 | def plot_training_history(history): 57 | """ 58 | Plots training and validation accuracy/loss curves. 59 | """ 60 | if history is None: 61 | return 62 | 63 | history_dict = history.history 64 | 65 | plt.figure(figsize=(12, 4)) 66 | 67 | # Accuracy 68 | plt.subplot(1, 2, 1) 69 | if 'accuracy' in history_dict: 70 | plt.plot(history_dict['accuracy'], label='Train Acc') 71 | if 'val_accuracy' in history_dict: 72 | plt.plot(history_dict['val_accuracy'], label='Val Acc') 73 | plt.title("Accuracy over Epochs") 74 | plt.xlabel("Epoch") 75 | plt.ylabel("Accuracy") 76 | plt.legend() 77 | 78 | # Loss 79 | plt.subplot(1, 2, 2) 80 | plt.plot(history_dict['loss'], label='Train Loss') 81 | if 'val_loss' in history_dict: 82 | plt.plot(history_dict['val_loss'], label='Val Loss') 83 | plt.title("Loss over Epochs") 84 | plt.xlabel("Epoch") 85 | plt.ylabel("Loss") 86 | plt.legend() 87 | 88 | plt.tight_layout() 89 | plt.show() 90 | 91 | # Test mode 92 | if __name__ == "__main__": 93 | import numpy as np 94 | from model_builder import build_model # Ensure this file exists or replace with inline model 95 | 96 | # Generate dummy data 97 | X_dummy = np.random.rand(100, 3) 98 | y_dummy = np.random.randint(0, 2, 100) 99 | 100 | model = build_model(input_shape=3, architecture='simple') 101 | model, history = train_model(model, X_dummy, y_dummy, epochs=5) 102 | -------------------------------------------------------------------------------- /fraud-detection-federated/src/preprocessing.py: -------------------------------------------------------------------------------- 1 | """ 2 | Applies normalization and preprocessing to input features. 3 | Supports MinMaxScaler and StandardScaler. 4 | """ 5 | 6 | import numpy as np 7 | import pandas as pd 8 | import argparse 9 | import os 10 | import joblib 11 | from sklearn.preprocessing import MinMaxScaler, StandardScaler 12 | 13 | def normalize_data(X, method="minmax", scaler=None): 14 | """ 15 | Normalizes data using MinMax or Standard scaling. 16 | 17 | Args: 18 | X (np.ndarray): Input data. 19 | method (str): 'minmax' or 'standard'. 20 | scaler: Optional pretrained scaler. 21 | 22 | Returns: 23 | np.ndarray: Scaled data. 24 | scaler: Trained scaler object. 25 | """ 26 | if scaler is None: 27 | if method == "minmax": 28 | scaler = MinMaxScaler() 29 | elif method == "standard": 30 | scaler = StandardScaler() 31 | else: 32 | raise ValueError("Unsupported scaling method") 33 | 34 | X_scaled = scaler.fit_transform(X) 35 | else: 36 | X_scaled = scaler.transform(X) 37 | 38 | return X_scaled, scaler 39 | 40 | def inverse_transform(X_scaled, scaler): 41 | """ 42 | Converts scaled data back to original scale. 43 | """ 44 | return scaler.inverse_transform(X_scaled) 45 | 46 | def save_scaler(scaler, path): 47 | """ 48 | Saves the scaler to a file. 49 | """ 50 | joblib.dump(scaler, path) 51 | 52 | def load_scaler(path): 53 | """ 54 | Loads a scaler from file. 55 | """ 56 | if not os.path.exists(path): 57 | raise FileNotFoundError(f"Scaler file not found: {path}") 58 | return joblib.load(path) 59 | 60 | def normalize_csv(input_path, output_path, method="minmax"): 61 | """ 62 | Normalizes numeric columns from CSV and writes output. 63 | """ 64 | df = pd.read_csv(input_path) 65 | num_cols = df.select_dtypes(include=[np.number]).columns 66 | X = df[num_cols].values 67 | 68 | X_scaled, scaler = normalize_data(X, method=method) 69 | df_scaled = pd.DataFrame(X_scaled, columns=num_cols) 70 | df_scaled.to_csv(output_path, index=False) 71 | 72 | print(f"Normalized data saved to {output_path}") 73 | return scaler 74 | 75 | # CLI usage 76 | def main(): 77 | parser = argparse.ArgumentParser(description="Normalize CSV data using MinMax or Standard scaler") 78 | parser.add_argument("--input", type=str, required=True, help="Input CSV file") 79 | parser.add_argument("--output", type=str, default="normalized_output.csv", help="Output CSV file") 80 | parser.add_argument("--method", choices=["minmax", "standard"], default="minmax", help="Scaling method") 81 | parser.add_argument("--save_scaler", type=str, help="Path to save scaler object") 82 | args = parser.parse_args() 83 | 84 | scaler = normalize_csv(args.input, args.output, method=args.method) 85 | 86 | if args.save_scaler: 87 | save_scaler(scaler, args.save_scaler) 88 | print(f"Scaler saved to {args.save_scaler}") 89 | 90 | # Run standalone 91 | if __name__ == "__main__": 92 | # Sample test 93 | X_dummy = np.array([[100], [2000], [500], [1500]]) 94 | X_scaled, scaler = normalize_data(X_dummy, method="standard") 95 | 96 | print("Original:\n", X_dummy) 97 | print("Scaled:\n", X_scaled) 98 | print("Inversed:\n", inverse_transform(X_scaled, scaler)) 99 | 100 | # Uncomment below to run as CLI 101 | # main() 102 | -------------------------------------------------------------------------------- /fraud-detection-federated/src/main.py: -------------------------------------------------------------------------------- 1 | 2 | import pandas as pd 3 | import matplotlib.pyplot as plt 4 | import seaborn as sns 5 | import argparse 6 | from datetime import datetime 7 | 8 | # Load dataset 9 | df = pd.read_csv("../data/synthetic_data.csv") 10 | 11 | # === Summary Statistics === 12 | def summarize_data(df): 13 | print("=== Summary Statistics ===") 14 | print(df.describe(include='all')) 15 | print("\nMissing Values:") 16 | print(df.isnull().sum()) 17 | 18 | # === Fraud Stats === 19 | def fraud_stats(df): 20 | fraud_count = df["is_fraud"].sum() 21 | total = len(df) 22 | fraud_rate = fraud_count / total * 100 23 | print(f"\nTotal Transactions: {total}") 24 | print(f"Fraudulent Transactions: {fraud_count}") 25 | print(f"Fraud Rate: {fraud_rate:.2f}%") 26 | 27 | # === Visualize Fraud vs Legit === 28 | def plot_fraud_distribution(df): 29 | plt.figure(figsize=(6,4)) 30 | df['is_fraud'].value_counts().plot(kind='bar', color=['blue', 'orange']) 31 | plt.title("Fraud vs Legit Transactions") 32 | plt.xticks([0, 1], ['Legit', 'Fraud']) 33 | plt.xlabel("Transaction Type") 34 | plt.ylabel("Count") 35 | plt.tight_layout() 36 | plt.savefig("../docs/fraud_distribution.png") 37 | plt.close() 38 | 39 | # === Transaction Amounts === 40 | def plot_amount_distribution(df): 41 | plt.figure(figsize=(8, 5)) 42 | sns.histplot(df['amount'], bins=30, kde=True) 43 | plt.title("Transaction Amount Distribution") 44 | plt.xlabel("Amount") 45 | plt.ylabel("Frequency") 46 | plt.tight_layout() 47 | plt.savefig("../docs/amount_distribution.png") 48 | plt.close() 49 | 50 | # === Fraud by Transaction Type === 51 | def fraud_by_transaction_type(df): 52 | type_fraud = df.groupby('transaction_type')['is_fraud'].mean() 53 | print("\nFraud Rate by Transaction Type:") 54 | print(type_fraud) 55 | 56 | # === High Risk Locations === 57 | def high_risk_locations(df): 58 | location_fraud = df.groupby('location')['is_fraud'].mean().sort_values(ascending=False) 59 | print("\nHigh Risk Locations (by fraud rate):") 60 | print(location_fraud) 61 | 62 | # === Top Users with Most Fraud === 63 | def top_users_by_fraud(df, top_n=5): 64 | user_fraud = df[df['is_fraud'] == 1].groupby('user_id').size().sort_values(ascending=False).head(top_n) 65 | print(f"\nTop {top_n} Users with Most Fraudulent Transactions:") 66 | print(user_fraud) 67 | 68 | # === Time Series of Transactions === 69 | def plot_time_series(df): 70 | df['timestamp'] = pd.to_datetime(df['timestamp']) 71 | ts = df.set_index('timestamp').resample('D').size() 72 | plt.figure(figsize=(10, 4)) 73 | ts.plot() 74 | plt.title("Daily Transaction Volume") 75 | plt.xlabel("Date") 76 | plt.ylabel("Transactions") 77 | plt.tight_layout() 78 | plt.savefig("../docs/daily_transactions.png") 79 | plt.close() 80 | 81 | # === CLI Handler === 82 | def main(): 83 | parser = argparse.ArgumentParser(description="Fraud Detection Data Analysis") 84 | parser.add_argument('--summary', action='store_true', help='Show data summary') 85 | parser.add_argument('--fraud', action='store_true', help='Show fraud statistics') 86 | parser.add_argument('--charts', action='store_true', help='Generate charts') 87 | parser.add_argument('--risks', action='store_true', help='Show risk analysis') 88 | args = parser.parse_args() 89 | 90 | if args.summary: 91 | summarize_data(df) 92 | if args.fraud: 93 | fraud_stats(df) 94 | if args.charts: 95 | plot_fraud_distribution(df) 96 | plot_amount_distribution(df) 97 | plot_time_series(df) 98 | if args.risks: 99 | fraud_by_transaction_type(df) 100 | high_risk_locations(df) 101 | top_users_by_fraud(df) 102 | 103 | if __name__ == "__main__": 104 | main() 105 | -------------------------------------------------------------------------------- /fraud-detection-federated/src/client_manager.py: -------------------------------------------------------------------------------- 1 | """ 2 | This module handles client manager. 3 | """ 4 | 5 | import numpy as np 6 | import pandas as pd 7 | 8 | def example_function_1(): 9 | result = [] 10 | for i in range(50): 11 | result.append(i ** 2) 12 | return result 13 | 14 | def example_function_2(): 15 | return np.random.rand(100) 16 | 17 | class ExampleClass: 18 | def __init__(self): 19 | self.data = pd.DataFrame({"A": range(100)}) 20 | 21 | def compute_sum(self): 22 | return self.data.sum() 23 | 24 | def print_preview(self): 25 | print(self.data.head()) 26 | 27 | if __name__ == "__main__": 28 | obj = ExampleClass() 29 | obj.print_preview() 30 | print(example_function_1()[:5]) 31 | print(example_function_2()[:5]) 32 | """ 33 | This module handles client manager. 34 | """ 35 | 36 | import numpy as np 37 | import pandas as pd 38 | 39 | def example_function_1(): 40 | result = [] 41 | for i in range(50): 42 | result.append(i ** 2) 43 | return result 44 | 45 | def example_function_2(): 46 | return np.random.rand(100) 47 | 48 | class ExampleClass: 49 | def __init__(self): 50 | self.data = pd.DataFrame({"A": range(100)}) 51 | 52 | def compute_sum(self): 53 | return self.data.sum() 54 | 55 | def print_preview(self): 56 | print(self.data.head()) 57 | 58 | if __name__ == "__main__": 59 | obj = ExampleClass() 60 | obj.print_preview() 61 | print(example_function_1()[:5]) 62 | print(example_function_2()[:5]) 63 | """ 64 | This module handles client manager. 65 | """ 66 | 67 | import numpy as np 68 | import pandas as pd 69 | 70 | def example_function_1(): 71 | result = [] 72 | for i in range(50): 73 | result.append(i ** 2) 74 | return result 75 | 76 | def example_function_2(): 77 | return np.random.rand(100) 78 | 79 | class ExampleClass: 80 | def __init__(self): 81 | self.data = pd.DataFrame({"A": range(100)}) 82 | 83 | def compute_sum(self): 84 | return self.data.sum() 85 | 86 | def print_preview(self): 87 | print(self.data.head()) 88 | 89 | if __name__ == "__main__": 90 | obj = ExampleClass() 91 | obj.print_preview() 92 | print(example_function_1()[:5]) 93 | print(example_function_2()[:5]) 94 | """ 95 | This module handles client manager. 96 | """ 97 | 98 | import numpy as np 99 | import pandas as pd 100 | 101 | def example_function_1(): 102 | result = [] 103 | for i in range(50): 104 | result.append(i ** 2) 105 | return result 106 | 107 | def example_function_2(): 108 | return np.random.rand(100) 109 | 110 | class ExampleClass: 111 | def __init__(self): 112 | self.data = pd.DataFrame({"A": range(100)}) 113 | 114 | def compute_sum(self): 115 | return self.data.sum() 116 | 117 | def print_preview(self): 118 | print(self.data.head()) 119 | 120 | if __name__ == "__main__": 121 | obj = ExampleClass() 122 | obj.print_preview() 123 | print(example_function_1()[:5]) 124 | print(example_function_2()[:5]) 125 | """ 126 | This module handles client manager. 127 | """ 128 | 129 | import numpy as np 130 | import pandas as pd 131 | 132 | def example_function_1(): 133 | result = [] 134 | for i in range(50): 135 | result.append(i ** 2) 136 | return result 137 | 138 | def example_function_2(): 139 | return np.random.rand(100) 140 | 141 | class ExampleClass: 142 | def __init__(self): 143 | self.data = pd.DataFrame({"A": range(100)}) 144 | 145 | def compute_sum(self): 146 | return self.data.sum() 147 | 148 | def print_preview(self): 149 | print(self.data.head()) 150 | 151 | if __name__ == "__main__": 152 | obj = ExampleClass() 153 | obj.print_preview() 154 | print(example_function_1()[:5]) 155 | print(example_function_2()[:5]) 156 | -------------------------------------------------------------------------------- /fraud-detection-federated/src/explainability.py: -------------------------------------------------------------------------------- 1 | """ 2 | This module handles explainability. 3 | """ 4 | 5 | import numpy as np 6 | import pandas as pd 7 | 8 | def example_function_1(): 9 | result = [] 10 | for i in range(50): 11 | result.append(i ** 2) 12 | return result 13 | 14 | def example_function_2(): 15 | return np.random.rand(100) 16 | 17 | class ExampleClass: 18 | def __init__(self): 19 | self.data = pd.DataFrame({"A": range(100)}) 20 | 21 | def compute_sum(self): 22 | return self.data.sum() 23 | 24 | def print_preview(self): 25 | print(self.data.head()) 26 | 27 | if __name__ == "__main__": 28 | obj = ExampleClass() 29 | obj.print_preview() 30 | print(example_function_1()[:5]) 31 | print(example_function_2()[:5]) 32 | """ 33 | This module handles explainability. 34 | """ 35 | 36 | import numpy as np 37 | import pandas as pd 38 | 39 | def example_function_1(): 40 | result = [] 41 | for i in range(50): 42 | result.append(i ** 2) 43 | return result 44 | 45 | def example_function_2(): 46 | return np.random.rand(100) 47 | 48 | class ExampleClass: 49 | def __init__(self): 50 | self.data = pd.DataFrame({"A": range(100)}) 51 | 52 | def compute_sum(self): 53 | return self.data.sum() 54 | 55 | def print_preview(self): 56 | print(self.data.head()) 57 | 58 | if __name__ == "__main__": 59 | obj = ExampleClass() 60 | obj.print_preview() 61 | print(example_function_1()[:5]) 62 | print(example_function_2()[:5]) 63 | """ 64 | This module handles explainability. 65 | """ 66 | 67 | import numpy as np 68 | import pandas as pd 69 | 70 | def example_function_1(): 71 | result = [] 72 | for i in range(50): 73 | result.append(i ** 2) 74 | return result 75 | 76 | def example_function_2(): 77 | return np.random.rand(100) 78 | 79 | class ExampleClass: 80 | def __init__(self): 81 | self.data = pd.DataFrame({"A": range(100)}) 82 | 83 | def compute_sum(self): 84 | return self.data.sum() 85 | 86 | def print_preview(self): 87 | print(self.data.head()) 88 | 89 | if __name__ == "__main__": 90 | obj = ExampleClass() 91 | obj.print_preview() 92 | print(example_function_1()[:5]) 93 | print(example_function_2()[:5]) 94 | """ 95 | This module handles explainability. 96 | """ 97 | 98 | import numpy as np 99 | import pandas as pd 100 | 101 | def example_function_1(): 102 | result = [] 103 | for i in range(50): 104 | result.append(i ** 2) 105 | return result 106 | 107 | def example_function_2(): 108 | return np.random.rand(100) 109 | 110 | class ExampleClass: 111 | def __init__(self): 112 | self.data = pd.DataFrame({"A": range(100)}) 113 | 114 | def compute_sum(self): 115 | return self.data.sum() 116 | 117 | def print_preview(self): 118 | print(self.data.head()) 119 | 120 | if __name__ == "__main__": 121 | obj = ExampleClass() 122 | obj.print_preview() 123 | print(example_function_1()[:5]) 124 | print(example_function_2()[:5]) 125 | """ 126 | This module handles explainability. 127 | """ 128 | 129 | import numpy as np 130 | import pandas as pd 131 | 132 | def example_function_1(): 133 | result = [] 134 | for i in range(50): 135 | result.append(i ** 2) 136 | return result 137 | 138 | def example_function_2(): 139 | return np.random.rand(100) 140 | 141 | class ExampleClass: 142 | def __init__(self): 143 | self.data = pd.DataFrame({"A": range(100)}) 144 | 145 | def compute_sum(self): 146 | return self.data.sum() 147 | 148 | def print_preview(self): 149 | print(self.data.head()) 150 | 151 | if __name__ == "__main__": 152 | obj = ExampleClass() 153 | obj.print_preview() 154 | print(example_function_1()[:5]) 155 | print(example_function_2()[:5]) 156 | -------------------------------------------------------------------------------- /fraud-detection-federated/src/deployment_utils.py: -------------------------------------------------------------------------------- 1 | """ 2 | This module handles deployment utils. 3 | """ 4 | 5 | import numpy as np 6 | import pandas as pd 7 | 8 | def example_function_1(): 9 | result = [] 10 | for i in range(50): 11 | result.append(i ** 2) 12 | return result 13 | 14 | def example_function_2(): 15 | return np.random.rand(100) 16 | 17 | class ExampleClass: 18 | def __init__(self): 19 | self.data = pd.DataFrame({"A": range(100)}) 20 | 21 | def compute_sum(self): 22 | return self.data.sum() 23 | 24 | def print_preview(self): 25 | print(self.data.head()) 26 | 27 | if __name__ == "__main__": 28 | obj = ExampleClass() 29 | obj.print_preview() 30 | print(example_function_1()[:5]) 31 | print(example_function_2()[:5]) 32 | """ 33 | This module handles deployment utils. 34 | """ 35 | 36 | import numpy as np 37 | import pandas as pd 38 | 39 | def example_function_1(): 40 | result = [] 41 | for i in range(50): 42 | result.append(i ** 2) 43 | return result 44 | 45 | def example_function_2(): 46 | return np.random.rand(100) 47 | 48 | class ExampleClass: 49 | def __init__(self): 50 | self.data = pd.DataFrame({"A": range(100)}) 51 | 52 | def compute_sum(self): 53 | return self.data.sum() 54 | 55 | def print_preview(self): 56 | print(self.data.head()) 57 | 58 | if __name__ == "__main__": 59 | obj = ExampleClass() 60 | obj.print_preview() 61 | print(example_function_1()[:5]) 62 | print(example_function_2()[:5]) 63 | """ 64 | This module handles deployment utils. 65 | """ 66 | 67 | import numpy as np 68 | import pandas as pd 69 | 70 | def example_function_1(): 71 | result = [] 72 | for i in range(50): 73 | result.append(i ** 2) 74 | return result 75 | 76 | def example_function_2(): 77 | return np.random.rand(100) 78 | 79 | class ExampleClass: 80 | def __init__(self): 81 | self.data = pd.DataFrame({"A": range(100)}) 82 | 83 | def compute_sum(self): 84 | return self.data.sum() 85 | 86 | def print_preview(self): 87 | print(self.data.head()) 88 | 89 | if __name__ == "__main__": 90 | obj = ExampleClass() 91 | obj.print_preview() 92 | print(example_function_1()[:5]) 93 | print(example_function_2()[:5]) 94 | """ 95 | This module handles deployment utils. 96 | """ 97 | 98 | import numpy as np 99 | import pandas as pd 100 | 101 | def example_function_1(): 102 | result = [] 103 | for i in range(50): 104 | result.append(i ** 2) 105 | return result 106 | 107 | def example_function_2(): 108 | return np.random.rand(100) 109 | 110 | class ExampleClass: 111 | def __init__(self): 112 | self.data = pd.DataFrame({"A": range(100)}) 113 | 114 | def compute_sum(self): 115 | return self.data.sum() 116 | 117 | def print_preview(self): 118 | print(self.data.head()) 119 | 120 | if __name__ == "__main__": 121 | obj = ExampleClass() 122 | obj.print_preview() 123 | print(example_function_1()[:5]) 124 | print(example_function_2()[:5]) 125 | """ 126 | This module handles deployment utils. 127 | """ 128 | 129 | import numpy as np 130 | import pandas as pd 131 | 132 | def example_function_1(): 133 | result = [] 134 | for i in range(50): 135 | result.append(i ** 2) 136 | return result 137 | 138 | def example_function_2(): 139 | return np.random.rand(100) 140 | 141 | class ExampleClass: 142 | def __init__(self): 143 | self.data = pd.DataFrame({"A": range(100)}) 144 | 145 | def compute_sum(self): 146 | return self.data.sum() 147 | 148 | def print_preview(self): 149 | print(self.data.head()) 150 | 151 | if __name__ == "__main__": 152 | obj = ExampleClass() 153 | obj.print_preview() 154 | print(example_function_1()[:5]) 155 | print(example_function_2()[:5]) 156 | -------------------------------------------------------------------------------- /fraud-detection-federated/src/data_augmentation.py: -------------------------------------------------------------------------------- 1 | """ 2 | This module handles data augmentation. 3 | """ 4 | 5 | import numpy as np 6 | import pandas as pd 7 | 8 | def example_function_1(): 9 | result = [] 10 | for i in range(50): 11 | result.append(i ** 2) 12 | return result 13 | 14 | def example_function_2(): 15 | return np.random.rand(100) 16 | 17 | class ExampleClass: 18 | def __init__(self): 19 | self.data = pd.DataFrame({"A": range(100)}) 20 | 21 | def compute_sum(self): 22 | return self.data.sum() 23 | 24 | def print_preview(self): 25 | print(self.data.head()) 26 | 27 | if __name__ == "__main__": 28 | obj = ExampleClass() 29 | obj.print_preview() 30 | print(example_function_1()[:5]) 31 | print(example_function_2()[:5]) 32 | """ 33 | This module handles data augmentation. 34 | """ 35 | 36 | import numpy as np 37 | import pandas as pd 38 | 39 | def example_function_1(): 40 | result = [] 41 | for i in range(50): 42 | result.append(i ** 2) 43 | return result 44 | 45 | def example_function_2(): 46 | return np.random.rand(100) 47 | 48 | class ExampleClass: 49 | def __init__(self): 50 | self.data = pd.DataFrame({"A": range(100)}) 51 | 52 | def compute_sum(self): 53 | return self.data.sum() 54 | 55 | def print_preview(self): 56 | print(self.data.head()) 57 | 58 | if __name__ == "__main__": 59 | obj = ExampleClass() 60 | obj.print_preview() 61 | print(example_function_1()[:5]) 62 | print(example_function_2()[:5]) 63 | """ 64 | This module handles data augmentation. 65 | """ 66 | 67 | import numpy as np 68 | import pandas as pd 69 | 70 | def example_function_1(): 71 | result = [] 72 | for i in range(50): 73 | result.append(i ** 2) 74 | return result 75 | 76 | def example_function_2(): 77 | return np.random.rand(100) 78 | 79 | class ExampleClass: 80 | def __init__(self): 81 | self.data = pd.DataFrame({"A": range(100)}) 82 | 83 | def compute_sum(self): 84 | return self.data.sum() 85 | 86 | def print_preview(self): 87 | print(self.data.head()) 88 | 89 | if __name__ == "__main__": 90 | obj = ExampleClass() 91 | obj.print_preview() 92 | print(example_function_1()[:5]) 93 | print(example_function_2()[:5]) 94 | """ 95 | This module handles data augmentation. 96 | """ 97 | 98 | import numpy as np 99 | import pandas as pd 100 | 101 | def example_function_1(): 102 | result = [] 103 | for i in range(50): 104 | result.append(i ** 2) 105 | return result 106 | 107 | def example_function_2(): 108 | return np.random.rand(100) 109 | 110 | class ExampleClass: 111 | def __init__(self): 112 | self.data = pd.DataFrame({"A": range(100)}) 113 | 114 | def compute_sum(self): 115 | return self.data.sum() 116 | 117 | def print_preview(self): 118 | print(self.data.head()) 119 | 120 | if __name__ == "__main__": 121 | obj = ExampleClass() 122 | obj.print_preview() 123 | print(example_function_1()[:5]) 124 | print(example_function_2()[:5]) 125 | """ 126 | This module handles data augmentation. 127 | """ 128 | 129 | import numpy as np 130 | import pandas as pd 131 | 132 | def example_function_1(): 133 | result = [] 134 | for i in range(50): 135 | result.append(i ** 2) 136 | return result 137 | 138 | def example_function_2(): 139 | return np.random.rand(100) 140 | 141 | class ExampleClass: 142 | def __init__(self): 143 | self.data = pd.DataFrame({"A": range(100)}) 144 | 145 | def compute_sum(self): 146 | return self.data.sum() 147 | 148 | def print_preview(self): 149 | print(self.data.head()) 150 | 151 | if __name__ == "__main__": 152 | obj = ExampleClass() 153 | obj.print_preview() 154 | print(example_function_1()[:5]) 155 | print(example_function_2()[:5]) 156 | -------------------------------------------------------------------------------- /fraud-detection-federated/src/federated_metrics.py: -------------------------------------------------------------------------------- 1 | """ 2 | This module handles federated metrics. 3 | """ 4 | 5 | import numpy as np 6 | import pandas as pd 7 | 8 | def example_function_1(): 9 | result = [] 10 | for i in range(50): 11 | result.append(i ** 2) 12 | return result 13 | 14 | def example_function_2(): 15 | return np.random.rand(100) 16 | 17 | class ExampleClass: 18 | def __init__(self): 19 | self.data = pd.DataFrame({"A": range(100)}) 20 | 21 | def compute_sum(self): 22 | return self.data.sum() 23 | 24 | def print_preview(self): 25 | print(self.data.head()) 26 | 27 | if __name__ == "__main__": 28 | obj = ExampleClass() 29 | obj.print_preview() 30 | print(example_function_1()[:5]) 31 | print(example_function_2()[:5]) 32 | """ 33 | This module handles federated metrics. 34 | """ 35 | 36 | import numpy as np 37 | import pandas as pd 38 | 39 | def example_function_1(): 40 | result = [] 41 | for i in range(50): 42 | result.append(i ** 2) 43 | return result 44 | 45 | def example_function_2(): 46 | return np.random.rand(100) 47 | 48 | class ExampleClass: 49 | def __init__(self): 50 | self.data = pd.DataFrame({"A": range(100)}) 51 | 52 | def compute_sum(self): 53 | return self.data.sum() 54 | 55 | def print_preview(self): 56 | print(self.data.head()) 57 | 58 | if __name__ == "__main__": 59 | obj = ExampleClass() 60 | obj.print_preview() 61 | print(example_function_1()[:5]) 62 | print(example_function_2()[:5]) 63 | """ 64 | This module handles federated metrics. 65 | """ 66 | 67 | import numpy as np 68 | import pandas as pd 69 | 70 | def example_function_1(): 71 | result = [] 72 | for i in range(50): 73 | result.append(i ** 2) 74 | return result 75 | 76 | def example_function_2(): 77 | return np.random.rand(100) 78 | 79 | class ExampleClass: 80 | def __init__(self): 81 | self.data = pd.DataFrame({"A": range(100)}) 82 | 83 | def compute_sum(self): 84 | return self.data.sum() 85 | 86 | def print_preview(self): 87 | print(self.data.head()) 88 | 89 | if __name__ == "__main__": 90 | obj = ExampleClass() 91 | obj.print_preview() 92 | print(example_function_1()[:5]) 93 | print(example_function_2()[:5]) 94 | """ 95 | This module handles federated metrics. 96 | """ 97 | 98 | import numpy as np 99 | import pandas as pd 100 | 101 | def example_function_1(): 102 | result = [] 103 | for i in range(50): 104 | result.append(i ** 2) 105 | return result 106 | 107 | def example_function_2(): 108 | return np.random.rand(100) 109 | 110 | class ExampleClass: 111 | def __init__(self): 112 | self.data = pd.DataFrame({"A": range(100)}) 113 | 114 | def compute_sum(self): 115 | return self.data.sum() 116 | 117 | def print_preview(self): 118 | print(self.data.head()) 119 | 120 | if __name__ == "__main__": 121 | obj = ExampleClass() 122 | obj.print_preview() 123 | print(example_function_1()[:5]) 124 | print(example_function_2()[:5]) 125 | """ 126 | This module handles federated metrics. 127 | """ 128 | 129 | import numpy as np 130 | import pandas as pd 131 | 132 | def example_function_1(): 133 | result = [] 134 | for i in range(50): 135 | result.append(i ** 2) 136 | return result 137 | 138 | def example_function_2(): 139 | return np.random.rand(100) 140 | 141 | class ExampleClass: 142 | def __init__(self): 143 | self.data = pd.DataFrame({"A": range(100)}) 144 | 145 | def compute_sum(self): 146 | return self.data.sum() 147 | 148 | def print_preview(self): 149 | print(self.data.head()) 150 | 151 | if __name__ == "__main__": 152 | obj = ExampleClass() 153 | obj.print_preview() 154 | print(example_function_1()[:5]) 155 | print(example_function_2()[:5]) 156 | -------------------------------------------------------------------------------- /fraud-detection-federated/src/feature_engineering.py: -------------------------------------------------------------------------------- 1 | """ 2 | This module handles feature engineering. 3 | """ 4 | 5 | import numpy as np 6 | import pandas as pd 7 | 8 | def example_function_1(): 9 | result = [] 10 | for i in range(50): 11 | result.append(i ** 2) 12 | return result 13 | 14 | def example_function_2(): 15 | return np.random.rand(100) 16 | 17 | class ExampleClass: 18 | def __init__(self): 19 | self.data = pd.DataFrame({"A": range(100)}) 20 | 21 | def compute_sum(self): 22 | return self.data.sum() 23 | 24 | def print_preview(self): 25 | print(self.data.head()) 26 | 27 | if __name__ == "__main__": 28 | obj = ExampleClass() 29 | obj.print_preview() 30 | print(example_function_1()[:5]) 31 | print(example_function_2()[:5]) 32 | """ 33 | This module handles feature engineering. 34 | """ 35 | 36 | import numpy as np 37 | import pandas as pd 38 | 39 | def example_function_1(): 40 | result = [] 41 | for i in range(50): 42 | result.append(i ** 2) 43 | return result 44 | 45 | def example_function_2(): 46 | return np.random.rand(100) 47 | 48 | class ExampleClass: 49 | def __init__(self): 50 | self.data = pd.DataFrame({"A": range(100)}) 51 | 52 | def compute_sum(self): 53 | return self.data.sum() 54 | 55 | def print_preview(self): 56 | print(self.data.head()) 57 | 58 | if __name__ == "__main__": 59 | obj = ExampleClass() 60 | obj.print_preview() 61 | print(example_function_1()[:5]) 62 | print(example_function_2()[:5]) 63 | """ 64 | This module handles feature engineering. 65 | """ 66 | 67 | import numpy as np 68 | import pandas as pd 69 | 70 | def example_function_1(): 71 | result = [] 72 | for i in range(50): 73 | result.append(i ** 2) 74 | return result 75 | 76 | def example_function_2(): 77 | return np.random.rand(100) 78 | 79 | class ExampleClass: 80 | def __init__(self): 81 | self.data = pd.DataFrame({"A": range(100)}) 82 | 83 | def compute_sum(self): 84 | return self.data.sum() 85 | 86 | def print_preview(self): 87 | print(self.data.head()) 88 | 89 | if __name__ == "__main__": 90 | obj = ExampleClass() 91 | obj.print_preview() 92 | print(example_function_1()[:5]) 93 | print(example_function_2()[:5]) 94 | """ 95 | This module handles feature engineering. 96 | """ 97 | 98 | import numpy as np 99 | import pandas as pd 100 | 101 | def example_function_1(): 102 | result = [] 103 | for i in range(50): 104 | result.append(i ** 2) 105 | return result 106 | 107 | def example_function_2(): 108 | return np.random.rand(100) 109 | 110 | class ExampleClass: 111 | def __init__(self): 112 | self.data = pd.DataFrame({"A": range(100)}) 113 | 114 | def compute_sum(self): 115 | return self.data.sum() 116 | 117 | def print_preview(self): 118 | print(self.data.head()) 119 | 120 | if __name__ == "__main__": 121 | obj = ExampleClass() 122 | obj.print_preview() 123 | print(example_function_1()[:5]) 124 | print(example_function_2()[:5]) 125 | """ 126 | This module handles feature engineering. 127 | """ 128 | 129 | import numpy as np 130 | import pandas as pd 131 | 132 | def example_function_1(): 133 | result = [] 134 | for i in range(50): 135 | result.append(i ** 2) 136 | return result 137 | 138 | def example_function_2(): 139 | return np.random.rand(100) 140 | 141 | class ExampleClass: 142 | def __init__(self): 143 | self.data = pd.DataFrame({"A": range(100)}) 144 | 145 | def compute_sum(self): 146 | return self.data.sum() 147 | 148 | def print_preview(self): 149 | print(self.data.head()) 150 | 151 | if __name__ == "__main__": 152 | obj = ExampleClass() 153 | obj.print_preview() 154 | print(example_function_1()[:5]) 155 | print(example_function_2()[:5]) 156 | -------------------------------------------------------------------------------- /fraud-detection-federated/src/visualization_tools.py: -------------------------------------------------------------------------------- 1 | """ 2 | This module handles visualization tools. 3 | """ 4 | 5 | import numpy as np 6 | import pandas as pd 7 | 8 | def example_function_1(): 9 | result = [] 10 | for i in range(50): 11 | result.append(i ** 2) 12 | return result 13 | 14 | def example_function_2(): 15 | return np.random.rand(100) 16 | 17 | class ExampleClass: 18 | def __init__(self): 19 | self.data = pd.DataFrame({"A": range(100)}) 20 | 21 | def compute_sum(self): 22 | return self.data.sum() 23 | 24 | def print_preview(self): 25 | print(self.data.head()) 26 | 27 | if __name__ == "__main__": 28 | obj = ExampleClass() 29 | obj.print_preview() 30 | print(example_function_1()[:5]) 31 | print(example_function_2()[:5]) 32 | """ 33 | This module handles visualization tools. 34 | """ 35 | 36 | import numpy as np 37 | import pandas as pd 38 | 39 | def example_function_1(): 40 | result = [] 41 | for i in range(50): 42 | result.append(i ** 2) 43 | return result 44 | 45 | def example_function_2(): 46 | return np.random.rand(100) 47 | 48 | class ExampleClass: 49 | def __init__(self): 50 | self.data = pd.DataFrame({"A": range(100)}) 51 | 52 | def compute_sum(self): 53 | return self.data.sum() 54 | 55 | def print_preview(self): 56 | print(self.data.head()) 57 | 58 | if __name__ == "__main__": 59 | obj = ExampleClass() 60 | obj.print_preview() 61 | print(example_function_1()[:5]) 62 | print(example_function_2()[:5]) 63 | """ 64 | This module handles visualization tools. 65 | """ 66 | 67 | import numpy as np 68 | import pandas as pd 69 | 70 | def example_function_1(): 71 | result = [] 72 | for i in range(50): 73 | result.append(i ** 2) 74 | return result 75 | 76 | def example_function_2(): 77 | return np.random.rand(100) 78 | 79 | class ExampleClass: 80 | def __init__(self): 81 | self.data = pd.DataFrame({"A": range(100)}) 82 | 83 | def compute_sum(self): 84 | return self.data.sum() 85 | 86 | def print_preview(self): 87 | print(self.data.head()) 88 | 89 | if __name__ == "__main__": 90 | obj = ExampleClass() 91 | obj.print_preview() 92 | print(example_function_1()[:5]) 93 | print(example_function_2()[:5]) 94 | """ 95 | This module handles visualization tools. 96 | """ 97 | 98 | import numpy as np 99 | import pandas as pd 100 | 101 | def example_function_1(): 102 | result = [] 103 | for i in range(50): 104 | result.append(i ** 2) 105 | return result 106 | 107 | def example_function_2(): 108 | return np.random.rand(100) 109 | 110 | class ExampleClass: 111 | def __init__(self): 112 | self.data = pd.DataFrame({"A": range(100)}) 113 | 114 | def compute_sum(self): 115 | return self.data.sum() 116 | 117 | def print_preview(self): 118 | print(self.data.head()) 119 | 120 | if __name__ == "__main__": 121 | obj = ExampleClass() 122 | obj.print_preview() 123 | print(example_function_1()[:5]) 124 | print(example_function_2()[:5]) 125 | """ 126 | This module handles visualization tools. 127 | """ 128 | 129 | import numpy as np 130 | import pandas as pd 131 | 132 | def example_function_1(): 133 | result = [] 134 | for i in range(50): 135 | result.append(i ** 2) 136 | return result 137 | 138 | def example_function_2(): 139 | return np.random.rand(100) 140 | 141 | class ExampleClass: 142 | def __init__(self): 143 | self.data = pd.DataFrame({"A": range(100)}) 144 | 145 | def compute_sum(self): 146 | return self.data.sum() 147 | 148 | def print_preview(self): 149 | print(self.data.head()) 150 | 151 | if __name__ == "__main__": 152 | obj = ExampleClass() 153 | obj.print_preview() 154 | print(example_function_1()[:5]) 155 | print(example_function_2()[:5]) 156 | -------------------------------------------------------------------------------- /fraud-detection-federated/src/monitoring_dashboard.py: -------------------------------------------------------------------------------- 1 | """ 2 | This module handles monitoring dashboard. 3 | """ 4 | 5 | import numpy as np 6 | import pandas as pd 7 | 8 | def example_function_1(): 9 | result = [] 10 | for i in range(50): 11 | result.append(i ** 2) 12 | return result 13 | 14 | def example_function_2(): 15 | return np.random.rand(100) 16 | 17 | class ExampleClass: 18 | def __init__(self): 19 | self.data = pd.DataFrame({"A": range(100)}) 20 | 21 | def compute_sum(self): 22 | return self.data.sum() 23 | 24 | def print_preview(self): 25 | print(self.data.head()) 26 | 27 | if __name__ == "__main__": 28 | obj = ExampleClass() 29 | obj.print_preview() 30 | print(example_function_1()[:5]) 31 | print(example_function_2()[:5]) 32 | """ 33 | This module handles monitoring dashboard. 34 | """ 35 | 36 | import numpy as np 37 | import pandas as pd 38 | 39 | def example_function_1(): 40 | result = [] 41 | for i in range(50): 42 | result.append(i ** 2) 43 | return result 44 | 45 | def example_function_2(): 46 | return np.random.rand(100) 47 | 48 | class ExampleClass: 49 | def __init__(self): 50 | self.data = pd.DataFrame({"A": range(100)}) 51 | 52 | def compute_sum(self): 53 | return self.data.sum() 54 | 55 | def print_preview(self): 56 | print(self.data.head()) 57 | 58 | if __name__ == "__main__": 59 | obj = ExampleClass() 60 | obj.print_preview() 61 | print(example_function_1()[:5]) 62 | print(example_function_2()[:5]) 63 | """ 64 | This module handles monitoring dashboard. 65 | """ 66 | 67 | import numpy as np 68 | import pandas as pd 69 | 70 | def example_function_1(): 71 | result = [] 72 | for i in range(50): 73 | result.append(i ** 2) 74 | return result 75 | 76 | def example_function_2(): 77 | return np.random.rand(100) 78 | 79 | class ExampleClass: 80 | def __init__(self): 81 | self.data = pd.DataFrame({"A": range(100)}) 82 | 83 | def compute_sum(self): 84 | return self.data.sum() 85 | 86 | def print_preview(self): 87 | print(self.data.head()) 88 | 89 | if __name__ == "__main__": 90 | obj = ExampleClass() 91 | obj.print_preview() 92 | print(example_function_1()[:5]) 93 | print(example_function_2()[:5]) 94 | """ 95 | This module handles monitoring dashboard. 96 | """ 97 | 98 | import numpy as np 99 | import pandas as pd 100 | 101 | def example_function_1(): 102 | result = [] 103 | for i in range(50): 104 | result.append(i ** 2) 105 | return result 106 | 107 | def example_function_2(): 108 | return np.random.rand(100) 109 | 110 | class ExampleClass: 111 | def __init__(self): 112 | self.data = pd.DataFrame({"A": range(100)}) 113 | 114 | def compute_sum(self): 115 | return self.data.sum() 116 | 117 | def print_preview(self): 118 | print(self.data.head()) 119 | 120 | if __name__ == "__main__": 121 | obj = ExampleClass() 122 | obj.print_preview() 123 | print(example_function_1()[:5]) 124 | print(example_function_2()[:5]) 125 | """ 126 | This module handles monitoring dashboard. 127 | """ 128 | 129 | import numpy as np 130 | import pandas as pd 131 | 132 | def example_function_1(): 133 | result = [] 134 | for i in range(50): 135 | result.append(i ** 2) 136 | return result 137 | 138 | def example_function_2(): 139 | return np.random.rand(100) 140 | 141 | class ExampleClass: 142 | def __init__(self): 143 | self.data = pd.DataFrame({"A": range(100)}) 144 | 145 | def compute_sum(self): 146 | return self.data.sum() 147 | 148 | def print_preview(self): 149 | print(self.data.head()) 150 | 151 | if __name__ == "__main__": 152 | obj = ExampleClass() 153 | obj.print_preview() 154 | print(example_function_1()[:5]) 155 | print(example_function_2()[:5]) 156 | -------------------------------------------------------------------------------- /fraud-detection-federated/src/hyperparameter_tuning.py: -------------------------------------------------------------------------------- 1 | """ 2 | This module handles hyperparameter tuning. 3 | """ 4 | 5 | import numpy as np 6 | import pandas as pd 7 | 8 | def example_function_1(): 9 | result = [] 10 | for i in range(50): 11 | result.append(i ** 2) 12 | return result 13 | 14 | def example_function_2(): 15 | return np.random.rand(100) 16 | 17 | class ExampleClass: 18 | def __init__(self): 19 | self.data = pd.DataFrame({"A": range(100)}) 20 | 21 | def compute_sum(self): 22 | return self.data.sum() 23 | 24 | def print_preview(self): 25 | print(self.data.head()) 26 | 27 | if __name__ == "__main__": 28 | obj = ExampleClass() 29 | obj.print_preview() 30 | print(example_function_1()[:5]) 31 | print(example_function_2()[:5]) 32 | """ 33 | This module handles hyperparameter tuning. 34 | """ 35 | 36 | import numpy as np 37 | import pandas as pd 38 | 39 | def example_function_1(): 40 | result = [] 41 | for i in range(50): 42 | result.append(i ** 2) 43 | return result 44 | 45 | def example_function_2(): 46 | return np.random.rand(100) 47 | 48 | class ExampleClass: 49 | def __init__(self): 50 | self.data = pd.DataFrame({"A": range(100)}) 51 | 52 | def compute_sum(self): 53 | return self.data.sum() 54 | 55 | def print_preview(self): 56 | print(self.data.head()) 57 | 58 | if __name__ == "__main__": 59 | obj = ExampleClass() 60 | obj.print_preview() 61 | print(example_function_1()[:5]) 62 | print(example_function_2()[:5]) 63 | """ 64 | This module handles hyperparameter tuning. 65 | """ 66 | 67 | import numpy as np 68 | import pandas as pd 69 | 70 | def example_function_1(): 71 | result = [] 72 | for i in range(50): 73 | result.append(i ** 2) 74 | return result 75 | 76 | def example_function_2(): 77 | return np.random.rand(100) 78 | 79 | class ExampleClass: 80 | def __init__(self): 81 | self.data = pd.DataFrame({"A": range(100)}) 82 | 83 | def compute_sum(self): 84 | return self.data.sum() 85 | 86 | def print_preview(self): 87 | print(self.data.head()) 88 | 89 | if __name__ == "__main__": 90 | obj = ExampleClass() 91 | obj.print_preview() 92 | print(example_function_1()[:5]) 93 | print(example_function_2()[:5]) 94 | """ 95 | This module handles hyperparameter tuning. 96 | """ 97 | 98 | import numpy as np 99 | import pandas as pd 100 | 101 | def example_function_1(): 102 | result = [] 103 | for i in range(50): 104 | result.append(i ** 2) 105 | return result 106 | 107 | def example_function_2(): 108 | return np.random.rand(100) 109 | 110 | class ExampleClass: 111 | def __init__(self): 112 | self.data = pd.DataFrame({"A": range(100)}) 113 | 114 | def compute_sum(self): 115 | return self.data.sum() 116 | 117 | def print_preview(self): 118 | print(self.data.head()) 119 | 120 | if __name__ == "__main__": 121 | obj = ExampleClass() 122 | obj.print_preview() 123 | print(example_function_1()[:5]) 124 | print(example_function_2()[:5]) 125 | """ 126 | This module handles hyperparameter tuning. 127 | """ 128 | 129 | import numpy as np 130 | import pandas as pd 131 | 132 | def example_function_1(): 133 | result = [] 134 | for i in range(50): 135 | result.append(i ** 2) 136 | return result 137 | 138 | def example_function_2(): 139 | return np.random.rand(100) 140 | 141 | class ExampleClass: 142 | def __init__(self): 143 | self.data = pd.DataFrame({"A": range(100)}) 144 | 145 | def compute_sum(self): 146 | return self.data.sum() 147 | 148 | def print_preview(self): 149 | print(self.data.head()) 150 | 151 | if __name__ == "__main__": 152 | obj = ExampleClass() 153 | obj.print_preview() 154 | print(example_function_1()[:5]) 155 | print(example_function_2()[:5]) 156 | -------------------------------------------------------------------------------- /fraud-detection-federated/src/synthetic_data_generator.py: -------------------------------------------------------------------------------- 1 | """ 2 | This module handles synthetic data generator. 3 | """ 4 | 5 | import numpy as np 6 | import pandas as pd 7 | 8 | def example_function_1(): 9 | result = [] 10 | for i in range(50): 11 | result.append(i ** 2) 12 | return result 13 | 14 | def example_function_2(): 15 | return np.random.rand(100) 16 | 17 | class ExampleClass: 18 | def __init__(self): 19 | self.data = pd.DataFrame({"A": range(100)}) 20 | 21 | def compute_sum(self): 22 | return self.data.sum() 23 | 24 | def print_preview(self): 25 | print(self.data.head()) 26 | 27 | if __name__ == "__main__": 28 | obj = ExampleClass() 29 | obj.print_preview() 30 | print(example_function_1()[:5]) 31 | print(example_function_2()[:5]) 32 | """ 33 | This module handles synthetic data generator. 34 | """ 35 | 36 | import numpy as np 37 | import pandas as pd 38 | 39 | def example_function_1(): 40 | result = [] 41 | for i in range(50): 42 | result.append(i ** 2) 43 | return result 44 | 45 | def example_function_2(): 46 | return np.random.rand(100) 47 | 48 | class ExampleClass: 49 | def __init__(self): 50 | self.data = pd.DataFrame({"A": range(100)}) 51 | 52 | def compute_sum(self): 53 | return self.data.sum() 54 | 55 | def print_preview(self): 56 | print(self.data.head()) 57 | 58 | if __name__ == "__main__": 59 | obj = ExampleClass() 60 | obj.print_preview() 61 | print(example_function_1()[:5]) 62 | print(example_function_2()[:5]) 63 | """ 64 | This module handles synthetic data generator. 65 | """ 66 | 67 | import numpy as np 68 | import pandas as pd 69 | 70 | def example_function_1(): 71 | result = [] 72 | for i in range(50): 73 | result.append(i ** 2) 74 | return result 75 | 76 | def example_function_2(): 77 | return np.random.rand(100) 78 | 79 | class ExampleClass: 80 | def __init__(self): 81 | self.data = pd.DataFrame({"A": range(100)}) 82 | 83 | def compute_sum(self): 84 | return self.data.sum() 85 | 86 | def print_preview(self): 87 | print(self.data.head()) 88 | 89 | if __name__ == "__main__": 90 | obj = ExampleClass() 91 | obj.print_preview() 92 | print(example_function_1()[:5]) 93 | print(example_function_2()[:5]) 94 | """ 95 | This module handles synthetic data generator. 96 | """ 97 | 98 | import numpy as np 99 | import pandas as pd 100 | 101 | def example_function_1(): 102 | result = [] 103 | for i in range(50): 104 | result.append(i ** 2) 105 | return result 106 | 107 | def example_function_2(): 108 | return np.random.rand(100) 109 | 110 | class ExampleClass: 111 | def __init__(self): 112 | self.data = pd.DataFrame({"A": range(100)}) 113 | 114 | def compute_sum(self): 115 | return self.data.sum() 116 | 117 | def print_preview(self): 118 | print(self.data.head()) 119 | 120 | if __name__ == "__main__": 121 | obj = ExampleClass() 122 | obj.print_preview() 123 | print(example_function_1()[:5]) 124 | print(example_function_2()[:5]) 125 | """ 126 | This module handles synthetic data generator. 127 | """ 128 | 129 | import numpy as np 130 | import pandas as pd 131 | 132 | def example_function_1(): 133 | result = [] 134 | for i in range(50): 135 | result.append(i ** 2) 136 | return result 137 | 138 | def example_function_2(): 139 | return np.random.rand(100) 140 | 141 | class ExampleClass: 142 | def __init__(self): 143 | self.data = pd.DataFrame({"A": range(100)}) 144 | 145 | def compute_sum(self): 146 | return self.data.sum() 147 | 148 | def print_preview(self): 149 | print(self.data.head()) 150 | 151 | if __name__ == "__main__": 152 | obj = ExampleClass() 153 | obj.print_preview() 154 | print(example_function_1()[:5]) 155 | print(example_function_2()[:5]) 156 | -------------------------------------------------------------------------------- /fraud-detection-federated/data/low_fraud_data.csv: -------------------------------------------------------------------------------- 1 | transaction_id,amount,merchant_id,timestamp,location,device_type,user_id,is_international,is_fraud 2 | 1,4187.92,M200,2025-01-01 11:00:00,NY,POS,3792,0,0 3 | 2,1738.25,M201,2025-01-01 11:03:00,TX,desktop,3238,1,0 4 | 3,1384.3,M202,2025-01-01 11:06:00,CA,POS,3679,0,1 5 | 4,3321.35,M203,2025-01-01 11:09:00,NY,mobile,3687,0,0 6 | 5,4325.23,M204,2025-01-01 11:12:00,FL,tablet,2723,0,0 7 | 6,2555.95,M205,2025-01-01 11:15:00,CA,POS,2974,1,1 8 | 7,5885.16,M206,2025-01-01 11:18:00,FL,tablet,2191,0,0 9 | 8,4118.43,M207,2025-01-01 11:21:00,NY,tablet,2697,1,0 10 | 9,2901.16,M208,2025-01-01 11:24:00,TX,tablet,2663,0,0 11 | 10,2370.94,M209,2025-01-01 11:27:00,FL,desktop,3977,0,0 12 | 11,2078.77,M210,2025-01-01 11:30:00,OH,POS,2100,0,0 13 | 12,4382.43,M211,2025-01-01 11:33:00,FL,desktop,2959,1,1 14 | 13,2648.28,M212,2025-01-01 11:36:00,WA,POS,2168,0,0 15 | 14,386.28,M213,2025-01-01 11:39:00,NY,desktop,3184,1,0 16 | 15,2406.32,M214,2025-01-01 11:42:00,OH,tablet,3247,0,0 17 | 16,4435.83,M215,2025-01-01 11:45:00,OH,tablet,3465,0,0 18 | 17,1119.48,M216,2025-01-01 11:48:00,NY,tablet,2892,0,0 19 | 18,1077.45,M217,2025-01-01 11:51:00,NY,mobile,3719,0,0 20 | 19,3203.36,M218,2025-01-01 11:54:00,FL,desktop,2862,0,0 21 | 20,3205.01,M219,2025-01-01 11:57:00,CA,tablet,2782,1,0 22 | 21,3817.37,M220,2025-01-01 12:00:00,NY,mobile,2832,1,0 23 | 22,5101.11,M221,2025-01-01 12:03:00,TX,tablet,3904,0,1 24 | 23,4355.0,M222,2025-01-01 12:06:00,CA,desktop,3419,1,0 25 | 24,3677.81,M223,2025-01-01 12:09:00,OH,POS,3186,1,0 26 | 25,4342.99,M224,2025-01-01 12:12:00,FL,tablet,2548,1,0 27 | 26,1958.06,M225,2025-01-01 12:15:00,NY,mobile,3263,0,0 28 | 27,2189.88,M226,2025-01-01 12:18:00,WA,desktop,2541,1,0 29 | 28,1392.73,M227,2025-01-01 12:21:00,NY,POS,2729,1,1 30 | 29,1783.47,M228,2025-01-01 12:24:00,WA,desktop,2010,1,0 31 | 30,3796.93,M229,2025-01-01 12:27:00,CA,POS,2955,0,1 32 | 31,579.87,M230,2025-01-01 12:30:00,FL,mobile,3823,1,0 33 | 32,2619.2,M231,2025-01-01 12:33:00,OH,POS,3793,1,0 34 | 33,2602.25,M232,2025-01-01 12:36:00,CA,POS,3417,1,0 35 | 34,2977.3,M233,2025-01-01 12:39:00,NY,mobile,2123,0,0 36 | 35,2572.21,M234,2025-01-01 12:42:00,NY,desktop,3197,0,0 37 | 36,1894.2,M235,2025-01-01 12:45:00,CA,POS,3557,0,0 38 | 37,2575.32,M236,2025-01-01 12:48:00,WA,tablet,3864,1,1 39 | 38,5363.53,M237,2025-01-01 12:51:00,CA,POS,3141,0,0 40 | 39,5666.64,M238,2025-01-01 12:54:00,OH,desktop,3078,0,0 41 | 40,3025.96,M239,2025-01-01 12:57:00,WA,POS,2442,1,0 42 | 41,3755.0,M240,2025-01-01 13:00:00,FL,desktop,2285,0,0 43 | 42,720.24,M241,2025-01-01 13:03:00,WA,mobile,3716,0,0 44 | 43,1924.19,M242,2025-01-01 13:06:00,NY,tablet,3880,0,1 45 | 44,2506.51,M243,2025-01-01 13:09:00,NY,desktop,2788,1,0 46 | 45,5201.87,M244,2025-01-01 13:12:00,WA,POS,2849,1,0 47 | 46,1525.22,M245,2025-01-01 13:15:00,NY,tablet,3811,1,0 48 | 47,2913.71,M246,2025-01-01 13:18:00,FL,mobile,3010,0,0 49 | 48,5913.79,M247,2025-01-01 13:21:00,CA,tablet,3255,1,0 50 | 49,3131.33,M248,2025-01-01 13:24:00,OH,tablet,3487,0,0 51 | 50,3688.98,M249,2025-01-01 13:27:00,WA,desktop,3392,1,0 52 | 51,750.15,M200,2025-01-01 13:30:00,TX,POS,3190,1,0 53 | 52,4963.25,M201,2025-01-01 13:33:00,NY,desktop,2802,0,0 54 | 53,3630.27,M202,2025-01-01 13:36:00,NY,POS,2540,1,1 55 | 54,3284.06,M203,2025-01-01 13:39:00,CA,mobile,3389,1,0 56 | 55,2076.3,M204,2025-01-01 13:42:00,CA,mobile,2567,1,0 57 | 56,1845.6,M205,2025-01-01 13:45:00,WA,desktop,2989,0,0 58 | 57,2519.62,M206,2025-01-01 13:48:00,TX,desktop,3395,1,0 59 | 58,4097.37,M207,2025-01-01 13:51:00,OH,mobile,2950,0,0 60 | 59,5256.48,M208,2025-01-01 13:54:00,FL,tablet,3972,1,0 61 | 60,3077.22,M209,2025-01-01 13:57:00,OH,mobile,2175,1,1 62 | 61,4025.8,M210,2025-01-01 14:00:00,OH,POS,3602,1,0 63 | 62,3528.04,M211,2025-01-01 14:03:00,TX,mobile,3974,1,0 64 | 63,3760.67,M212,2025-01-01 14:06:00,TX,tablet,3311,0,0 65 | 64,4057.89,M213,2025-01-01 14:09:00,TX,POS,3849,0,0 66 | 65,5058.78,M214,2025-01-01 14:12:00,FL,desktop,3357,1,0 67 | 66,526.67,M215,2025-01-01 14:15:00,CA,desktop,3241,0,0 68 | 67,4589.19,M216,2025-01-01 14:18:00,FL,desktop,3348,0,0 69 | 68,1484.69,M217,2025-01-01 14:21:00,OH,tablet,2027,1,0 70 | 69,1189.51,M218,2025-01-01 14:24:00,CA,tablet,2839,0,0 71 | 70,3447.57,M219,2025-01-01 14:27:00,FL,tablet,2620,1,0 72 | 71,601.4,M220,2025-01-01 14:30:00,TX,desktop,3775,0,0 73 | 72,5315.4,M221,2025-01-01 14:33:00,FL,mobile,2480,0,0 74 | 73,3774.68,M222,2025-01-01 14:36:00,CA,tablet,3763,1,0 75 | 74,4348.8,M223,2025-01-01 14:39:00,CA,tablet,3851,0,0 76 | 75,126.29,M224,2025-01-01 14:42:00,OH,mobile,2780,0,0 77 | 76,3578.76,M225,2025-01-01 14:45:00,NY,POS,2467,0,0 78 | 77,3354.01,M226,2025-01-01 14:48:00,NY,POS,3297,1,0 79 | 78,978.99,M227,2025-01-01 14:51:00,TX,POS,2946,1,0 80 | 79,943.83,M228,2025-01-01 14:54:00,FL,tablet,2049,0,0 81 | 80,4182.31,M229,2025-01-01 14:57:00,TX,POS,2979,1,0 82 | 81,1933.04,M230,2025-01-01 15:00:00,CA,tablet,2298,0,0 83 | 82,4161.06,M231,2025-01-01 15:03:00,FL,desktop,2736,1,0 84 | 83,3339.67,M232,2025-01-01 15:06:00,TX,mobile,3876,0,0 85 | 84,2352.03,M233,2025-01-01 15:09:00,TX,tablet,3325,0,0 86 | 85,5553.04,M234,2025-01-01 15:12:00,CA,POS,2023,1,1 87 | 86,5054.77,M235,2025-01-01 15:15:00,CA,desktop,2987,0,0 88 | 87,2163.66,M236,2025-01-01 15:18:00,TX,desktop,2004,0,0 89 | 88,290.24,M237,2025-01-01 15:21:00,WA,mobile,3949,0,0 90 | 89,1849.47,M238,2025-01-01 15:24:00,OH,desktop,3322,1,0 91 | 90,2407.17,M239,2025-01-01 15:27:00,WA,mobile,3844,1,0 92 | 91,4238.6,M240,2025-01-01 15:30:00,TX,mobile,2919,0,0 93 | 92,5972.29,M241,2025-01-01 15:33:00,FL,desktop,3638,0,0 94 | 93,2154.81,M242,2025-01-01 15:36:00,OH,POS,3421,1,0 95 | 94,4582.41,M243,2025-01-01 15:39:00,WA,desktop,3763,0,0 96 | 95,3571.27,M244,2025-01-01 15:42:00,NY,desktop,3443,0,0 97 | 96,4159.46,M245,2025-01-01 15:45:00,TX,tablet,2153,1,0 98 | 97,932.23,M246,2025-01-01 15:48:00,NY,POS,3782,0,0 99 | 98,2411.29,M247,2025-01-01 15:51:00,TX,POS,3804,0,0 100 | 99,1467.91,M248,2025-01-01 15:54:00,WA,desktop,2231,1,1 101 | 100,2080.43,M249,2025-01-01 15:57:00,FL,desktop,2788,0,0 102 | 101,3093.38,M200,2025-01-01 16:00:00,FL,POS,2345,0,0 103 | 102,4009.75,M201,2025-01-01 16:03:00,NY,tablet,3377,0,0 104 | 103,662.27,M202,2025-01-01 16:06:00,OH,mobile,2551,0,1 105 | 104,811.44,M203,2025-01-01 16:09:00,OH,mobile,3229,0,0 106 | 105,1952.22,M204,2025-01-01 16:12:00,NY,tablet,2810,0,0 107 | 106,3979.54,M205,2025-01-01 16:15:00,TX,tablet,2570,1,1 108 | 107,5083.64,M206,2025-01-01 16:18:00,NY,tablet,2560,0,0 109 | 108,3332.95,M207,2025-01-01 16:21:00,NY,desktop,2174,1,0 110 | 109,5131.08,M208,2025-01-01 16:24:00,WA,tablet,3777,0,0 111 | 110,2327.48,M209,2025-01-01 16:27:00,OH,desktop,3170,1,0 112 | 111,1921.22,M210,2025-01-01 16:30:00,FL,mobile,3931,0,0 113 | 112,2144.96,M211,2025-01-01 16:33:00,TX,desktop,2291,1,0 114 | 113,1051.36,M212,2025-01-01 16:36:00,WA,mobile,2377,0,0 115 | 114,4979.8,M213,2025-01-01 16:39:00,FL,POS,3885,0,0 116 | 115,2051.86,M214,2025-01-01 16:42:00,FL,POS,3899,1,1 117 | 116,3327.65,M215,2025-01-01 16:45:00,CA,POS,2032,1,0 118 | 117,3483.95,M216,2025-01-01 16:48:00,CA,desktop,2619,1,0 119 | 118,3143.55,M217,2025-01-01 16:51:00,NY,POS,3406,0,0 120 | 119,46.05,M218,2025-01-01 16:54:00,NY,mobile,2342,1,0 121 | 120,5930.42,M219,2025-01-01 16:57:00,CA,desktop,2829,0,0 122 | 121,5434.89,M220,2025-01-01 17:00:00,WA,tablet,3960,0,0 123 | 122,1269.59,M221,2025-01-01 17:03:00,TX,desktop,2460,0,0 124 | 123,1776.16,M222,2025-01-01 17:06:00,WA,tablet,2219,1,0 125 | 124,3134.46,M223,2025-01-01 17:09:00,FL,POS,3243,1,0 126 | 125,5414.41,M224,2025-01-01 17:12:00,FL,mobile,2786,0,0 127 | 126,5902.28,M225,2025-01-01 17:15:00,WA,tablet,3124,1,0 128 | 127,1567.53,M226,2025-01-01 17:18:00,NY,mobile,3566,1,1 129 | 128,3399.22,M227,2025-01-01 17:21:00,FL,desktop,3585,1,0 130 | 129,4847.6,M228,2025-01-01 17:24:00,WA,mobile,2681,1,0 131 | 130,2384.39,M229,2025-01-01 17:27:00,CA,tablet,3894,0,0 132 | 131,4394.51,M230,2025-01-01 17:30:00,TX,tablet,2016,0,0 133 | 132,991.58,M231,2025-01-01 17:33:00,WA,mobile,2731,1,0 134 | 133,3616.17,M232,2025-01-01 17:36:00,OH,tablet,3731,1,0 135 | 134,5199.21,M233,2025-01-01 17:39:00,TX,desktop,2773,0,0 136 | 135,5901.62,M234,2025-01-01 17:42:00,NY,mobile,3339,1,0 137 | 136,503.81,M235,2025-01-01 17:45:00,WA,desktop,2786,1,0 138 | 137,2587.23,M236,2025-01-01 17:48:00,NY,POS,2697,1,0 139 | 138,1251.12,M237,2025-01-01 17:51:00,FL,POS,2214,0,0 140 | 139,2720.3,M238,2025-01-01 17:54:00,OH,desktop,3575,1,0 141 | 140,3300.15,M239,2025-01-01 17:57:00,TX,desktop,3403,1,0 142 | 141,587.16,M240,2025-01-01 18:00:00,TX,desktop,2812,1,0 143 | 142,1802.26,M241,2025-01-01 18:03:00,FL,POS,2041,0,0 144 | 143,5567.68,M242,2025-01-01 18:06:00,WA,tablet,3861,0,0 145 | 144,3426.95,M243,2025-01-01 18:09:00,CA,POS,3175,0,0 146 | 145,2760.75,M244,2025-01-01 18:12:00,CA,tablet,2661,0,0 147 | 146,4528.55,M245,2025-01-01 18:15:00,OH,POS,2052,0,0 148 | 147,4458.92,M246,2025-01-01 18:18:00,TX,desktop,3748,0,0 149 | 148,320.02,M247,2025-01-01 18:21:00,WA,tablet,2333,1,0 150 | 149,4260.92,M248,2025-01-01 18:24:00,TX,desktop,3175,1,0 151 | 150,5040.28,M249,2025-01-01 18:27:00,TX,tablet,2920,0,0 152 | 151,1020.65,M200,2025-01-01 18:30:00,NY,POS,2144,0,1 153 | 152,4692.56,M201,2025-01-01 18:33:00,CA,POS,2122,0,0 154 | 153,1740.62,M202,2025-01-01 18:36:00,WA,POS,3138,1,1 155 | 154,1859.62,M203,2025-01-01 18:39:00,OH,desktop,2877,0,0 156 | 155,4001.61,M204,2025-01-01 18:42:00,TX,POS,2930,0,0 157 | 156,695.01,M205,2025-01-01 18:45:00,WA,tablet,3232,0,0 158 | 157,3999.29,M206,2025-01-01 18:48:00,OH,desktop,2567,0,0 159 | 158,5330.51,M207,2025-01-01 18:51:00,WA,desktop,3307,0,0 160 | 159,4186.98,M208,2025-01-01 18:54:00,WA,desktop,2705,0,0 161 | 160,2658.76,M209,2025-01-01 18:57:00,CA,desktop,2545,1,0 162 | 161,2646.14,M210,2025-01-01 19:00:00,FL,POS,3088,1,0 163 | 162,4597.62,M211,2025-01-01 19:03:00,CA,POS,2622,1,0 164 | 163,3406.88,M212,2025-01-01 19:06:00,WA,tablet,3919,1,0 165 | 164,536.88,M213,2025-01-01 19:09:00,CA,POS,3666,1,0 166 | 165,3508.55,M214,2025-01-01 19:12:00,OH,mobile,2442,0,0 167 | 166,4894.62,M215,2025-01-01 19:15:00,OH,POS,3847,1,0 168 | 167,2042.29,M216,2025-01-01 19:18:00,NY,POS,3045,0,0 169 | 168,5567.63,M217,2025-01-01 19:21:00,CA,POS,2425,0,0 170 | 169,4511.78,M218,2025-01-01 19:24:00,WA,tablet,2387,0,0 171 | 170,3457.16,M219,2025-01-01 19:27:00,OH,tablet,3486,0,0 172 | 171,4517.31,M220,2025-01-01 19:30:00,CA,mobile,2099,0,0 173 | 172,502.52,M221,2025-01-01 19:33:00,NY,POS,3766,0,0 174 | 173,5160.55,M222,2025-01-01 19:36:00,NY,POS,3653,0,0 175 | 174,4934.38,M223,2025-01-01 19:39:00,CA,desktop,3803,1,0 176 | 175,5461.93,M224,2025-01-01 19:42:00,WA,mobile,3316,1,0 177 | 176,797.93,M225,2025-01-01 19:45:00,WA,tablet,2751,0,0 178 | 177,518.23,M226,2025-01-01 19:48:00,TX,POS,3576,1,0 179 | 178,856.34,M227,2025-01-01 19:51:00,WA,POS,3081,0,0 180 | 179,2414.29,M228,2025-01-01 19:54:00,OH,tablet,2062,1,0 181 | 180,2563.11,M229,2025-01-01 19:57:00,FL,POS,3350,0,0 182 | 181,3386.44,M230,2025-01-01 20:00:00,OH,POS,3502,1,0 183 | 182,759.79,M231,2025-01-01 20:03:00,WA,desktop,2900,1,0 184 | 183,1232.36,M232,2025-01-01 20:06:00,FL,POS,2090,1,0 185 | 184,4875.52,M233,2025-01-01 20:09:00,FL,mobile,3368,0,0 186 | 185,2823.89,M234,2025-01-01 20:12:00,TX,POS,3552,0,0 187 | 186,4853.39,M235,2025-01-01 20:15:00,OH,mobile,3947,1,0 188 | 187,74.34,M236,2025-01-01 20:18:00,TX,tablet,3910,1,1 189 | 188,3323.01,M237,2025-01-01 20:21:00,WA,mobile,3946,1,0 190 | 189,5593.63,M238,2025-01-01 20:24:00,WA,POS,2436,1,0 191 | 190,3505.59,M239,2025-01-01 20:27:00,FL,tablet,2793,1,0 192 | 191,1260.39,M240,2025-01-01 20:30:00,TX,POS,2688,0,0 193 | 192,4315.01,M241,2025-01-01 20:33:00,TX,desktop,2092,0,0 194 | 193,2292.55,M242,2025-01-01 20:36:00,WA,mobile,3339,0,0 195 | 194,4020.25,M243,2025-01-01 20:39:00,NY,desktop,3562,1,0 196 | 195,205.04,M244,2025-01-01 20:42:00,NY,desktop,2592,0,0 197 | 196,3826.33,M245,2025-01-01 20:45:00,OH,desktop,2636,1,0 198 | 197,222.22,M246,2025-01-01 20:48:00,NY,desktop,3061,1,0 199 | 198,4476.34,M247,2025-01-01 20:51:00,TX,POS,3359,1,0 200 | 199,2853.29,M248,2025-01-01 20:54:00,NY,tablet,3928,0,0 201 | 200,756.87,M249,2025-01-01 20:57:00,OH,POS,3823,1,0 202 | 201,3269.54,M200,2025-01-01 21:00:00,OH,mobile,3792,1,0 203 | 202,428.64,M201,2025-01-01 21:03:00,NY,mobile,3544,1,0 204 | 203,3930.59,M202,2025-01-01 21:06:00,WA,desktop,3329,1,0 205 | 204,5976.64,M203,2025-01-01 21:09:00,WA,mobile,3478,1,0 206 | 205,4623.3,M204,2025-01-01 21:12:00,CA,POS,3771,1,0 207 | 206,3455.43,M205,2025-01-01 21:15:00,NY,POS,2932,1,0 208 | 207,642.73,M206,2025-01-01 21:18:00,FL,POS,2743,0,0 209 | 208,4208.01,M207,2025-01-01 21:21:00,NY,desktop,2754,1,0 210 | 209,3977.17,M208,2025-01-01 21:24:00,NY,mobile,2876,1,0 211 | 210,323.11,M209,2025-01-01 21:27:00,OH,desktop,2507,1,0 212 | 211,4760.03,M210,2025-01-01 21:30:00,OH,desktop,2510,0,0 213 | 212,3126.74,M211,2025-01-01 21:33:00,NY,tablet,2133,1,0 214 | 213,2572.43,M212,2025-01-01 21:36:00,NY,POS,2164,1,0 215 | 214,4735.48,M213,2025-01-01 21:39:00,WA,POS,3149,0,1 216 | 215,2487.07,M214,2025-01-01 21:42:00,WA,mobile,2806,0,0 217 | 216,2901.73,M215,2025-01-01 21:45:00,NY,tablet,2643,1,0 218 | 217,1114.32,M216,2025-01-01 21:48:00,CA,POS,3968,0,0 219 | 218,1948.27,M217,2025-01-01 21:51:00,CA,tablet,3444,0,0 220 | 219,5077.83,M218,2025-01-01 21:54:00,NY,mobile,3225,1,0 221 | 220,1145.82,M219,2025-01-01 21:57:00,FL,tablet,3929,0,0 222 | 221,2521.23,M220,2025-01-01 22:00:00,OH,POS,3136,0,0 223 | 222,5934.54,M221,2025-01-01 22:03:00,OH,POS,3890,0,0 224 | 223,1442.5,M222,2025-01-01 22:06:00,WA,desktop,3543,0,0 225 | 224,5503.49,M223,2025-01-01 22:09:00,OH,POS,2534,1,0 226 | 225,5512.83,M224,2025-01-01 22:12:00,TX,desktop,3136,1,0 227 | 226,575.04,M225,2025-01-01 22:15:00,FL,mobile,3267,1,0 228 | 227,2798.01,M226,2025-01-01 22:18:00,OH,desktop,3862,1,0 229 | 228,3028.23,M227,2025-01-01 22:21:00,OH,mobile,3396,1,1 230 | 229,1902.6,M228,2025-01-01 22:24:00,WA,POS,3214,0,0 231 | 230,312.62,M229,2025-01-01 22:27:00,TX,tablet,3601,1,0 232 | 231,1472.86,M230,2025-01-01 22:30:00,OH,desktop,2293,0,0 233 | 232,600.31,M231,2025-01-01 22:33:00,OH,tablet,2659,1,0 234 | 233,1452.35,M232,2025-01-01 22:36:00,CA,desktop,3950,1,0 235 | 234,4852.51,M233,2025-01-01 22:39:00,OH,desktop,3693,1,0 236 | 235,5373.02,M234,2025-01-01 22:42:00,OH,POS,2175,1,0 237 | 236,288.04,M235,2025-01-01 22:45:00,CA,POS,3752,1,0 238 | 237,1832.62,M236,2025-01-01 22:48:00,WA,mobile,2009,0,1 239 | 238,5884.08,M237,2025-01-01 22:51:00,WA,mobile,2699,0,0 240 | 239,3250.84,M238,2025-01-01 22:54:00,TX,mobile,2080,1,0 241 | 240,3769.07,M239,2025-01-01 22:57:00,CA,mobile,3928,1,0 242 | 241,63.11,M240,2025-01-01 23:00:00,OH,tablet,3898,1,0 243 | 242,2924.91,M241,2025-01-01 23:03:00,OH,POS,2825,1,0 244 | 243,5930.32,M242,2025-01-01 23:06:00,FL,mobile,3951,0,0 245 | 244,2269.86,M243,2025-01-01 23:09:00,CA,tablet,3111,0,0 246 | 245,609.32,M244,2025-01-01 23:12:00,TX,desktop,2399,1,1 247 | 246,2787.6,M245,2025-01-01 23:15:00,CA,tablet,2109,1,1 248 | 247,5779.14,M246,2025-01-01 23:18:00,FL,desktop,3291,0,0 249 | 248,2070.73,M247,2025-01-01 23:21:00,CA,desktop,2418,0,0 250 | 249,4799.57,M248,2025-01-01 23:24:00,FL,tablet,3268,1,0 251 | 250,4799.11,M249,2025-01-01 23:27:00,NY,POS,2362,0,0 252 | -------------------------------------------------------------------------------- /fraud-detection-federated/data/synthetic_data.csv: -------------------------------------------------------------------------------- 1 | transaction_id,amount,merchant_id,timestamp,location,device_type,user_id,is_international,is_fraud 2 | 1,7089.86,M303,2025-01-01 12:00:00,CA,desktop,4970,0,0 3 | 2,641.74,M303,2025-01-01 12:04:00,TX,mobile,3341,1,0 4 | 3,7837.58,M305,2025-01-01 12:08:00,NY,tablet,4953,0,1 5 | 4,1996.42,M301,2025-01-01 12:12:00,NY,tablet,4697,1,0 6 | 5,6028.02,M302,2025-01-01 12:16:00,TX,POS,4085,1,0 7 | 6,4222.87,M302,2025-01-01 12:20:00,FL,POS,3816,1,0 8 | 7,7262.28,M303,2025-01-01 12:24:00,FL,desktop,3009,0,0 9 | 8,7074.88,M305,2025-01-01 12:28:00,FL,mobile,4722,0,0 10 | 9,732.37,M303,2025-01-01 12:32:00,FL,POS,4579,0,0 11 | 10,4148.41,M304,2025-01-01 12:36:00,NY,mobile,4906,0,0 12 | 11,2762.1,M302,2025-01-01 12:40:00,NY,POS,4528,1,0 13 | 12,1714.1,M302,2025-01-01 12:44:00,CA,desktop,3519,1,0 14 | 13,2898.17,M301,2025-01-01 12:48:00,NY,desktop,4762,0,0 15 | 14,2180.79,M301,2025-01-01 12:52:00,MA,tablet,4977,0,0 16 | 15,6097.77,M305,2025-01-01 12:56:00,NY,desktop,4685,1,0 17 | 16,3834.77,M301,2025-01-01 13:00:00,CA,desktop,4323,0,0 18 | 17,809.98,M303,2025-01-01 13:04:00,FL,POS,4675,1,0 19 | 18,2217.65,M305,2025-01-01 13:08:00,FL,POS,4899,0,0 20 | 19,6359.53,M302,2025-01-01 13:12:00,MA,POS,3492,1,0 21 | 20,4121.48,M303,2025-01-01 13:16:00,NY,mobile,4660,0,1 22 | 21,3637.29,M302,2025-01-01 13:20:00,MA,desktop,4360,0,0 23 | 22,2056.11,M304,2025-01-01 13:24:00,FL,desktop,3389,1,0 24 | 23,929.53,M305,2025-01-01 13:28:00,FL,mobile,3131,1,0 25 | 24,6598.02,M302,2025-01-01 13:32:00,CA,desktop,3288,1,0 26 | 25,2555.67,M302,2025-01-01 13:36:00,FL,tablet,3911,0,0 27 | 26,1235.41,M305,2025-01-01 13:40:00,CA,mobile,4845,0,0 28 | 27,1735.54,M301,2025-01-01 13:44:00,MA,POS,3135,0,0 29 | 28,7298.64,M301,2025-01-01 13:48:00,NY,mobile,3973,0,0 30 | 29,364.06,M304,2025-01-01 13:52:00,TX,POS,4277,0,1 31 | 30,3020.1,M305,2025-01-01 13:56:00,NY,desktop,3588,0,0 32 | 31,2557.37,M301,2025-01-01 14:00:00,CA,mobile,3588,1,0 33 | 32,2845.18,M302,2025-01-01 14:04:00,CA,desktop,4348,1,0 34 | 33,7468.19,M302,2025-01-01 14:08:00,NY,desktop,3180,1,0 35 | 34,3120.59,M302,2025-01-01 14:12:00,CA,desktop,3425,0,0 36 | 35,7169.6,M301,2025-01-01 14:16:00,MA,mobile,3965,1,1 37 | 36,1181.12,M303,2025-01-01 14:20:00,FL,POS,3154,0,0 38 | 37,3933.08,M301,2025-01-01 14:24:00,TX,tablet,3014,1,0 39 | 38,7388.26,M304,2025-01-01 14:28:00,FL,desktop,3698,1,1 40 | 39,6414.46,M304,2025-01-01 14:32:00,FL,tablet,3739,1,0 41 | 40,6790.01,M304,2025-01-01 14:36:00,CA,desktop,3275,0,0 42 | 41,5330.26,M305,2025-01-01 14:40:00,NY,tablet,3704,1,0 43 | 42,1162.89,M302,2025-01-01 14:44:00,MA,mobile,4135,1,0 44 | 43,946.43,M305,2025-01-01 14:48:00,MA,desktop,4027,1,0 45 | 44,637.62,M305,2025-01-01 14:52:00,TX,desktop,4347,1,0 46 | 45,3075.64,M302,2025-01-01 14:56:00,CA,tablet,3489,0,1 47 | 46,1188.51,M304,2025-01-01 15:00:00,NY,tablet,4930,1,0 48 | 47,3593.9,M301,2025-01-01 15:04:00,TX,mobile,3675,0,0 49 | 48,2857.11,M301,2025-01-01 15:08:00,NY,tablet,3571,0,0 50 | 49,3476.47,M302,2025-01-01 15:12:00,FL,POS,3034,0,0 51 | 50,6410.44,M301,2025-01-01 15:16:00,FL,desktop,3430,1,0 52 | 51,2852.95,M305,2025-01-01 15:20:00,NY,POS,4237,1,1 53 | 52,401.05,M304,2025-01-01 15:24:00,CA,POS,3606,0,0 54 | 53,6799.64,M302,2025-01-01 15:28:00,NY,mobile,3834,1,0 55 | 54,4994.94,M302,2025-01-01 15:32:00,CA,POS,4135,1,1 56 | 55,1149.96,M301,2025-01-01 15:36:00,TX,mobile,4351,1,0 57 | 56,7976.7,M305,2025-01-01 15:40:00,FL,mobile,3310,0,0 58 | 57,3455.8,M304,2025-01-01 15:44:00,NY,tablet,4389,0,0 59 | 58,7382.36,M302,2025-01-01 15:48:00,FL,mobile,4165,1,0 60 | 59,1858.64,M301,2025-01-01 15:52:00,NY,POS,3980,0,0 61 | 60,4144.45,M301,2025-01-01 15:56:00,FL,POS,4513,0,0 62 | 61,5944.75,M304,2025-01-01 16:00:00,CA,POS,4662,1,0 63 | 62,718.73,M302,2025-01-01 16:04:00,FL,desktop,4314,0,1 64 | 63,1646.4,M303,2025-01-01 16:08:00,FL,mobile,4668,0,0 65 | 64,4459.83,M303,2025-01-01 16:12:00,MA,mobile,4423,1,0 66 | 65,75.4,M302,2025-01-01 16:16:00,FL,POS,3919,0,1 67 | 66,2865.76,M303,2025-01-01 16:20:00,FL,tablet,4767,1,1 68 | 67,6800.74,M303,2025-01-01 16:24:00,TX,POS,4600,1,0 69 | 68,748.65,M305,2025-01-01 16:28:00,TX,desktop,3494,0,0 70 | 69,1060.04,M303,2025-01-01 16:32:00,CA,mobile,4373,1,1 71 | 70,6558.24,M304,2025-01-01 16:36:00,MA,mobile,4291,1,0 72 | 71,5695.87,M301,2025-01-01 16:40:00,NY,POS,3290,0,0 73 | 72,4134.81,M304,2025-01-01 16:44:00,CA,desktop,3012,1,0 74 | 73,2641.37,M301,2025-01-01 16:48:00,TX,desktop,4281,0,1 75 | 74,4957.59,M301,2025-01-01 16:52:00,NY,tablet,4615,0,0 76 | 75,6630.95,M305,2025-01-01 16:56:00,FL,desktop,3972,0,0 77 | 76,4161.07,M303,2025-01-01 17:00:00,MA,tablet,3505,1,0 78 | 77,5218.69,M305,2025-01-01 17:04:00,MA,desktop,4006,0,0 79 | 78,6778.98,M305,2025-01-01 17:08:00,CA,POS,3136,1,0 80 | 79,3834.16,M301,2025-01-01 17:12:00,NY,mobile,4109,1,0 81 | 80,5768.65,M301,2025-01-01 17:16:00,NY,tablet,4550,0,0 82 | 81,5651.66,M304,2025-01-01 17:20:00,FL,POS,3247,1,0 83 | 82,6200.23,M304,2025-01-01 17:24:00,FL,mobile,3665,1,0 84 | 83,1279.43,M302,2025-01-01 17:28:00,CA,mobile,3337,0,0 85 | 84,821.47,M303,2025-01-01 17:32:00,MA,mobile,3801,0,1 86 | 85,5125.91,M303,2025-01-01 17:36:00,FL,mobile,4681,1,0 87 | 86,995.49,M303,2025-01-01 17:40:00,TX,mobile,4243,1,0 88 | 87,4358.27,M305,2025-01-01 17:44:00,CA,tablet,3062,0,0 89 | 88,3393.8,M304,2025-01-01 17:48:00,NY,tablet,4085,1,1 90 | 89,6000.06,M301,2025-01-01 17:52:00,CA,tablet,4644,1,0 91 | 90,131.53,M304,2025-01-01 17:56:00,FL,desktop,4190,0,0 92 | 91,6797.07,M302,2025-01-01 18:00:00,CA,mobile,3755,1,0 93 | 92,6241.8,M305,2025-01-01 18:04:00,TX,desktop,4721,0,0 94 | 93,1919.84,M303,2025-01-01 18:08:00,TX,mobile,3996,1,0 95 | 94,6964.52,M303,2025-01-01 18:12:00,TX,POS,4088,0,1 96 | 95,3560.71,M301,2025-01-01 18:16:00,TX,POS,4470,0,0 97 | 96,1502.6,M305,2025-01-01 18:20:00,FL,desktop,3217,1,0 98 | 97,7419.59,M301,2025-01-01 18:24:00,MA,POS,3495,1,1 99 | 98,1185.16,M305,2025-01-01 18:28:00,MA,POS,3887,0,0 100 | 99,4518.99,M304,2025-01-01 18:32:00,FL,desktop,4807,0,0 101 | 100,7510.01,M303,2025-01-01 18:36:00,TX,POS,4627,0,0 102 | 101,2194.74,M302,2025-01-01 18:40:00,TX,mobile,3302,1,0 103 | 102,5392.89,M303,2025-01-01 18:44:00,NY,desktop,4016,0,0 104 | 103,2394.22,M305,2025-01-01 18:48:00,FL,tablet,3359,0,1 105 | 104,7562.94,M303,2025-01-01 18:52:00,TX,desktop,4533,0,1 106 | 105,5590.05,M302,2025-01-01 18:56:00,NY,POS,3164,1,0 107 | 106,5900.16,M301,2025-01-01 19:00:00,MA,POS,3636,1,0 108 | 107,7264.7,M305,2025-01-01 19:04:00,NY,tablet,4814,1,1 109 | 108,812.81,M302,2025-01-01 19:08:00,NY,mobile,3136,0,0 110 | 109,3719.93,M303,2025-01-01 19:12:00,NY,POS,4414,1,0 111 | 110,112.38,M303,2025-01-01 19:16:00,MA,POS,3155,1,1 112 | 111,2273.0,M302,2025-01-01 19:20:00,TX,desktop,3306,0,0 113 | 112,6271.38,M304,2025-01-01 19:24:00,MA,desktop,3907,1,1 114 | 113,2049.66,M302,2025-01-01 19:28:00,CA,tablet,3915,0,1 115 | 114,2462.44,M303,2025-01-01 19:32:00,TX,POS,4220,1,0 116 | 115,247.2,M305,2025-01-01 19:36:00,MA,POS,3319,0,0 117 | 116,4403.93,M302,2025-01-01 19:40:00,FL,desktop,4690,0,0 118 | 117,2185.23,M303,2025-01-01 19:44:00,CA,mobile,4501,0,0 119 | 118,1474.52,M301,2025-01-01 19:48:00,TX,desktop,4900,1,0 120 | 119,6928.28,M301,2025-01-01 19:52:00,FL,desktop,3716,1,0 121 | 120,1275.14,M302,2025-01-01 19:56:00,CA,desktop,3070,0,0 122 | 121,2056.57,M305,2025-01-01 20:00:00,CA,POS,3176,1,0 123 | 122,5244.03,M304,2025-01-01 20:04:00,NY,POS,4130,1,0 124 | 123,200.42,M302,2025-01-01 20:08:00,NY,tablet,3848,0,0 125 | 124,7696.07,M304,2025-01-01 20:12:00,NY,tablet,3599,0,1 126 | 125,7182.98,M303,2025-01-01 20:16:00,MA,mobile,3751,1,0 127 | 126,981.99,M305,2025-01-01 20:20:00,CA,desktop,3521,0,0 128 | 127,5782.28,M305,2025-01-01 20:24:00,TX,tablet,4888,1,0 129 | 128,7670.78,M303,2025-01-01 20:28:00,NY,mobile,3079,0,0 130 | 129,3964.34,M301,2025-01-01 20:32:00,CA,tablet,4200,0,0 131 | 130,7511.52,M305,2025-01-01 20:36:00,NY,POS,4747,1,0 132 | 131,3992.05,M301,2025-01-01 20:40:00,FL,mobile,3722,0,0 133 | 132,4446.5,M305,2025-01-01 20:44:00,MA,tablet,3616,0,0 134 | 133,4025.6,M303,2025-01-01 20:48:00,NY,desktop,4023,0,0 135 | 134,6684.32,M301,2025-01-01 20:52:00,CA,mobile,3203,0,0 136 | 135,995.87,M302,2025-01-01 20:56:00,NY,tablet,4405,0,0 137 | 136,645.49,M302,2025-01-01 21:00:00,FL,tablet,4378,0,0 138 | 137,3535.62,M304,2025-01-01 21:04:00,TX,POS,3452,1,0 139 | 138,2423.4,M305,2025-01-01 21:08:00,NY,mobile,4069,0,0 140 | 139,6762.37,M303,2025-01-01 21:12:00,CA,desktop,3790,0,0 141 | 140,5367.81,M304,2025-01-01 21:16:00,TX,desktop,4061,1,0 142 | 141,6324.57,M304,2025-01-01 21:20:00,FL,mobile,4915,0,0 143 | 142,653.27,M304,2025-01-01 21:24:00,MA,tablet,4922,1,0 144 | 143,5271.77,M301,2025-01-01 21:28:00,TX,mobile,3578,0,0 145 | 144,1783.97,M305,2025-01-01 21:32:00,NY,desktop,3359,0,0 146 | 145,2845.0,M304,2025-01-01 21:36:00,NY,POS,3756,1,1 147 | 146,4733.81,M304,2025-01-01 21:40:00,FL,mobile,4857,0,0 148 | 147,3999.94,M303,2025-01-01 21:44:00,FL,desktop,4779,0,0 149 | 148,6327.66,M304,2025-01-01 21:48:00,CA,POS,3541,0,0 150 | 149,3778.67,M302,2025-01-01 21:52:00,NY,tablet,4270,0,0 151 | 150,2344.49,M305,2025-01-01 21:56:00,TX,tablet,3525,0,0 152 | 151,3795.36,M305,2025-01-01 22:00:00,TX,desktop,3749,1,0 153 | 152,6115.63,M302,2025-01-01 22:04:00,CA,mobile,4378,0,1 154 | 153,6217.62,M301,2025-01-01 22:08:00,MA,tablet,4776,1,0 155 | 154,1792.47,M305,2025-01-01 22:12:00,FL,POS,4568,1,1 156 | 155,2554.66,M303,2025-01-01 22:16:00,MA,desktop,4772,1,0 157 | 156,3746.9,M304,2025-01-01 22:20:00,FL,mobile,4560,0,0 158 | 157,151.39,M302,2025-01-01 22:24:00,FL,mobile,4087,0,0 159 | 158,5481.47,M303,2025-01-01 22:28:00,MA,desktop,4435,0,0 160 | 159,7985.98,M304,2025-01-01 22:32:00,MA,POS,4860,1,0 161 | 160,6975.82,M305,2025-01-01 22:36:00,CA,tablet,3174,1,0 162 | 161,1840.31,M304,2025-01-01 22:40:00,NY,POS,3957,0,0 163 | 162,7474.42,M302,2025-01-01 22:44:00,CA,POS,3329,0,0 164 | 163,4614.79,M304,2025-01-01 22:48:00,NY,tablet,4927,0,0 165 | 164,6887.06,M301,2025-01-01 22:52:00,FL,POS,4734,0,0 166 | 165,3499.63,M302,2025-01-01 22:56:00,CA,desktop,4120,0,0 167 | 166,6301.7,M301,2025-01-01 23:00:00,CA,desktop,3566,1,0 168 | 167,2615.11,M303,2025-01-01 23:04:00,TX,mobile,4907,1,1 169 | 168,2895.49,M304,2025-01-01 23:08:00,TX,POS,4229,1,0 170 | 169,1841.21,M304,2025-01-01 23:12:00,NY,desktop,4912,1,0 171 | 170,7517.8,M305,2025-01-01 23:16:00,CA,mobile,3374,0,1 172 | 171,4997.93,M304,2025-01-01 23:20:00,FL,tablet,4979,1,0 173 | 172,2368.73,M302,2025-01-01 23:24:00,MA,desktop,3059,0,0 174 | 173,5943.28,M305,2025-01-01 23:28:00,CA,tablet,3832,1,0 175 | 174,2542.04,M302,2025-01-01 23:32:00,CA,desktop,4853,1,0 176 | 175,342.86,M301,2025-01-01 23:36:00,FL,mobile,4732,0,1 177 | 176,5372.87,M302,2025-01-01 23:40:00,NY,desktop,4011,1,1 178 | 177,1043.84,M302,2025-01-01 23:44:00,NY,mobile,3898,0,0 179 | 178,336.24,M302,2025-01-01 23:48:00,CA,tablet,3604,0,0 180 | 179,6380.59,M303,2025-01-01 23:52:00,NY,tablet,4423,0,0 181 | 180,208.82,M304,2025-01-01 23:56:00,FL,desktop,4935,0,0 182 | 181,2813.94,M302,2025-01-02 00:00:00,TX,POS,3869,1,0 183 | 182,7567.04,M302,2025-01-02 00:04:00,CA,mobile,4165,0,0 184 | 183,1475.77,M305,2025-01-02 00:08:00,CA,tablet,3734,1,0 185 | 184,6347.82,M302,2025-01-02 00:12:00,CA,POS,4789,0,1 186 | 185,548.35,M303,2025-01-02 00:16:00,MA,tablet,3787,0,0 187 | 186,6202.57,M304,2025-01-02 00:20:00,TX,desktop,4043,1,0 188 | 187,6600.02,M303,2025-01-02 00:24:00,CA,POS,4124,0,1 189 | 188,6978.63,M303,2025-01-02 00:28:00,FL,mobile,4826,1,0 190 | 189,7969.58,M301,2025-01-02 00:32:00,TX,POS,4616,1,0 191 | 190,5380.95,M303,2025-01-02 00:36:00,CA,desktop,4877,1,0 192 | 191,1655.13,M302,2025-01-02 00:40:00,NY,POS,4935,0,1 193 | 192,717.4,M302,2025-01-02 00:44:00,NY,desktop,4957,1,0 194 | 193,5755.3,M301,2025-01-02 00:48:00,NY,tablet,4656,0,0 195 | 194,1809.56,M302,2025-01-02 00:52:00,NY,tablet,3594,1,0 196 | 195,4621.81,M304,2025-01-02 00:56:00,FL,POS,4584,0,0 197 | 196,6321.03,M304,2025-01-02 01:00:00,FL,POS,4427,0,0 198 | 197,2830.65,M302,2025-01-02 01:04:00,FL,mobile,3858,1,0 199 | 198,4817.85,M304,2025-01-02 01:08:00,FL,desktop,3663,0,0 200 | 199,7873.48,M301,2025-01-02 01:12:00,TX,tablet,3334,0,0 201 | 200,1479.23,M305,2025-01-02 01:16:00,MA,tablet,3892,1,0 202 | 201,6374.02,M305,2025-01-02 01:20:00,FL,tablet,3740,1,0 203 | 202,6811.7,M301,2025-01-02 01:24:00,TX,mobile,3783,0,0 204 | 203,3191.53,M305,2025-01-02 01:28:00,FL,POS,4318,1,0 205 | 204,7567.45,M302,2025-01-02 01:32:00,TX,mobile,3931,0,0 206 | 205,4555.83,M305,2025-01-02 01:36:00,MA,mobile,3264,0,0 207 | 206,5042.4,M305,2025-01-02 01:40:00,CA,tablet,3202,0,0 208 | 207,3443.84,M303,2025-01-02 01:44:00,NY,desktop,4430,0,0 209 | 208,2317.57,M304,2025-01-02 01:48:00,TX,POS,4479,1,0 210 | 209,3074.63,M303,2025-01-02 01:52:00,FL,mobile,4065,1,0 211 | 210,5698.45,M305,2025-01-02 01:56:00,NY,mobile,3396,1,0 212 | 211,7781.7,M303,2025-01-02 02:00:00,CA,mobile,4365,1,0 213 | 212,2691.28,M302,2025-01-02 02:04:00,CA,desktop,4168,0,0 214 | 213,5745.87,M304,2025-01-02 02:08:00,CA,tablet,4389,1,0 215 | 214,6729.12,M303,2025-01-02 02:12:00,FL,desktop,3467,0,0 216 | 215,7076.43,M302,2025-01-02 02:16:00,FL,desktop,4013,1,0 217 | 216,4417.61,M304,2025-01-02 02:20:00,FL,mobile,4580,1,1 218 | 217,7198.95,M305,2025-01-02 02:24:00,CA,POS,3063,1,0 219 | 218,6227.33,M304,2025-01-02 02:28:00,CA,desktop,3048,1,0 220 | 219,5507.66,M301,2025-01-02 02:32:00,FL,desktop,4642,1,0 221 | 220,2774.28,M302,2025-01-02 02:36:00,TX,desktop,4086,1,1 222 | 221,6908.17,M302,2025-01-02 02:40:00,MA,tablet,4460,1,0 223 | 222,6770.9,M304,2025-01-02 02:44:00,TX,desktop,4575,0,0 224 | 223,679.23,M302,2025-01-02 02:48:00,TX,tablet,4577,1,0 225 | 224,7012.48,M303,2025-01-02 02:52:00,CA,desktop,4053,0,0 226 | 225,381.21,M305,2025-01-02 02:56:00,TX,mobile,4801,1,0 227 | 226,3417.38,M305,2025-01-02 03:00:00,TX,tablet,4735,0,0 228 | 227,4918.11,M304,2025-01-02 03:04:00,TX,desktop,3227,1,0 229 | 228,4890.77,M302,2025-01-02 03:08:00,CA,desktop,3896,1,0 230 | 229,4163.37,M301,2025-01-02 03:12:00,CA,mobile,3692,0,0 231 | 230,4314.0,M301,2025-01-02 03:16:00,FL,desktop,3777,1,1 232 | 231,6321.24,M304,2025-01-02 03:20:00,NY,POS,4502,1,0 233 | 232,7743.05,M302,2025-01-02 03:24:00,CA,tablet,4579,0,1 234 | 233,841.14,M301,2025-01-02 03:28:00,NY,desktop,3969,1,0 235 | 234,1347.34,M302,2025-01-02 03:32:00,NY,POS,4678,1,0 236 | 235,5953.25,M301,2025-01-02 03:36:00,MA,POS,3378,0,0 237 | 236,7423.45,M305,2025-01-02 03:40:00,CA,POS,4275,0,0 238 | 237,672.4,M302,2025-01-02 03:44:00,NY,desktop,3172,0,0 239 | 238,4346.21,M304,2025-01-02 03:48:00,TX,desktop,4891,0,0 240 | 239,591.96,M303,2025-01-02 03:52:00,NY,mobile,4164,1,0 241 | 240,7491.16,M304,2025-01-02 03:56:00,MA,tablet,3738,0,0 242 | 241,7803.91,M303,2025-01-02 04:00:00,CA,mobile,3514,1,0 243 | 242,3999.25,M303,2025-01-02 04:04:00,MA,POS,3488,1,0 244 | 243,4189.59,M302,2025-01-02 04:08:00,CA,desktop,3021,1,1 245 | 244,7435.4,M302,2025-01-02 04:12:00,NY,desktop,4718,0,0 246 | 245,6720.9,M302,2025-01-02 04:16:00,TX,tablet,3941,1,0 247 | 246,4250.3,M304,2025-01-02 04:20:00,FL,desktop,3677,1,0 248 | 247,675.68,M302,2025-01-02 04:24:00,TX,POS,4468,1,0 249 | 248,3740.74,M303,2025-01-02 04:28:00,FL,tablet,3143,0,0 250 | 249,1347.35,M305,2025-01-02 04:32:00,FL,desktop,4239,1,0 251 | 250,6396.98,M304,2025-01-02 04:36:00,FL,mobile,3049,0,0 252 | -------------------------------------------------------------------------------- /fraud-detection-federated/data/high_fraud_data.csv: -------------------------------------------------------------------------------- 1 | transaction_id,amount,merchant_id,timestamp,location,device_type,user_id,is_international,is_fraud 2 | 1,1903.97,M100,2025-01-10 10:00:00,IL,mobile,1644,0,0 3 | 2,4756.04,M101,2025-01-10 10:02:00,IL,desktop,1232,0,0 4 | 3,3673.37,M102,2025-01-10 10:04:00,NY,mobile,1523,1,0 5 | 4,3013.36,M103,2025-01-10 10:06:00,TX,tablet,1345,1,0 6 | 5,822.29,M104,2025-01-10 10:08:00,CA,tablet,1045,1,0 7 | 6,822.17,M105,2025-01-10 10:10:00,NY,mobile,1545,1,0 8 | 7,337.51,M106,2025-01-10 10:12:00,CA,mobile,1944,0,0 9 | 8,4337.57,M107,2025-01-10 10:14:00,CA,desktop,1077,0,0 10 | 9,3025.52,M108,2025-01-10 10:16:00,TX,tablet,1729,1,0 11 | 10,3554.96,M109,2025-01-10 10:18:00,CA,tablet,1812,0,0 12 | 11,151.89,M110,2025-01-10 10:20:00,CA,mobile,1922,1,0 13 | 12,4851.05,M111,2025-01-10 10:22:00,TX,desktop,1072,1,0 14 | 13,4170.59,M112,2025-01-10 10:24:00,CA,tablet,1793,1,0 15 | 14,1101.08,M113,2025-01-10 10:26:00,CA,tablet,1248,0,0 16 | 15,950.03,M114,2025-01-10 10:28:00,CA,desktop,1046,1,0 17 | 16,957.85,M115,2025-01-10 10:30:00,NY,desktop,1120,1,0 18 | 17,1556.0,M116,2025-01-10 10:32:00,NY,tablet,1213,1,0 19 | 18,2647.54,M117,2025-01-10 10:34:00,NY,tablet,1238,0,0 20 | 19,2188.13,M118,2025-01-10 10:36:00,TX,desktop,1055,0,1 21 | 20,1491.58,M119,2025-01-10 10:38:00,IL,tablet,1349,1,0 22 | 21,3078.67,M120,2025-01-10 10:40:00,CA,mobile,1106,0,0 23 | 22,740.49,M121,2025-01-10 10:42:00,CA,mobile,1830,0,0 24 | 23,1496.12,M122,2025-01-10 10:44:00,TX,desktop,1047,0,0 25 | 24,1863.49,M123,2025-01-10 10:46:00,CA,desktop,1572,0,0 26 | 25,2307.55,M124,2025-01-10 10:48:00,NY,desktop,1336,0,0 27 | 26,3936.62,M125,2025-01-10 10:50:00,IL,mobile,1025,0,0 28 | 27,1038.39,M126,2025-01-10 10:52:00,FL,tablet,1803,0,0 29 | 28,2595.46,M127,2025-01-10 10:54:00,CA,mobile,1256,0,0 30 | 29,2982.45,M128,2025-01-10 10:56:00,NY,tablet,1007,0,0 31 | 30,279.93,M129,2025-01-10 10:58:00,FL,mobile,1624,0,0 32 | 31,3057.35,M100,2025-01-10 11:00:00,IL,tablet,1866,1,0 33 | 32,894.09,M101,2025-01-10 11:02:00,FL,mobile,1252,1,0 34 | 33,372.01,M102,2025-01-10 11:04:00,NY,desktop,1691,0,0 35 | 34,4746.98,M103,2025-01-10 11:06:00,FL,mobile,1718,1,1 36 | 35,4829.88,M104,2025-01-10 11:08:00,TX,tablet,1302,1,0 37 | 36,4051.57,M105,2025-01-10 11:10:00,FL,mobile,1638,0,0 38 | 37,1557.84,M106,2025-01-10 11:12:00,CA,mobile,1055,0,1 39 | 38,533.48,M107,2025-01-10 11:14:00,CA,mobile,1725,0,1 40 | 39,3436.95,M108,2025-01-10 11:16:00,TX,desktop,1525,1,0 41 | 40,2228.75,M109,2025-01-10 11:18:00,NY,mobile,1473,1,0 42 | 41,654.09,M110,2025-01-10 11:20:00,CA,desktop,1027,0,0 43 | 42,2501.13,M111,2025-01-10 11:22:00,IL,desktop,1982,0,0 44 | 43,220.22,M112,2025-01-10 11:24:00,CA,mobile,1077,0,0 45 | 44,4551.14,M113,2025-01-10 11:26:00,CA,mobile,1215,1,0 46 | 45,1330.96,M114,2025-01-10 11:28:00,NY,mobile,1385,1,0 47 | 46,3329.49,M115,2025-01-10 11:30:00,FL,tablet,1364,1,0 48 | 47,1592.97,M116,2025-01-10 11:32:00,CA,mobile,1665,1,0 49 | 48,2624.34,M117,2025-01-10 11:34:00,TX,desktop,1525,0,0 50 | 49,2756.22,M118,2025-01-10 11:36:00,FL,mobile,1698,0,0 51 | 50,965.03,M119,2025-01-10 11:38:00,IL,tablet,1311,0,1 52 | 51,4849.44,M120,2025-01-10 11:40:00,NY,mobile,1882,0,0 53 | 52,3886.91,M121,2025-01-10 11:42:00,IL,tablet,1006,1,0 54 | 53,4700.52,M122,2025-01-10 11:44:00,FL,tablet,1002,1,0 55 | 54,4479.4,M123,2025-01-10 11:46:00,FL,mobile,1622,0,0 56 | 55,3009.6,M124,2025-01-10 11:48:00,FL,desktop,1918,0,0 57 | 56,4613.28,M125,2025-01-10 11:50:00,IL,tablet,1749,1,0 58 | 57,488.04,M126,2025-01-10 11:52:00,FL,mobile,1362,0,0 59 | 58,1020.12,M127,2025-01-10 11:54:00,IL,mobile,1750,1,0 60 | 59,273.88,M128,2025-01-10 11:56:00,FL,desktop,1507,0,0 61 | 60,1660.39,M129,2025-01-10 11:58:00,TX,tablet,1273,0,0 62 | 61,1973.95,M100,2025-01-10 12:00:00,FL,tablet,1505,0,0 63 | 62,1393.18,M101,2025-01-10 12:02:00,IL,mobile,1805,0,1 64 | 63,4152.25,M102,2025-01-10 12:04:00,CA,mobile,1738,0,0 65 | 64,1815.93,M103,2025-01-10 12:06:00,FL,desktop,1882,0,0 66 | 65,1440.63,M104,2025-01-10 12:08:00,CA,desktop,1014,0,0 67 | 66,2736.35,M105,2025-01-10 12:10:00,TX,tablet,1191,1,1 68 | 67,747.57,M106,2025-01-10 12:12:00,NY,tablet,1984,1,0 69 | 68,4020.88,M107,2025-01-10 12:14:00,TX,mobile,1630,1,0 70 | 69,419.03,M108,2025-01-10 12:16:00,FL,tablet,1484,1,0 71 | 70,4935.09,M109,2025-01-10 12:18:00,CA,desktop,1027,1,0 72 | 71,3872.61,M110,2025-01-10 12:20:00,CA,desktop,1713,0,0 73 | 72,1033.64,M111,2025-01-10 12:22:00,IL,mobile,1038,0,0 74 | 73,77.33,M112,2025-01-10 12:24:00,CA,desktop,1952,1,0 75 | 74,4086.53,M113,2025-01-10 12:26:00,IL,desktop,1272,0,0 76 | 75,3548.94,M114,2025-01-10 12:28:00,NY,desktop,1230,1,0 77 | 76,3658.59,M115,2025-01-10 12:30:00,FL,desktop,1085,1,0 78 | 77,3867.79,M116,2025-01-10 12:32:00,IL,mobile,1473,0,0 79 | 78,416.52,M117,2025-01-10 12:34:00,NY,mobile,1125,0,1 80 | 79,1824.41,M118,2025-01-10 12:36:00,CA,tablet,1811,0,0 81 | 80,623.55,M119,2025-01-10 12:38:00,CA,desktop,1536,1,0 82 | 81,4322.36,M120,2025-01-10 12:40:00,NY,tablet,1144,0,0 83 | 82,3135.33,M121,2025-01-10 12:42:00,CA,mobile,1524,1,0 84 | 83,1687.95,M122,2025-01-10 12:44:00,NY,mobile,1211,1,0 85 | 84,364.61,M123,2025-01-10 12:46:00,IL,mobile,1024,1,0 86 | 85,1589.36,M124,2025-01-10 12:48:00,IL,mobile,1579,0,0 87 | 86,1659.66,M125,2025-01-10 12:50:00,NY,mobile,1393,0,0 88 | 87,3661.55,M126,2025-01-10 12:52:00,IL,mobile,1066,1,0 89 | 88,3205.91,M127,2025-01-10 12:54:00,IL,mobile,1232,0,0 90 | 89,4441.7,M128,2025-01-10 12:56:00,IL,desktop,1108,0,0 91 | 90,2387.46,M129,2025-01-10 12:58:00,TX,tablet,1145,0,0 92 | 91,641.99,M100,2025-01-10 13:00:00,FL,mobile,1110,1,0 93 | 92,3580.56,M101,2025-01-10 13:02:00,CA,desktop,1227,1,0 94 | 93,3815.89,M102,2025-01-10 13:04:00,TX,desktop,1110,0,0 95 | 94,2828.32,M103,2025-01-10 13:06:00,IL,tablet,1469,1,0 96 | 95,3866.29,M104,2025-01-10 13:08:00,NY,mobile,1033,0,0 97 | 96,2494.29,M105,2025-01-10 13:10:00,IL,tablet,1622,0,0 98 | 97,2637.53,M106,2025-01-10 13:12:00,FL,mobile,1775,0,0 99 | 98,2166.33,M107,2025-01-10 13:14:00,IL,desktop,1935,0,0 100 | 99,175.82,M108,2025-01-10 13:16:00,NY,desktop,1368,1,0 101 | 100,584.06,M109,2025-01-10 13:18:00,FL,desktop,1747,1,0 102 | 101,205.57,M110,2025-01-10 13:20:00,IL,desktop,1594,1,0 103 | 102,3200.23,M111,2025-01-10 13:22:00,FL,tablet,1553,0,0 104 | 103,1606.06,M112,2025-01-10 13:24:00,CA,mobile,1424,0,1 105 | 104,2567.42,M113,2025-01-10 13:26:00,CA,mobile,1612,0,0 106 | 105,4542.45,M114,2025-01-10 13:28:00,IL,tablet,1517,1,0 107 | 106,1284.0,M115,2025-01-10 13:30:00,FL,mobile,1691,0,0 108 | 107,2081.4,M116,2025-01-10 13:32:00,NY,desktop,1281,1,0 109 | 108,3789.98,M117,2025-01-10 13:34:00,IL,mobile,1319,1,0 110 | 109,1182.55,M118,2025-01-10 13:36:00,CA,desktop,1737,1,0 111 | 110,431.05,M119,2025-01-10 13:38:00,CA,tablet,1442,1,1 112 | 111,1484.27,M120,2025-01-10 13:40:00,IL,mobile,1951,1,0 113 | 112,848.05,M121,2025-01-10 13:42:00,FL,tablet,1314,1,0 114 | 113,4652.0,M122,2025-01-10 13:44:00,CA,mobile,1876,0,1 115 | 114,4050.2,M123,2025-01-10 13:46:00,FL,desktop,1965,0,0 116 | 115,3185.35,M124,2025-01-10 13:48:00,CA,tablet,1740,1,1 117 | 116,4363.73,M125,2025-01-10 13:50:00,CA,mobile,1376,1,0 118 | 117,4028.18,M126,2025-01-10 13:52:00,TX,desktop,1288,0,0 119 | 118,973.52,M127,2025-01-10 13:54:00,CA,tablet,1436,1,0 120 | 119,4468.17,M128,2025-01-10 13:56:00,NY,tablet,1661,1,0 121 | 120,2719.74,M129,2025-01-10 13:58:00,IL,mobile,1276,0,0 122 | 121,4046.83,M100,2025-01-10 14:00:00,IL,mobile,1709,1,0 123 | 122,4485.65,M101,2025-01-10 14:02:00,FL,mobile,1581,1,0 124 | 123,1624.12,M102,2025-01-10 14:04:00,CA,desktop,1502,1,1 125 | 124,594.76,M103,2025-01-10 14:06:00,NY,mobile,1623,0,0 126 | 125,1178.28,M104,2025-01-10 14:08:00,FL,tablet,1515,0,0 127 | 126,2164.18,M105,2025-01-10 14:10:00,TX,tablet,1349,0,0 128 | 127,4099.17,M106,2025-01-10 14:12:00,FL,mobile,1842,1,0 129 | 128,4310.62,M107,2025-01-10 14:14:00,FL,mobile,1445,1,0 130 | 129,84.41,M108,2025-01-10 14:16:00,CA,tablet,1829,0,0 131 | 130,2578.2,M109,2025-01-10 14:18:00,TX,desktop,1349,1,0 132 | 131,2116.18,M110,2025-01-10 14:20:00,FL,mobile,1606,1,0 133 | 132,1149.43,M111,2025-01-10 14:22:00,NY,mobile,1663,1,0 134 | 133,643.33,M112,2025-01-10 14:24:00,NY,tablet,1822,1,0 135 | 134,1721.2,M113,2025-01-10 14:26:00,IL,mobile,1136,1,0 136 | 135,4717.4,M114,2025-01-10 14:28:00,TX,desktop,1758,0,0 137 | 136,1649.85,M115,2025-01-10 14:30:00,TX,tablet,1898,1,1 138 | 137,2618.01,M116,2025-01-10 14:32:00,IL,mobile,1242,0,0 139 | 138,3529.94,M117,2025-01-10 14:34:00,FL,tablet,1542,1,0 140 | 139,1849.97,M118,2025-01-10 14:36:00,TX,mobile,1039,0,0 141 | 140,4860.32,M119,2025-01-10 14:38:00,NY,mobile,1228,1,0 142 | 141,4814.11,M120,2025-01-10 14:40:00,NY,mobile,1547,0,1 143 | 142,1296.32,M121,2025-01-10 14:42:00,CA,desktop,1919,1,0 144 | 143,2511.38,M122,2025-01-10 14:44:00,TX,desktop,1222,0,0 145 | 144,1539.35,M123,2025-01-10 14:46:00,FL,tablet,1005,1,0 146 | 145,1459.96,M124,2025-01-10 14:48:00,IL,mobile,1321,0,0 147 | 146,232.59,M125,2025-01-10 14:50:00,IL,mobile,1467,1,1 148 | 147,3067.34,M126,2025-01-10 14:52:00,FL,desktop,1731,0,0 149 | 148,2538.26,M127,2025-01-10 14:54:00,CA,mobile,1074,0,0 150 | 149,304.82,M128,2025-01-10 14:56:00,IL,desktop,1003,1,0 151 | 150,1429.3,M129,2025-01-10 14:58:00,TX,mobile,1846,1,0 152 | 151,4545.92,M100,2025-01-10 15:00:00,CA,tablet,1645,0,0 153 | 152,1235.83,M101,2025-01-10 15:02:00,TX,mobile,1117,1,1 154 | 153,767.23,M102,2025-01-10 15:04:00,NY,mobile,1880,0,1 155 | 154,2472.79,M103,2025-01-10 15:06:00,CA,desktop,1605,0,0 156 | 155,4928.97,M104,2025-01-10 15:08:00,IL,mobile,1503,0,0 157 | 156,1248.17,M105,2025-01-10 15:10:00,CA,mobile,1997,1,0 158 | 157,3377.07,M106,2025-01-10 15:12:00,CA,desktop,1946,0,0 159 | 158,3820.02,M107,2025-01-10 15:14:00,CA,tablet,1573,0,0 160 | 159,1226.31,M108,2025-01-10 15:16:00,CA,tablet,1440,1,0 161 | 160,3654.67,M109,2025-01-10 15:18:00,TX,desktop,1193,1,1 162 | 161,1870.53,M110,2025-01-10 15:20:00,NY,desktop,1846,1,0 163 | 162,3179.91,M111,2025-01-10 15:22:00,FL,desktop,1714,1,0 164 | 163,3185.97,M112,2025-01-10 15:24:00,CA,desktop,1391,0,0 165 | 164,2702.08,M113,2025-01-10 15:26:00,IL,desktop,1025,0,0 166 | 165,496.93,M114,2025-01-10 15:28:00,CA,tablet,1434,0,0 167 | 166,4184.75,M115,2025-01-10 15:30:00,IL,tablet,1172,0,0 168 | 167,1637.86,M116,2025-01-10 15:32:00,TX,desktop,1299,1,0 169 | 168,973.27,M117,2025-01-10 15:34:00,IL,mobile,1644,0,0 170 | 169,251.84,M118,2025-01-10 15:36:00,FL,desktop,1325,0,0 171 | 170,2974.92,M119,2025-01-10 15:38:00,NY,mobile,1409,1,0 172 | 171,3403.94,M120,2025-01-10 15:40:00,IL,desktop,1117,0,0 173 | 172,132.11,M121,2025-01-10 15:42:00,IL,desktop,1835,0,0 174 | 173,2584.86,M122,2025-01-10 15:44:00,NY,tablet,1786,0,0 175 | 174,1171.15,M123,2025-01-10 15:46:00,FL,mobile,1723,0,0 176 | 175,3243.61,M124,2025-01-10 15:48:00,CA,mobile,1224,0,0 177 | 176,913.11,M125,2025-01-10 15:50:00,IL,tablet,1531,0,0 178 | 177,3470.14,M126,2025-01-10 15:52:00,NY,tablet,1112,1,0 179 | 178,1964.34,M127,2025-01-10 15:54:00,TX,tablet,1139,1,0 180 | 179,4686.81,M128,2025-01-10 15:56:00,NY,tablet,1558,0,0 181 | 180,730.73,M129,2025-01-10 15:58:00,TX,mobile,1000,0,0 182 | 181,1738.28,M100,2025-01-10 16:00:00,FL,mobile,1089,1,0 183 | 182,611.69,M101,2025-01-10 16:02:00,CA,desktop,1653,0,0 184 | 183,4627.23,M102,2025-01-10 16:04:00,NY,desktop,1319,0,0 185 | 184,4392.83,M103,2025-01-10 16:06:00,IL,tablet,1549,0,0 186 | 185,1326.81,M104,2025-01-10 16:08:00,FL,tablet,1804,1,0 187 | 186,3316.92,M105,2025-01-10 16:10:00,NY,tablet,1893,0,0 188 | 187,4095.25,M106,2025-01-10 16:12:00,IL,desktop,1138,1,0 189 | 188,2798.24,M107,2025-01-10 16:14:00,NY,desktop,1510,0,0 190 | 189,2671.77,M108,2025-01-10 16:16:00,TX,desktop,1867,1,0 191 | 190,1247.17,M109,2025-01-10 16:18:00,NY,desktop,1844,1,0 192 | 191,510.86,M110,2025-01-10 16:20:00,NY,desktop,1258,0,0 193 | 192,4491.22,M111,2025-01-10 16:22:00,NY,desktop,1672,1,0 194 | 193,4507.07,M112,2025-01-10 16:24:00,FL,desktop,1901,0,1 195 | 194,3183.85,M113,2025-01-10 16:26:00,NY,tablet,1689,1,0 196 | 195,1728.2,M114,2025-01-10 16:28:00,IL,tablet,1009,0,0 197 | 196,1778.59,M115,2025-01-10 16:30:00,TX,tablet,1260,0,0 198 | 197,3643.48,M116,2025-01-10 16:32:00,TX,tablet,1918,1,1 199 | 198,4490.7,M117,2025-01-10 16:34:00,NY,desktop,1649,0,0 200 | 199,4441.08,M118,2025-01-10 16:36:00,FL,mobile,1171,0,0 201 | 200,3910.38,M119,2025-01-10 16:38:00,FL,desktop,1897,1,0 202 | 201,3228.06,M120,2025-01-10 16:40:00,IL,mobile,1012,0,0 203 | 202,466.49,M121,2025-01-10 16:42:00,NY,tablet,1167,0,0 204 | 203,850.06,M122,2025-01-10 16:44:00,TX,desktop,1641,1,0 205 | 204,4497.84,M123,2025-01-10 16:46:00,FL,tablet,1595,1,0 206 | 205,3051.82,M124,2025-01-10 16:48:00,NY,desktop,1320,0,0 207 | 206,95.53,M125,2025-01-10 16:50:00,FL,tablet,1318,0,0 208 | 207,552.28,M126,2025-01-10 16:52:00,FL,mobile,1612,1,0 209 | 208,3334.33,M127,2025-01-10 16:54:00,TX,mobile,1328,1,0 210 | 209,75.05,M128,2025-01-10 16:56:00,CA,mobile,1784,0,0 211 | 210,846.0,M129,2025-01-10 16:58:00,IL,desktop,1776,1,0 212 | 211,2766.23,M100,2025-01-10 17:00:00,IL,mobile,1970,0,0 213 | 212,3474.88,M101,2025-01-10 17:02:00,TX,desktop,1910,0,0 214 | 213,3277.21,M102,2025-01-10 17:04:00,FL,mobile,1919,0,0 215 | 214,1160.13,M103,2025-01-10 17:06:00,NY,mobile,1549,0,0 216 | 215,3575.29,M104,2025-01-10 17:08:00,FL,desktop,1418,0,0 217 | 216,1224.38,M105,2025-01-10 17:10:00,TX,desktop,1605,1,0 218 | 217,1660.73,M106,2025-01-10 17:12:00,IL,mobile,1094,1,0 219 | 218,3745.13,M107,2025-01-10 17:14:00,FL,desktop,1816,1,1 220 | 219,3265.68,M108,2025-01-10 17:16:00,IL,mobile,1580,1,0 221 | 220,4253.66,M109,2025-01-10 17:18:00,NY,desktop,1317,0,0 222 | 221,3305.18,M110,2025-01-10 17:20:00,IL,tablet,1955,0,0 223 | 222,2863.13,M111,2025-01-10 17:22:00,IL,tablet,1235,0,0 224 | 223,513.69,M112,2025-01-10 17:24:00,CA,tablet,1945,0,1 225 | 224,1870.19,M113,2025-01-10 17:26:00,CA,tablet,1333,1,0 226 | 225,1362.75,M114,2025-01-10 17:28:00,CA,tablet,1884,0,0 227 | 226,1257.75,M115,2025-01-10 17:30:00,IL,mobile,1375,0,0 228 | 227,4866.4,M116,2025-01-10 17:32:00,TX,tablet,1458,1,1 229 | 228,1995.83,M117,2025-01-10 17:34:00,IL,tablet,1136,1,0 230 | 229,4465.63,M118,2025-01-10 17:36:00,TX,tablet,1929,1,0 231 | 230,3174.14,M119,2025-01-10 17:38:00,TX,tablet,1587,1,1 232 | 231,3984.32,M120,2025-01-10 17:40:00,CA,desktop,1994,0,1 233 | 232,2538.05,M121,2025-01-10 17:42:00,FL,mobile,1546,0,0 234 | 233,2905.67,M122,2025-01-10 17:44:00,NY,tablet,1512,1,0 235 | 234,2487.96,M123,2025-01-10 17:46:00,CA,tablet,1295,0,0 236 | 235,1016.45,M124,2025-01-10 17:48:00,CA,tablet,1319,0,0 237 | 236,3626.14,M125,2025-01-10 17:50:00,FL,mobile,1917,0,0 238 | 237,1439.82,M126,2025-01-10 17:52:00,NY,desktop,1571,1,0 239 | 238,170.36,M127,2025-01-10 17:54:00,IL,mobile,1831,0,0 240 | 239,3245.09,M128,2025-01-10 17:56:00,IL,desktop,1348,1,0 241 | 240,926.7,M129,2025-01-10 17:58:00,CA,tablet,1839,0,0 242 | 241,4705.27,M100,2025-01-10 18:00:00,NY,tablet,1778,0,0 243 | 242,4771.95,M101,2025-01-10 18:02:00,CA,mobile,1872,0,1 244 | 243,4578.58,M102,2025-01-10 18:04:00,TX,mobile,1228,1,0 245 | 244,1882.29,M103,2025-01-10 18:06:00,CA,desktop,1269,0,0 246 | 245,126.51,M104,2025-01-10 18:08:00,CA,desktop,1827,1,0 247 | 246,4645.18,M105,2025-01-10 18:10:00,IL,mobile,1797,1,0 248 | 247,2169.51,M106,2025-01-10 18:12:00,IL,desktop,1290,1,0 249 | 248,4834.94,M107,2025-01-10 18:14:00,IL,mobile,1724,0,0 250 | 249,4819.92,M108,2025-01-10 18:16:00,TX,desktop,1164,0,0 251 | 250,4272.4,M109,2025-01-10 18:18:00,IL,mobile,1004,0,0 252 | --------------------------------------------------------------------------------