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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> сравнение файлов, странный результат 
:(
    Опции темы
Zuzu
Дата 26.1.2007, 11:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Цитата(LisaST @  26.1.2007,  00:42 Найти цитируемый пост)
надо будет просто дополнить <regex>


`` You mean some of the defendants made statements admitting this '' ? ?


Напиши, пожалуйста, что было до обработки этого предложения  (там, возможно, были пробелы)

Про <to be>.

Приведи, пожалуйста, точный пример: 

Исходное предложение:
То же предложение, "обработанное" goldStandart:
То же предложение, обработанное tagger:

Математическая модельтребует, чтобы тексты (для tagger и goldStandart) были абсолютно, слово в слово, одинаковые. 

Проблему с I'm можно решить, путем переведения "I'm" в "I am" (для goldStandart) либо обратно "I am"  в I'm для (tagger).  По этому поводу можно либо написать маленькую программку и обработать ей goldStandart (или tagger) - текст  Затем, для первого случая, - по накатанной дорожке (убрать тэги, скормить tagger'у, скормить програмрамме - считальщику качества тэггера). После этого было бы неплохо сравнить "пословно" файлы. В принципе, программа-анализатор, в качестве бесплатного приложения, это сделает.

Третий способ (в моем случае) - взять данные "как есть" и возложить эту непосильную задачу (по приведению I'am r I am) на объект GoldStorage или TaggerStorage Как чувствовал, что будут проблемы с исходными данными! Поэтому при проектировании не воспользовался одним классом Storage, а породил от него два класса: GoldStorage и TaggerStorage!

LisaST, спасибо за отзыв по коду. Если по каким-то причинам нет возможности (или, как вариант, времени на изучение) ООП-механизмов на Perl, напиши, как тебе удобнее. Тем более, что с "трансформерами" я несколько перемудрил. В принципе, для "приведения диалекта тэга к каноническому виду", достаточно такого механизма, как хэш.

P.S. По терминологии ООП, которую я использовал: интерфейс класса (или порожденного от  него объекта) - есть множество (или совокупность) методов и свойств, которые разрешены к использованию по отношению к объекты (в терминологии классического ООП - public методы и свойства). Понятия свойство и метод - аналогичны классическим определениям. Понятия "пакет" и "модуль" вроде не использовал. Уж очень отличаются эти понятия в контексте UML и perl, например. Но это здесь offtopic.
--------------------
Проводить эксперименты на живом сервере опасно, а на мертвом - бесполезно.
PM   Вверх
amg
Дата 26.1.2007, 13:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1145
Регистрация: 3.8.2006
Где: Новосибирск

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



Цитата(Zuzu @  26.1.2007,  11:24 Найти цитируемый пост)
Математическая модельтребует, чтобы тексты (для tagger и goldStandart) были абсолютно, слово в слово, одинаковые.
 Вот с этим, кажется, будут проблемы: смотрите сами, что мне навыдавал CRFTagger, даже на нескольких предложениях уже несколько несоответствий с GoldStandard в количестве слов. 
Код

word       | GoldStandard  | CRFTagger
-----------------------------------------------
Atlanta's  | Atlanta's/np$ | Atlanta/NNP 's/POS
Jr.        | Jr./np        | Jr/NNP ./.
I'm        | I'm/ppss+bem  | I/PRP 'm/VBP
Can't      |               | Ca/MD n't/RB

Убрать все несоответствия на многомегабайтном файле не очень реально, особенно если разные таггеры будут вести себя по разному, все равно останется много ручной работы. 

Повторю (скорее для себя) что уже предлагал Zuzu:
  • 1. Взять GoldStandard (gold.pos) и удалить из него все тэги.
  • 2. Полученный текст пропустить через тестируемый тэггер. Получим tagger.pos
  • 3. В gold.pos и из tagger.pos сделать обозначения тэгов единообразными.
Эти пункты легко осуществить и сомнений они, вроде, не вызывают. А вот дальше хотелось бы соответствующие строки полученных файлов привести в соответствие друг с другом, например, сделав некое их пересечение. Определенные мысли по этому поводу у меня есть, могу попробовать реализовать.
PM MAIL   Вверх
Zuzu
Дата 26.1.2007, 13:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Мысли по поводу решения задачи в связи с появлением такого артефакта, как "разные слова". 

В математической модели я потребовал, в качестве определения контекста слова расположение по отношению (ко всем) к другим словам в тексте.  Это несколько больше, чем определение контекста с точки зрения лингвистики (ИМХО, могу и ошибаться). Если сузить определение контекста до взаимного расположения слов внутри предложения (нужно еще, конечно, четко определить, что такое предложение smile ), а те предложения, внутри котрых определение контекста нарушается просто выкинуть из данных (на этапе обработки), то получим, на большом тексте, достаточно точную оценку работы тэггера. И останемся в рамках модели, что гарантирует правильность результата. smile



--------------------
Проводить эксперименты на живом сервере опасно, а на мертвом - бесполезно.
PM   Вверх
amg
Дата 26.1.2007, 14:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1145
Регистрация: 3.8.2006
Где: Новосибирск

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



Цитата(Zuzu @  26.1.2007,  13:29 Найти цитируемый пост)
Если сузить определение контекста до взаимного расположения слов внутри предложения
 Вроде, CRFTagger так и делает (могу ошибаться).

Цитата(Zuzu @  26.1.2007,  13:29 Найти цитируемый пост)
нужно еще, конечно, четко определить, что такое предложение 
То, что находится в пределах одной строки (так в GoldStandard'е, а другого текста и иным расположением предложений, я так понимаю, все равно взять неоткуда, точнее, взять то можно, но не с чем будет сравнивать).

Цитата(Zuzu @  26.1.2007,  13:29 Найти цитируемый пост)
а те предложения, внутри котрых определение контекста нарушается просто выкинуть из данных (на этапе обработки)
Хорошая мысль. Это легко реализовать. Хотя из тех 6-ти предложений GoldStandard'а, что приводила LisaST, для 3-х CRFTagger дает другое кол-во слов.

PM MAIL   Вверх
LisaST
Дата 26.1.2007, 21:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Цитата

1. Напиши, пожалуйста, что было до обработки этого предложения  (там, возможно, были пробелы)

Про <to be>.

2.Приведи, пожалуйста, точный пример: 

Исходное предложение:
То же предложение, "обработанное" goldStandart:
То же предложение, обработанное tagger:


1. нет, пробелов не было, самое интересное, что двойные точки не остались, а ?, !, :,; остались в двойном варианте, но мы знаки препинания все равно будем игнорировать, я удалила двойные с помощью sed и протестировала таггер на этом голдстандард тексте

2. внизу пример для одного и того же предложения, т.е. в голдстандард кол-во слов будет на 1 меньше, но таких примеров будет очень много, как ты предлагаешь позднее- их лучше после проверки игнорировать, т.к. они очень усложняют задачу.

ps Еще в голдстандард варианте с тегами видимо проводили chunking, поэтому на теги иногда навешаны дополнительные теги к части речи не имеющие ничего общего (-tl, -hl, -tl-hl),  мне их надо удалить, чтобы упростить нахождение соотв. тегов. 

 

 

goldstandard.txt
Код

I'm/ppss+bem willing/jj to/to stake/vb my/pp$ political/jj career/nn on/in it/ppo ''/'' ./.

tagger.txt

Код

I/PRP 'm/VBP willing/JJ to/TO stake/VB my/PRP$ political/JJ career/NN on/IN it/PRP ''/'' ./.


Цитата

Эти пункты легко осуществить и сомнений они, вроде, не вызывают. А вот дальше хотелось бы соответствующие строки полученных файлов привести в соответствие друг с другом, например, сделав некое их пересечение. Определенные мысли по этому поводу у меня есть, могу попробовать реализовать.


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

например, один из вариантов посчитать "/" (что будет подразумевать кол-во тегов) для каждого предложения, если есть расхождения, то предложения в анализе не использовать (т.е. там будут расхождения как в примере выше)

Это сообщение отредактировал(а) LisaST - 26.1.2007, 21:47
PM MAIL   Вверх
Zuzu
Дата 27.1.2007, 09:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



По поводу "предложений с разными словами" есть такая сырая идея. 

Основная мысль, собственно, проста. Исходные тексты у нас нормальные - мы их сами такими старались-готовили. И, наверно, даже проверяли, чтобы они изначально были "пословно равны"!.  Если собака-тэггер попортил наши данные, путем "вставления в предложения" нового слова, то удаление этого слова может только улучшить ситуачию, т.к. приводит ее к тому виду, который был раньше.  smile 

Опять-же, сильно он напортить не мог. Ему ведь отдали "нормальное предложение", его задача не "испортить предложение", а тэги расставить! А то, что предложения испортилоси это получилось у него так, случайно, случайно. smile

1. Пусть предложения равны, если они "пословно" равны.

2. Пронумеруем предложения сверху вниз по двум текстам (от tagger и goldStandart).

3. По построению (т.е. текст-то мы делали сами!) у нас получается, что кол-во предложений в первом тексте и во втором - одинаковое. 

4. Если не сошлось кол-во предложений - оставшиеся предложения в каком-то тексте отбросим, результат посчитаем, но будем считать его недостоверным - это повод проверить исходные данные.

5. Пусть в некотором числовом выражении мы получили критерий "степени равенства предложений". Это должна быть некоторая функция, определенная на двух предложениях (из разного текста, но с одним номером), которая, как вариант, достигает своего локального (на этих двух предложениях), максимального значения при равенстве предложений (пословно). 

Или, говоря по-русски, в каждый момент времени, нас интересует ее максимум на этой "двойке предложений" (т.е. локальный максимум). В этот момент на остальные предложения нам абсолютно наплевать. И вообще, как соотносятся эти максимумы для разных "двоек" - нам тоже абсолютно безразлично.

6. Итак, взяли двойку предложений, пронумеровали слова, сравнили их пословно, выяснили, что предложения не равны.

7. Находим в предложениях то слово, по которому они не сошлись. Т.е. находим такое n (слова), что w1(n) ne w2(n), где w1(n), w2(n) - слова с номером n в первом и втором предложении соответственно, "ne" - операция сравнения строк на неравенство от Perl.

8. Считаем исходный "критерий равенства предложений", запоминаем его в c0. 

9. Из исходного первого предложения выбрасываем слово с номером n, считаем "критерий равенства предложений" для "поправленного первого" и "исходного второго" предложения, запоминаем в c1

10. Аналогично поступаем со вторым предложением, запоминаем значение в c2

11. Выбрасываем слово с номером n и из первого (исходного) и из второго (исходного) предложения, считаем "критерий равенства", запоминаем значение в с3

12. По максимальному значению из с0, c1, с2, с3 выбираем тот способ, которые "лучше уравнивает предложения", его и пременяем к двойке предложений. Т.е. выбрасываем слово либо из первого предложения, либо слово из второго либо слово с номером n из первого и из второго предложения. Либо ничего ниоткуда не выбрасываем. 

13. Если что-то выбросили , сравниваем предложения. Если не равны - переходим к п. 7.

14. Если получилось, что исходные предложения не равны, а значение с0 - максимально, предложение бракуем - оно не участвует в подсчете качества тэггера.

smile

Как определить "критерий равенства предложений"? С этим сложнее... Надо смотреть... Пока четкой мысли нет.

P.S. Разговор про локальный максимум функции. Наверно вспоминается (кому-то пресловутый) курс математического анализа. Как находили локальный экстремум (минимум, максимум, перегиб) функции в мат. анализе? Правильно, путем двойного последовательного дифференцирования функции, приравнивания первой  производной для нахождения точек экстремума и выяснения знака второй производной в этой точке для выяснения типа точек экстремума. 

Казалось бы, все просто. НО! У нас-то функция дискретная, а значит не являющаяся непрерывной! Следовательно, ее нельзя дифференцировать.  Значит вся эта "крутая теория" в нашем случае неприемлима. Я кстати, изначально слукавил - в теоремах про нахождение локального максимума и минимума изначально говорится о том, что они пименимы к два раза диференцируемым (читай - непрерывным и с непрерывной первой произодной) функциям.

К чему я все это? Так вот. Если вдруг удастся построить функцию "критерия равенства" таким образом, что бы она была непрерывна, то можно будет решить задачу "выбрасывания лишних слов" аналитически, т.е. не перебирая все варианты. В чем прикол? А в том, что затем ее можно будет применить к какому угодно большому тексту и время которое будет необходимо для "выбрасывания" слов будет зависеть только от количества "плохих слов", а не от размера самого текста. Вот так. Высшая математика (а пока мы коснулись только ее основ - на уровне первого курса вуза) РУЛИТ!


Это сообщение отредактировал(а) Zuzu - 27.1.2007, 10:29
--------------------
Проводить эксперименты на живом сервере опасно, а на мертвом - бесполезно.
PM   Вверх
Zuzu
Дата 27.1.2007, 10:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



LisaST, и еще. Как бы я реализовывал все это дело (программу в целом). С учетом разных слов.

Следал бы объект "предложение". Он бы запрашивам предложения у объекта "хранилище".

(см. мой код)

Написал бы метод, который бы "нормализовал" два предложения.  Т.к. пока непонятно как он должне работать - он бы просто ничего интеллектуального не делал. Разве что предложения друг с другом сравнивал пословно и возводил в обоих объектах-предложениях флажок, если предложения не равны.

Слово и тип слова запрашивал  бы у объекта "предложение", пока там есть слова. Попросил бы объект "предложение" возвращать слова только в том случае, если предложения равны.

Вот собственно. В первом приближениии получится, что "предложения с разными словами" мы будем пропускать.

В реальном проекте, если не хватит ресурсов (времени на разработку или денег у заказчика, как вариант) получил бы работающий в некотором приближении проект, которому в дальнейшем (при появлении ресурсов) можно достаточно просто "добавить интеллекта", не переписывая его целиком (и, собственно, особо не вникая во всю проблему, а только обозначив ее часть - функцию "критерий равенства предложения").

Это сообщение отредактировал(а) Zuzu - 27.1.2007, 11:02
--------------------
Проводить эксперименты на живом сервере опасно, а на мертвом - бесполезно.
PM   Вверх
amg
Дата 27.1.2007, 10:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1145
Регистрация: 3.8.2006
Где: Новосибирск

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



Цитата(LisaST @  26.1.2007,  21:42 Найти цитируемый пост)
один из вариантов посчитать "/" (что будет подразумевать кол-во тегов) для каждого предложения
Но может же встретиться, например, дата в формате 2007/1/27 ? Лучше, возможно, подсчитывать кол-во слов:
Код

$count++ while /\S+/g; # или
$count = scalar split;



Это сообщение отредактировал(а) amg - 27.1.2007, 12:01
PM MAIL   Вверх
amg
Дата 27.1.2007, 15:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1145
Регистрация: 3.8.2006
Где: Новосибирск

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



LisaST, предлагаю Вам набор скриптов. К сожалению, совсем некогда сейчас подробно расписывать, что они делают. Если что не понятно будет, то позже поясню. Собственно, осталось только реализовать алгоритм подсчета индексов, который Вы с Zuzu обсуждали, на "нормализованных" файлах это должно быть легко.
Первые 4 скрипта используют конструкцию while (<>) {} и печатают на stdout, т.е. можно использовать конвейеры:
tag-good GoldStandart.pos | tag-uni -G > GoldStandart.pos.uni
tag-good CRFTagger.pos | tag-uni -С > CRFTagger.pos.uni
tag-norm GoldStandart.pos.uni CRFTagger.pos.uni
Код


# tag_rm: remove tags

while (<>) {
  chomp;
  s/\/\S+//g;
  s/\s+/ /g;
  s/^\s+//;
  s/\s+$//;
  print "$_\n";
}

Код

# tag_good: remove word/tag with "bad" words

$good_word = qr/^[^\W\d_]+$/; # Only letters
#$good_word = qr/^[[:^punct:]]+$/; # Except punctuations

while (<>) {
  chomp;
  $str = '';
  while (/((\S+)\/\S+)/g) {
    ($wt,$w) = ($1,$2);
    $str .= "$wt " if $w =~ /$good_word/o;
  }
  chop $str;
  print "$str\n";
}

Код

# tag-uni: unification of tags

use Getopt::Std;
getopts('GC', \%opts);

# Для каждого тэггера нужно задать свою опцию и раскладку тэгов
# Незаданные тэги будут превращаться в "xx"
if      ($opts{G}) {
  map {$hash{$_}='nn'} qw(nn nn-tl nns np np$ np-tl nr);
  map {$hash{$_}='vb'} qw(vb vbd vbg vbn vbz);
} elsif ($opts{C}) {
  map {$hash{$_}='nn'} qw(NN NNP NNPS NNS);
  map {$hash{$_}='vb'} qw(VB VBD VBG VBN VBP VBZ);
} else {
  die "
Usage: $0 -option tag-file
option: G - for GolgStandatd
        C - for CRFTagger\n";
}

while (<>) {
  s/\/(\S+)(\s|\n)+/"\/".($hash{$1} or 'xx').$2/eg;
        print;
}

Код

# tag_stat: tag statistics

$need_word_statistics = 0; # 1

while (<>) {
  chomp;
  $TAG{$2}{$1}++ while m/(\S+)\/(\S+)/g;
}

foreach $tag (sort keys %TAG) {
  $count = 0;
  $count += $_ foreach values %{$TAG{$tag}};
  print "$tag\t\t$count\n";
  if ($need_word_statistics) {
    foreach (sort keys %{$TAG{$tag}}) {
      print "\t$_\t$TAG{$tag}{$_}\n";
    }
  }
}

Код

# tag-norm: normalize two tagged files

require 5.007; # For fast &our_sort

$file1=shift and $file2=shift or die "Usage: $0 file1 file2\n";
#die "Inconsistent files\n" if `wc -l < $file1` != `wc -l < $file2`;

open INP1, $file1 or die "Can't open $file1: $!\n";
open OUT1, "> $file1.norm" or die "Can't wrte to $file1.norm: $!\n";

open INP2, $file2 or die "Can't open $file2: $!\n";
open OUT2, "> $file2.norm" or die "Can't wrte to $file2.norm: $!\n";

while (defined($str1 = <INP1>) and defined($str2 = <INP2>)) {
  ($str1,$str2) = norm($str1,$str2);
  print OUT1 "$str1\n";
  print OUT2 "$str2\n";
}

close INP1; close INP2; close OUT1; close OUT2; 

sub norm {
  my @ar1 = our_sort($_[0]);
  my @ar2 = our_sort($_[1]);
  #print "@ar1\n@ar2\n";
  my $i = 0;
  while ($i < $#ar1 && $i < $#ar2) {
    if ($i == $#ar1 && $#ar2 > $#ar1) {
      print 'Delete ', splice(@ar2,$i+1), " from $file2, at end of line $.\n"; 
      last;
    }
    if ($i == $#ar2 && $#ar1 > $#ar2) {
      print 'Delete ', splice(@ar1,$i+1), " from $file1, at end of line $.\n";
      last;
    }
    $ar1[$i] =~ /^(\S+)\//, my $v1 = $1;
    $ar2[$i] =~ /^(\S+)\//, my $v2 = $1;
    my $cmp = $v1 cmp $v2;
    #print "$cmp = $v1 cmp $v2\n";
    if      ($cmp == 0 ) {
      $i++;
      next;
    } elsif ($cmp == 1 ) {
      print 'Delete ', splice(@ar2,$i,1), " from $file2, line $.\n";
    } elsif ($cmp == -1) {
      print 'Delete ', splice(@ar1,$i,1), " from $file1, line $.\n";
    } else { die "Bad cpm\n" }
  }
  return join(' ',@ar1), join(' ', @ar2);
}

sub our_sort {
  return 
  sort {
    my ($aa) = $a=~/(\S+)\//;
    my ($bb) = $b=~/(\S+)\//;
    $aa cmp $bb;
  } 
  split ' ', $_[0];
}


Это сообщение отредактировал(а) amg - 30.1.2007, 10:02
PM MAIL   Вверх
LisaST
Дата 27.1.2007, 18:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Цитата

LisaST, и еще. Как бы я реализовывал все это дело (программу в целом). С учетом разных слов.

Следал бы объект "предложение". Он бы запрашивам предложения у объекта "хранилище".

(см. мой код)

Написал бы метод, который бы "нормализовал" два предложения.  Т.к. пока непонятно как он должне работать - он бы просто ничего интеллектуального не делал. Разве что предложения друг с другом сравнивал пословно и возводил в обоих объектах-предложениях флажок, если предложения не равны.

Слово и тип слова запрашивал  бы у объекта "предложение", пока там есть слова. Попросил бы объект "предложение" возвращать слова только в том случае, если предложения равны.

Вот собственно. В первом приближениии получится, что "предложения с разными словами" мы будем пропускать.



спасибо вам большое обоим за участие в решении проблемы и помощь. нормализацию, как я поняла амг реализовал в последнем отрывке кода, я попробую завтра все это потестировать. Высшую мат-ку я, к сожалению, не проходила, из определения мах и мин помню только Lagrangian algorithm 

Цитата

Но может же встретиться, например, дата в формате 2007/1/27 ? Лучше, возможно, подсчитывать кол-во слов:


согласна, "/" в голдстандард без тегов не встречается, но в другом тексте вполне вероятно 


--------------------------------
к коду от амг, я там многого не понимаю, конечно

1. ($good_word = qr/^[^\W\d_]+$/; # Only letters ->  я так поняла, что "[^\W\d_]" = \w
^ перед [, это начало сроки? 
   #$good_word = qr/^[[:^punct:]]+$/; # Except punctuations) -> 
в этом отрывке кода мы пытаемся удалить -tl, -hl etc? оставив только слово и тег после него, кот. тоже является словом?


!возникает проблема, т.к. существуют "нормальные теги" , которые заканчиваются на $, например pp$


2. 
Код

$TAG{$2}{$1}++ while m/(\S+)\/(\S+)/g;
}
foreach $tag (sort keys %TAG)
 

не совсем понимаю, что в $TAG keys, a что values?


3. 
Код

return grep {s/\/\d{3}/\//}
         sort 
         grep {s/^(\S+)\/(\S+)$/$1."\/".sprintf("%03d",$i++).$2/e} 



не понятно, что имелось ввиду с digits (\d) здесь?
и вот с этим выражением не разобралась :
sprintf("%03d",$i++)
-------------------------------------------------------------------------
sorry за простые вопросы, но я в модулях перл никак и вообще дальше user не забредала

PM MAIL   Вверх
Zuzu
Дата 29.1.2007, 10:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Обещанная полное описание требований и определений для задачи:


Понятия: слово, предложение, часть речи (по отношению к слову), текст, равенство слов определяются исходя из общеупотребительного значения соответствующего понятия.

Два слова равны, если они побуквенно, слева направо, равны.

Слово обозначим за wrd.

Контекст (слова) - взаимное расположение слова относительно слов в преджложении.

Тип слова  - часть речи, к которой принадлежит слово.

Канонический тип слова - название типа слова, которое выбрал пользователь для каждого типа слова. Если не указано особо, подразумевается именно канонический тип слова.

Наречие таггера, названия типов слов, которое возвращает таггер. Обозначим также как тип слова от таггера.

Таггер (tagger) - некая процедура, которая ставит слову в соответствие его тип из множества типов из наречия таггера. Различают тестируемый таггер - тот качество которого мы оценивает, назовем его собственно таггер() (или tagger()) и tagger - образец, который сопоставляет слову его тип заведомо правильно. Назовем его goldStandart() . Результатом работы таггера является тип слова в соответствии с наречием таггера.

Трансформация наречия (таггера)  - некий механизм приведения наречия таггера к каноническому виду. Возможно реализуется в виде отношения много (типов от таггера) к одному (каноническому типу). Обозначим соответственно trT() и trG() для tagger() и goldStandart() соответственно. Возможен вариант, когда элемент наречия таггера не имеет значения в каноническом типе.

Для определения равенства предложений, будем считать предложение также упорядоченным множеством слов, его составляющим. Для этого пронумеруем слова в предложении слева направо.

Предложения равны, если слова с одинаковыми номерами в первом и втором предложении равны. 

Для определения равенства текстов пронумеруем предложения в тексте с начала до конца тектса.

Тексты равны, если предложения первого и второго текста с одинаковыми номерами равны. 

Множество слов W - определим как упорядоченное множество троек (p, n, wrd), где p - порядковый номер предложения в тексте, n - порядковый номер слова в предложении, w слово. p(W) - количество (число) элементов в этом множестве. Двух одинаковых элементов-слов в (одном) множестве нет! Элемент множества (тройку (p, n, wrd)) обозначим за w

Дополнительно заметим, что tagger() и goldStandart() должны быть определены на всем этом множестве W. 

Релевантность - правильность определения tagger()'oм типа слова. Может принимать только значения "да" или "нет". Для w из W релевантность считается истиной, если trT(tagger(w)) == trG(goldStandart(w)). 

Заметим, если слова, (в общем случае) взяты из разных текстов, то релевантность для слов (не для тройки w!) имеет смысл только если эти слова (как слова) равны и взяты в одинаковом контексте (т.е. из одинаковых (равных) предложений, слова с одинаковыми номерами). Это уменьшение строгости , в принципе, позволяет применять определение релевантности к "неравным" текстам и по ним считать Recall и Precision (естественно, для этого, множество W должно быть специальным построено по этим двум текстам!).

Напомним, что t - некоторый канонический тип слова. Общее кол-во отпределенных слов одного типа - количество элементов w из всего W, тип которым тэггер определил как t (правильно или нет - нас не интересует). Обозначм как NT(t) (для типа t).

Общее кол-во правильных слов одного типа - количество элементов w из всего W, тип которым goldStantart определил как t (обязательно правильно - по построению goldStandart) Обозначм как NG(t) (для типа t).

Общее кол-во правильно определенных слов одного типа - количество элементов w из всего W, тип которым тэггер определил как t  правильно (т.е. так же как goldStandart) или, другими словами, релевантно. Обозначим N(t) (для типа t).

И, собственно, самое главное (наконец-то!)

Еще раз: t - тип слова.

Precision (насколько точно выбирает) Отношение кол-ва правильно выбранных (релевантных) слов к общему кол-ву выбранных тэггером для определенного типа.  Precision(t) = (N(t) / NT(t)) * 100%

Recall (как вообще выбирает) Отношение кол-ва релевантно выбранных тэггером слов к общему кол-ву правильных слов для определенного типа.  Recall(t) = (N(t) / NG(t)) * 100%

Вроде все. За границами остался алгоритм "нормализации" предложений. если они не равны.

Смтрите, может где ошибся - немаленький текст получился. smile


Это сообщение отредактировал(а) Zuzu - 31.1.2007, 11:42
--------------------
Проводить эксперименты на живом сервере опасно, а на мертвом - бесполезно.
PM   Вверх
amg
Дата 29.1.2007, 11:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1145
Регистрация: 3.8.2006
Где: Новосибирск

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



Цитата(LisaST @  27.1.2007,  18:54 Найти цитируемый пост)
$good_word = qr/^[^\W\d_]+$/; # Only letters ->  я так поняла, что "[^\W\d_]" = \w
[^\W\d_] - это \w без \d и _, т.е. только буква

Цитата(LisaST @  27.1.2007,  18:54 Найти цитируемый пост)
#$good_word = qr/^[[:^punct:]]+$/; # Except punctuations) -> в этом отрывке кода мы пытаемся удалить -tl, -hl etc? оставив только слово и тег после него, кот. тоже является словом?
Не так. У меня $good_word - это то, что в конструкции word/tag находится до последнего экземпляра "/". Если хочется обработать тэги, то нужно что-то вроде
Код

# Убрать из тэгов символы начиная с "небуквы" и до конца
while (<>) {
  chomp;
  s|(\S+/[^\W\d_]+)\S+|$1|g;
  print "$_\n";
}


Цитата(LisaST @  27.1.2007,  18:54 Найти цитируемый пост)
не совсем понимаю, что в $TAG keys, a что values?
В выражении $TAG{$2}{$1}++ while m/(\S+)\/(\S+)/g; %TAG - это хэш хэшей. Его ключи - это тэги, значения - ссылки на хэши. У последних ключи - это слова, значения - кол-во слов. Например, $TAG{nn}{work} == 12 означает, что среди слов, помеченных тэгом "nn", слово "work"  встретилось 12 раз. LisaST, обратите, пожалуйста внимание, насколько хорошо perl приспособлен для подобного рода задач! Одно короткое выражение разбирает строку и создает довольно нетривиальную структуру данных (все остальное - лишь представление результатов).

Цитата(LisaST @  27.1.2007,  18:54 Найти цитируемый пост)
не понятно, что имелось ввиду с digits (\d) здесь?...и вот с этим выражением не разобралась: sprintf("%03d",$i++)
Пользуясь случаем, расскажу, как реализована нормировка. Суть нормировки в том, чтобы сравнить две строки и "уникальные" элементы в каждой из строк выкинуть. Элемент - это word/tag. Элементы совпадают, если у них совпадают части "word". 

1. Сортируем элементы каждой строки по алфавиту. Если в пределах одной строки нет совпадающих элементов, то этого достаточно. Соответствие строк не нарушится. Но строки могут выглядеть так:
aaa/xx  work/nn  bbb/xx  work/vb
aaa/xx  work/vb  bbb/xx  work/nn
и простая сортировка по алфавиту даст
aaa/xx  bbb/xx  work/nn  work/vb
aaa/xx  bbb/xx  work/nn  work/vb
Это неправильно. Поэтому сначала элементы нумеруются, затем сортируются и нумерация удаляется.
aaa/xx  work/nn  bbb/xx  work/vb  =>  aaa/001xx  work/002nn  bbb/003xx  work/004vb
aaa/xx  work/vb  bbb/xx  work/nn  =>  aaa/001xx  work/002vb  bbb/003xx  work/004nn
sprintf("%03d",$i++) как раз для вставки номера: это выражение возвращает номер с нулями и затем этот номер инкрементирует.
Кстати, после внимательного прочтения perldoc -f sort выяснилось, что для perl 5.7 и выше функцию, возвращающую сортированный массив, можно упростить. Дело в том, что в этой версии perl ввели алгоритм сортировки, который в случае, если с точки зрения sort элементы совпадают, то сохраняется тот порядок элементов, который был в источнике.
Код

sub our_sort {
  return 
  sort {
    my ($aa) = $a=~/(\S+)\//;
    my ($bb) = $b=~/(\S+)\//;
    $aa cmp $bb;
  } 
  split ' ', $_[0];
}


2. Дальше сравниваем отсортированные массивы: 
- Если элементы совпадают, то переходим к следующим элементам. 
- Если в 1-ом массиве i-й элемент "меньше" (с точки зрения cmp), чем во i-й элемент второго, то удаляем этот элемент из 1-го массива, если "больше" - то из 2-го массива
- Снова сравниваем i-е элементы

Добавлено @ 11:20 
Zuzu, как во-время твой пост! Я как раз собрался листать все 4 страницы этого топика, чтобы точно понять, что такое Recall & Precision. А тут все в одном месте с четкими определениями. 

Кстати, глянь, пожалуйста, алгоритм нормализации и покритикуй, если есть за что.
PM MAIL   Вверх
Zuzu
Дата 29.1.2007, 12:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Цитата(amg @  29.1.2007,  14:08 Найти цитируемый пост)
2. Дальше сравниваем отсортированные массивы: 
- Если элементы совпадают, то переходим к следующим элементам. 
- Если в 1-ом массиве i-й элемент "меньше" (с точки зрения cmp), чем во i-й элемент второго, то удаляем этот элемент из 1-го массива, если "больше" - то из 2-го массива
- Снова сравниваем i-е элементы


То, что алгоритм работает правильно, неочевидно (по крайней мере для меня). Несколько смущает изменение порядка слов. Но на примерах вроде работает. К сожалению доказать неправильность (подобрать хотя бы один пример, когда не сработает) не могу. Строго доказать правильность (что выбросит именно неверные слова) - тоже не приходит на ум, как это можно сделать математически точно. 

Сам код пока не смотрел. 

Предлагаю просто сейчас оставить алгоритм как есть, т.к. (если он работает по задуманному), то на одинаковые предложения он не реагирует. Дополнительно вывести в отдельный файл результаты "нормализации" (где она сработала) и просто оценить "глазами", сработало правильно или нет (да уж, кропотливый труд предстоит!)
--------------------
Проводить эксперименты на живом сервере опасно, а на мертвом - бесполезно.
PM   Вверх
amg
Дата 29.1.2007, 13:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1145
Регистрация: 3.8.2006
Где: Новосибирск

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



Цитата(Zuzu @  29.1.2007,  12:53 Найти цитируемый пост)
Предлагаю просто сейчас оставить алгоритм как есть, т.к. (если он работает по задуманному), то на одинаковые предложения он не реагирует. Дополнительно вывести в отдельный файл результаты "нормализации" (где она сработала) и просто оценить "глазами", сработало правильно или нет (да уж, кропотливый труд предстоит!)
Для проверки можно использовать такой способ:
Код

# Нормализуем два тэггированных файла
tag-norm file1 file2
# Удаляем из каждого из нормализованных файлов тэги
tag-rm file1.norm > file1.norm_
tag-rm file2.norm > file2.norm_
# Получившиеся файлы (без тэгов) должны совпадать
diff file1.norm_ file2.norm_
Это, конечно, не достаточное, но необходимое условие




Это сообщение отредактировал(а) amg - 29.1.2007, 13:18
PM MAIL   Вверх
Zuzu
Дата 29.1.2007, 13:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



amg, здраво, конечно. К сожалению, строго не доказывает, что удалены именно "неправильные" слова. Могут быть с таким же успехом быть удалены и "нормальные" слова (попарно) из обоих текстов.

Для дополнительной проверки можно посчитать кол-во удаленных слов. По специфике построения текста от tager, из него должно быть удалено слов в два раза больше, чем из текста от goldStandart. Это условие должно выполняться для каждого (неверного) предложения текста и, следовательно, для всего текста в целом. LisaST поправит, если это не так.

В целом, т.к. соблюдается указанное тобой в предыдущем топике условие (тексты равны пословно) и нормализация затрагивает только одно предложение (в каждый момент выполнения), думаю, что можно назвать алгоритм "условно правильным".
--------------------
Проводить эксперименты на живом сервере опасно, а на мертвом - бесполезно.
PM   Вверх
Страницы: (6) Все « Первая ... 2 3 [4] 5 6 
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Perl"
korob2001
sharq
  • В этом разделе обсуждаются общие вопросы по языку Perl
  • Если ваш вопрос относится к системному программированию, задавайте его здесь
  • Если ваш вопрос относится к CGI программированию, задавайте его здесь
  • Интерпретатор Perl можно скачать здесь ActiveState, O'REILLY, The source for Perl
  • Справочное руководство "Установка perl-модулей", можно скачать здесь


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

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


 




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


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

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