MrThinker098 commited on
Commit
72058ba
·
verified ·
1 Parent(s): 76c145e

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +13 -28
app.py CHANGED
@@ -1,15 +1,12 @@
1
  import numpy as np
2
  import pandas as pd
3
- from datetime import datetime
4
  import gradio as gr
5
 
6
- # --------------------------
7
- # Helpers
8
- # --------------------------
9
  def month_start(ts):
10
  """Return the first day of the month as Timestamp."""
11
  ts = pd.to_datetime(ts)
12
- return ts.to_period("M").to_timestamp() # safe, gives YYYY-MM-01
13
 
14
  def prep_monthly_features(df: pd.DataFrame) -> pd.DataFrame:
15
  """
@@ -17,15 +14,13 @@ def prep_monthly_features(df: pd.DataFrame) -> pd.DataFrame:
17
  amount: +inflows, -spend
18
  """
19
  df = df.copy()
20
-
21
- # Parse dates safely
22
  df["date"] = pd.to_datetime(df["date"], errors="coerce")
23
  df = df.dropna(subset=["date"])
24
 
25
- # Month bucket (always the 1st of month)
26
  df["month"] = df["date"].apply(month_start)
27
 
28
- # Monthly aggregates
29
  month_agg = (
30
  df.groupby("month", as_index=False)
31
  .agg(
@@ -36,7 +31,7 @@ def prep_monthly_features(df: pd.DataFrame) -> pd.DataFrame:
36
  )
37
  )
38
 
