[ https://issues.apache.org/jira/browse/OPENNLP-1539?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=17849055#comment-17849055 ]
ASF GitHub Bot commented on OPENNLP-1539: ----------------------------------------- jzonthemtn commented on code in PR #601: URL: https://github.com/apache/opennlp/pull/601#discussion_r1612105341 ########## opennlp-tools/src/main/java/opennlp/tools/postag/POSTagFormatMapper.java: ########## @@ -0,0 +1,207 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package opennlp.tools.postag; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Objects; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * A mapping implementation for converting between different POS tag formats. + * This class supports conversion between Penn Treebank (PENN) and Universal Dependencies (UD) formats. + * The conversion is based on the <a href="https://universaldependencies.org/tagset-conversion/en-penn-uposf.html">Universal Dependencies conversion table.</a> + * Please note that when converting from UD to Penn format, there may be ambiguity in some cases. + */ +public class POSTagFormatMapper { + + private static final Logger logger = LoggerFactory.getLogger(POSTagFormatMapper.class); + + private static final Map<String, String> CONVERSION_TABLE_PENN_TO_UD = new HashMap<>(); + private static final Map<String, String> CONVERSION_TABLE_UD_TO_PENN = new HashMap<>(); + + static { + /* + * This is a conversion table to convert PENN to UD format as described in + * https://universaldependencies.org/tagset-conversion/en-penn-uposf.html + */ + CONVERSION_TABLE_PENN_TO_UD.put("#", "SYM"); + CONVERSION_TABLE_PENN_TO_UD.put("$", "SYM"); + CONVERSION_TABLE_PENN_TO_UD.put("''", "PUNCT"); + CONVERSION_TABLE_PENN_TO_UD.put(",", "PUNCT"); + CONVERSION_TABLE_PENN_TO_UD.put("-LRB-", "PUNCT"); + CONVERSION_TABLE_PENN_TO_UD.put("-RRB-", "PUNCT"); + CONVERSION_TABLE_PENN_TO_UD.put(".", "PUNCT"); + CONVERSION_TABLE_PENN_TO_UD.put(":", "PUNCT"); + CONVERSION_TABLE_PENN_TO_UD.put("AFX", "ADJ"); + CONVERSION_TABLE_PENN_TO_UD.put("CC", "CCONJ"); + CONVERSION_TABLE_PENN_TO_UD.put("CD", "NUM"); + CONVERSION_TABLE_PENN_TO_UD.put("DT", "DET"); + CONVERSION_TABLE_PENN_TO_UD.put("EX", "PRON"); + CONVERSION_TABLE_PENN_TO_UD.put("FW", "X"); + CONVERSION_TABLE_PENN_TO_UD.put("HYPH", "PUNCT"); + CONVERSION_TABLE_PENN_TO_UD.put("IN", "ADP"); + CONVERSION_TABLE_PENN_TO_UD.put("JJ", "ADJ"); + CONVERSION_TABLE_PENN_TO_UD.put("JJR", "ADJ"); + CONVERSION_TABLE_PENN_TO_UD.put("JJS", "ADJ"); + CONVERSION_TABLE_PENN_TO_UD.put("LS", "X"); + CONVERSION_TABLE_PENN_TO_UD.put("MD", "VERB"); + CONVERSION_TABLE_PENN_TO_UD.put("NIL", "X"); + CONVERSION_TABLE_PENN_TO_UD.put("NN", "NOUN"); + CONVERSION_TABLE_PENN_TO_UD.put("NNP", "PROPN"); + CONVERSION_TABLE_PENN_TO_UD.put("NNPS", "PROPN"); + CONVERSION_TABLE_PENN_TO_UD.put("NNS", "NOUN"); + CONVERSION_TABLE_PENN_TO_UD.put("PDT", "DET"); + CONVERSION_TABLE_PENN_TO_UD.put("POS", "PART"); + CONVERSION_TABLE_PENN_TO_UD.put("PRP", "PRON"); + CONVERSION_TABLE_PENN_TO_UD.put("PRP$", "DET"); + CONVERSION_TABLE_PENN_TO_UD.put("RB", "ADV"); + CONVERSION_TABLE_PENN_TO_UD.put("RBR", "ADV"); + CONVERSION_TABLE_PENN_TO_UD.put("RBS", "ADV"); + CONVERSION_TABLE_PENN_TO_UD.put("RP", "ADP"); + CONVERSION_TABLE_PENN_TO_UD.put("SYM", "SYM"); + CONVERSION_TABLE_PENN_TO_UD.put("TO", "PART"); + CONVERSION_TABLE_PENN_TO_UD.put("UH", "INTJ"); + CONVERSION_TABLE_PENN_TO_UD.put("VB", "VERB"); + CONVERSION_TABLE_PENN_TO_UD.put("VBD", "VERB"); + CONVERSION_TABLE_PENN_TO_UD.put("VBG", "VERB"); + CONVERSION_TABLE_PENN_TO_UD.put("VBN", "VERB"); + CONVERSION_TABLE_PENN_TO_UD.put("VBP", "VERB"); + CONVERSION_TABLE_PENN_TO_UD.put("VBZ", "VERB"); + CONVERSION_TABLE_PENN_TO_UD.put("WDT", "DET"); + CONVERSION_TABLE_PENN_TO_UD.put("WP", "PRON"); + CONVERSION_TABLE_PENN_TO_UD.put("WP$", "DET"); + CONVERSION_TABLE_PENN_TO_UD.put("WRB", "ADV"); + + /* + * Note: The back conversion might lose information. + */ + CONVERSION_TABLE_UD_TO_PENN.put("ADJ", "JJ"); + CONVERSION_TABLE_UD_TO_PENN.put("ADP", "IN"); + CONVERSION_TABLE_UD_TO_PENN.put("ADV", "RB"); + CONVERSION_TABLE_UD_TO_PENN.put("AUX", "MD"); + CONVERSION_TABLE_UD_TO_PENN.put("CCONJ", "CC"); + CONVERSION_TABLE_UD_TO_PENN.put("DET", "DT"); + CONVERSION_TABLE_UD_TO_PENN.put("INTJ", "UH"); + CONVERSION_TABLE_UD_TO_PENN.put("NOUN", "NN"); + CONVERSION_TABLE_UD_TO_PENN.put("NUM", "CD"); + CONVERSION_TABLE_UD_TO_PENN.put("PART", "RP"); + CONVERSION_TABLE_UD_TO_PENN.put("PRON", "PRP"); + CONVERSION_TABLE_UD_TO_PENN.put("PROPN", "NNP"); + CONVERSION_TABLE_UD_TO_PENN.put("PUNCT", "."); + CONVERSION_TABLE_UD_TO_PENN.put("SCONJ", "IN"); + CONVERSION_TABLE_UD_TO_PENN.put("SYM", "SYM"); + CONVERSION_TABLE_UD_TO_PENN.put("VERB", "VB"); + CONVERSION_TABLE_UD_TO_PENN.put("X", "FW"); + } + + private final POSTagFormat modelFormat; + + protected POSTagFormatMapper(final String[] possibleOutcomes) { + Objects.requireNonNull(possibleOutcomes, "Outcomes must not be NULL."); + this.modelFormat = guessModelTagFormat(possibleOutcomes); Review Comment: Good point. I don't think there is. > Introduce parameter for POSTaggerME to configure output POS tag format > ---------------------------------------------------------------------- > > Key: OPENNLP-1539 > URL: https://issues.apache.org/jira/browse/OPENNLP-1539 > Project: OpenNLP > Issue Type: Improvement > Components: POS Tagger > Affects Versions: 2.0.0, 2.1.0, 2.2.0, 2.3.0 > Reporter: Martin Wiesner > Assignee: Richard Zowalla > Priority: Major > Fix For: 2.4.0 > > > [Classic (legacy) POS models|https://opennlp.sourceforge.net/models-1.5/] > output tags in the [PENN Treebank POS > tag|https://www.ling.upenn.edu/courses/Fall_2003/ling001/penn_treebank_pos.html] > format. > The modern UD-based models, however, differ in the [longer output > format|https://universaldependencies.org/u/pos/], e.g. "VB" (Penn) vs. "VERB" > (UD). Extended (UD) word features are covered here: > https://universaldependencies.org/u/feat/index.html > This difference results in mismatches and will cause existing IT / tests to > fail, if executed. Luckily, a mapping table is found here: > https://universaldependencies.org/tagset-conversion/en-penn-uposf.html > To provide compatibility for existing applications and/or use-cases, we need > to provide a way to retrieve both POS formats. > Aims: > - Introduce a constructor parameter for POSTaggerME to configure tag format / > style: Penn or UD style > - Implement a mapping between both POS tag formats: UD <==> Penn > - Update the OpenNLP Manual to explain differences of POS tag format and > configuration parameter > Conceptual idea: > - {{new POSTaggerME("en")}} => by _default_: UD format "as is" > - {{new POSTaggerME("en", POSTagFormat.PENN)}} => by _intention_, here: Penn > style > Benefit: > 1. It should be explicit so devs / user see what they will get via > {{POSTagFormat}}. Enum values: POSTagFormat.UD, POSTagFormat.PENN, > POSTagFormat.DEFAULT > 2. IT tests can now be formulated to work on both modern and legacy models. -- This message was sent by Atlassian Jira (v8.20.10#820010)