-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathdata_generation.py
More file actions
93 lines (75 loc) · 4.65 KB
/
Copy pathdata_generation.py
File metadata and controls
93 lines (75 loc) · 4.65 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
import pandas as pd
import numpy as np
import random
from datetime import datetime, timedelta
def generate_synthetic_data(num_customers=1000, random_seed=42):
"""
Simulates realistic customer financial data with behavioral patterns leading to financial stress.
"""
np.random.seed(random_seed)
random.seed(random_seed)
data = []
for i in range(1, num_customers + 1):
customer_id = f"CUST_{i:04d}"
# Base attributes
monthly_salary = np.random.choice([25000, 35000, 50000, 75000, 100000, 150000]) * np.random.uniform(0.9, 1.1)
loan_emi_amount = monthly_salary * np.random.uniform(0.1, 0.4) # EMI is 10-40% of salary
# Determine if this customer will miss a payment (approx 45% financial stress rate for demonstration)
missed_payment = 1 if np.random.random() < 0.45 else 0
if missed_payment:
# Behavioral patterns for financially stressed customers
salary_credit_delay_days = np.random.randint(3, 15) # Salary is delayed
weekly_bank_balance = monthly_salary * np.random.uniform(0.01, 0.1) # Low balance
upi_tx_count = np.random.randint(30, 80) # High number of small transactions
upi_tx_amount = monthly_salary * np.random.uniform(0.6, 0.9)
spending_food = monthly_salary * np.random.uniform(0.3, 0.5)
spending_entertainment = monthly_salary * np.random.uniform(0.01, 0.05) # Cut down on entertainment
spending_bills = monthly_salary * np.random.uniform(0.1, 0.2)
utility_payment_timing = np.random.choice(["Late", "On-Time"], p=[0.7, 0.3])
atm_withdrawals_count = np.random.randint(5, 12) # Increased ATM withdrawals
atm_withdrawals_amount = monthly_salary * np.random.uniform(0.15, 0.3)
upi_lending_apps_flag = 1 if np.random.random() < 0.6 else 0 # High chance of using lending apps
# Trend features over last 4 weeks (simulated)
balance_change_wow_pct = np.random.uniform(-0.5, -0.1) # Balance dropping 10-50% week over week
spending_drop_ratio = np.random.uniform(0.3, 0.8) # Significant drop in overall spending
else:
# Behavioral patterns for healthy customers
salary_credit_delay_days = np.random.randint(-1, 2) # Salary on time or 1 day late/early
weekly_bank_balance = monthly_salary * np.random.uniform(0.3, 1.5) # Healthy balance
upi_tx_count = np.random.randint(15, 50)
upi_tx_amount = monthly_salary * np.random.uniform(0.3, 0.6)
spending_food = monthly_salary * np.random.uniform(0.15, 0.3)
spending_entertainment = monthly_salary * np.random.uniform(0.1, 0.25)
spending_bills = monthly_salary * np.random.uniform(0.1, 0.2)
utility_payment_timing = np.random.choice(["Early", "On-Time", "Late"], p=[0.4, 0.5, 0.1])
atm_withdrawals_count = np.random.randint(0, 4)
atm_withdrawals_amount = monthly_salary * np.random.uniform(0.01, 0.05)
upi_lending_apps_flag = 1 if np.random.random() < 0.1 else 0 # Low chance
balance_change_wow_pct = np.random.uniform(-0.05, 0.1) # Stable or growing balance
spending_drop_ratio = np.random.uniform(0.9, 1.1) # Consistent spending
data.append({
"customer_id": customer_id,
"monthly_salary": round(monthly_salary, 2),
"salary_credit_delay_days": salary_credit_delay_days,
"weekly_bank_balance": round(weekly_bank_balance, 2),
"upi_tx_count": upi_tx_count,
"upi_tx_amount": round(upi_tx_amount, 2),
"spending_food": round(spending_food, 2),
"spending_entertainment": round(spending_entertainment, 2),
"spending_bills": round(spending_bills, 2),
"utility_payment_timing": utility_payment_timing,
"atm_withdrawals_count": atm_withdrawals_count,
"atm_withdrawals_amount": round(atm_withdrawals_amount, 2),
"loan_emi_amount": round(loan_emi_amount, 2),
"upi_lending_apps_flag": upi_lending_apps_flag,
"balance_change_wow_pct": round(balance_change_wow_pct, 4),
"spending_drop_ratio": round(spending_drop_ratio, 4),
"missed_payment": missed_payment
})
df = pd.DataFrame(data)
return df
if __name__ == "__main__":
df = generate_synthetic_data()
print(df.head())
print(f"Total shape: {df.shape}")
print(f"Financial Stress Rate: {df['missed_payment'].mean():.2%}")