Eric Spencer
projects
A group project for COMP 379: Machine Learning. It compares several machine learning algorithms for fraud detection on a dataset that has been anonymized and transformed with PCA.
https://colab.research.google.com/drive/1dP9ev-j5ZRE3_MmWzLhHxXAbEtG5qKbT?usp=sharing
import os
import subprocess
import numpy as np
import pandas as pd
from sklearn.model_selection import StratifiedKFold, cross_validate
from sklearn.preprocessing import StandardScaler
from imblearn.pipeline import Pipeline
from imblearn.over_sampling import SMOTE
from sklearn.linear_model import LogisticRegression
from sklearn.ensemble import RandomForestClassifier
from sklearn.svm import SVC
from xgboost import XGBClassifier
from lightgbm import LGBMClassifier
from sklearn.neighbors import KNeighborsClassifier
def download_dataset():
"""Download the Kaggle creditcardfraud dataset if not present."""
if not os.path.exists('creditcard.csv'):
print("→ Downloading dataset via Kaggle CLI...")
subprocess.run([
'kaggle', 'datasets', 'download',
'-d', 'mlg-ulb/creditcardfraud',
'-p', '.', '--unzip'
], check=True)
else:
print("→ creditcard.csv already exists, skipping download.")
# Run the download
download_dataset()
def load_data():
"""Load the CSV into a pandas DataFrame."""
return pd.read_csv('creditcard.csv')
# Load and preview
df = load_data()
df.head()
def compare_models(df):
# 1) Features & target
features = [f'V{i}' for i in range(1,29)] + ['Amount', 'Time']
X = df[features].values
y = df['Class'].values
# 2) Classifiers to compare
models = {
"LogisticRegression": LogisticRegression(max_iter=1000, class_weight='balanced'),
"RandomForest" : RandomForestClassifier(n_estimators=100, class_weight='balanced'),
"XGBoost" : XGBClassifier(use_label_encoder=False, eval_metric='logloss'),
"LightGBM" : LGBMClassifier(),
"SVM (RBF)" : SVC(kernel='rbf', probability=True, class_weight='balanced'),
"KNN" : KNeighborsClassifier(n_neighbors=5)
}
# 3) Pipeline builder
def make_pipeline(clf):
return Pipeline([
("smote", SMOTE(random_state=42)),
("scaler", StandardScaler()),
("classifier", clf)
])
# 4) Scoring metrics
scoring = {
"accuracy" : "accuracy",
"precision": "precision",
"recall" : "recall",
"f1" : "f1",
"roc_auc" : "roc_auc",
"pr_auc" : "average_precision"
}
# 5) Stratified 5-fold CV
cv = StratifiedKFold(n_splits=5, shuffle=True, random_state=42)
results = []
for name, clf in models.items():
print(f"Evaluating {name}...")
pipe = make_pipeline(clf)
cv_res = cross_validate(pipe, X, y,
cv=cv, scoring=scoring,
return_train_score=False, n_jobs=-1)
# Aggregate mean scores
row = {metric: np.mean(cv_res[f"test_{metric}"]) for metric in scoring}
row["model"] = name
results.append(row)
# 6) Results DataFrame
df_res = pd.DataFrame(results).set_index("model")
df_res = df_res.sort_values("roc_auc", ascending=False)
return df_res
# Run comparison and display results
results_df = compare_models(df)
print("=== Model Comparison Results ===")
results_df
Mean scores across a stratified 5-fold cross-validation, ordered by ROC AUC:
The Jupyter notebook above was Eric Spencer's individual contribution to the group project, along with the dataset visualizations in the notebook report.