VMD:变分模态分解
BWO:白鲸优化算法
原理网上很多就不说了!
VMD需要优化的参数是k和alpha,预设的 K 值决定着 IMF 分量的个数,惩罚系数 α 决定着 IMF 分量的带宽。 惩罚系数越小, 各 IMF 分量的带宽越大,过大的带宽会使得某些分量包含其他分量信号;α值越大,各IMF分量的带宽越小,过小的带宽使得被分解的信号中某些信号丢失。
适应度函数:最小样本熵(用的最多,还有局部熵什么的,都可以自行设定)
最小样本熵定义如下:
#定义一个求样本熵的函数
def SampEn(U, m, r):
"""
用于量化时间序列的可预测性
:param U: 时间序列
:param m: 模板向量维数
:param r: 距离容忍度,一般取0.1~0.25倍的时间序列标准差,也可以理解为相似度的度量阈值
:return: 返回一个-np.log(A/B),该值越大,序列就越复杂
"""
def _maxdist(x_i, x_j):
"""
Chebyshev distance
:param x_i:
:param x_j:
:return:
"""
return max([abs(ua - va) for ua, va in zip(x_i, x_j)])
def _phi(m):
x = [[U[j] for j in range(i, i + m - 1 + 1)] for i in range(N - m + 1)]
C = [len([1 for j in range(len(x)) if i != j and _maxdist(x[i], x[j]) <= r]) for i in range(len(x))]
result=sum(C)/(N-m)
return result
N = len(U)
return -np.log(_phi(m + 1) / _phi(m))
适应度函数定义如下:
def fitness(pop):
np.random.seed(0)
K = int(pop[0])
alpha = int(pop[1])*10
#print(K,alpha)
tau = 0
DC = 0
init = 1
tol = 1e-7
imf,u_hat,omega=VMD(data_try, alpha, tau, K, DC, init, tol)
comp=np.vstack([imf])
SE = 0
se_imf=[]
for i in range(comp.shape[0]):#k个Imf
temp= SampEn(comp[i,:],2, 0.2 * np.std(comp[i,:]))
SE +=temp
se_imf.append(temp)
fit = min(se_imf)
np.random.seed(int(time.time()))
return fit
输入数据:用电量序列
#下面是我们的用电量数据
biaoge = pd.read_excel('负荷数据.xlsx')
data=biaoge.iloc[ : ,1:97 ]#data0和label0是表格数据
data_day=data.iloc[1:data.shape[0],1]
data_day1=np.array(data_day)
#将所有数据按照小时排成列
data_shape0=np.array(data.iloc[1:data.shape[0],:])
data_dayshape=data_shape0.reshape(1096*96,-1)
data_try=data_dayshape[200:400]
原始序列图:
main主程序:
best_whale, best_score = whale_optimization_algorithm(objective_function, num_iterations=50, num_whales=5, search_space=(search_min,search_max))
print('Best solution:', best_whale)
print('Best obj function value:', best_score)
得到结果:
Best solution: [8.94110409 3.26992535]
Best obj function value: 0.017517304838002352
结果为:k取8(IMF个数),alpha取300,结果最优,
此时最小样本熵最小,为0.017517304838002352
完整代码(可直接运行)+QQ获取(2948824501)(码代码不易,10软妹币获取,不接受勿扰)