Inframat-x commited on
Commit
f862d3a
·
verified ·
1 Parent(s): 80fa737

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +22 -45
app.py CHANGED
@@ -1,7 +1,7 @@
1
  # ================================================================
2
  # Self-Sensing Concrete Assistant — Predictor (XGB) + Hybrid RAG
3
- # - Predictor tab: required fields marked with *
4
- # - Prediction fixed: NA is accepted for required categoricals
5
  # - RAG page-extraction regex fixed for [[PAGE=...]]
6
  # ================================================================
7
 
@@ -106,14 +106,7 @@ CATEGORICAL_COLS = {
106
  "Current Type"
107
  }
108
 
109
- OPTIONAL_FIELDS = {
110
- "Filler 2 Type",
111
- "Filler 2 Diameter (µm)",
112
- "Filler 2 Length (mm)",
113
- "Filler 2 Dimensionality",
114
- }
115
-
116
- # Required fields (as you specified earlier)
117
  REQUIRED_FIELDS = {
118
  "Filler 1 Type",
119
  "Filler 1 Diameter (µm)",
@@ -162,18 +155,21 @@ def _canon_cat(v: Any) -> str:
162
  return CANON_NA
163
  return s
164
 
 
 
 
 
 
 
 
 
 
165
  def _coerce_to_row(form_dict: dict) -> pd.DataFrame:
166
  row = {}
167
  for col in MAIN_VARIABLES:
168
  v = form_dict.get(col, None)
169
  if col in NUMERIC_COLS:
170
- if v in ("", None):
171
- row[col] = np.nan
172
- else:
173
- try:
174
- row[col] = float(v)
175
- except Exception:
176
- row[col] = np.nan
177
  elif col in CATEGORICAL_COLS:
178
  row[col] = _canon_cat(v)
179
  else:
@@ -181,33 +177,12 @@ def _coerce_to_row(form_dict: dict) -> pd.DataFrame:
181
  row[col] = s if s else CANON_NA
182
  return pd.DataFrame([row], columns=MAIN_VARIABLES)
183
 
184
- def _is_complete(form_dict: dict) -> bool:
185
- """
186
- FIX: For required *categoricals*, NA counts as 'provided' (acceptable),
187
- so users aren't blocked when NA is a legitimate choice.
188
- Numeric required fields must be non-NaN.
189
- """
190
- for col in REQUIRED_FIELDS:
191
- v = form_dict.get(col, None)
192
- if col in NUMERIC_COLS:
193
- try:
194
- if v in ("", None) or (isinstance(v, float) and np.isnan(v)):
195
- return False
196
- except Exception:
197
- return False
198
- else:
199
- # Required categoricals/text: accept any non-empty after canonicalization,
200
- # and accept CANON_NA as "provided".
201
- s = _canon_cat(v)
202
- if s == "" or s is None:
203
- return False
204
- return True
205
-
206
  def _align_columns_to_model(df: pd.DataFrame, mdl) -> pd.DataFrame:
207
  """Align incoming dataframe columns to the model's expected feature order."""
208
  try:
209
  feat = getattr(mdl, "feature_names_in_", None)
210
  if feat is not None and len(feat) > 0:
 
211
  for c in feat:
212
  if c not in df.columns:
213
  df[c] = np.nan
@@ -218,9 +193,13 @@ def _align_columns_to_model(df: pd.DataFrame, mdl) -> pd.DataFrame:
218
  return df
219
 
220
  def predict_fn(**kwargs):
221
- # Keep your contract: 0.0 if incomplete or on error
222
- if not _is_complete(kwargs):
223
- return 0.0
 
 
 
 
224
  mdl = _load_model_or_error()
225
  if mdl is None:
226
  return 0.0
@@ -233,9 +212,7 @@ def predict_fn(**kwargs):
233
  else:
234
  y = y_raw
235
  y = float(np.asarray(y).ravel()[0])
236
- if y < 0:
237
- y = 0.0
238
- return y
239
  except Exception as e:
240
  print(f"[Predict] {e}")
241
  traceback.print_exc()
 
1
  # ================================================================
2
  # Self-Sensing Concrete Assistant — Predictor (XGB) + Hybrid RAG
3
+ # - Easier conditions: no completion gate; always attempt prediction
4
+ # - Stable categoricals "NA"; feature alignment to model
5
  # - RAG page-extraction regex fixed for [[PAGE=...]]
6
  # ================================================================
7
 
 
106
  "Current Type"
107
  }
108
 
109
+ # (Labels with * remain; UI unchanged)
 
 
 
 
 
 
 
110
  REQUIRED_FIELDS = {
111
  "Filler 1 Type",
112
  "Filler 1 Diameter (µm)",
 
155
  return CANON_NA
156
  return s
157
 
158
+ def _to_float_or_nan(v):
159
+ if v in ("", None):
160
+ return np.nan
161
+ try:
162
+ # allow "1,234.5" by stripping commas
163
+ return float(str(v).replace(",", ""))
164
+ except Exception:
165
+ return np.nan
166
+
167
  def _coerce_to_row(form_dict: dict) -> pd.DataFrame:
168
  row = {}
169
  for col in MAIN_VARIABLES:
170
  v = form_dict.get(col, None)
171
  if col in NUMERIC_COLS:
172
+ row[col] = _to_float_or_nan(v)
 
 
 
 
 
 
173
  elif col in CATEGORICAL_COLS:
174
  row[col] = _canon_cat(v)
175
  else:
 
177
  row[col] = s if s else CANON_NA
178
  return pd.DataFrame([row], columns=MAIN_VARIABLES)
179
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
180
  def _align_columns_to_model(df: pd.DataFrame, mdl) -> pd.DataFrame:
181
  """Align incoming dataframe columns to the model's expected feature order."""
182
  try:
183
  feat = getattr(mdl, "feature_names_in_", None)
184
  if feat is not None and len(feat) > 0:
185
+ # add any missing columns as NaN, keep extras (model will ignore via transformer)
186
  for c in feat:
187
  if c not in df.columns:
188
  df[c] = np.nan
 
193
  return df
194
 
195
  def predict_fn(**kwargs):
196
+ """
197
+ SUPER-LENIENT: Always attempt prediction.
198
+ - No completeness checks
199
+ - Missing numerics -> NaN
200
+ - Categoricals -> canonical 'NA'
201
+ - If model missing or inference error -> return 0.0 (keeps UI stable)
202
+ """
203
  mdl = _load_model_or_error()
204
  if mdl is None:
205
  return 0.0
 
212
  else:
213
  y = y_raw
214
  y = float(np.asarray(y).ravel()[0])
215
+ return 0.0 if y < 0 else y
 
 
216
  except Exception as e:
217
  print(f"[Predict] {e}")
218
  traceback.print_exc()