simhash_server
simhash_server copied to clipboard
请教个使用问题
这样计算出来每篇内容的simhash值,然后进行比对么?我的网站是PHP的,服务器上已经安装了,怎么计算两个值的相似度呢?请问有PHP的计算的代码么?
PHP 用这个吧, simhash算法, hash用的md5
class Simhash
{
/**
* 通过分词计算simhash
* @param array &$set ['词1', '词2', '词1'] 或 ['词1' => 2, '词2' => 1]
* @param int $length 返回的bit长度,一般如下值:32, 64, 128
* @return string 二进制文本
*/
public static function hash(array &$set, int $length = 128)
{
$boxes = array_fill(0, $length, 0);
if (is_int(key($set)))
$dict = array_count_values($set);
else
$dict = &$set;
foreach ($dict as $element => $weight) {
$hash = substr(hash('md5', $element), 0, $length / 8);
$gmp = gmp_init($hash, 16);
for ($i = 0; $i < $length; $i++)
$boxes[$i] += gmp_testbit($gmp, $i) ? $weight : -$weight;
}
$result = gmp_init(str_repeat('0', $length), 2);
foreach ($boxes as $i => $box) {
if ($box > 0)
gmp_setbit($result, $i);
}
return gmp_export($result); // 这里输出的是二进制 使用MySQL varbinary(16)存储
}
/**
* 计算两个Simhash的汉明距离,然后得到相似度
* Hamming distance
*
* @param string $h1
* @param string $h2
* @return float
*/
public static function hamdist(string $h1, string $h2)
{
if (($length = strlen($h1)) != strlen($h2) || $length <= 0)
throw new \RuntimeException('strlen($h1) != strlen($h2) or zero size.');
$b1 = gmp_import($h1);
$b2 = gmp_import($h2);
return 1 - gmp_hamdist($b1, $b2) / ($length * 8);
}
}
例子,肯定要先分词
$a = Simhash::hash(['我', '是', '中央电视台','的','员工', '对吧']);
$b = Simhash::hash(['我', '不是', '中央电视台','的','员工', '对吧']);
echo Simhash::hamdist($a, $b); // 0.859375
Simhash算法对长文本还不错,但是上面的短句,效果就那样
短文本用余弦定理