我有一个代码来绘制一组数据的热图,表示为(x, y, f(x, y))
,我想找到局部最小点。
import numpy as np
import math
import matplotlib.pyplot as plt
import matplotlib as mpl
from scipy.interpolate import griddata
data = np.genfromtxt('data.dat',
skip_header=1,
delimiter=' ')
x, y, z = data[:, 1], data[::, 0], data[:, 2]
x, y, z = x*180/math.pi, y*180/math.pi, z - min(z)
xi, yi = np.linspace(max(x), min(x), 1000), np.linspace(max(y), min(y), 1000)
xi, yi = np.meshgrid(xi, yi)
zi = griddata((x, y), z, (xi, yi), method='linear')
plt.figure(figsize=(10,5))
plt.pcolormesh(xi, yi, zi, shading='auto', cmap='jet')
plt.colorbar(label='Heatmap')
plt.gca().invert_yaxis()
plt.show()
下面是生成一些假数据的代码:
import math
with open('data.dat', 'w') as arquivo:
for x in range(20):
for y in range(20):
z = -math.exp(math.sin(x*y)- math.cos(y))
arquivo.write(f"{x}\t\t{y}\t\t{z}\n")
圈出最小点的热图示例:
我试着使用np.gradient
,以为通过求两个导数,我就可以确定局部极小点(一阶导数为零,二阶导数为负),但我无法使任何一个函数起作用。
2条答案
按热度按时间unguejic1#
为了找到局部最小值,我们通常使用一些基于梯度的优化,如梯度下降。然而,要找到所有的局部极小值并不容易,除非做很多“重启”(通常人们对一个局部极小值很满意)。解决问题的一个简单方法是使用网格搜索:如果当前点小于它周围的相邻点,则它是一个局部最小值。代码片段如下所示
然后画出局部最小值
hof1towb2#
有几种方法可以做到这一点,但我的方法是使用scipy过滤器(如均匀过滤器)创建Map背景的模型,其大小足以包含Map上的几个主要特征(例如图像大小的一半)。然后使用标准差过滤器创建贴图标准差的另一个模型。
局部极小值出现在
(original_map - background) / standard_deviation < threshold_value
处。你可以随意使用
threshold_value
(也许负2-3就可以)和过滤窗口的大小。python代码作为练习。:)