解决干旱预测模型中LinearRegression的0样本ValueError问题
干旱预测算法ValueError解决方案
问题背景
构建干旱预测算法,输入起止年份、月份、城市后输出干旱指数柱状图,但运行时触发错误:
ValueError: Found array with 0 sample(s) (shape=(0, 5)) while a minimum of 1 is required by LinearRegression.
错误原因
问题出在predict_drought函数:调用predict_drought(best_model, 'Anuradhapura', 2030, 2040)时,grouped_data[(grouped_data['City'] == city) & (grouped_data['Year'].between(start_year, end_year))]返回空DataFrame。因为训练数据grouped_data中没有2030-2040年的该城市数据,导致输入模型的特征数组X_city样本量为0,无法满足模型预测的最低要求。
原代码逻辑错误:当前predict_drought仅从已有历史数据中筛选对应城市年份的数据做预测,而非用ARIMA生成的未来气候数据推导未来CDI。
解决方案
核心修正方向
先通过ARIMA按城市预测未来气候变量(温度、降水、蒸散量),再生成对应年份的特征数据输入回归模型,得到未来CDI预测结果。
修改后的代码示例
1. 调整ARIMA预测函数,支持按城市预测
def forecast_arima_by_city(data, city, column, order, steps): city_data = data[data['City'] == city] model = ARIMA(city_data[column], order=order) model_fit = model.fit() forecast = model_fit.forecast(steps=steps) return forecast
2. 重写predict_drought函数,实现未来预测逻辑
def predict_drought(model, city, start_year, end_year): # 生成目标年月序列 years = range(start_year, end_year + 1) months = range(1, 13) future_dates = [pd.to_datetime(f"{y}-{m}-01") for y in years for m in months] total_steps = len(future_dates) # 预测该城市未来气候变量 temp_forecast = forecast_arima_by_city(df, city, 'Average_temperature_month', order=(5,1,0), steps=total_steps) precip_forecast = forecast_arima_by_city(df, city, 'Average_precipitation_month', order=(5,1,0), steps=total_steps) evap_forecast = forecast_arima_by_city(df, city, 'Average_evapotranspiration_month', order=(5,1,0), steps=total_steps) # 构建模型输入特征 future_features = pd.DataFrame({ 'Year': [d.year for d in future_dates], 'Month': [d.month for d in future_dates], 'Average_temperature_month': temp_forecast.values, 'Average_precipitation_month': precip_forecast.values, 'Average_evapotranspiration_month': evap_forecast.values }) # 预测CDI并计算实际CDI(用于对比) future_features['Predicted_CDI'] = model.predict(future_features) future_features['Norm_Temperature'] = (future_features['Average_temperature_month'] - df['Average_temperature_month'].min()) / (df['Average_temperature_month'].max() - df['Average_temperature_month'].min()) future_features['Norm_Precipitation'] = (future_features['Average_precipitation_month'] - df['Average_precipitation_month'].min()) / (df['Average_precipitation_month'].max() - df['Average_precipitation_month'].min()) future_features['Norm_Evapotranspiration'] = (future_features['Average_evapotranspiration_month'] - df['Average_evapotranspiration_month'].min()) / (df['Average_evapotranspiration_month'].max() - df['Average_evapotranspiration_month'].min()) future_features['CDI'] = (future_features['Norm_Precipitation'] + (1 - future_features['Norm_Temperature']) + future_features['Norm_Evapotranspiration']) / 3 return future_features
3. 防御性编程补充(可选)
如果需要保留历史数据查询功能,可在原函数中加入空数据检查:
def predict_drought(model, city, start_year, end_year): city_data = grouped_data[(grouped_data['City'] == city) & (grouped_data['Year'].between(start_year, end_year))] if city_data.empty: print(f"Error: No data found for city {city} between {start_year} and {end_year}") return None X_city = city_data[['Year', 'Month', 'Average_temperature_month', 'Average_precipitation_month', 'Average_evapotranspiration_month']] predictions = model.predict(X_city) city_data['Predicted_CDI'] = predictions return city_data
关键说明
- 原代码逻辑误区:试图从不存在的未来年份历史数据中筛选特征,导致输入模型的特征为空。
- 正确的未来预测逻辑:先通过时间序列模型生成未来气候特征,再输入回归模型预测CDI。
内容的提问来源于stack exchange,提问作者Viper Rate
相关产品推荐
相关产品推荐

