基于Keras Conv1D的时间序列建模疑问:参数设置与低精度问题
Hey there! Let's break down your questions and fix the issues with your Conv1D time series setup step by step:
First, let's address your core questions
1. TrainX/TestX Reshaping & Input Shape
Your original reshaping logic is correct! For Conv1D in Keras, the required input shape is (number of time steps, number of features). Since you set look_back=1 (using 1 week of data to predict the next), reshaping to (samples, 1, 1) matches this requirement perfectly, and your input_shape=(1,1) is aligned with that.
2. Kernel Size Choice
This is where your setup misses the point of using Conv1D for time series. A kernel_size=1 means each filter only looks at a single time step—this is functionally identical to a dense layer, and you're not leveraging Conv1D's strength: capturing local temporal patterns (like how sales in week t relate to week t-1, t-2, etc.). You need to set kernel_size > 1 to let filters learn relationships across consecutive time steps.
Why Your Model Has Poor "Accuracy" (And How to Fix It)
First, a critical note: regression tasks (like sales forecasting) don't use "accuracy" as a metric. Your line print("Accuracy: %.2f%%" % (scores[1]*100)) is misleading—scores[1] is MAE (Mean Absolute Error), not a classification accuracy percentage. MAE measures average absolute difference between predictions and actual values, so a value of 0.1091 means your predictions are off by ~10.91% of the normalized data range, not 10.91% "correct".
Beyond that, here are key fixes to improve your model:
1. Increase Look Back (Time Steps)
Using only 1 week of data to predict the next is too limited for time series. Try a larger look_back (e.g., 4, 8, or 12 weeks) to let the model capture weekly/seasonal trends.
2. Adjust Kernel Size & Model Structure
- Remove
MaxPooling1D(pool_size=1): A pool size of 1 does nothing—it doesn't reduce the input shape, just adds unnecessary computation. - Use a meaningful
kernel_size: Iflook_back=4, trykernel_size=2or3to let filters learn patterns across 2-3 consecutive weeks. - Tune layer sizes: Your original
Dense(250)is likely overkill for this dataset and can cause overfitting.
3. Fix Evaluation Metrics
Report MSE and MAE directly, and optionally convert MAE back to the original sales scale to get a concrete sense of prediction error.
Modified Code Example
Here's an adjusted version of your code with these fixes:
from pandas import read_csv import matplotlib.pyplot as plt import numpy from keras.models import Sequential from keras.layers import Dense, Flatten, Conv1D, MaxPooling1D from sklearn.preprocessing import MinMaxScaler from sklearn.metrics import mean_squared_error def create_dataset(dataset, look_back=1): dataX, dataY = [], [] for i in range(len(dataset)-look_back): a = dataset[i:(i+look_back), 0] dataX.append(a) dataY.append(dataset[i + look_back, 0]) return numpy.array(dataX), numpy.array(dataY) seed = 7 numpy.random.seed(seed) # Load and preprocess data dataframe = read_csv('D:/MIS793/Dataset/Academic Dataset External 2/Python scripts/totalsale _byweek.csv', usecols=[1], engine='python') plt.plot(dataframe) plt.show() dataset = dataframe.values.astype('float32') scaler = MinMaxScaler(feature_range=(0, 1)) dataset = scaler.fit_transform(dataset) # Split train/test train_size = int(len(dataset) * 0.67) train, test = dataset[0:train_size,:], dataset[train_size:len(dataset),:] # Use 4 weeks of history to predict the next week look_back = 4 trainX, trainY = create_dataset(train, look_back) testX, testY = create_dataset(test, look_back) # Reshape for Conv1D: (samples, time steps, features) trainX = trainX.reshape(trainX.shape[0], trainX.shape[1], 1).astype('float32') testX = testX.reshape(testX.shape[0], testX.shape[1], 1).astype('float32') # Build improved model model = Sequential() # Input shape matches look_back (4) and 1 feature model.add(Conv1D(filters=32, kernel_size=2, padding='same', activation='relu', input_shape=(look_back, 1))) model.add(MaxPooling1D(pool_size=2)) # Compress time steps from 4 to 2 model.add(Flatten()) model.add(Dense(64, activation='relu')) model.add(Dense(1, activation='linear')) model.compile(loss='mse', optimizer='adam', metrics=['mae']) print(model.summary()) # Train with adjusted hyperparameters model.fit(trainX, trainY, validation_data=(testX, testY), epochs=50, batch_size=32) # Evaluate correctly mse, mae = model.evaluate(testX, testY, verbose=0) print(f"Test MSE: {mse:.4f}, Test MAE (normalized): {mae:.4f}") # Convert MAE back to original sales scale original_mae = mae * (scaler.data_max_[0] - scaler.data_min_[0]) print(f"Test MAE (original sales scale): {original_mae:.2f}")
Additional Tips
- Experiment with
look_backvalues: Try 8 or 12 to capture longer seasonal trends. - Add dropout: Insert
Dropout(0.2)after the Dense layer to reduce overfitting. - Try stacking Conv1D layers: Add a second
Conv1D(filters=16, kernel_size=2, activation='relu')after the first pooling layer for deeper pattern learning.
内容的提问来源于stack exchange,提问作者app_developer

