Beam Search(集束搜索)是一种启发式图搜索算法,通常用在图的解空间比较大的情况下,为了减少搜索所占用的空间和时间,在每一步深度扩展的时候,剪掉一些质量比较差的结点,保留下一些质量较高的结点。这样减少了空间消耗,并提高了时间效率,但缺点就是有可能存在潜在的最佳方案被丢弃,因此,Beam Search算法是不完全的,一般用于解空间较大的系统中。
关于理论部分请看链接:
https://www.zhihu.com/question/54356960
Python代码如下:
from math import log
import numpy as np
def beam_search_decoder(data, k):
sequences = [[list(), 1.0]]
for row in data:
all_candidates = list()
for i in range(len(sequences)):
seq, score = sequences[i]
for j in range(len(row)):
candidate = [seq + [j], score * -log(row[j])]
all_candidates.append(candidate)
ordered = sorted(all_candidates, key=lambda tup: tup[1]) # 按score排序
sequences = ordered[:k] # 选择前k个最好的
return sequences
def greedy_decoder(data):
return [np.argmax(s) for s in data]
if __name__ == '__main__':
data = [[0.1, 0.5, 0.4],
[0.3, 0.2, 0.5],
[0.5, 0.3, 0.2]]
data = np.array(data)
result = beam_search_decoder(data, 3)
print("****use beam search decoder****")
for seq in result:
print(seq)
print("****use greedy decoder****")
print(greedy_decoder(data))
输出结果:
****use beam search decoder****
[[1, 2, 0], 0.33302465198892944]
[[2, 2, 0], 0.4402346437542523]
[[1, 2, 1], 0.5784523625139449]
****use greedy decoder****
[1, 2, 0]
Process finished with exit code 0
结果解释:
beam search,例如输出第二行[1,2,0]表示,1表示从data第一行取索引1;2表示从data第二行取索引2;0表示从data第三行取索引0,相当于找出每一行最大值所在的索引。所以最终取出来的元素是[0.5, 0.5, 0.5],这是概率最大的一条路径。[2, 2, 0]表示取出的元素是[0.4, 0.5, 0.5],这是概率第二大的路径。
greedy search,只输出概率最大的一条路径[1, 2, 0]。