title imbalanced classification credit card fraud detection fchollethttps twitter comfchollet date created 20190528 last modified 20200417 description demonstration of how to handle highly imbalanced classification problems accelerator gpu introduction this example looks at the kaggle credit card fraud detectionhttps www kaggle commlgulbcreditcardfraud dataset to demonstrate how to train a classification model on data with highly imbalanced classes first vectorize the csv data get the real data from https www kaggle commlgulbcreditcardfraud prepare a validation set analyze class imbalance in the targets normalize the data using training set statistics build a binary classification model train the model with classweight argument conclusions at the end of training out of 56 961 validation transactions we are correctly identifying 66 of them as fraudulent missing 9 fraudulent transactions at the cost of incorrectly flagging 441 legitimate transactions in the real world one would put an even higher weight on class 1 so as to reflect that false negatives are more costly than false positives next time your credit card gets declined in an online purchase this is why example available on huggingface trained model demo generic badgehttps img shields iobadge20modelimbalanced20classificationblack svghttps huggingface cokerasioimbalancedclassification generic badgehttps img shields iobadge20spacesimbalanced20classificationblack svghttps huggingface cospaceskerasiocreditcardfrauddetection introduction this example looks at the kaggle credit card fraud detection https www kaggle com mlg ulb creditcardfraud dataset to demonstrate how to train a classification model on data with highly imbalanced classes first vectorize the csv data get the real data from https www kaggle com mlg ulb creditcardfraud skip header prepare a validation set analyze class imbalance in the targets normalize the data using training set statistics build a binary classification model train the model with class_weight argument conclusions at the end of training out of 56 961 validation transactions we are correctly identifying 66 of them as fraudulent missing 9 fraudulent transactions at the cost of incorrectly flagging 441 legitimate transactions in the real world one would put an even higher weight on class 1 so as to reflect that false negatives are more costly than false positives next time your credit card gets declined in an online purchase this is why example available on huggingface trained model demo generic badge https img shields io badge 20model imbalanced 20classification black svg https huggingface co keras io imbalanced_classification generic badge https img shields io badge 20spaces imbalanced 20classification black svg https huggingface co spaces keras io credit_card_fraud_detection
import numpy as np
import keras


fname = "/Users/fchollet/Downloads/creditcard.csv"

all_features = []
all_targets = []
with open(fname) as f:
    for i, line in enumerate(f):
        if i == 0:
            print("HEADER:", line.strip())
            continue  
        fields = line.strip().split(",")
        all_features.append([float(v.replace('"', "")) for v in fields[:-1]])
        all_targets.append([int(fields[-1].replace('"', ""))])
        if i == 1:
            print("EXAMPLE FEATURES:", all_features[-1])

features = np.array(all_features, dtype="float32")
targets = np.array(all_targets, dtype="uint8")
print("features.shape:", features.shape)
print("targets.shape:", targets.shape)



num_val_samples = int(len(features) * 0.2)
train_features = features[:-num_val_samples]
train_targets = targets[:-num_val_samples]
val_features = features[-num_val_samples:]
val_targets = targets[-num_val_samples:]

print("Number of training samples:", len(train_features))
print("Number of validation samples:", len(val_features))



counts = np.bincount(train_targets[:, 0])
print(
    "Number of positive samples in training data: {} ({:.2f}% of total)".format(
        counts[1], 100 * float(counts[1]) / len(train_targets)
    )
)

weight_for_0 = 1.0 / counts[0]
weight_for_1 = 1.0 / counts[1]



mean = np.mean(train_features, axis=0)
train_features -= mean
val_features -= mean
std = np.std(train_features, axis=0)
train_features /= std
val_features /= std



model = keras.Sequential(
    [
        keras.layers.Dense(
            256, activation="relu", input_shape=(train_features.shape[-1],)
        ),
        keras.layers.Dense(256, activation="relu"),
        keras.layers.Dropout(0.3),
        keras.layers.Dense(256, activation="relu"),
        keras.layers.Dropout(0.3),
        keras.layers.Dense(1, activation="sigmoid"),
    ]
)
model.summary()



metrics = [
    keras.metrics.FalseNegatives(name="fn"),
    keras.metrics.FalsePositives(name="fp"),
    keras.metrics.TrueNegatives(name="tn"),
    keras.metrics.TruePositives(name="tp"),
    keras.metrics.Precision(name="precision"),
    keras.metrics.Recall(name="recall"),
]

model.compile(
    optimizer=keras.optimizers.Adam(1e-2),
    loss="binary_crossentropy",
    metrics=metrics,
)

callbacks = [
    keras.callbacks.ModelCheckpoint("fraud_model_at_epoch_{epoch}.keras")
]
class_weight = {0: weight_for_0, 1: weight_for_1}

model.fit(
    train_features,
    train_targets,
    batch_size=2048,
    epochs=30,
    verbose=2,
    callbacks=callbacks,
    validation_data=(val_features, val_targets),
    class_weight=class_weight,
)