EMD+CNN时间序列预测:IMF数量不一致问题及技术咨询
时间序列预测EMD+CNN维度不匹配问题与技术疑问
我正在开展一项时间序列预测项目,计划采用EMD+CNN技术进行输出预测。对训练数据执行EMD分解后,得到了14个本征模函数(IMF),据此构建了维度为(30100, 20, 14, 1)的CNN神经网络(其中20代表窗口大小)。但对测试数据进行EMD分解时仅得到11个IMF,这种数量不一致导致CNN模型运行报错。当前使用Python中的EMD-signal库,提出两个技术问题:
- 是否存在强制EMD分解生成固定数量IMF的方法?
- 若不存在该方法,是否有自动选择重要IMF的可行方案?
相关代码实现
import numpy as np import matplotlib.pyplot as plt from scipy.signal import stft from keras.models import Sequential from PyEMD import EMD spectrogrames = EMD(data2.values[:,-1],max_imf=10) #spectrogram, res = ssa.get_imfs_and_residue() print(spectrogrames.shape) print(spectrogrames.shape) spectrogrames = spectrogrames.T print(spectrogrames.shape) import pickle import joblib #print(train_size) sf=data2.values print(data2.shape) # Concatenate the two NumPy arrays horizontally spectrogram=spectrogrames[:,:11] concatenated_array = np.hstack((spectrogram,sf)) # Convert the concatenated array back to a DataFrame with appropriate column names df1 = pd.DataFrame(concatenated_array) #training=sf[:train_size,:] #testing=sf[train_size:,:] print(df1.shape) ahead=0 def signal_segmentation(dt,steps,ahead): end=0 start=0 x=[] y=[] for i in range(steps,dt.shape[0]): if i+ahead<dt.shape[0]: x.append(dt[i-steps:i,0:-1]) y.append(dt[i+ahead,-1]) return np.array(x),np.array(y) from tensorflow.keras.losses import MeanAbsoluteError from keras.regularizers import L1L2 from keras.layers import LeakyReLU from tensorflow.keras.layers import LSTM, Dense, BatchNormalization from keras import regularizers n_hours=20 features=df1.shape[1]-1 #sf=data2.values #train, test = train_test_split(sf, test_size=0.1, random_state=0) #print(train.shape) #print(test.shape) #x_train,y_train=signal_segmentation(train,n_hours,ahead) #x_test,y_test=signal_segmentation(test,n_hours,ahead) #print(x_train.shape) #x_train, x_test = b[:train_size,:], b[train_size:,:] #y_train, y_test = n[:train_size], n[train_size:] #x_train=np.reshape(x_train,(x_train.shape[0],x_train.shape[1]*x_train.shape[2])) #x_test=np.reshape(x_test,(x_test.shape[0],x_test.shape[1]*x_test.shape[2])) #scaler = MinMaxScaler((0,1)).fit(x_train) #x_train=scaler.transform(x_train) #x_test=scaler.transform(x_test) #print(x_train.shape)sss #x_train=np.array(x_train, dtype=np.float64) #y_train=np.array(y_train, dtype=np.float64) #x_test=np.array(x_test, dtype=np.float64) #y_test=np.array(y_test, dtype=np.float64) #x_train=np.reshape(x_train,(x_train.shape[0],n_hours,features)) #x_test=np.reshape(x_test,(x_test.shape[0],n_hours,features)) #y_train=np.array(y_train).reshape((len(y_train),1)) #y_test=np.array(y_test).reshape((len(y_test),1)) from sklearn.model_selection import train_test_split print("steps:",n_hours) x,y=signal_segmentation(df1.values,n_hours,ahead) x_trainlstm, x_testlstm, y_trainlstm, y_testlstm = train_test_split(x, y, test_size=0.1)
问题解答
1. 强制EMD生成固定数量IMF的方法
EMD是自适应分解算法,无法严格强制生成固定数量的IMF,因为IMF的生成依赖信号自身的局部极值特性,当无法分解出满足定义的分量时会自动停止。但可通过调整参数尽可能逼近目标数量:
- 设置
max_imf上限:在PyEMD.EMD中,max_imf参数可指定IMF的最大生成数量,但这只是上限,若信号提前满足停止条件,实际生成数量仍会小于该值。 - 调松停止准则:降低
sd_threshold(默认0.2),让分解更深入,尽可能生成更多IMF。示例:emd = EMD(sd_threshold=0.1, max_imf=14) imfs = emd(data)
需注意,以上方法无法保证每次都生成恰好指定数量的IMF,仅能尽可能接近。
2. 自动选择重要IMF的可行方案
当训练与测试数据IMF数量不一致时,更可靠的方案是筛选关键IMF,统一模型输入维度:
- 方差贡献度筛选:计算每个IMF的方差占原始信号总方差的比例,保留贡献度高的前N个IMF(如前11个)。代码示例:
emd = EMD() imfs = emd(data) # 计算各IMF方差贡献 variances = np.var(imfs, axis=1) total_var = variances.sum() contrib_ratios = variances / total_var # 取贡献度前11的IMF top_k = 11 top_indices = np.argsort(contrib_ratios)[::-1][:top_k] selected_imfs = imfs[top_indices] - 预测相关性筛选:用简单模型(如线性回归、LSTM)单独预测每个IMF对应的分量,选择预测误差最小的前N个IMF,这类分量对最终预测贡献更大。
- 能量贡献筛选:计算每个IMF的能量(平方和),保留能量占比高的分量,原理与方差贡献类似,高能量分量通常包含更多有效信息。
- 统一训练阶段IMF数量:训练时就只保留测试数据能生成的IMF数量(如11个),而非训练数据的14个,从根源避免维度不匹配。
内容的提问来源于stack exchange,提问作者nad66
相关产品推荐
相关产品推荐

