PHP:比较文本问题

时间:2018-08-01 02:53:41

标签: php

考虑这种情况:

  • 文本文档的多个版本
  • 客户端请求列出具有比较这些版本的指标的列表

对于少于5k个字符的文本,可以通过similar_text函数轻松地即时完成。但是,对于较长的文本,执行时间成为问题:

+-------------------------------------------+
| number of characters | execution time (s) |
+-------------------------------------------+
| 10k                  | 1                  |
| 20k                  | 3                  |
| 30k                  | 9                  |
| 40k                  | 12                 |
| 50k                  | 20                 |
| 60k                  | 30                 |
| 65k                  | **timeout**        |
+-------------------------------------------+

注意:65k是一个重要的里程碑,因为它大约是MySQL中TEXT字段类型的最大长度。

因此,对于更长的文本,无法即时使用similar_text。一种可能的解决方法是,以前用这样的similar_text指标填充表,然后再将其检索到客户端。

问题

  1. 上述解决方法极有可能需要较长的执行时间。有什么建议可以避免“最大执行时间限制”错误?
  2. 此解决方法推荐使用哪个:cronjob或后台脚本?其他?
  3. 有没有比较简单的方法?

1 个答案:

答案 0 :(得分:1)

您可以使用余弦相似度来度量两个字符串之间的相似度。 你可以在这里读更多关于它的内容。 Cosine Similarity

PHP中实现了基本代码,供您参考。

<?php
/**
    Convert string to array/vector of ASCII values of the characters

    @param1 $words String to be converted to the array/vector of ASCII values
    @param2 $output Stores the output array/vector of ASCII values
    @return Magnitude of the vector/array
*/
function convert_to_vector($words, &$output) {
    $magnitude = 0;

    $output = [];

    $length = strlen($words);

    for($i = 0 ; $i < $length; $i++){
        $char = substr($words, $i, 1);
        $ascii = ord($char);
        $magnitude += pow($ascii, 2);
        array_push($output, $ascii);
    }

    return sqrt($magnitude);
}

/**
    * Calculate dot product of two vectors/arrays
    @param1 $a Vector/Array A
    @param2 $b Vector/Array B
    @return dot product of two vectors/arrays
*/
function dot($a, $b){
    $magnitude = 0;

    $length_a = count($a);
    $length_b = count($b);


    $length = ($length_a <= $length_b)? $length_a : $length_b;

    for($i = 0; $i < $length; $i++){
        $magnitude += $a[$i] * $b[$i];
    }

    return $magnitude;
}

// Declare two vector/arrays
$output_a = array();
$output_b = array();

// Calculate the magnitude of the vectors
$magnitude_a = convert_to_vector($a,$output_a);
$magnitude_b = convert_to_vector($b,$output_b);

// Calculate the dot vector of two vectors/arrays
$dot_ab = dot($output_a, $output_b);

// Calculate the cosine similarity
// The similarity scores is between 0 to 1. O being unequal and 1 being equal.
$similarity = $dot_ab / ($magnitude_a * $magnitude_b);
$similarity_percent =  $similarity * 100.0;
?>