Модераторы: korob2001, ginnie

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Как определить похожие фразы? 
:(
    Опции темы
Suppir
Дата 22.9.2011, 10:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 588
Регистрация: 20.4.2009

Репутация: нет
Всего: нет



Есть ряд фраз. Необходимо найти похожие фразы, которые стоят рядом друг с другом.
Я выбрал их вручную и выделил жирным шрифтом. Можно ли сделать подобное с помощью Perl? Какие алгоритмы можете подсказать. 


обращение с отходами потребления
органы управления в области садоводства
оформление прав собственности на землю
оценка земель садоводческих объединений
право на ведение садоводства
предоставление земли для ведения садоводства
предоставление земли для садоводства

предоставление земля для ведения личного подсобного хозяйства
предприятие развития Московского региона
строительные нормы и правила СНиП
программы развития садоводства
программы по развитию садоводства

фонды проката


Это сообщение отредактировал(а) Suppir - 22.9.2011, 10:49
PM MAIL   Вверх
Suppir
Дата 22.9.2011, 12:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 588
Регистрация: 20.4.2009

Репутация: нет
Всего: нет



Подумал, может быть следующим способом:

1) исключаем все союзы и предлоги (и, а, но, по, не, для и т.п.), знаки препинания, переводим в нижний регистр
2) разбиваем фразу на массив слов ('предоставление', 'земли', 'ведения', 'садоводства')
3) теперь хорошо бы привести все элементы массива в именительный падеж
4) потом проверяем количество совпадающих слов между каждыми соседними фразами
PM MAIL   Вверх
alezzz
Дата 22.9.2011, 13:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


сплю...
**


Профиль
Группа: Участник
Сообщений: 499
Регистрация: 17.8.2009

Репутация: 1
Всего: 14



Для ангиского есть несколько алгоритмов, с русским сложнее. Я пробовал адаптировать soundex под русский язык, получилось конечно не очень, но поделюсь опытом. Что такое soundex можно погуглить.
Код

my @pr = qw(а и у в на не при до или из за из-за с для по);

while (my $line=<DATA>){
    my @words = split /\s+/, $line;
    foreach my $w (0..$#words){
        foreach (@pr){
            if ($words[$w] eq $_){
                undef $words[$w];
            }
        }
        print soundex($words[$w]) . " " if $words[$w];
    }
    print "\n";
}

sub soundex
{
    my $word = shift || $_; 
    $word =~ tr/А-Я/а-я/;       
 
    my $fl = substr $word, 0, 1;
    $word  = substr $word, 1;
 
    $word =~ tr/бпфвгхджшщчзсцрктнмлmйуеъыаоэяиью/11111112222333455667/ds;
    $word = "$fl$word";
    #return $word;                                              # Измененый 
    return substr($word, 0, 4)."0" x (4 - length($word));       # Классический
}

__DATA__
обращение с отходами потребления
органы управления в области садоводства
оформление прав собственности на землю
оценка земель садоводческих объединений
право на ведение садоводства
предоставление земли для ведения садоводства
предоставление земли для садоводства
предоставление земля для ведения личного подсобного хозяйства
предприятие развития Московского региона
строительные нормы и правила СНиП
программы развития садоводства
программы по развитию садоводства
фонды проката

Удаляю все предлоги (или почти все, может забыл что-то) и кодирую слова, в результате получается такое:
Код

о142 о516 п541 
о416 у141 о173 с135 
о146 п410 с135 з670 
о365 з670 с123 о160 
п410 в160 с135 
п413 з670 в160 с135 
п413 з670 с135 
п413 з670 в160 л261 п131 х351 
п414 р315 м351 р160 
с545 н460 п417 с610 
п414 р315 с135 
п414 р315 с135 
ф610 п450

Видно что строки:
программы развития садоводства
программы по развитию садоводства

одинаковы, а вот строки:
предоставление земли для ведения садоводства
предоставление земли для садоводства

немного отличаются, но можно посчитать процент совпадения.

Вобщем вот такая заготовка, если нравится то модернезируйте ее на свое усмотрение.

Пишут что для русского языка больше подходит аглоритм Metaphone, можно попробовать его.
PM MAIL   Вверх
Suppir
Дата 22.9.2011, 13:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 588
Регистрация: 20.4.2009

Репутация: нет
Всего: нет



Спасибо, попробую!
PM MAIL   Вверх
Suppir
Дата 22.9.2011, 14:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 588
Регистрация: 20.4.2009

Репутация: нет
Всего: нет



