Алгоритм Шинглов – определяем уникальность текста
Пример:
< ?php
include_once('shingles.php');
//; Список стоп-символов
$stop_symbols = "x27 x22 x60 \t \n \r ' , . / « » # ; : @ ~ [ ] { } = - + ) ( * & ^ % $ < > ? !";
; Список стоп-слов через запятую (в cp1251 кодировке)
$stop_words = "а, без, более, бы, был, была, были, было, быть, в, вам, вас, весь, во, вот, все, всего, всех, вы, где, да, даже, для, до, его, ее, если, есть, ещё, же, за, здесь, и, из, из-за, или, им, их, к, как, как-то, ко, когда, кто, ли, либо, мне, может, мы, на, надо, наш, не, него, неё, нет, ни, них, но, ну, о, об, однако, он, она, они, оно, от, очень, по, под, при, с, со, так, также, такой, там, те, тем, то, того, тоже, той, только, том, ты, у, уже, хотя, чего, чей, чем, что, чтобы, чьё, чья, эта, эти, это, я";
//; Длина шингла
length = 10
$setting=array(
'stop_symbols'=>$stop_symbols,
'stop_words'=>$stop_words
);
$shingles = new Shingles($setting);
$shingles->addText('То, что старшая сестра держалась на собрании так уверенно, меня сперва беспокоило, а на Макмерфи не подействовало никак');
$shingles->addText('То, что главная сестра держалась на собрании так уверенно, меня сперва беспокоило, а на Макмерфи не подействовало никак');
echo 'Тексты схожи на ' . $shingles->compaire($shingles->getShigles()) . '%';
?>
Файл shingle.php содержащий Класс:
<?php
class Shingles
{
/**
* Класс для реализации Шинглов на PHP
*
*/
protected $_params = array();
/**
* Cтоп-символы, которые будут удаленны из строки
*/
protected $_stopSymbols = array();
/**
* Массив стоп-слов, которые будут удаленны из строки
*
*/
protected $_stopWords = array();
/**
* Массив текстов для обработки
*
*/
protected $_texts = array();
/**
* Двухмерный массив шинглов
*
*/
protected $_shingles = array();
/**
* Метод выполняющий канонизацию строки. Сначала вырезаем из строки все
* стоп-символы. Затем перебираем слова. Те которых нет в массиве стоп-слов,
* оставляем. Приводим строку к нижнему регистру.
*
*/
protected function _canonizeString($string)
{
$result = array();
$string = str_replace($this->_stopSymbols, null, $string);
foreach (explode(' ', $string) as $word) {
if (strlen($word) && !in_array($word, $this->_stopWords)) {
$result[] = trim($word);
}
}
return strtolower(implode(' ', $result));
}
/**
* Выполняет канонизацию всех добавленных для обработки текстов
*
*/
protected function _canonizeTexts()
{
if (empty($this->_texts)) {
return $this;
}
foreach ($this->_texts as $key => $text) {
$this->_texts[$key] = $this->_canonizeString($text);
}
return $this;
}
/**
* Создает массив шинглов строки
*
*/
protected function _getShinglesFromString($string)
{
if (!$this->getParam('length')) {
throw new Exception('Not found param of length');
}
$shingles = array();
$length = intval($this->getParam('length'));
$words = explode(' ', $string);
if (count($words) < $length) {
return $shingles;
}
for ($i = 1; $i <= count($words) - $length; $i ++) {
$shingles[] = md5(implode(' ', array_slice($words, $i, $length)));
}
return $shingles;
}
/**
* Создает массив шинглов для каждого текста
*
*/
protected function _setShingles()
{
foreach ($this->_texts as $text) {
$this->_shingles[] = $this->_getShinglesFromString($text);
}
return $this;
}
/**
* Конструктор класса
*
*/
public function __construct(array $setting = array())
{
if (isset($setting['stop_symbols'])) {
$this->setStopSymbols(explode(' ', $setting['stop_symbols']));
}
if (isset($setting['stop_words'])) {
$this->setStopWords(explode(', ', $setting['stop_words']));
}
if (isset($setting['length'])) {
$this->setParam('length', $setting['length']);
}
}
/**
* Определяет массив стоп-символов
*
*/
public function setStopSymbols(array $symbols)
{
$this->_stopSymbols = $symbols;
return $this;
}
/**
* Возвращает массив стоп-символов
*/
public function getStopSymbols()
{
return $this->_stopSymbols;
}
/**
* Определяет массив стоп-слов
*
*/
public function setStopWords(array $words)
{
$this->_stopWords = $words;
return $this;
}
/**
* Возвращает массив стоп-слов
*
*/
public function getStopWords()
{
return $this->_stopWords;
}
/**
* Возвращает параметр
*
*/
public function getParam($key)
{
if (isset($this->_params[$key])) {
return $this->_params[$key];
}
return null;
}
/**
* Возвращает массив всех параметров
*
*/
public function getParams()
{
return $this->_params;
}
/**
* Определяет массив параметров
*
*/
public function setParams(array $params)
{
$this->_params = $params;
return $this;
}
/**
* Определяет параметр
*
*/
public function setParam($key, $value)
{
$this->_params[$key] = $value;
return $this;
}
/**
* Добавляет текст для проверки
*
*/
public function addText($text)
{
$this->_texts[] = $text;
return $this;
}
/**
* Проверяет двухмерный массив шинглов на уникальность
*
*/
public function compaire(array $shingles)
{
$same = 0;
foreach ($shingles[0] as $key => $shingle) {
if ($shingle === $shingles[1][$key]) {
$same ++;
}
}
return round($same / count($shingles[0]) * 100, 2);
}
/**
* Возвращает массив шинглов для всех добавленных текстов
*
*/
public function getShigles()
{
return $this->_canonizeTexts()->_setShingles()->_shingles;
}
}
?>
[:]