Spaces:
Configuration error
Configuration error
| 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 | |