Попробовал. Soundex конкретно для моего случая мало подходит :( много лишних совпадений получается. 
PM MAIL   Вверх
ginnie
Дата 22.9.2011, 14:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Комодератор
Сообщений: 1287
Регистрация: 6.1.2008
Где: Москва

Репутация: 38
Всего: 49



Suppir, я попробовал два модуля с CPAN: String::Similarity и String::Trigram

код

Код

#! /usr/bin/perl

use strict;
use warnings;

use String::Similarity;
use String::Trigram;

my @strings;
push(@strings, 'обращение с отходами потребления');
push(@strings, 'органы управления в области садоводства');
push(@strings, 'оформление прав собственности на землю');
push(@strings, 'оценка земель садоводческих объединений');
push(@strings, 'право на ведение садоводства');
push(@strings, 'предоставление земли для ведения садоводства');
push(@strings, 'предоставление земли для садоводства');
push(@strings, 'предоставление земля для ведения личного подсобного хозяйства');
push(@strings, 'предприятие развития Московского региона');
push(@strings, 'строительные нормы и правила СНиП');
push(@strings, 'программы развития садоводства');
push(@strings, 'программы по развитию садоводства');
push(@strings, 'фонды проката');

my $prev_string = '';

for my $string (@strings) {
    unless ($prev_string) {
        $prev_string = $string;
        next;
    }
    my $similarity = String::Similarity::similarity($prev_string, $string);
    my $similatiry_trigram = String::Trigram::compare($prev_string, $string);
    warn sprintf('%s : %s %.3f %.3f', $prev_string, $string, $similarity, $similatiry_trigram), $/;
    $prev_string = $string;
}


результат

Код

обращение с отходами потребления : органы управления в области садоводства 0.394 0.087
органы управления в области садоводства : оформление прав собственности на землю 0.468 0.110
оформление прав собственности на землю : оценка земель садоводческих объединений 0.364 0.066
оценка земель садоводческих объединений : право на ведение садоводства 0.448 0.109
право на ведение садоводства : предоставление земли для ведения садоводства 0.667 0.382
предоставление земли для ведения садоводства : предоставление земли для садоводства 0.900 0.826
предоставление земли для садоводства : предоставление земля для ведения личного подсобного хозяйства 0.660 0.365
предоставление земля для ведения личного подсобного хозяйства : предприятие развития Московского региона 0.436 0.094
предприятие развития Московского региона : строительные нормы и правила СНиП 0.301 0.013
строительные нормы и правила СНиП : программы развития садоводства 0.349 0.031
программы развития садоводства : программы по развитию садоводства 0.921 0.718
программы по развитию садоводства : фонды проката 0.348 0.087


может поможет



--------------------
Написать код, понятный компьютеру, может каждый, но только хорошие программисты пишут код, понятный людям. (Мартин Фаулер. Рефакторинг)
PM MAIL Skype Jabber   Вверх
Suppir
Дата 22.9.2011, 15:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 588
Регистрация: 20.4.2009

Репутация: нет
Всего: нет



Сейчас потестю smile


PM MAIL   Вверх
ginnie
Дата 22.9.2011, 15:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Комодератор
Сообщений: 1287
Регистрация: 6.1.2008
Где: Москва

Репутация: 38
Всего: 49



До кучи еще можно расстояние Левенштейна определить (Text::LevenshteinXS):

Код

обращение с отходами потребления : органы управления в области садоводства 0.394 0.087 29
органы управления в области садоводства : оформление прав собственности на землю 0.468 0.110 29
оформление прав собственности на землю : оценка земель садоводческих объединений 0.364 0.066 33
оценка земель садоводческих объединений : право на ведение садоводства 0.448 0.109 29
право на ведение садоводства : предоставление земли для ведения садоводства 0.667 0.382 20
предоставление земли для ведения садоводства : предоставление земли для садоводства 0.900 0.826 8
предоставление земли для садоводства : предоставление земля для ведения личного подсобного хозяйства 0.660 0.365 29
предоставление земля для ведения личного подсобного хозяйства : предприятие развития Московского региона 0.436 0.094 42
предприятие развития Московского региона : строительные нормы и правила СНиП 0.301 0.013 33
строительные нормы и правила СНиП : программы развития садоводства 0.349 0.031 27
программы развития садоводства : программы по развитию садоводства 0.921 0.718 4
программы по развитию садоводства : фонды проката 0.348 0.087 25


Это сообщение отредактировал(а) ginnie - 22.9.2011, 15:23


--------------------
Написать код, понятный компьютеру, может каждый, но только хорошие программисты пишут код, понятный людям. (Мартин Фаулер. Рефакторинг)
PM MAIL Skype Jabber   Вверх
Suppir
Дата 22.9.2011, 15:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 588
Регистрация: 20.4.2009

Репутация: нет
Всего: нет



Расстояния Левенштейна иногда использую. С помощью него хорошо искать опечатки (разницу в 1-3 буквы), вроде:

программы по развитию садоводства
программы но развитию садоводства


Но при этом невозможно применять в таких случаях:
программы по развитию садоводства
программы по развитию частного садоводства

потому что если учитывать разницу в 5 и более букв, то будет очень много лишнего находиться.





Добавлено @ 16:00
Сейчас передо мной стоит следующая частная задача.

Есть два массива:

@a = ('мама', 'мыла', 'раму');
@b = ('мама', 'помыла', 'раму');

Необходимо подсчитать степень соответствия между двумя массивами. При этом нужно учитывать:
1) количество одинаковых слов <разделить на>  общее количество слов  //это легко, сам могу smile
2) правильность порядка слов в массивах //это не получается  smile 

