UCS2014 commited on
Commit
a68e4d3
·
verified ·
1 Parent(s): be0d41a

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +29 -14
app.py CHANGED
@@ -1,4 +1,4 @@
1
- # app_ucs.py — ST_GeoMech_UCS (Unified workflow like Tc)
2
 
3
  import io, json, os, base64, math
4
  from pathlib import Path
@@ -15,7 +15,7 @@ import matplotlib.pyplot as plt
15
  from matplotlib.ticker import FuncFormatter
16
 
17
  import plotly.graph_objects as go
18
- from sklearn.metrics import mean_squared_error, mean_absolute_error
19
 
20
  # =========================
21
  # Constants / Defaults
@@ -138,6 +138,18 @@ def pearson_r(y_true, y_pred) -> float:
138
  if np.all(a == a[0]) or np.all(p == p[0]): return float("nan")
139
  return float(np.corrcoef(a, p)[0, 1])
140
 
 
 
 
 
 
 
 
 
 
 
 
 
141
  @st.cache_resource(show_spinner=False)
142
  def load_model(model_path: str):
143
  return joblib.load(model_path)
@@ -321,7 +333,7 @@ def build_export_workbook(selected: list[str] | None = None) -> tuple[bytes|None
321
  sheets["Validation_Summary"] = _round_numeric(pd.DataFrame([sv])); order.append("Validation_Summary")
322
  oor_tbl = res.get("oor_tbl")
323
  if oor_tbl is not None and isinstance(oor_tbl, pd.DataFrame) and not oor_tbl.empty:
324
- sheets["Validation_ORE"] = _round_numeric(oor_tbl.reset_index(drop=True)); order.append("Validation_ORE")
325
 
326
  # Prediction
327
  if ("Prediction" in (selected or _available_sections())) and "PredictOnly" in res:
@@ -406,7 +418,6 @@ def cross_plot_static(actual, pred):
406
  a = pd.Series(actual, dtype=float)
407
  p = pd.Series(pred, dtype=float)
408
 
409
- # Use data-driven limits with a small pad (or keep your fixed 6000–10000 if you prefer)
410
  lo = float(min(a.min(), p.min()))
411
  hi = float(max(a.max(), p.max()))
412
  pad = 0.03 * (hi - lo if hi > lo else 1.0)
@@ -707,14 +718,14 @@ if st.session_state.app_step == "dev":
707
 
708
  st.session_state.results["Train"]=tr; st.session_state.results["Test"]=te
709
  st.session_state.results["m_train"]={
710
- "R": pearson_r(tr[TARGET], tr[PRED_COL]),
711
  "RMSE": rmse(tr[TARGET], tr[PRED_COL]),
712
- "MAE": mean_absolute_error(tr[TARGET], tr[PRED_COL])
713
  }
714
  st.session_state.results["m_test"]={
715
- "R": pearson_r(te[TARGET], te[PRED_COL]),
716
  "RMSE": rmse(te[TARGET], te[PRED_COL]),
717
- "MAE": mean_absolute_error(te[TARGET], te[PRED_COL])
718
  }
719
 
720
  tr_min = tr[FEATURES].min().to_dict(); tr_max = tr[FEATURES].max().to_dict()
@@ -723,12 +734,14 @@ if st.session_state.app_step == "dev":
723
 
724
  def _dev_block(df, m):
725
  c1,c2,c3 = st.columns(3)
726
- c1.metric("R", f"{m['R']:.3f}"); c2.metric("RMSE", f"{m['RMSE']:.2f}"); c3.metric("MAE", f"{m['MAE']:.2f}")
 
 
727
  st.markdown("""
728
  <div style='text-align: left; font-size: 0.8em; color: #6b7280; margin-top: -16px; margin-bottom: 8px;'>
729
  <strong>R:</strong> Pearson Correlation Coefficient<br>
730
  <strong>RMSE:</strong> Root Mean Square Error<br>
731
- <strong>MAE:</strong> Mean Absolute Error
732
  </div>
733
  """, unsafe_allow_html=True)
734
  col_track, col_cross = st.columns([2, 3], gap="large")
@@ -785,9 +798,9 @@ if st.session_state.app_step == "validate":
785
  lambda r:", ".join([c for c,v in r.items() if v]), axis=1
786
  )
787
  st.session_state.results["m_val"]={
788
- "R": pearson_r(df[TARGET], df[PRED_COL]),
789
  "RMSE": rmse(df[TARGET], df[PRED_COL]),
790
- "MAE": mean_absolute_error(df[TARGET], df[PRED_COL])
791
  }
792
  st.session_state.results["sv_val"]={"n":len(df), "pred_min":float(df[PRED_COL].min()), "pred_max":float(df[PRED_COL].max()), "oor":oor_pct}
793
  st.session_state.results["oor_tbl"]=tbl
@@ -795,12 +808,14 @@ if st.session_state.app_step == "validate":
795
  if "Validate" in st.session_state.results:
796
  m = st.session_state.results["m_val"]
797
  c1,c2,c3 = st.columns(3)
798
- c1.metric("R", f"{m['R']:.3f}"); c2.metric("RMSE", f"{m['RMSE']:.2f}"); c3.metric("MAE", f"{m['MAE']:.2f}")
 
 
799
  st.markdown("""
800
  <div style='text-align: left; font-size: 0.8em; color: #6b7280; margin-top: -16px; margin-bottom: 8px;'>
801
  <strong>R:</strong> Pearson Correlation Coefficient<br>
802
  <strong>RMSE:</strong> Root Mean Square Error<br>
803
- <strong>MAE:</strong> Mean Absolute Error
804
  </div>
805
  """, unsafe_allow_html=True)
