使用Categorical Crossentropy后LSTM测试准确率仍为0的问题求助
基于日期预测访问量时LSTM测试准确率为0的问题解决
我尝试基于visit_date(日期类型)预测visit_count(整数类型),但测试准确率始终为0.0,训练结果如下:
输入数据样例
| index | visit_date | visit_count |
|---|---|---|
| 0 | 2020-07-09 | 12 |
| 1 | 2020-07-10 | 8 |
| 2 | 2020-07-11 | 14 |
| 3 | 2020-07-12 | 12 |
| 4 | 2020-07-13 | 6 |
完整代码
# seperating the date and count date = data3['visit_date'] count = data3['visit_count'] labels = pd.get_dummies(date) X_train, X_test, y_train, y_test = train_test_split(count, labels, test_size=0.2, random_state=42) # Split the data into training and testing sets # Define the LSTM model architecture embedding_dim = 100 model = Sequential() model.add(Embedding(100, embedding_dim, input_length=100)) model.add(SpatialDropout1D(0.2)) model.add(LSTM(100, dropout=0.2, recurrent_dropout=0.2)) model.add(Dense(len(labels.columns), activation='softmax')) model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy']) # Train the LSTM model epochs = 100 batch_size = 640 history = model.fit(X_train, y_train, epochs=epochs, batch_size=batch_size, validation_data=(X_test, y_test), verbose=2) loss, accuracy = model.evaluate(X_test, y_test, verbose=0) print("LSTM Test Accuracy:", accuracy)
尽管使用了categorical_crossentropy作为损失函数,LSTM模型的测试准确率仍为0,需要解决该问题。
问题根源分析
- 任务类型完全错误:你要做的是回归任务(预测整数型访问量),但代码按多分类任务构建:
- 用
pd.get_dummies(date)把日期转成独热编码当标签,实际标签应该是visit_count categorical_crossentropy损失和accuracy指标都是分类任务的配置,完全不匹配回归场景
- 用
- 输入输出颠倒:代码把
count(访问量)作为模型输入,date的独热编码作为标签,和「用日期预测访问量」的目标完全相反 - LSTM输入格式错误:LSTM要求输入是三维张量
(样本数, 时间步长, 特征数),但当前输入是一维的count,且Embedding层参数完全不符合日期特征的处理逻辑
修正方案
1. 调整任务定位与数据处理
把任务回归化,正确划分输入(日期特征)和标签(访问量),先将日期转成数值型特征:
import pandas as pd import numpy as np from sklearn.model_selection import train_test_split from tensorflow.keras.models import Sequential from tensorflow.keras.layers import LSTM, Dense # 日期转datetime格式并提取特征 data3['visit_date'] = pd.to_datetime(data3['visit_date']) data3['year'] = data3['visit_date'].dt.year data3['month'] = data3['visit_date'].dt.month data3['day'] = data3['visit_date'].dt.day data3['weekday'] = data3['visit_date'].dt.weekday # 定义输入特征和标签 X = data3[['year', 'month', 'day', 'weekday']].values y = data3['visit_count'].values # 划分训练测试集 X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42) # 调整LSTM输入格式为三维:(样本数, 时间步长, 特征数),这里时间步长设为1 X_train = X_train.reshape((X_train.shape[0], 1, X_train.shape[1])) X_test = X_test.reshape((X_test.shape[0], 1, X_test.shape[1]))
2. 构建回归型LSTM模型
# 定义回归模型,输出单个数值 model = Sequential() model.add(LSTM(50, input_shape=(X_train.shape[1], X_train.shape[2]))) model.add(Dense(1)) # 回归任务用均方误差(MSE)作为损失,平均绝对误差(MAE)作为评估指标 model.compile(optimizer='adam', loss='mse', metrics=['mae']) # 训练模型 history = model.fit(X_train, y_train, epochs=50, batch_size=32, validation_data=(X_test, y_test), verbose=2) # 评估模型 loss, mae = model.evaluate(X_test, y_test, verbose=0) print("LSTM Test MAE:", mae)
3. 进阶优化:时序滑动窗口
如果是用过去N天的数据预测下一天访问量,可构建滑动窗口数据集:
def create_dataset(X, y, time_steps=3): Xs, ys = [], [] for i in range(len(X) - time_steps): # 取过去time_steps天的特征 Xs.append(X[i:(i + time_steps)]) # 取第time_steps+1天的访问量作为标签 ys.append(y[i + time_steps]) return np.array(Xs), np.array(ys) # 用过去3天的特征预测第4天的访问量 X_seq, y_seq = create_dataset(X, y, time_steps=3) X_train_seq, X_test_seq, y_train_seq, y_test_seq = train_test_split(X_seq, y_seq, test_size=0.2, random_state=42) # 构建模型 model = Sequential() model.add(LSTM(50, input_shape=(X_train_seq.shape[1], X_train_seq.shape[2]))) model.add(Dense(1)) model.compile(optimizer='adam', loss='mse') history = model.fit(X_train_seq, y_train_seq, epochs=50, batch_size=32, validation_data=(X_test_seq, y_test_seq), verbose=2)
内容的提问来源于stack exchange,提问作者Sonny
相关产品推荐
相关产品推荐

