Python加载pickle模型预测时报'DataFrame'无'predict'属性错误解决
丰田卡罗拉价格预测LSTM模型加载报错解决方案
错误根本原因
- 序列化存储对象错误:生成pickle文件时保存的是预测结果DataFrame
df_forecast,而非训练好的LSTM模型对象,所以加载后得到的是DataFrame,自然没有predict方法 - 语法错误:报错代码中调用
predict方法使用了方括号model.predict[x_test],方法调用需用圆括号 - 标准化逻辑不匹配:训练时使用
StandardScaler做数据标准化,预测时换成了MinMaxScaler,且直接调用fit_transform重新拟合,会导致数据分布与训练时不一致,预测结果失效 - 输入维度不匹配:LSTM要求输入为三维格式
(样本数, 历史时间步长, 特征数),当前的x_test是二维结构,即使模型加载正确也会报错
修复步骤
1. 重新生成正确的模型存储文件
Keras模型优先使用自带的save方法存储,兼容性更好,同时要保存训练时拟合好的标准化器,替换原pickle生成代码:
# 训练完成后执行 # 保存LSTM模型 model.save('toyota_corolla_lstm.h5') # 保存训练阶段拟合好的标准化器 import joblib joblib.dump(scaler, 'standard_scaler.pkl')
2. 修正加载预测代码
import pandas as pd import numpy as np from tensorflow.keras.models import load_model import joblib # 加载训练好的模型和标准化器 model = load_model('toyota_corolla_lstm.h5') scaler = joblib.load('standard_scaler.pkl') # 读取测试数据 x = pd.read_csv('Dataset.csv') cols = list(x)[1:2] df_test = x[cols].astype(float) # 用训练好的标准化器做转换,不要重新fit df_test_scaled = scaler.transform(df_test) # 构造符合LSTM要求的三维输入,和训练时的历史步长n_past保持一致(训练时取值为14) n_past = 14 testX = [] for i in range(n_past, len(df_test_scaled) + 1): testX.append(df_test_scaled[i - n_past:i, :]) testX = np.array(testX) # 调用predict方法预测 y_pred_scaled = model.predict(testX) # 逆标准化得到真实价格 pred_copies = np.repeat(y_pred_scaled, df_test.shape[1], axis=-1) y_pred = scaler.inverse_transform(pred_copies)[:, 0]
额外优化建议
- 训练代码中两次编译模型,第二次误用了分类任务的损失函数
categorical_crossentropy,价格预测属于回归任务,应该保留第一次的mse损失函数 - 回归任务用
accuracy作为评估指标没有意义,可替换为mae(平均绝对误差)等回归类指标
内容的提问来源于stack exchange,提问作者Anupama Balasooriya
相关产品推荐
相关产品推荐

