rust 如何使用n-gram查找最相似的字符串

pgvzfuti  于 2022-12-13  发布在  其他
关注(0)|答案(1)|浏览(154)

我尝试使用n-gram来为列表中的每个字符串找到最相似的字符串,目前我有这个字符串向量

let arr = [
        "Bilbo Baggins",
        "Gandalf",
        "Thorin",
        "Balin",
        "Kili",
        "Fili",
        "John",
        "Frodo Baggins",
    ]

使用下面的代码,我为每个字符串创建二元模型,并将它们存储在一个向量中:

let arr = [
        "Bilbo Baggins",
        "Gandalf",
        "Thorin",
        "Balin",
        "Kili",
        "Fili",
        "John",
        "Frodo Baggins",
    ]
        .iter()
        .map(|elem| 
            elem
            .len()
            .rem(2)
            .ne(&0)
            .then_some(format!("{elem} "))
            .unwrap_or(elem.to_string())
        )
        .map(|elem| elem.chars().array_chunks().collect::<Vec<[char; 2]>>())
        .collect::<Vec<_>>();

输出量:

[['B', 'i'], ['l', 'b'], ['o', ' '], ['B', 'a'], ['g', 'g'], ['i', 'n'], ['s', ' ']]
[['G', 'a'], ['n', 'd'], ['a', 'l'], ['f', ' ']]
[['T', 'h'], ['o', 'r'], ['i', 'n']]
[['B', 'a'], ['l', 'i'], ['n', ' ']]
[['K', 'i'], ['l', 'i']]
[['F', 'i'], ['l', 'i']]
[['J', 'o'], ['h', 'n']]
[['F', 'r'], ['o', 'd'], ['o', ' '], ['B', 'a'], ['g', 'g'], ['i', 'n'], ['s', ' ']]

问题是,我如何将某种集合逻辑应用于这些二元模型向量,以找到每个字符串最相似的字符串,并得到以下输出?

'Bilbo Baggins' most similar string: 'Frodo Baggins'
'Gandalf' most similar string: None
'Thoring' most similar string: 'Balin'
'Balin' most similar string: 'Thorin'
'Kili' most similar string: 'Fili'
'Fili' most similar string: 'Kili'
'John' most similar string: None
'Frodo Baggins' most similar string: 'Bilbo Baggins'
5n0oy7gb

5n0oy7gb1#

有很多不同的算法可以用来计算字符串之间的距离。你正在寻找的bigram的算法可能是cosine similarity函数。它可以用来迭代bigram并计算一个值来表示两个向量(或者字符串,在这个例子中)之间的相似性。它似乎更倾向于匹配更长的字符串,因为它们之间有更多的重复字符组。
下面是通过余弦相似度查找最接近的名称的示例:
第一个
Balin看起来并不完全正确,因为余弦距离没有考虑字符串长度。另一种流行的方法是求Levenshtein distance(我使用Wagner Fischer algorithm来计算它),它是将一个字符串转换为另一个字符串所需的插入、删除或替换的次数
第一次
Balin仍然不是你想要的,因为它只需要最少的修改就可以得到Kili,但是它看起来确实更接近了。希望这能帮助你更接近你想要的,但是你可能需要使用算法的组合,或者如果你想让Balin 匹配Thorin,找到一个对单词的开头/结尾加权不同的算法。

相关问题