首页 > 解决方案 > 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. 有没有更简单的方法来进行这种比较?

标签: php

解决方案


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

在 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;
?>

推荐阅读