Spaces:
Running
Running
Commit
·
9037654
1
Parent(s):
db023ce
Changes in deployment++
Browse files- main.py +1 -0
- routes/predictions.py +3 -2
- services/market_services.py +10 -12
main.py
CHANGED
|
@@ -12,6 +12,7 @@ origins = [
|
|
| 12 |
"http://localhost:5501",
|
| 13 |
"http://127.0.0.1:5500",
|
| 14 |
"http://localhost:5500",
|
|
|
|
| 15 |
]
|
| 16 |
|
| 17 |
app.add_middleware(
|
|
|
|
| 12 |
"http://localhost:5501",
|
| 13 |
"http://127.0.0.1:5500",
|
| 14 |
"http://localhost:5500",
|
| 15 |
+
"https://agro-vision-frontend.vercel.app"
|
| 16 |
]
|
| 17 |
|
| 18 |
app.add_middleware(
|
routes/predictions.py
CHANGED
|
@@ -264,7 +264,8 @@ def predict_commodity_price(commodity: str):
|
|
| 264 |
|
| 265 |
if not test_df.empty:
|
| 266 |
FEATURES = [col for col in test_df.columns if col != 'modal_price']
|
| 267 |
-
|
|
|
|
| 268 |
X_input = pd.DataFrame(test_df[FEATURES].values, columns=FEATURES, index=test_df.index)
|
| 269 |
|
| 270 |
predictions = model.predict(X_input)
|
|
@@ -286,7 +287,7 @@ def predict_commodity_price(commodity: str):
|
|
| 286 |
for date, row in daily_forecast_df.iterrows():
|
| 287 |
price = row['forecast']
|
| 288 |
|
| 289 |
-
# --- CRITICAL FIX: Handle NaN values
|
| 290 |
if pd.isna(price) or np.isnan(price):
|
| 291 |
final_price = None
|
| 292 |
else:
|
|
|
|
| 264 |
|
| 265 |
if not test_df.empty:
|
| 266 |
FEATURES = [col for col in test_df.columns if col != 'modal_price']
|
| 267 |
+
|
| 268 |
+
# FIX: Ensure DataFrame format for XGBoost
|
| 269 |
X_input = pd.DataFrame(test_df[FEATURES].values, columns=FEATURES, index=test_df.index)
|
| 270 |
|
| 271 |
predictions = model.predict(X_input)
|
|
|
|
| 287 |
for date, row in daily_forecast_df.iterrows():
|
| 288 |
price = row['forecast']
|
| 289 |
|
| 290 |
+
# --- CRITICAL FIX: Handle NaN values safely ---
|
| 291 |
if pd.isna(price) or np.isnan(price):
|
| 292 |
final_price = None
|
| 293 |
else:
|
services/market_services.py
CHANGED
|
@@ -13,7 +13,7 @@ models = {}
|
|
| 13 |
if os.path.exists(MODELS_DIR):
|
| 14 |
for model_file in os.listdir(MODELS_DIR):
|
| 15 |
if model_file.endswith('.pkl'):
|
| 16 |
-
# Normalize filename to commodity name
|
| 17 |
commodity_name = model_file.replace('.pkl', '').replace('_', '/')
|
| 18 |
try:
|
| 19 |
models[commodity_name] = joblib.load(os.path.join(MODELS_DIR, model_file))
|
|
@@ -48,8 +48,8 @@ def _create_features(df):
|
|
| 48 |
df['rolling_mean_30'] = df['modal_price'].shift(1).rolling(window=30).mean()
|
| 49 |
df['rolling_std_30'] = df['modal_price'].shift(1).rolling(window=30).std()
|
| 50 |
|
| 51 |
-
#
|
| 52 |
-
#
|
| 53 |
return df
|
| 54 |
|
| 55 |
def get_market_prediction(model, df_full, commodity, last_known_date):
|
|
@@ -69,8 +69,7 @@ def get_market_prediction(model, df_full, commodity, last_known_date):
|
|
| 69 |
# 3. Combine history and future placeholder
|
| 70 |
df_extended = pd.concat([df_daily, future_df])
|
| 71 |
|
| 72 |
-
# 4.
|
| 73 |
-
# We take the last 50 valid days to determine feature columns
|
| 74 |
valid_sample = _create_features(df_daily.tail(50)).dropna()
|
| 75 |
FEATURES = [col for col in valid_sample.columns if col != 'modal_price']
|
| 76 |
|
|
@@ -81,25 +80,24 @@ def get_market_prediction(model, df_full, commodity, last_known_date):
|
|
| 81 |
# Safety check: ensure we have enough data for 30-day rolling window
|
| 82 |
if len(subset) < 35: continue
|
| 83 |
|
| 84 |
-
# Generate features
|
| 85 |
featured_subset = _create_features(subset)
|
| 86 |
|
| 87 |
-
#
|
| 88 |
if date not in featured_subset.index: continue
|
| 89 |
featured_row = featured_subset.loc[[date]]
|
| 90 |
|
| 91 |
-
# ---
|
| 92 |
-
# XGBoost requires a DataFrame with specific column names.
|
| 93 |
-
# We explicitly recreate the DataFrame to ensure headers are present.
|
| 94 |
try:
|
|
|
|
| 95 |
X_input = pd.DataFrame(featured_row[FEATURES].values, columns=FEATURES, index=featured_row.index)
|
|
|
|
| 96 |
prediction = model.predict(X_input)[0]
|
| 97 |
df_extended.loc[date, 'modal_price'] = prediction
|
| 98 |
except Exception as e:
|
| 99 |
-
#
|
| 100 |
print(f"Prediction error for {date}: {e}")
|
| 101 |
break
|
| 102 |
-
# --- CRITICAL FIX END ---
|
| 103 |
|
| 104 |
daily_forecast_df = df_extended.loc[future_dates].copy()
|
| 105 |
daily_forecast_df.rename(columns={'modal_price': 'forecast'}, inplace=True)
|
|
|
|
| 13 |
if os.path.exists(MODELS_DIR):
|
| 14 |
for model_file in os.listdir(MODELS_DIR):
|
| 15 |
if model_file.endswith('.pkl'):
|
| 16 |
+
# Normalize filename to commodity name
|
| 17 |
commodity_name = model_file.replace('.pkl', '').replace('_', '/')
|
| 18 |
try:
|
| 19 |
models[commodity_name] = joblib.load(os.path.join(MODELS_DIR, model_file))
|
|
|
|
| 48 |
df['rolling_mean_30'] = df['modal_price'].shift(1).rolling(window=30).mean()
|
| 49 |
df['rolling_std_30'] = df['modal_price'].shift(1).rolling(window=30).std()
|
| 50 |
|
| 51 |
+
# CRITICAL: Do NOT dropna() here. We need the future row (which has NaNs) to survive
|
| 52 |
+
# so we can predict it.
|
| 53 |
return df
|
| 54 |
|
| 55 |
def get_market_prediction(model, df_full, commodity, last_known_date):
|
|
|
|
| 69 |
# 3. Combine history and future placeholder
|
| 70 |
df_extended = pd.concat([df_daily, future_df])
|
| 71 |
|
| 72 |
+
# 4. Determine feature columns from a valid historical sample
|
|
|
|
| 73 |
valid_sample = _create_features(df_daily.tail(50)).dropna()
|
| 74 |
FEATURES = [col for col in valid_sample.columns if col != 'modal_price']
|
| 75 |
|
|
|
|
| 80 |
# Safety check: ensure we have enough data for 30-day rolling window
|
| 81 |
if len(subset) < 35: continue
|
| 82 |
|
| 83 |
+
# Generate features
|
| 84 |
featured_subset = _create_features(subset)
|
| 85 |
|
| 86 |
+
# Get the row for the prediction date
|
| 87 |
if date not in featured_subset.index: continue
|
| 88 |
featured_row = featured_subset.loc[[date]]
|
| 89 |
|
| 90 |
+
# --- FIX: Ensure strict DataFrame format for XGBoost ---
|
|
|
|
|
|
|
| 91 |
try:
|
| 92 |
+
# Reconstruct DataFrame with explicit columns to satisfy XGBoost
|
| 93 |
X_input = pd.DataFrame(featured_row[FEATURES].values, columns=FEATURES, index=featured_row.index)
|
| 94 |
+
|
| 95 |
prediction = model.predict(X_input)[0]
|
| 96 |
df_extended.loc[date, 'modal_price'] = prediction
|
| 97 |
except Exception as e:
|
| 98 |
+
# If prediction fails, we break. The NaNs will remain and be handled by the route.
|
| 99 |
print(f"Prediction error for {date}: {e}")
|
| 100 |
break
|
|
|
|
| 101 |
|
| 102 |
daily_forecast_df = df_extended.loc[future_dates].copy()
|
| 103 |
daily_forecast_df.rename(columns={'modal_price': 'forecast'}, inplace=True)
|