我们假设我有一些大量的数据行,其中行中的每个元素都是(键,值)对:
1) [(bird, "eagle"), (fish, "cod"), ... , (soda, "coke")]
2) [(bird, "lark"), (fish, "bass"), ..., (soda, "pepsi")]
n) ....
n+1) [(bird, "robin"), (fish, "flounder"), ..., (soda, "fanta")]
我希望能够运行一些允许我确定新行的计算,与该行“最相似”的行是什么?
我能想到找到任何特定行的“最相似”行的最直接方法是直接将所述行与所有其他行进行比较。这显然在计算上非常昂贵。
我正在寻找以下表格的解决方案。
一个可以占用一行的函数,并为该行生成一些派生整数。这个返回的整数将是该行的一种“签名”。这个签名的重要特性是,如果两行非常“相似”,它们将生成非常接近的整数,如果行非常“不同”,它们将生成远程整数。显然,如果它们是相同的行,它们将生成相同的签名。
然后,我可以使用这些生成的签名及其指向的行的索引,并根据其签名对它们进行排序。我会保留这个数据结构,以便我可以快速查找。称之为数据库B.
当我有一个新行时,我想知道数据库B中哪个存在的行最相似,我会:
我知道他们在这个问题上挥手很多。我的问题是我实际上并不知道会产生这个签名的功能是什么。我看到Levenshtein距离,但那些代表了转换成本,而不是签名。我看到我可以尝试有损压缩,两个东西可能是“桶状”,因为它们压缩到同一个东西。我正在寻找有关如何做到这一点的其他想法。
谢谢。
答案 0 :(得分:1)
如果您有大量数据,并且想要做这个硬核,我会建议使用PLSA或PSVM这样的统计方法,它可以从文本中提取识别主题并识别具有类似主题的文档概率。
更简单但不太准确的方法是使用Soundex,它可用于多种语言。你可以存储soundex(这将是一个短字符串,而不是我害怕的整数),并寻找与soundex完全匹配,这应该指向类似的行。
我认为期望函数将一系列字符串转换为整数使得彼此接近的整数映射到类似的字符串是不现实的。你可能最接近的是对每个元组进行校验和,并将新行的校验和与现有行的校验和进行比较,但我猜你正试图想出一个你可以索引的数字。
答案 1 :(得分:1)
编辑:这是我的原始答案,我们将其称为案例1,其中优先键
您不能将其作为排序整数,因为它是一维的,您的数据是多维的。因此,在这种意义上的“接近”不能在一条线上建立起来。
你的例子显示了所有3行的鸟,鱼和苏打水。钥匙是固定和已知的吗?如果不是,那么您的第一步是散列行的键以建立具有相同键的行。
对于这些价值观,请将此视为穷人的周六夜相似技巧。散列值,在该散列上匹配的任何两行都是完全匹配,并表示相同的“点”,零距离。
如果N是键/值对的数量:
最接近的非精确“接近度”意味着匹配N个值中的N-1。因此,您生成N个更多哈希值,每个哈希值都会丢弃其中一个值。在这些哈希值上匹配的任何两行都有N-1个共同的N值。
下一个最接近的非精确“接近度”将意味着在N个值中匹配N-2。因此,您生成的N个哈希值超过N个(我最近无法计算二进制数),这次每个哈希都会遗漏两个值的组合。在这些哈希上匹配的任何两行都有N-2个共同的N值。
所以你可以看到它的发展方向。在合乎逻辑的极端,你最终会得到2 ^ N个哈希值,而不是非常美味,但我假设你不会那么远,因为你达到了一个太少的匹配值被认为是“远”值得考虑的点。
编辑:要了解我们如何逃避维度,请仅考虑两个键,值为1-9。在图表上绘制所有可能的值。我们看到{1,1}接近{2,2},但{5,6}接近{6,7}。所以我们得到一个头脑风暴,我们说,啊哈!我将使用毕达哥拉斯定理计算每个点与原点的距离!这将使{1,1}和{2,2}都易于检测。但是这两个点{1,10}和{10,1}将获得相同的数字,即使它们与图上的距离相差很远。所以我们说,好的,我需要为每个添加角度。在相同距离处的两个点通过它们的角度来区分,在相同角度处的两个点通过它们的距离来区分。但是,当然现在我们已经在两个维度上绘制了它们。
编辑:案例2是当键有优先时,键1比键2更重要,这比键3更重要,等等。在这种情况下,如果允许的值为AZ,则将值组合在一起,就像它们是数字一样,以获得可排序的值。 ABC非常接近ABD,但离BBD很远。