806
 
 
1
+ # app_ucs.py — ST_GeoMech_UCS (Unified workflow like Tc) — MAPE instead of MAE
2
 
3
  import io, json, os, base64, math
4
  from pathlib import Path
 
15
  from matplotlib.ticker import FuncFormatter
16
 
17
  import plotly.graph_objects as go
18
+ from sklearn.metrics import mean_squared_error # MAE removed
19
 
20
  # =========================
21
  # Constants / Defaults
 
138
  if np.all(a == a[0]) or np.all(p == p[0]): return float("nan")
139
  return float(np.corrcoef(a, p)[0, 1])
140
 
141
+ def mape(y_true, y_pred, eps: float = 1e-8) -> float:
142
+ """
143
+ Mean Absolute Percentage Error in PERCENT.
144
+ Ignores rows where |y_true| < eps to avoid division blowups.
145
+ """
146
+ a = np.asarray(y_true, dtype=float)
147
+ p = np.asarray(y_pred, dtype=float)
148
+ denom = np.where(np.abs(a) < eps, np.nan, np.abs(a))
149
+ pct = np.abs(a - p) / denom * 100.0
150
+ val = np.nanmean(pct)
151
+ return float(val) if np.isfinite(val) else float("nan")
152
+
153
  @st.cache_resource(show_spinner=False)
154
  def load_model(model_path: str):
155
  return joblib.load(model_path)
 
333
  sheets["Validation_Summary"] = _round_numeric(pd.DataFrame([sv])); order.append("Validation_Summary")
334
  oor_tbl = res.get("oor_tbl")
335
  if oor_tbl is not None and isinstance(oor_tbl, pd.DataFrame) and not oor_tbl.empty:
336
+ sheets["Validation_OOR"] = _round_numeric(oor_tbl.reset_index(drop=True)); order.append("Validation_OOR")
337
 
338
  # Prediction
339
  if ("Prediction" in (selected or _available_sections())) and "PredictOnly" in res:
 
418
  a = pd.Series(actual, dtype=float)
419
  p = pd.Series(pred, dtype=float)
420
 
 
421
  lo = float(min(a.min(), p.min()))
422
  hi = float(max(a.max(), p.max()))
423
  pad = 0.03 * (hi - lo if hi > lo else 1.0)
 
718
 
719
  st.session_state.results["Train"]=tr; st.session_state.results["Test"]=te
720
  st.session_state.results["m_train"]={
721
+ "R": pearson_r(tr[TARGET], tr[PRED_COL]),
722
  "RMSE": rmse(tr[TARGET], tr[PRED_COL]),
723
+ "MAPE": mape(tr[TARGET], tr[PRED_COL])
724
  }
725
  st.session_state.results["m_test"]={
726
+ "R": pearson_r(te[TARGET], te[PRED_COL]),
727
  "RMSE": rmse(te[TARGET], te[PRED_COL]),
728
+ "MAPE": mape(te[TARGET], te[PRED_COL])
729
  }
730
 
731
  tr_min = tr[FEATURES].min().to_dict(); tr_max = tr[FEATURES].max().to_dict()
 
734
 
735
  def _dev_block(df, m):
736
  c1,c2,c3 = st.columns(3)
737
+ c1.metric("R", f"{m['R']:.3f}")
738
+ c2.metric("RMSE", f"{m['RMSE']:.2f}")
739
+ c3.metric("MAPE (%)", f"{m['MAPE']:.2f}%")
740
  st.markdown("""
741
  <div style='text-align: left; font-size: 0.8em; color: #6b7280; margin-top: -16px; margin-bottom: 8px;'>
742
  <strong>R:</strong> Pearson Correlation Coefficient<br>
743
  <strong>RMSE:</strong> Root Mean Square Error<br>
744
+ <strong>MAPE:</strong> Mean Absolute Percentage Error (percent of actual; rows with near-zero actuals are ignored).
745
  </div>
746
  """, unsafe_allow_html=True)
747
  col_track, col_cross = st.columns([2, 3], gap="large")
 
798
  lambda r:", ".join([c for c,v in r.items() if v]), axis=1
799
  )
800
  st.session_state.results["m_val"]={
801
+ "R": pearson_r(df[TARGET], df[PRED_COL]),
802
  "RMSE": rmse(df[TARGET], df[PRED_COL]),
803
+ "MAPE": mape(df[TARGET], df[PRED_COL])
804
  }
805
  st.session_state.results["sv_val"]={"n":len(df), "pred_min":float(df[PRED_COL].min()), "pred_max":float(df[PRED_COL].max()), "oor":oor_pct}
806
  st.session_state.results["oor_tbl"]=tbl
 
808
  if "Validate" in st.session_state.results:
809
  m = st.session_state.results["m_val"]
810
  c1,c2,c3 = st.columns(3)
811
+ c1.metric("R", f"{m['R']:.3f}")
812
+ c2.metric("RMSE", f"{m['RMSE']:.2f}")
813
+ c3.metric("MAPE (%)", f"{m['MAPE']:.2f}%")
814
  st.markdown("""
815
  <div style='text-align: left; font-size: 0.8em; color: #6b7280; margin-top: -16px; margin-bottom: 8px;'>
816
  <strong>R:</strong> Pearson Correlation Coefficient<br>
817
  <strong>RMSE:</strong> Root Mean Square Error<br>
818
+ <strong>MAPE:</strong> Mean Absolute Percentage Error (percent of actual; rows with near-zero actuals are ignored).
819
  </div>
820
  """, unsafe_allow_html=True)
821