3 UTVIKLE STRATEGI FOR MER ROBUST LAKSENÆRING
3.3 Implementér!
B.4 Padrões para Reconhecimento de Relações Es-
pecíficas
Como visto na sessão 5.5.2, vários padrões foram utilizados no reconhecimento de relações específicas. A seguir é listado o código que implementa as gramáticas de reconhecimento expressas em JAPE e o código Java que gera as anotações correspon- dentes.
//******************************************************************** //Identifica sentenças que contenham definições de conceitos,
// classes e subclasses, definições de grupo / composição. //Usa como insumo os POS tags do etiquetador (baseado em Hepple). //Cria anotações do tipo "TERM" com as seguintes features: // * string - o fragmento de texto que foi anotado
//******************************************************************** Phase: AchaDefinicoes
Input: Token
Options: control = appelt
//******************************************************************** // M A C R O S //******************************************************************** Macro: FULLSTOP ( {Token.string=="."} ) Macro: THREEDOTS ( {Token.string=="."} {Token.string=="."} {Token.string=="."} ) Macro: PUNCT ( ({Token.string == "!"} | {Token.string == "?"} | {Token.string == ";"} ) ) Macro: SUBSTANTIVO (
{Token.category == NN, Token.kind == word} | {Token.category == NNS, Token.kind == word}| {Token.category == NNP, Token.kind == word} | {Token.category == NNPS, Token.kind == word} | {Token.category == NP, Token.kind == word} | {Token.category == NPS, Token.kind == word} | {Token.category == CD, Token.kind == word} )
Macro: ARTIGODEF (
{Token.string == "the"} | {Token.string == "The"} | {Token.string == "THE"} )
B.4 Padrões para Reconhecimento de Relações Específicas 120
Macro: ARTIGOINDEF (
{Token.string == "a"} | {Token.string == "an"} | {Token.string == "A"} | {Token.string == "An"} )
Macro: ADJETIVO (
{Token.category == JJ, Token.kind == word} | {Token.category == JJR, Token.kind == word} | {Token.category == JJS, Token.kind == word} )
Macro: POSSESSIVO (
{Token.category == POS, Token.kind == word} )
Macro: ADVERBIO (
{Token.category == RB, Token.kind == word} | {Token.category == RBR, Token.kind == word} | {Token.category == RBS, Token.kind == word} )
Macro: BE (
{Token.root == "be"} )
Macro: MODAL (
{Token.string == "can"} | {Token.string == "may"} | {Token.string == "should"} |
{Token.string == "could"} | {Token.string == "must"} )
Macro: CARACTERIZA1
// (relação: EH_DESCRITA_POR) ( (BE)
(ADVERBIO)?
(({Token.string == "defined"} {Token.string == "by"}) | ({Token.string == "described"} {Token.string == "by"}) | ({Token.string == "determined"} {Token.string == "by"}) | ({Token.string == "part"} {Token.string == "of"}) | ({Token.string == "considered"} {Token.string == "as"}) | ({Token.string == "referred"} {Token.string == "to"}
{Token.string == "as"}) |
({Token.string == "thought"} {Token.string == "of"} {Token.string == "as"}) |
({Token.string == "known"} {Token.string == "as"}) // ({Token.string=="a"}|{Token.string=="an"}|
// {Token.string=="the"}|{Token.string=="many"}|{Token.string=="various"}) )
)
Macro: DEFINE ( ({Token.string == "define"} | {Token.string == "defines"} |
(({Token.string == "consist"} | {Token.string == "consists"}) ({Token.string == "of"})) |
{Token.string == "describe"} | {Token.string == "describes"} |
B.4 Padrões para Reconhecimento de Relações Específicas 121
{Token.string == "determine"} | {Token.string == "determines"} | {Token.string == "mean"} | {Token.string == "means"} |
{Token.string == "signify"} | {Token.string == "signifies"} ) )
Macro: CARACTERIZA2 ( (BE) (ADVERBIO)?
({Token.string == "used"} {Token.string == "to"}) (DEFINE)
// ({Token.string=="a"}|{Token.string=="an"}|{Token.string=="the"}| // {Token.string=="many"}|{Token.string=="various"})
)
Macro: CARACTERIZA3 ( (ADVERBIO)? (DEFINE)
(ADVERBIO)?
// ({Token.string=="a"}|{Token.string=="an"}|{Token.string=="the"}| // {Token.string=="many"}|{Token.string=="various"})
)
// achar composição ("part holonym"): "um trem é dividido em vagões" (NA VOZ PASSIVA) // exemplo: X (can) (usually) be divided into Y ou X... is (usually) divided into ... // para ser usado em: NP DIVIDIDO_EM NP
Macro: DIVIDIDO_EM ( (MODAL)? (ADVERBIO)?
(BE) (ADVERBIO)?
(({Token.string == "divided"} {Token.string == "into"}) | ({Token.string == "subdivided"} {Token.string == "into"}) | ({Token.string == "part"} {Token.string == "of"}) |
({Token.string == "composed"} {Token.string == "of"}) | ({Token.string == "formed"} {Token.string == "by"}) | ({Token.string == "constituted"} {Token.string == "of"}))
// ({Token.string=="a"}|{Token.string=="an"}|{Token.string=="the"}| // {Token.string=="many"}|{Token.string=="various"})
)
// achar composição ("part holonym"): "um time inclue um lider e // vários trabalhadores" (NA VOZ ATIVA)
// exemplo: X... includes ... para ser usado em: NP DIVIDE_SE_EM NP Macro: DIVIDE_SE_EM ( (ADVERBIO)?
({Token.string == "involve"} | {Token.string == "involves"} | {Token.string == "include"} | {Token.string == "includes"} ) // ({Token.string=="a"}|{Token.string=="an"}|{Token.string=="the"}| // {Token.string=="many"}|{Token.string=="various"})
)
// achar hypernyms: "a project is a type of undertaking" // projeto é uma subclasse da classe undertaking
// exemplo: X... is generally a type of ... para ser usado em: NP UM_TIPO_DE NP Macro: UM_TIPO_DE
( (BE) (ADVERBIO)? (ARTIGOINDEF)?
((({Token.string == "type"} | {Token.string == "types"}) ({Token.string == "of"})) | (({Token.string == "part"} | {Token.string == "parts"}) ({Token.string == "of"})) |
B.4 Padrões para Reconhecimento de Relações Específicas 122
(({Token.string == "kind"} | {Token.string == "kinds"}) ({Token.string == "of"})) | (({Token.string == "sort"} | {Token.string == "sorts"}) ({Token.string == "of"})) | (({Token.string == "class"} | {Token.string == "classes"})
({Token.string == "of"})) |
(({Token.string == "category"} | {Token.string == "categories"}) ({Token.string == "of"}))
)
//({Token.string=="a"}|{Token.string=="an"}|{Token.string=="the"}| // {Token.string=="many"}|{Token.string=="various"})
)
// achar GRUPOS : "a program is a group of projects" - projeto é uma // subclasse da classe programa
// exemplo: X... is a set of ... para ser usado em: NP is GRUPO_DE NP Macro: GRUPO_DE
( (({Token.string == "group"} {Token.string =="of"}) | ({Token.string == "grouping"} {Token.string == "of"}) | ({Token.string == "set"} {Token.string == "of"}) | ({Token.string == "ensemble"} {Token.string == "of"}) | ({Token.string == "collection"} {Token.string == "of"}) ) //({Token.string=="a"}|{Token.string=="an"}|{Token.string=="the"}| // {Token.string=="many"}|{Token.string=="various"}) ) //******************************************************************************** //******************************************************************************** // R E G R A S //******************************************************************************** Rule: DEF1 Priority: 50 ( ((ARTIGOINDEF) | (ARTIGODEF))? (ADJETIVO)? (ADJETIVO)?
(SUBSTANTIVO) (SUBSTANTIVO)? (SUBSTANTIVO)? ({Token.string=="of"} | {Token.string=="from"} )? (SUBSTANTIVO)? (SUBSTANTIVO)? (SUBSTANTIVO)? ({Token.string=="is"} | {Token.string=="are"} )
({Token.string=="a"}|{Token.string=="an"}|{Token.string=="the"}) (ADJETIVO)? (ADJETIVO)? (SUBSTANTIVO)? (SUBSTANTIVO)?
({Token.kind == word}|{Token.string == ","}|{Token.kind == number})* ({Token.string == "."}|{Token.string == ";"})
):def1 // (split) --> {
try{
AnnotationSet defAnnot = (AnnotationSet)bindings.get("def1");
TreeMap defsMap = new TreeMap(); Vector vDefs = new Vector(); String definicao = "";
//cria um ordered Map com os termos, ordenado pelas posições no texto Iterator defsIt = defAnnot.iterator();
B.4 Padrões para Reconhecimento de Relações Específicas 123 FeatureMap features; while (defsIt.hasNext()){ umaDef = (Annotation)defsIt.next(); features = umaDef.getFeatures(); defsMap.put(umaDef.getStartNode().getOffset(), features.get("string")); }
//transforma o treemap no termo composto (pode ser um ou mais substantivos) Iterator mapIt = defsMap.keySet().iterator();
Long key;
while (mapIt.hasNext()){ key = (Long)mapIt.next();
definicao = definicao + " " + (String)defsMap.get(key); vDefs.add((String)defsMap.get(key));
}
// definicao = definicao + " " + headnoun.getFeatures().get("string"); definicao = definicao.trim();
// cria uma estrutura de features e preenche com as características FeatureMap term_features = Factory.newFeatureMap();
term_features.put("string", definicao.toLowerCase()); term_features.put("relation", "IsA");
term_features.put("rule", "DEF1");
// salva a anotação e suas features no documento outputAS.add(defAnnot.firstNode().getOffset(), defAnnot.lastNode().getOffset(), "Definition", term_features); }catch(InvalidOffsetException ioe){ ioe.printStackTrace(); } } //***************************************************************************** Rule: DEF2 Priority: 50 ( ((ARTIGOINDEF) | (ARTIGODEF))? (ADJETIVO)? (ADJETIVO)?
(SUBSTANTIVO) (SUBSTANTIVO)? (SUBSTANTIVO)? ({Token.string=="of"} | {Token.string=="from"} )? (SUBSTANTIVO)? (SUBSTANTIVO)? (SUBSTANTIVO)? ({Token.string=="is"} | {Token.string=="are"} )
({Token.string=="a"}|{Token.string=="an"}|{Token.string=="the"}) (GRUPO_DE) // MANDATóRIO !!!
(ADJETIVO)? (ADJETIVO)? (SUBSTANTIVO)? (SUBSTANTIVO)?
({Token.kind == word}|{Token.string == ","}|{Token.kind == number})* ({Token.string == "."}|{Token.string == ";"})
):def2 --> { try{
AnnotationSet defAnnot = (AnnotationSet)bindings.get("def2");
TreeMap defsMap = new TreeMap(); Vector vDefs = new Vector();
B.4 Padrões para Reconhecimento de Relações Específicas 124
String definicao = "";
//cria um ordered Map com os termos, ordenado pelas posições no texto Iterator defsIt = defAnnot.iterator();
Annotation umaDef; FeatureMap features; while (defsIt.hasNext()){ umaDef = (Annotation)defsIt.next(); features = umaDef.getFeatures(); defsMap.put(umaDef.getStartNode().getOffset(), features.get("string")); }
//transforma o treemap no termo composto (pode ser um ou mais substantivos) Iterator mapIt = defsMap.keySet().iterator();
Long key;
while (mapIt.hasNext()){ key = (Long)mapIt.next();
definicao = definicao + " " + (String)defsMap.get(key); vDefs.add((String)defsMap.get(key));
}
// definicao = definicao + " " + headnoun.getFeatures().get("string"); definicao = definicao.trim();
// cria uma estrutura de features e preenche com as características FeatureMap term_features = Factory.newFeatureMap();
term_features.put("string", definicao.toLowerCase()); term_features.put("relation", "IsACollectionOf"); term_features.put("rule", "DEF2");
// salva a anotação e suas features no documento outputAS.add(defAnnot.firstNode().getOffset(), defAnnot.lastNode().getOffset(), "Definition", term_features); }catch(InvalidOffsetException ioe){ ioe.printStackTrace(); } } //*************************************************************************** Rule: CARACT1 Priority: 40 ( ((ARTIGODEF)|(ARTIGOINDEF))? (ADJETIVO)? (ADJETIVO)?
(SUBSTANTIVO) (SUBSTANTIVO)? (SUBSTANTIVO)? ({Token.string=="of"} | {Token.string=="from"} )? (SUBSTANTIVO)? (SUBSTANTIVO)? (SUBSTANTIVO)? ((CARACTERIZA1) | (CARACTERIZA2) | (CARACTERIZA3))
({Token.kind == word}|{Token.string == ","}|{Token.kind == number})* ({Token.string == "."}|{Token.string == ";"})
):def3 --> { try{
AnnotationSet defAnnot = (AnnotationSet)bindings.get("def3");
B.4 Padrões para Reconhecimento de Relações Específicas 125
Vector vDefs = new Vector(); String definicao = "";
//cria um ordered Map com os termos, ordenado pelas posições no texto Iterator defsIt = defAnnot.iterator();
Annotation umaDef; FeatureMap features; while (defsIt.hasNext()){ umaDef = (Annotation)defsIt.next(); features = umaDef.getFeatures(); defsMap.put(umaDef.getStartNode().getOffset(), features.get("string")); }
//transforma o treemap no termo composto (pode ser um ou mais substantivos) Iterator mapIt = defsMap.keySet().iterator();
Long key;
while (mapIt.hasNext()){ key = (Long)mapIt.next();
definicao = definicao + " " + (String)defsMap.get(key); vDefs.add((String)defsMap.get(key));
}
// definicao = definicao + " " + headnoun.getFeatures().get("string"); definicao = definicao.trim();
// cria uma estrutura de features e preenche com as características FeatureMap term_features = Factory.newFeatureMap();
term_features.put("string", definicao.toLowerCase()); term_features.put("relation", "Describes");
term_features.put("rule", "CARACT1");
// salva a anotação e suas features no documento outputAS.add(defAnnot.firstNode().getOffset(), defAnnot.lastNode().getOffset(), "Definition", term_features); }catch(InvalidOffsetException ioe){ ioe.printStackTrace(); } } //**************************************************************************** Rule: PARTE1 Priority: 40 ( ((ARTIGODEF)|(ARTIGOINDEF))? (ADJETIVO)? (ADJETIVO)?
(SUBSTANTIVO) (SUBSTANTIVO)? (SUBSTANTIVO)? ({Token.string=="of"} | {Token.string=="from"} )? (SUBSTANTIVO)? (SUBSTANTIVO)? (SUBSTANTIVO)? ((DIVIDIDO_EM) | (DIVIDE_SE_EM))
({Token.kind == word}|{Token.string == ","}|{Token.kind == number})* ({Token.string == "."}|{Token.string == ";"})
):def4 --> { try{
B.4 Padrões para Reconhecimento de Relações Específicas 126
TreeMap defsMap = new TreeMap(); Vector vDefs = new Vector(); String definicao = "";
//cria um ordered Map com os termos, ordenado pelas posições no texto Iterator defsIt = defAnnot.iterator();
Annotation umaDef; FeatureMap features; while (defsIt.hasNext()){ umaDef = (Annotation)defsIt.next(); features = umaDef.getFeatures(); defsMap.put(umaDef.getStartNode().getOffset(), features.get("string")); }
//transforma o treemap no termo composto (pode ser um ou mais substantivos) Iterator mapIt = defsMap.keySet().iterator();
Long key;
while (mapIt.hasNext()){ key = (Long)mapIt.next();
definicao = definicao + " " + (String)defsMap.get(key); vDefs.add((String)defsMap.get(key));
}
// definicao = definicao + " " + headnoun.getFeatures().get("string"); definicao = definicao.trim();
// cria uma estrutura de features e preenche com as características FeatureMap term_features = Factory.newFeatureMap();
term_features.put("string", definicao.toLowerCase()); term_features.put("relation", "IsComposedOf"); term_features.put("rule", "PARTE1");
// salva a anotação e suas features no documento outputAS.add(defAnnot.firstNode().getOffset(), defAnnot.lastNode().getOffset(), "Definition", term_features); }catch(InvalidOffsetException ioe){ ioe.printStackTrace(); } } //************************************************************************************ Rule: PARTE2 Priority: 40 ( ((ARTIGODEF)|(ARTIGOINDEF))? (ADJETIVO)? (ADJETIVO)?
(SUBSTANTIVO) (SUBSTANTIVO)? (SUBSTANTIVO)? ({Token.string=="of"} | {Token.string=="from"} )? (SUBSTANTIVO)? (SUBSTANTIVO)? (SUBSTANTIVO)? (UM_TIPO_DE)
({Token.kind == word}|{Token.string == ","}|{Token.kind == number})* ({Token.string == "."}|{Token.string == ";"})
):def5 --> { try{
B.4 Padrões para Reconhecimento de Relações Específicas 127
TreeMap defsMap = new TreeMap(); Vector vDefs = new Vector(); String definicao = "";
//cria um ordered Map com os termos, ordenado pelas posições no texto Iterator defsIt = defAnnot.iterator();
Annotation umaDef; FeatureMap features; while (defsIt.hasNext()){ umaDef = (Annotation)defsIt.next(); features = umaDef.getFeatures(); defsMap.put(umaDef.getStartNode().getOffset(), features.get("string")); }
//transforma o treemap no termo composto (pode ser um ou mais substantivos) Iterator mapIt = defsMap.keySet().iterator();
Long key;
while (mapIt.hasNext()){ key = (Long)mapIt.next();
definicao = definicao + " " + (String)defsMap.get(key); vDefs.add((String)defsMap.get(key));
}
// definicao = definicao + " " + headnoun.getFeatures().get("string"); definicao = definicao.trim();
// cria uma estrutura de features e preenche com as características FeatureMap term_features = Factory.newFeatureMap();
term_features.put("string", definicao.toLowerCase()); term_features.put("relation", "IsATypeOf");
term_features.put("rule", "PARTE2");
// salva a anotação e suas features no documento outputAS.add(defAnnot.firstNode().getOffset(), defAnnot.lastNode().getOffset(), "Definition", term_features); }catch(InvalidOffsetException ioe){ ioe.printStackTrace(); } }