class Lingo::Attendee::Sequencer

Der Sequencer ist von seiner Funktion her ähnlich dem Multiworder. Der Multiworder nutzt zur Erkennung von Mehrwortgruppen spezielle Wörterbücher, der Sequencer hingegen definierte Folgen von Wortklassen. Mit dem Sequencer können Indexterme generiert werden, die sich über mehrere Wörter erstrecken. Die Textfolge “automatische Indexierung und geniale Indexierung” wird bisher in die Indexterme “automatisch”, “Indexierung” und “genial” zerlegt. Über die Konfiguration kann der Sequencer Mehrwortgruppen identifizieren, die z.B. aus einem Adjektiv und einem Substantiv bestehen. Mit der o.g. Textfolge würde dann auch “Indexierung, automatisch” und “Indexierung, genial” als Indexterm erzeugt werden. Welche Wortklassenfolgen erkannt werden sollen und wie die Ausgabe aussehen soll, wird dem Sequencer über seine Konfiguration mitgeteilt.

Mögliche Verlinkung

Erwartet

Daten vom Typ Word z.B. von Wordsearcher, Decomposer, Ocr_variator, Multiworder

Erzeugt

Daten vom Typ Word (mit Attribut WA_SEQUENCE). Je erkannter Mehrwortgruppe wird ein zusätzliches Word-Objekt in den Datenstrom eingefügt. Z.B. für Ocr_variator, Sequencer, Noneword_filter, Vector_filter

Parameter

Kursiv dargestellte Parameter sind optional (ggf. mit Angabe der Voreinstellung). Alle anderen Parameter müssen zwingend angegeben werden.

in

siehe allgemeine Beschreibung des Attendee

out

siehe allgemeine Beschreibung des Attendee

stopper

(Standard: TA_PUNCTUATION, TA_OTHER) Gibt die Begrenzungen an, zwischen denen der Sequencer suchen soll, i.d.R. Satzzeichen und Sonderzeichen, weil sie kaum in einer Mehrwortgruppen vorkommen.

Konfiguration

Der Sequencer benötigt zur Identifikation von Mehrwortgruppen Regeln, nach denen er arbeiten soll. Die benötigten Regeln werden nicht als Parameter, sondern in der Sprachkonfiguration hinterlegt, die sich standardmäßig in der Datei de.lang befindet (YAML-Format).

language:
  attendees:
    sequencer:
      sequences: [ [AS, "2, 1"], [AK, "2, 1"] ]

Hiermit werden dem Sequencer zwei Regeln mitgeteilt: Er soll Adjektiv-Substantiv- (AS) und Adjektiv-Kompositum-Folgen (AK) erkennen. Zusätzlich ist angegeben, in welchem Format die dadurch ermittelte Wortfolge ausgegeben werden soll. In diesem Beispiel also zuerst das Substantiv und durch Komma getrennt das Adjektiv.

Beispiele

Bei der Verarbeitung einer normalen Textdatei mit der Ablaufkonfiguration t1.cfg

meeting:
  attendees:
    - text_reader:   { out: lines, files: '$(files)' }
    - tokenizer:     { in: lines, out: token }
    - word_searcher: { in: token, out: words, source: 'sys-dic' }
    - sequencer:     { in: words, out: seque }
    - debugger:      { in: seque, prompt: 'out>' }

ergibt die Ausgabe über den Debugger: lingo -c t1 test.txt

out> *FILE('test.txt')
out> <Lingo|?>
out> <kann = [(koennen/v)]>
out> <indexierung, automatisch|SEQ = [(indexierung, automatisch/q)]>
out> <automatische = [(automatisch/a)]>
out> <Indexierung = [(indexierung/s)]>
out> <und = [(und/w)]>
out> <indexierung, genial|SEQ = [(indexierung, genial/q)]>
out> <geniale = [(genial/a), (genialisch/a)]>
out> <Indexierung = [(indexierung/s)]>
out> :./PUNC:
out> *EOL('test.txt')
out> *EOF('test.txt')

Protected Instance Methods

control(cmd, param) click to toggle source
# File lib/lingo/attendee/sequencer.rb, line 107
def control(cmd, param)
  process_buffer if [STR_CMD_RECORD, STR_CMD_EOF].include?(cmd)
end
init() click to toggle source
# File lib/lingo/attendee/sequencer.rb, line 97
def init
  @stopper = get_array('stopper', DEFAULT_SKIP, :upcase)

  @seq = get_key('sequences').map { |string, format|
    [string = string.downcase, string.split(%r/), format]
  }

  raise MissingConfigError.new(:sequences) if @seq.empty?
end
process_buffer() click to toggle source
# File lib/lingo/attendee/sequencer.rb, line 116
def process_buffer
  insert_sequences if @buffer.size > 1
  forward_buffer
end
process_buffer?() click to toggle source
# File lib/lingo/attendee/sequencer.rb, line 111
def process_buffer?
  (obj = @buffer.last).is_a?(WordForm) && (obj.is_a?(Word) &&
    obj.unknown? || @stopper.include?(obj.attr.upcase))
end

Private Instance Methods

insert_sequences() click to toggle source
# File lib/lingo/attendee/sequencer.rb, line 123
def insert_sequences
  matches, buf, seq = Hash.new { |h, k| h[k] = [] }, @buffer, @seq

  map = buf.map { |obj|
    obj.is_a?(Word) && !obj.unknown? ? obj.attrs(false) : ['#']
  }

  map.shift.product(*map).map!(&:join).tap(&:uniq!).each { |q|
    seq.each { |string, classes, format|
      while pos = q.index(string, pos || 0)
        inc('Anzahl erkannter Sequenzen')

        fmt = format.dup

        classes.each_with_index { |wc, i|
          buf[pos + i].lexicals.find { |l|
            fmt.gsub!(i.succ.to_s, l.form) if l.attr == wc
          } or break
        } or next

        matches[pos] << fmt

        pos += 1
      end
    }
  }

  matches.sort.each { |pos, forms| forms.tap(&:uniq!).each { |form|
    @inserts << [pos, Word.new_lexical(form, WA_SEQUENCE, LA_SEQUENCE)]
  } }
end