Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Perl: Общие вопросы > Inverted File indexer


Автор: LisaST 23.4.2006, 16:48
я практически в отчаянии,т.к. мне как совершенно начинающему надо написать "Inverted file indexer" для списка текстов (без HTML тегов). 
Даже не знаю, с какой стороны мне подойти к этой проблеме...может быть кто-то посоветует, что где почитать или идеи для алгоритма. Нашла в инете много теории, ну и также знаю, что есть Perlfect Search, кот. индексирует веб страницы.  

Автор: rcdimon 24.4.2006, 07:37
Пожалуйста подробнее изложите суть проблемы 

Автор: LisaST 24.4.2006, 13:57

Имеется корпус текстовый(архив):http://www.cis.uni-muenchen.de/~heller/docs/corpora/heise-newsticker.tar.gz

Мне надо написать программу, кот. индексирует этот корпус (http://en.wikipedia.org/wiki/Inverted_file_index), подробностей больше в задании не указано, только написать "inverted file indexer"



 

Автор: rcdimon 24.4.2006, 16:21
МНе кажется что здесь очень хорошо было бы использовать базу данных. например MySQL. И проводить индексацию ее средствами, благо там они очень хорошо развиты. Вынимать и засовывать информацию из базы- одно удовольствие. Так что советую, если возможно, сделать именно с ней. И тогда дополнительная, ручная индексация не потребуется

Добавлено @ 16:23 
А если вам так необходимо сделать индексацию вручную, то для начала неплохо бы разработать алгоритм индексации.  

Автор: nitr 24.4.2006, 17:07
чуть оффтоп: 
Цитата(rcdimon @  24.4.2006,  16:21 Найти цитируемый пост)
Вынимать и засовывать информацию из базы- одно удовольствие.

А можно привести примерчик импортирования из xls в БД (mysql) (xls - Excel 2.0)
 

Автор: LisaST 24.4.2006, 23:08
В Databases  я вообще полный ноль, еще хуже чем в Perl. Вот тут нашла примерно, что мне надо сделать в виде алгоритма (http://web.cs.wpi.edu/~cs4241/2000d/invfile.pdf), но как это сделать  smile  подскажите, есть ли какие-то модули и как например считывать в перл не отд. файл , а директорию с файлами?

Я думаю, для начала мне надо удалить все стоп слова+знаки препинания и нормализировать все слова (стемминг).   


 

Автор: rcdimon 25.4.2006, 07:16
ПО моему с базой данных легче разобраться  smile 

Тем более что она вам еще не одну сотню рас пригодится потом

Добавлено @ 07:18 
Давайте поясним зачем вам индексация. Вы хотите производить поиск по тексту? Или как?
У вас один текстовый файл для индексации или множество? Как планируется выводить результаты после поиска, если это все для поиска? 

Автор: LisaST 26.4.2006, 01:11
Цитата
Давайте поясним зачем вам индексация. Вы хотите производить поиск по тексту? Или как?
У вас один текстовый файл для индексации или множество? Как планируется выводить результаты после поиска, если это все для поиска? 


у меня просто такая нагрузка сейчас, что совсем нет времени заниматся ДБ, но месяца через 2-3 придется освоить. 

Для чего будут в дальнейшем использоваться индекс. файлы, я не знаю, но по дефолту скорее всего для поиска. Файлов множество и все они сохранены в директории.как выводить результаты, пока не знаю, скорей всего просто список, где слева слово-токен, а справа, номера документов, в кот. оно встречается, наверное в виде key- value.

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

Автор: BlackLFL 26.4.2006, 08:02
Цитата(LisaST @  26.4.2006,  02:11 Найти цитируемый пост)
остались все те же вопросы: как считывать все файлы в директории и в дальнейшем при чтении токена записывать каждый в отд. файл???   

http://moongate.ru/perl/examples/tree.pl 

Автор: rcdimon 26.4.2006, 08:17
Считать файл

open (MYFILE, "1.txt");
$/ = undef;
$content = <MYFILE>;
close (MYFILE);

Или можно считать построчно. Каждая строка текста в файле станет элементом массива- по моему очень удобно!

open (MYFILE, "1.txt");
@content = <MYFILE>;
close (MYFILE);


Ну а запись так

open (MYFILE, ">>1.txt");
print MYFILE $text;
close (MYFILE);

Это добавляет в конц файла новые данные

open (MYFILE, ">1.txt");
print MYFILE $text;
close (MYFILE);

Это очищает полностью файл перед записью, а потом записывает. 

Автор: LisaST 26.4.2006, 13:14
Спасибо большое за ссылку "дерево каталоговь, попытаюсь осилить tokenizer 

Автор: LisaST 30.4.2006, 19:42
Кое-что обнаружила в интернете у "совместными усилиями" пытаюсь написать tokenizer. Этот код выдает ошибку readline() on closed filehandle FILE at indexer1.pl line 17, в чем проблема? как записать каждый токен в отдельный файл, где также указан номер(=название) документа из которого он происходит smile
И еще вопрос, что обозначает ? не после блока , а в   начале в regular expressions?

спасибо




Код

#!/usr/bin/perl -w

use strict;

 my $directory = "/newsticker/meldung";
 opendir(DIR, $directory) || die "$directory: $!";
 my @files = readdir(DIR);
 closedir(DIR);

 my @output = ();
 my @input = @_;

 foreach(@files){

  open(FILE, "<$_");

  my $title = $_;
  @input = <FILE>;
 

 FIRST: foreach (@input) {
    my $line;
    my $i;
    my @words;
    $line = $_;
    chomp($line);
    if ($line =~ /^\s*$/) {
      next FIRST;
    }
    $line =~ s/^\s*//;
    $line =~ s/\s*$//;
    @words = split(/\s+/,$line);
    $line = "";
    $i = 0;
    while ($i <= $#words) {
      # remove punctuation from start of word
      if ($words[$i] =~ /^(["'\(\)\[\]\$:;,\/\%])(.+)$/ and 
          $words[$i] !~ /^'[dsm]$/i and $words[$i] !~ /^'re$/i and
          $words[$i] !~ /^'ve$/i and $words[$i] !~ /^'ll$/i) {
    splice(@words,$i,1,$1,$2);
    $i++;
    # remove sentence breaking punctuation with quote from end of word
      } elsif ($words[$i] =~ /^(.+)([?!\.])(["'])$/) {
    splice(@words,$i,1,$1,"$2$3"," ");
    # remove non-sentence-breaking punctuation from end of word
      } elsif ($words[$i] =~ /^(.+)([:;,"'\)\(\[\]\%])$/) {
    splice(@words,$i,1,$1,$2);
    # remove sentence-breaking punctuation (not period) from end of word
      } elsif ($words[$i] =~ /^(.+)([?!])$/ or
               $words[$i] =~ /^(.+[^\.])(\.\.+)$/) {
    splice(@words,$i,1,$1,$2," ");
    # separate currency symbol from value
      } elsif ($words[$i] =~ /^([A-Za-z]+\$)(.+)$/i) {
    splice(@words,$i,1,$1,$2);
    $i++;
    # separate currency symbol other symbols
      } elsif ($words[$i] =~ /^(.*)-\$(.*)$/i) {
    splice(@words,$i,1,$1,"-","\$",$2);
    $i++;
    # split words like we're did't etcetera
      } elsif ($words[$i] =~ /^(.+)('re|'ve|'ll|n't|'[dsm])$/i) {
    splice(@words,$i,1,$1,$2);
    # split words with punctuation in the middle
      } elsif ($words[$i] =~ /^(.*[a-z].*)([",\(\)])(.*[a-z].*)$/i) {
    splice(@words,$i,1,$1,$2,$3);
    # separate words linked with sequence (>=2) of periods
      } elsif ($words[$i] =~ /^(.*[^\.])(\.\.+)([^\.].*)$/) {
    splice(@words,$i,1,"$1$2",$3);
    # remove initial hyphens from word
      } elsif ($words[$i] =~ /^(-+)([^\-].*)$/ and $words[$i] ne "-DOCSTART-") {
    splice(@words,$i,1,$1,$2);
    
    # separate number and word linked with hyphen
      } elsif ($words[$i] =~ /^([0-9\/]+)-([A-Z][a-z].*)$/) {
    splice(@words,$i,1,$1,"-",$2);
    # separate number and word linked with period
      } elsif ($words[$i] =~ /^([0-9\/]+)\.([A-Z][a-z].*)$/) {
    splice(@words,$i,1,"$1.",$2);
    # separate number and word linked with period
      } elsif ($words[$i] =~ /^(.*)\.-([A-Z][a-z].*)$/) {
    splice(@words,$i,1,"$1.","-",$2);
    # separate initial from name
      } elsif ($words[$i] =~ /^([A-Z]\.)([A-Z][a-z].*)$/) {
    splice(@words,$i,1,$1,$2);
    # introduce sentence break after number followed by period
      } elsif ($i != 0 and $words[$i] =~ /^(.*[0-9])(\.)$/) {
    splice(@words,$i,1,$1,$2," ");
    # split words containing a slash if they are not a URI
      } elsif ($words[$i] !~ /^(ht|f)tps*/i and 
               $words[$i] =~ /[^0-9\/\-]/ and
               $words[$i] =~ /^(.+)\/(.+)$/) {
    splice(@words,$i,1,$1,"/",$2);
    # put sentence break after period if it is not an abbreviation
      } elsif ($words[$i] =~ /^(.+)(\.)$/ and $words[$i] !~ /^\.+$/ and
               $words[$i] !~ /^[0-9]+\./) {
     my $word = $1;
    if ($i != $#words and &abbrev($word)) {
      $i++;
    } else { 
      splice(@words,$i,1,$1,$2," ");
    }
      } else {
    $i++;
      }
    }
    $line = join(" ",@words);
    $line =~ s/\s+/ /g;
#    $line =~ s/ ([?!\.]) (["']) / $1 $2 /g;
#    $line =~ s/ *\n *//g;
#    $line =~ tr/A-Z/a-z/;
    push @output, $line;
  }
  my($retval) = join(" ", @output);
  chomp($retval);
 
}
 

Автор: LisaST 30.4.2006, 23:51
еще одна проблема, загрузила CPAN модуль, установила его, как написано в readme, при  компиляции ошибка: can't locate Text/German.pm in @INC (@INC contains: usr/lib/perl5/5.8/cygwin/usr/lib/per5/5.8 ....и так еще 5 раз, потом  Lingua/Stem/De.pm line 39
Compilation failed in require at indexer1.pl line 3 


Я модулями еще никогда не пользовалась, что я делаю неверно?

Код

use Lingua::Stem::De;
    my $stems   = Lingua::Stem::De::stem({ -words => $word_list_reference,
                                          -locale => 'de',
                                      -exceptions => $exceptions_hash,
                                     });
 

Автор: nitr 1.5.2006, 22:17
введи >perl -MCPAN -e 'install Text::German' 

Автор: LisaST 1.5.2006, 23:21
ввела, не компилируется пишет: 

Can't use an undefined value as an ARRAY reference at /usr/lib/perl5/site_perl/5.8/Lingua/Stem/De.pm line 94

т.е. что-то в самом пакете не так, а что я могу сделать? 

Автор: LisaST 4.5.2006, 23:09
up 

Автор: LisaST 12.5.2006, 01:48
так, все ясно, я совсем чайник полный, разобралась, но еще кучу всего надо исправлять и доделывать 

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)