henriquebap commited on
Commit
c92b8d9
·
1 Parent(s): ca004d8

fix(app): make predict robust to feature count mismatches, avoid ValueError

Browse files
Files changed (1) hide show
  1. app.py +27 -6
app.py CHANGED
@@ -120,14 +120,35 @@ def load_or_train(strict: bool = False):
120
  return "Modelo salvo não encontrado. Exporte via notebook 07 e garanta o arquivo em data/models/wine_quality_regressor.joblib."
121
  return train()
122
 
123
- def predict(fixed_acidity, volatile_acidity, citric_acid, residual_sugar, chlorides,
124
- free_sulfur_dioxide, total_sulfur_dioxide, density, pH, sulphates, alcohol):
 
 
 
 
 
125
  if model is None:
126
  load_or_train()
127
- x = pd.DataFrame([[
128
- fixed_acidity, volatile_acidity, citric_acid, residual_sugar, chlorides,
129
- free_sulfur_dioxide, total_sulfur_dioxide, density, pH, sulphates, alcohol
130
- ]], columns=feature_cols)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
131
  pred = float(model.predict(x)[0])
132
  return f"{pred:.2f} (arredondado: {int(round(pred))})"
133
 
 
120
  return "Modelo salvo não encontrado. Exporte via notebook 07 e garanta o arquivo em data/models/wine_quality_regressor.joblib."
121
  return train()
122
 
123
+ def predict(*values):
124
+ """Make a single prediction from UI inputs, robust to feature count mismatches.
125
+
126
+ Aligns provided values to the model's expected number of features to avoid
127
+ shape/column mismatches when the persisted model was trained with a
128
+ different feature set than the current UI defaults.
129
+ """
130
  if model is None:
131
  load_or_train()
132
+
133
+ # Determine how many features the model expects
134
+ expected_n = getattr(model, "n_features_in_", None)
135
+ cols = list(feature_cols)
136
+ if expected_n is None:
137
+ expected_n = len(cols) if len(cols) > 0 else len(values)
138
+
139
+ # Trim or pad the provided values to match the expected feature count
140
+ vals = list(values)[:expected_n]
141
+ if len(vals) < expected_n:
142
+ vals += [np.nan] * (expected_n - len(vals))
143
+
144
+ # Use feature names if available for the expected size; otherwise, fall back
145
+ # to generated placeholder names. Most sklearn estimators ignore column names.
146
+ if len(cols) >= expected_n:
147
+ used_cols = cols[:expected_n]
148
+ else:
149
+ used_cols = cols + [f"f{i}" for i in range(len(cols), expected_n)]
150
+
151
+ x = pd.DataFrame([vals], columns=used_cols)
152
  pred = float(model.predict(x)[0])
153
  return f"{pred:.2f} (arredondado: {int(round(pred))})"
154