用于比较词汇相似度的数值哈希

时间:2011-06-26 13:25:43

标签: search text hash pruning

是否有某种形式的散列算法可以为类似的单词生成相似的数值?我想会有一些误报,但它似乎对搜索修剪有用。

编辑:Soundex很整洁,可能派上用场,但理想情况下,我想要的东西是这样的:abs(f('horse') - f('hoarse')) < abs(f('horse') - f('goat'))

4 个答案:

答案 0 :(得分:2)

Soundex算法生成与输入字中的音素对应的键串。 http://www.archives.gov/research/census/soundex.html

如果您只想比较字符串之间的相似性,请尝试Levenstein Distance。 http://en.wikipedia.org/wiki/Levenshtein_distance

答案 1 :(得分:1)

你所说的是Locality-sensitive Hashing。它可以应用于不同类型的输入(图像,音乐,文本,空间位置,无论您需要什么)。

不幸的是(尽管搜索)我找不到任何实用的字符串LSH算法。

答案 2 :(得分:0)

您可以随时尝试Soundex,看看它是否符合您的需求。

答案 3 :(得分:0)

查看维基百科上的Soundex算法,您尚未指定语言,但有多种语言的示例实现链接。显然,这会给你一个字符串哈希,对于类似的发声词,你想要一个整数,但你可以应用他们在Boost.Hash中使用的字符串 - >整数哈希方法。

编辑:为了澄清,这是一个示例C ++实现...

#include <boost/foreach.hpp>
#include <boost/functional/hash.hpp>

#include <algorithm>
#include <string>
#include <iostream>

char SoundexChar(char ch)
{
    switch (ch)
    {
        case 'B':
        case 'F':
        case 'P':
        case 'V':
            return '1';
        case 'C':
        case 'G':
        case 'J':
        case 'K':
        case 'Q':
        case 'S':
        case 'X':
        case 'Z':
            return '2';
        case 'D':
        case 'T':
            return '3';
        case 'M':
        case 'N':
            return '5';
        case 'R':
            return '6';
        default:
            return '.';
    }
}

std::size_t SoundexHash(const std::string& word)
{
    std::string soundex;
    soundex.reserve(word.length());

    BOOST_FOREACH(char ch, word)
    {
        if (std::isalpha(ch))
        {
            ch = std::toupper(ch);

            if (soundex.length() == 0)
            {
                soundex.append(1, ch);
            }
            else
            {
                ch = SoundexChar(ch);

                if (soundex.at(soundex.length() - 1) != ch)
                {
                    soundex.append(1, ch);
                }
            }
        }
    }

    soundex.erase(std::remove(soundex.begin(), soundex.end(), '.'), soundex.end());

    if (soundex.length() < 4)
    {
        soundex.append(4 - soundex.length(), '0');
    }
    else if (soundex.length() > 4)
    {
        soundex = soundex.substr(0, 4);
    }

    return boost::hash_value(soundex);
}

int main()
{
    std::cout << "Color = " << SoundexHash("Color") << std::endl;
    std::cout << "Colour = " << SoundexHash("Colour") << std::endl;

    std::cout << "Gray = " << SoundexHash("Gray") << std::endl;
    std::cout << "Grey = " << SoundexHash("Grey") << std::endl;

    return 0;
}