39
- # Category counts per month (diversity proxy)
40
  cats = (
41
  df.assign(cnt=1)
42
  .pivot_table(index="month", columns="category", values="cnt",
@@ -46,7 +41,7 @@ def prep_monthly_features(df: pd.DataFrame) -> pd.DataFrame:
46
 
47
  out = month_agg.merge(cats, left_on="month", right_index=True, how="left").fillna(0)
48
 
49
- # Sort and create target/lag features
50
  out = out.sort_values("month").reset_index(drop=True)
51
  out["target_next_spend"] = out["spend"].shift(-1)
52
 
@@ -81,24 +76,21 @@ def train_model(monthly_df: pd.DataFrame):
81
  return model, feature_cols, mae
82
 
83
  def predict_next(monthly_df: pd.DataFrame, model, feature_cols):
84
- # Predict next month using last row features
85
  last = monthly_df.iloc[[-1]][feature_cols]
86
  pred = float(model.predict(last)[0])
87
 
88
- # Overspend risk (more negative spend = higher spend)
89
  p10 = float(np.percentile(monthly_df["spend"], 10))
90
  risk = "High" if pred <= p10 else "Low"
91
 
92
- # Format next month label
93
  last_month = monthly_df["month"].iloc[-1]
94
  next_month = month_start(last_month + pd.offsets.MonthBegin(1)).strftime("%Y-%m")
95
  return next_month, pred, risk
96
 
97
- # --------------------------
98
- # App logic
99
- # --------------------------
100
  def load_or_demo(file, budget):
101
- # Demo data if no file
102
  if file is None:
103
  rng = pd.date_range("2024-01-01", periods=365, freq="D")
104
  cats = ["groceries", "rent", "utilities", "fun", "transport"]
@@ -108,7 +100,6 @@ def load_or_demo(file, budget):
108
  for d in rng:
109
  if d.day == 1:
110
  rows.append({"date": d, "amount": income, "category": "income", "income": income})
111
- # Poisson number of daily spend txns
112
  for _ in range(rng_seed.poisson(2)):
113
  amt = -float(rng_seed.choice([15, 25, 40, 60, 120, 300], p=[.25, .25, .2, .15, .1, .05]))
114
  rows.append({"date": d, "amount": amt, "category": rng_seed.choice(cats), "income": income})
@@ -127,7 +118,7 @@ def load_or_demo(file, budget):
127
  model, feats, mae = train_model(m)
128
  next_m, spend_pred, risk = predict_next(m, model, feats)
129
 
130
- # Budget evaluation
131
  try:
132
  budget_val = float(budget) if budget not in (None, "") else 0.0
133
  except Exception:
@@ -156,26 +147,20 @@ def safe_run(file, budget):
156
  print("TRACEBACK:\n", traceback.format_exc())
157
  raise gr.Error(str(e))
158
 
159
- # --------------------------
160
- # Gradio UI
161
- # --------------------------
162
  with gr.Blocks(title="Retail Finance: Spend Forecast") as demo:
163
  gr.Markdown(
164
  "## Retail Finance Spend Forecaster\n"
165
  "Upload your transactions CSV (columns: `date, amount, category, income`) or use demo data. "
166
  "The model forecasts **next-month spend** and flags **overspend risk**."
167
  )
168
- with gr.Row():
169
- file = gr.File(label="Upload CSV (optional)")
170
- budget = gr.Number(value=2500, label="Monthly budget (positive number)")
171
- income_override = gr.Number(value=None, label="Expected income next month (optional)")
172
  with gr.Row():
173
  file = gr.File(label="Upload CSV (optional)")
174
  budget = gr.Number(value=2500, label="Monthly budget (positive number)")
175
  btn = gr.Button("Run Forecast")
176
  summary = gr.Dataframe(label="Summary")
177
  monthly_table = gr.Dataframe(label="Monthly aggregates used by the model")
178
- btn.click(safe_run, inputs=[file, budget, income_override], outputs=[summary, monthly_table])
179
 
180
  if __name__ == "__main__":
181
  demo.launch()
 
1
  import numpy as np
2
  import pandas as pd
 
3
  import gradio as gr
4
 
5
+ # -------- helpers --------
 
 
6
  def month_start(ts):
7
  """Return the first day of the month as Timestamp."""
8
  ts = pd.to_datetime(ts)
9
+ return ts.to_period("M").to_timestamp() # YYYY-MM-01
10
 
11
  def prep_monthly_features(df: pd.DataFrame) -> pd.DataFrame:
12
  """
 
14
  amount: +inflows, -spend
15
  """
16
  df = df.copy()
 
 
17
  df["date"] = pd.to_datetime(df["date"], errors="coerce")
18
  df = df.dropna(subset=["date"])
19
 
20
+ # month bucket
21
  df["month"] = df["date"].apply(month_start)
22
 
23
+ # monthly aggregates
24
  month_agg = (
25
  df.groupby("month", as_index=False)
26
  .agg(
 
31
  )
32
  )
33
 
34
+ # category counts per month (diversity proxy)
35
  cats = (
36
  df.assign(cnt=1)
37
  .pivot_table(index="month", columns="category", values="cnt",
 
41
 
42
  out = month_agg.merge(cats, left_on="month", right_index=True, how="left").fillna(0)
43
 
44
+ # target & lags
45
  out = out.sort_values("month").reset_index(drop=True)
46
  out["target_next_spend"] = out["spend"].shift(-1)
47
 
 
76
  return model, feature_cols, mae
77
 
78
  def predict_next(monthly_df: pd.DataFrame, model, feature_cols):
 
79
  last = monthly_df.iloc[[-1]][feature_cols]
80
  pred = float(model.predict(last)[0])
81
 
82
+ # overspend risk (more negative spend = higher spend)
83
  p10 = float(np.percentile(monthly_df["spend"], 10))
84
  risk = "High" if pred <= p10 else "Low"
85
 
86
+ # next month label
87
  last_month = monthly_df["month"].iloc[-1]
88
  next_month = month_start(last_month + pd.offsets.MonthBegin(1)).strftime("%Y-%m")
89
  return next_month, pred, risk
90
 
91
+ # -------- app logic --------
 
 
92
  def load_or_demo(file, budget):
93
+ # demo data if no file
94
  if file is None:
95
  rng = pd.date_range("2024-01-01", periods=365, freq="D")
96
  cats = ["groceries", "rent", "utilities", "fun", "transport"]
 
100
  for d in rng:
101
  if d.day == 1:
102
  rows.append({"date": d, "amount": income, "category": "income", "income": income})
 
103
  for _ in range(rng_seed.poisson(2)):
104
  amt = -float(rng_seed.choice([15, 25, 40, 60, 120, 300], p=[.25, .25, .2, .15, .1, .05]))
105
  rows.append({"date": d, "amount": amt, "category": rng_seed.choice(cats), "income": income})
 
118
  model, feats, mae = train_model(m)
119
  next_m, spend_pred, risk = predict_next(m, model, feats)
120
 
121
+ # budget evaluation
122
  try:
123
  budget_val = float(budget) if budget not in (None, "") else 0.0
124
  except Exception:
 
147
  print("TRACEBACK:\n", traceback.format_exc())
148
  raise gr.Error(str(e))
149
 
150
+ # -------- UI --------
 
 
151
  with gr.Blocks(title="Retail Finance: Spend Forecast") as demo:
152
  gr.Markdown(
153
  "## Retail Finance Spend Forecaster\n"
154
  "Upload your transactions CSV (columns: `date, amount, category, income`) or use demo data. "
155
  "The model forecasts **next-month spend** and flags **overspend risk**."
156
  )
 
 
 
 
157
  with gr.Row():
158
  file = gr.File(label="Upload CSV (optional)")
159
  budget = gr.Number(value=2500, label="Monthly budget (positive number)")
160
  btn = gr.Button("Run Forecast")
161
  summary = gr.Dataframe(label="Summary")
162
  monthly_table = gr.Dataframe(label="Monthly aggregates used by the model")
163
+ btn.click(safe_run, inputs=[file, budget], outputs=[summary, monthly_table])
164
 
165
  if __name__ == "__main__":
166
  demo.launch()