1. SSA(Sparrow Search Algorithm)
简介:
SSA是一种新兴的群体智能优化算法,模拟麻雀觅食行为。麻雀群体中的“发现者”负责寻找食物,并将信息传递给“追随者”,后者根据这一信息进行觅食。SSA通过这种合作机制寻找最优解。
SSA在优化问题中可以视为一种元启发式算法,擅长在复杂搜索空间中找到全局最优解,而不是陷入局部最优。
详细功能:
- 全局搜索: SSA通过模拟麻雀群体的觅食行为,在整个参数空间内进行全局搜索,确保不会错过最佳参数组合。
- 动态更新: 麻雀群体的成员不断更新自己的位置,模拟觅食过程中对环境的适应和调整。这种动态更新机制有助于找到最优解。
- 避免局部最优: 通过多样化个体行为,SSA避免了模型陷入局部最优,提高了找到全局最优解的可能性。
应用:
- 超参数优化: SSA可用于优化深度学习模型的超参数,如CNN的卷积核大小、LSTM的隐藏层数、学习率等,从而提高模型性能。
2. CNN(卷积神经网络)
简介:
CNN是深度学习中最常用的模型之一,主要用于处理具有局部结构信息的数据(如图像)。它通过卷积操作提取输入数据中的局部特征,并通过层叠的方式逐层提取更高层次的特征。
在时间序列预测中,CNN可以用于捕捉序列数据中的局部模式,如周期性模式或趋势。
详细功能:
- 卷积层: 卷积层通过卷积核(filter)对输入数据进行滑动窗口操作,提取局部特征。卷积核的大小决定了提取特征的范围。
- 池化层: 池化层用于降低特征图的维度,减少计算量,同时保留最重要的特征。这通常通过最大池化(Max Pooling)或平均池化(Average Pooling)来实现。
- 激活函数: 通常使用ReLU(Rectified Linear Unit)作为激活函数,非线性地处理特征,提升模型的表达能力。
- 全连接层: 最终的全连接层将提取到的特征映射到输出层,用于分类或回归任务。
应用:
- 特征提取: 在时间序列预测中,CNN能够自动从数据中提取重要的局部模式,如短期波动、周期性信号等。
- 高效计算: CNN的并行计算能力能够加速模型训练,特别是在处理大规模时间序列数据时表现优越。
3. LSTM(长短期记忆网络)
简介:
LSTM是一种特殊的RNN,设计用于解决传统RNN在处理长时间序列时出现的梯度消失问题。通过引入记忆单元和门机制,LSTM能够在训练过程中有效保留重要的历史信息,并逐步遗忘无关信息。
详细功能:
- 记忆单元(Cell State): 记忆单元是LSTM的核心,用于存储长期信息。它通过“遗忘门”(Forget Gate)、“输入门”(Input Gate)和“输出门”(Output Gate)来更新和控制信息流。
- 遗忘门: 决定记忆单元中的哪些信息应该被遗忘。这有助于防止记忆单元过度累积无关信息。
- 输入门: 决定新的输入信息应如何影响记忆单元。通过控制信息的输入,LSTM能够将新的重要信息加入记忆单元。
- 输出门: 决定当前时间步的输出应该基于哪些记忆信息。这最终影响LSTM的预测结果。
应用:
- 长期依赖捕捉: 在时间序列预测中,LSTM能够有效捕捉长期的依赖关系,例如长期趋势或长期记忆效应。
- 处理非线性和噪声数据: LSTM擅长处理复杂的时间序列数据,能够适应非线性特性并具有一定的抗噪声能力。
4.结合的优势
-
SSA优化超参数: 通过SSA优化CNN和LSTM的超参数,模型能够在最优参数组合下运行,从而提升预测性能。SSA的全局搜索和动态更新机制使得找到最佳超参数更加可靠。
-
CNN提取局部特征: CNN在时间序列数据中提取局部模式,如短期波动、周期性信号,这些特征能够为LSTM提供丰富的输入信息,进一步提升LSTM的预测能力。
-
LSTM捕捉长期依赖: LSTM能够在接收CNN提取的局部特征后,进一步挖掘数据中的长期依赖关系,使得模型不仅能够捕捉到短期变化,还能识别出长期趋势。
-
模型的鲁棒性和预测精度: 通过SSA的优化,CNN的局部特征提取能力与LSTM的长期依赖捕捉能力相结合,整个模型能够在复杂的时间序列预测任务中表现出色,具有较强的鲁棒性和更高的预测精度。
5.代码
SSA优化
def SSA(P,T,Pt,Tt):
M=2 # M最大迭代次数
pop=2 #pop种群数量 #M和pop这两个参数设置的越大 相对来说寻优出来适应度越好效果越好 ,但是算法运行花的时间就越多
P_percent=0.2
dim=3 #搜索维度,
# 第一个是学习率[0.001 0.01]
# 第二个是神经元个数[10-100]
# 第三个batch_size
Lb=[0.001,10,10]
Ub=[0.01 ,100,45]
#M 迭代次数
#pop 麻雀种群数量
#dim 寻优维度
#P_percent 麻雀在生产者的比例
pNum = round( pop * P_percent )#pNum是生产者
x=np.zeros((pop,dim))
fit=np.zeros((pop,1))
# 种群初始化
for i in range(pop):
for j in range(dim):
# 初始化种群,遍历每个个体的每个维度。
if j == 0: # 学习率是小数 其他的是整数
# 对于第一个参数(假设是学习率),在其上下界之间随机选择一个浮点数。
x[i][j] = (Ub[j] - Lb[j]) * np.random.rand() + Lb[j]
else:
# 对于其他参数,随机选择一个整数。
x[i][j] = np.random.randint(Lb[j], Ub[j])
# 评估个体的适应度
fit[i] = fun(x[i, :], P, T, Pt, Tt)
# 使用fun函数计算每个个体的适应度。
# 初始化个体历史最优值和位置
pFit = fit.copy()
pX = x.copy()
# 复制当前适应度和位置作为个体的历史最优。
# 初始化全局最优
fMin = np.min(fit)
bestI = np.argmin(fit)
bestX = x[bestI, :].copy()
# 找出最优适应度及其对应的个体位置。
# 初始化记录收敛曲线和每次迭代的最优结果
Convergence_curve = np.zeros((M,))
result = np.zeros((M, dim))
# 创建记录收敛曲线和每次迭代最优结果的数组。
for t in range(M):
# 准备进行迭代。
# 对适应度进行排序,找出最差个体
sortIndex = np.argsort(pFit.reshape(-1,)).reshape(-1,)
fmax = np.max(pFit)
B = np.argmax(pFit)
worse = x[B, :].copy()
# 记录最差个体的位置。
r2 = np.random.rand()
# 生成一个随机数,用于后续计算。
## 这一部分为发现者(探索者)的位置更新
if r2<0.8:#%预警值较小,说明没有捕食者出现
for i in range(pNum):#r2小于0.8时发现者改变位置
r1=np.random.rand()
x[sortIndex[i],:]=pX[sortIndex[i],:]*np.exp(-i/(r1*M))
x[sortIndex[i],:]=boundary(x[sortIndex[i],:],Lb,Ub)
temp=fun( x[ sortIndex[ i ], : ],P,T,Pt,Tt )
fit[ sortIndex[ i ] ] = temp# 计算新的适应度值
else:#预警值较大,说明有捕食者出现威胁到了种群的安全,需要去其它地方觅食
for i in range(pNum):#r2大于0.8时发现者改变位置
r1=np.random.rand()
x[sortIndex[i],:]=pX[sortIndex[i],:] + np.random.normal()*np.ones((1,dim))
x[sortIndex[i],:]=boundary(x[sortIndex[i],:],Lb,Ub)
fit[ sortIndex[ i ] ] = fun( x[ sortIndex[ i ], : ],P,T,Pt,Tt )# 计算新的适应度值
bestII=np.argmin( fit )
bestXX = x[ bestII, : ].copy()
##这一部分为加入者(追随者)的位置更新
for i in range(pNum + 1,pop):#剩下的个体变化
A=np.floor(np.random.rand(1,dim)*2)*2-1
if i > pop/2: #这个代表这部分麻雀处于十分饥饿的状态(因为它们的能量很低,也是是适应度值很差),需要到其它地方觅食
x[ sortIndex[i ], : ]=np.random.normal()*np.exp((worse-pX[sortIndex[ i ], : ])/(i**2))
else:#这一部分追随者是围绕最好的发现者周围进行觅食,其间也有可能发生食物的争夺,使其自己变成生产者
x[ sortIndex[ i ], : ]=bestXX+np.abs( pX[ sortIndex[ i ], : ]-bestXX).dot(A.T*(A*A.T)**(-1))*np.ones((1,dim))
x[sortIndex[ i ], : ] = boundary( x[ sortIndex[ i ], : ],Lb,Ub)#判断边界是否超出
fit[ sortIndex[ i ] ] = fun( x[ sortIndex[ i ], : ],P,T,Pt,Tt )#计算适应度值
#这一部分为意识到危险(注意这里只是意识到了危险,不代表出现了真正的捕食者)的麻雀的位置更新
c=random.sample(range(sortIndex.shape[0]),sortIndex.shape[0])#这个的作用是在种群中随机产生其位置(也就是这部分的麻雀位置一开始是随机的,意识到危险了要进行位置移动,
b=sortIndex[np.array(c)[0:round(pop*0.2)]].reshape(-1,)
for j in range(b.shape[0]):
if pFit[sortIndex[b[j]]]> fMin:#处于种群外围的麻雀的位置改变
x[ sortIndex[ b[j] ], : ]=bestX+np.random.normal(1,dim)*(np.abs( pX[ sortIndex[ b[j] ], : ] -bestX))
else: #处于种群中心的麻雀的位置改变
x[ sortIndex[ b[j] ], : ] =pX[ sortIndex[ b[j] ], : ] + (2*np.random.rand()-1)*(np.abs(pX[ sortIndex[ b[j] ], : ]-worse)) / (pFit[sortIndex[b[j]]]-fmax+1e-50)
x[ sortIndex[b[j] ], : ] = boundary( x[ sortIndex[b[j]], : ],Lb,Ub)
fit[ sortIndex[b[j] ] ] = fun( x[ sortIndex[b[j] ], : ],P,T,Pt,Tt )#计算适应度值
# 这部分是最终的最优解更新
for i in range(pop):
if fit[ i ] < pFit[ i ] :
pFit[ i ] = fit[ i ].copy()
pX[ i, : ] = x[ i, : ].copy()
if pFit[i ] < fMin:
fMin= pFit[ i ,0].copy()
bestX = pX[ i, :].copy()
result[t,:]=bestX
print(t+1,fMin,[int(bestX[i]) if i>0 else bestX[i] for i in range(len(Lb))])
Convergence_curve[t]=fMin
return bestX,Convergence_curve,result
数据集
数据集都可以,只要是时间序列格式,不限领域,类似功率预测,风电光伏预测,负荷预测,流量预测,浓度预测,机械领域预测等等各种时间序列直接预测。可以做验证模型,对比模型。格式类似顶刊ETTH的时间序列格式即可。
比如这里是时间列+7列影响特征+1列预测特征
实验结果
拟合效果还是相对比较优秀的。精度很高。模型也可以继续优化,比如加注意力机制等等,或者替换其他方法,
源码地址
源码地址:https://m.tb.cn/h.goSimt6?tk=KAxa3gzitBr
6.补充
代码都是自己编写整理,如果还需要其他源码也可私信博主!