Showing posts with label lexicon. Show all posts
Showing posts with label lexicon. Show all posts

Tuesday, August 4, 2009

Colazzo and Costantino (1998)

Luigi Colazzo and Marco Costantino (1998): 'Multi-user hypertextual didactic glossaries' (International Journal of Artificial Intelligence in Education, 9: 111-127).

MOTIVATION: Traditional technical glossaries (either printed or electronic, either monolingual or bilingual) suffer from a number of limitations from the perspective of the user: (a) 'loss of reading context' - the user must 'move away' from the text he is reading to look a word up in the glossary; (b) it can take a non-native speaker of the language a significant amount of time to identify the correct 'citation form' of the word he wants to look up in the dictionary; (c) glossaries are traditionally 'closed' or 'static' - it is not possible for the user to MODIFY entries or ADD new entries; (d) users who are used to working with traditional printed glossaries often fail to make use of the most useful 'search' features of electronic glossaries (i.e. they lack a sophisticated 'mental model' of the glossary - Marchionini, 1989). There are also many problems for authors of 'hypertext glossaries' (where words or phrases in the text are marked up as 'anchors' (i.e. hyperlinks) to glossary entries): (a) such annotation is very time consuming when done by hand; (b) the glossary text may not be stored in a linkable format (e.g. binary doc files); (c) if annotation is to be done automatically, then the source text needs to be morphologically analysed to identify the underlying lexemes; (d) although overlapped/embedded anchors are occasionally desirable, they are impossible to code.

Four models of hypertext glossary lookup (Black, Wright, Black and Norman, 1992): (a) TABS - the glossary entry for the selected word completely replaces the source text (it is not possible to view both at the same time, but the user had to toggle between the two tabs); (b) POPUPS - the glossary entry for the selected word effaces only a small (hopefully unimportant) part of the source text; (c) SIDEBAR - there is a permanent sidebar for displaying the selected glossary entry; (d) PREDICTIVE SIDEBAR - there is a permanent sidebar containing the glossary entries for all relevant words in the current paragraph of the source text. However, none of these models make it clear how to handle RECURSIVE lookups, i.e. where the glossary definition itself contains a word which needs to be looked up.

SOLUTIONS: (a) the glossary is indexed by 'stems' rather than particular word-forms; (b) the lookup method relies on a 'word-stemming algorithm' (what about irregular forms?); (c) links are created 'automatically' from the text to the glossary, i.e. no explicit 'anchors'; (d) the popup window containing the glossary definition should be a proper window, able to be moved around, iconised and destroyed independently of the main text window - this also provides a solution to the 'recursive lookup' problem. Also, the user can access the glossary in two distinct ways: (a) RETRIEVAL - send the glossary a text string and get back a definition; (b) BROWSING - either using an alphabetical index organised as a card file, or performing a sequential scan of entries. There is a dynamic (i.e. can be extended by the user) word-stemming algorithm, which is based on a list of all the stems in Italian, as well as the regular suffixes (but it cannot handle irregular morphology or do any POS disambiguation). The system also allows the glossary to updated by multiple users (i.e. it is a wiki).

Monday, June 1, 2009

opennlp.ccg.lexicon.MacroItem

macro @name
  > fs*
  > lf
private String name;
private FeatureStructure[] featStrucs;
private LF[] preds;

opennlp.ccg.lexicon.MorphItem

This class parses the entry elements in morph.xml files:

entry @word @pos (@stem) (@class) (@coart) (@macros) (@excluded)

There are the following fields:

private Word surfaceWord;
private Word word;
private Word coartIndexingWord;
private String[] macros;
private String[] excluded;
private boolean coart = false;

The constructor is quite complicated. The value of 'macros' and 'excluded' is straightforward - you just split the value up into string tokens (macro names and excluded strings). The value of 'surfaceWord' comes from passing the value of the word attribute through the tokeniser in some strange way:

surfaceWord = Grammar.theGrammar.lexicon.tokenizer.parseToken(e.getAttributeValue("word"),coart);

The value of 'word' is derived as follows:

word = word.createFullWord(surfaceWord, 
                           e.getAttributeValue("stem"), 
                           e.getAttributeValue("pos"), 
                           null, 
                           e.getAttributeValue("class"));

opennlp.ccg.lexicon.DataItem

This class parses member elements inside family elements inside lexicon.xml files:

member @stem (@pred)

The fields and constructor are obvious:

private String stem;
private String pred;
public DataItem(org.jdom.Element e) { ... }

If there is no 'pred' attribute, its value is the same as 'stem'.

opennlp.ccg.lexicon.EntriesItem

This class is used to parse entry elements from inside family elements in lexicon.xml files:

entry @name (@stem) (@active) (@indexRel)
  > category

The fields for this class are:

private String name;
private String stem;
private Boolean active;
private String indexRel;
private Category cat;
private Family family;

The constructor method is obvious too:

public EntriesItem(org.jdom.Element e, Family f) {
    this.family = f;
    ...
    cat = CatReader.getCat((Element) e.getChildren().get(0));
}

If there is no 'stem' attribute, this field gets the value Lexicon.DEFAULT_VAL, i.e. "[*DEFAULT*]". The default value of 'active' is Boolean.TRUE. If there is no 'indexRel' attribute, then the value of this field comes from that of the family. Obviously, the last line is the most interesting - it takes the first child only and converts it into a category? What if there are other children?

There are the usual 'get' methods, as well as a couple that get attributes of the immediate superfamily, as well a toString() method.

opennlp.ccg.lexicon.Family

This class is used to parse XML family elements in OpenCCG lexicon.xml files:

family @name @pos (@closed) (@indexRel) (@coartRel)
  > entry*
  > member*

The fields of a Family object are thus as follows:

private String name;
private String pos;
private Boolean closed; 
private String indexRel;
private String coartRel;
private EntriesItem[] entries;
private DataItem[] data; //members
private String supertag;

The supertag is formed by removing slash modalities and other minor features from a category (i.e. from the family name). There are get and set accessor methods for each field. The constructor method is exactly as you'd think:

public Family(org.jdom.Element e) { ... }

See also: opennlp.ccg.lexicon.EntriesItem and opennlp.ccg.lexicon.DataItem.

opennlp.ccg.lexicon.Lexicon

The constructor method of the opennlp.ccg.grammar.Grammar class contains the following code:

public final Lexicon lexicon;
lexicon = new Lexicon(this);
lexicon.init(lexiconUrl,morphUrl);

Here we turn to the code for the opennlp.ccg.lexicon.Lexicon class. Here are two basic fields and the constructor:

public final Grammar grammar;
public final Tokenizer tokenizer;

public Lexicon(Grammar g) {
    this.grammar = g;
    this.tokenizer = new DefaultTokenizer();
}

The init method starts as follows, where there are two input parameters, lexiconUrl and morphUrl:

List<Family> lexicon = null;
List<MorphItem> morph = null;
List<MacroItem> macroModel = null;
lexicon = getLexicon(lexiconUrl);
Pair<List<MorphItem>,List<MacroItem>> morphInfo = getMorph(morphUrl);
morph = morphInfo.a;
macroModel = morphInfo.b;

See also opennlp.ccg.lexicon.Family, opennlp.ccg.lexicon.MorphItem, and opennlp.ccg.lexicon.MacroItem.