技术问询:如何从同一文本的归一化Trigram列表筛选匹配Bigram的条目
实现思路与代码示例
要解决这个问题,核心是高效匹配trigram的前两个词是否存在于bigram列表中,下面是分步的实现思路:
预处理bigram列表,提升查找效率:
列表的成员检查是线性操作,当bigram数量较多时会拖慢速度。我们可以把每个bigram转换成元组(列表是可变类型,无法存入集合),再将所有bigram元组存入一个集合。这样后续的成员检查时间复杂度会从O(n)降到O(1),大幅提升效率。遍历并筛选trigram:
逐个遍历每个trigram,取出它的前两个词组成元组,检查这个元组是否在我们创建的bigram集合中。如果存在,就把该trigram加入结果列表。归一化数据的注意点:
你提到两组列表都是归一化后的,所以不需要额外处理大小写、标点、词形还原等问题,直接比较词序列即可。
代码示例(Python)
# 假设输入的归一化bigrams和trigrams都是词组成的列表的列表 normalized_bigrams = [["spam", "eggs"], ["hello", "world"], ["foo", "bar"]] normalized_trigrams = [["spam", "eggs", "blabla"], ["hello", "foo", "bar"], ["spam", "eggs", "test"], ["foo", "bar", "baz"]] # 把bigrams转成元组集合,方便快速查找 bigram_set = set(tuple(bg) for bg in normalized_bigrams) # 筛选符合条件的trigrams matched_trigrams = [tg for tg in normalized_trigrams if tuple(tg[:2]) in bigram_set] print(matched_trigrams) # 输出:[['spam', 'eggs', 'blabla'], ['spam', 'eggs', 'test'], ['foo', 'bar', 'baz']]
特殊情况处理(字符串形式的n-grams)
如果你的n-grams是以空格分隔的字符串形式存储的(比如"spam eggs"而不是["spam", "eggs"]),只需要先把字符串拆分成词列表再处理即可:
# 处理字符串形式的n-grams bigram_strings = ["spam eggs", "hello world"] trigram_strings = ["spam eggs blabla", "hello foo bar"] bigram_set = set(tuple(bg.split()) for bg in bigram_strings) matched_trigrams = [tg for tg in trigram_strings if tuple(tg.split()[:2]) in bigram_set]
内容的提问来源于stack exchange,提问作者Alex Nikitin
相关产品推荐
相关产品推荐

