bank-fraud / tests /unit /test_features.py
root
init
942b115
Raw
History Blame Contribute Delete
2.82 kB
import pandas as pd
from app.features import FEATURE_COLUMNS, engineer_features
def _raw_frame() -> pd.DataFrame:
return pd.DataFrame(
[
# step, type, amount, nameOrig, oldOrig, newOrig, nameDest, oldDest, newDest
[1, "TRANSFER", 100.0, "C1", 100.0, 0.0, "C2", 0.0, 0.0],
[2, "PAYMENT", 50.0, "C1", 0.0, 0.0, "M1", 0.0, 0.0],
[3, "CASH_OUT", 200.0, "C3", 500.0, 300.0, "C2", 1000.0, 1200.0],
],
columns=[
"step",
"type",
"amount",
"nameOrig",
"oldbalanceOrg",
"newbalanceOrig",
"nameDest",
"oldbalanceDest",
"newbalanceDest",
],
)
def test_engineer_features_adds_all_feature_columns():
out = engineer_features(_raw_frame())
for col in FEATURE_COLUMNS:
assert col in out.columns
def test_type_one_hot_is_mutually_exclusive():
out = engineer_features(_raw_frame())
type_cols = [c for c in out.columns if c.startswith("type_")]
assert (out[type_cols].sum(axis=1) == 1).all()
def test_orig_zero_after_flag_detects_fraud_like_pattern():
out = engineer_features(_raw_frame())
row = out[out["nameOrig"] == "C1"].iloc[0]
assert row["orig_zero_after_flag"] == 1
def test_dest_is_merchant_flag():
out = engineer_features(_raw_frame())
row = out[out["nameDest"] == "M1"].iloc[0]
assert row["dest_is_merchant"] == 1
row2 = out[out["nameDest"] == "C2"].iloc[0]
assert row2["dest_is_merchant"] == 0
def test_velocity_only_counts_prior_transactions():
df = pd.DataFrame(
[
[1, "PAYMENT", 10.0, "C1", 100.0, 90.0, "M1", 0.0, 0.0],
[2, "PAYMENT", 10.0, "C1", 90.0, 80.0, "M1", 0.0, 0.0],
[3, "PAYMENT", 10.0, "C1", 80.0, 70.0, "M1", 0.0, 0.0],
],
columns=[
"step",
"type",
"amount",
"nameOrig",
"oldbalanceOrg",
"newbalanceOrig",
"nameDest",
"oldbalanceDest",
"newbalanceDest",
],
)
out = engineer_features(df)
counts = out.sort_values("step")["orig_prior_txn_count"].tolist()
assert counts == [0, 1, 2]
def test_balance_consistency_flags_true_when_arithmetic_matches():
df = pd.DataFrame(
[[1, "CASH_OUT", 100.0, "C1", 500.0, 400.0, "C2", 200.0, 300.0]],
columns=[
"step",
"type",
"amount",
"nameOrig",
"oldbalanceOrg",
"newbalanceOrig",
"nameDest",
"oldbalanceDest",
"newbalanceDest",
],
)
out = engineer_features(df)
assert out.iloc[0]["orig_balance_consistent"] == 1
assert out.iloc[0]["dest_balance_consistent"] == 1