Подскажите, плиз 


Это сообщение отредактировал(а) Suppir - 22.9.2011, 16:00
PM MAIL   Вверх
ginnie
Дата 22.9.2011, 16:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Комодератор
Сообщений: 1287
Регистрация: 6.1.2008
Где: Москва

Репутация: 38
Всего: 49



А что такое "правильность порядка слов в массивах"?


--------------------
Написать код, понятный компьютеру, может каждый, но только хорошие программисты пишут код, понятный людям. (Мартин Фаулер. Рефакторинг)
PM MAIL Skype Jabber   Вверх
KSURi
Дата 22.9.2011, 16:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 887
Регистрация: 8.6.2006
Где: Russia

Репутация: 20
Всего: 27



Все эти модули оперируют на уровне символов или их последовательнстей, что в данном случае не очень полезно.

Наиболее очевидным вариантом кажется уже предложенный алгоритм:
убрать стоп-слова, нормализовать (в т.ч. словоформы), отсортировать (?), сравнить.


--------------------
Died at Life.pl line 21
PM Jabber   Вверх
Suppir
Дата 22.9.2011, 16:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 588
Регистрация: 20.4.2009

Репутация: нет
Всего: нет



А что такое "правильность порядка слов в массивах"? 

Вот что:

Если 
@a = ('мама', 'мыла', 'раму');
@b = ('мама', 'помыла', 'раму');
то здесь повторяются "мама" и "раму". Они занимают одинаковые позиции (0 и 2 элемент массива).

Если 
@a = ('мама', 'мыла', 'раму');
@b = ('помыла', 'мама', 'раму');
то здесь повторяются "мама" и "раму". НО здесь только слово "раму" занимает одинаковую позицию. 
Поэтому степень совпадения двух массивов должна быть меньшей, чем в первом случае. 

При этом, перед тем как подсчитывать позиции, необходимо исключить из массива не совпадающие слова (для которых нет совпадений). 
Иначе получим следующее:

@a = ('сегодня', 'мама', 'мыла', 'раму');
@b = ('мама', 'мыла', 'раму');

По первой проверке имеем всего лишь одно лишнее слово "сегодня". Но из-за того, что это слово "сдвинуло" всю цепочку, по второй проверке (на правильность порядка) мы получим полное несоответствие (1 != 0, 2 != 1, 3 != 2). Поэтому перед второй проверкой нужно исключать слова, у которых нет соответствий. 



Это сообщение отредактировал(а) Suppir - 22.9.2011, 16:26
PM MAIL   Вверх
alezzz
Дата 22.9.2011, 17:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


сплю...
**


Профиль
Группа: Участник
Сообщений: 499
Регистрация: 17.8.2009

Репутация: 1
Всего: 14



PM MAIL   Вверх
ginnie
Дата 22.9.2011, 17:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Комодератор
Сообщений: 1287
Регистрация: 6.1.2008
Где: Москва

Репутация: 38
Всего: 49



KSURi, как ты предлагаешь модифицированные строки сравнить?


--------------------
Написать код, понятный компьютеру, может каждый, но только хорошие программисты пишут код, понятный людям. (Мартин Фаулер. Рефакторинг)
PM MAIL Skype Jabber   Вверх
KSURi
Дата 22.9.2011, 18:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 887
Регистрация: 8.6.2006
Где: Russia

Репутация: 20
Всего: 27



Модифицированные это в смысле разные словоформы? Если да, то я упомнул, что их надо нормализовать — лемматизировать.
Иначе не понятно, что имелось в виду.


--------------------
Died at Life.pl line 21
PM Jabber   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Perl"
korob2001
sharq
  • В этом разделе обсуждаются общие вопросы по языку Perl
  • Если ваш вопрос относится к системному программированию, задавайте его здесь
  • Если ваш вопрос относится к CGI программированию, задавайте его здесь
  • Интерпретатор Perl можно скачать здесь ActiveState, O'REILLY, The source for Perl
  • Справочное руководство "Установка perl-модулей", можно скачать здесь


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, korob2001, sharq.

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Perl: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.1259 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.