Search code examples
javanlpwordnetjwi

Get antonyms for a word in java - Wordnet JWI


I am interested in finding antonyms for a word using wordnet in Java. I am currently using this method to find antonyms but I have yet to find any words which have antonyms. Are antonyms not common in Wordnet? Or is this implementation flawed?

public List<String> getAntonyms(String baseWord) {
    List<String> synonymList = new ArrayList<>();
    IIndexWord[] baseWordPOS = getAllPOSForBaseWord(baseWord);
    for (IIndexWord iIndexWord : baseWordPOS) {
        if (iIndexWord == null) {
            continue;
        }
        for (IWordID wordID : iIndexWord.getWordIDs()) {
            IWord word = dict.getWord(wordID);
            ISynset synset = word.getSynset();
            Map<IPointer, List<ISynsetID>> relatedMap = synset.getRelatedMap();
            for (Map.Entry<IPointer, List<ISynsetID>> entry : relatedMap.entrySet()) {
                IPointer iPointer = entry.getKey();
                if (iPointer.equals(Pointer.ANTONYM)) {
                    List<ISynsetID> iSunsetIDS = entry.getValue();
                    for (ISynsetID iSynsetID : iSunsetIDS) {
                        ISynset synset1 = dict.getSynset(iSynsetID);
                        for (IWord w : synset1.getWords()) {
                            synonymList.add(ConvertToPolyFormat(w.getLemma()));
                        }
                    }
                }
            }
        }
    }
    return synonymList.stream()
            .distinct()
            .filter(s -> !s.equals(baseWord))
            .collect(Collectors.toList());
} 

I am testing with these words:

String[] testWords = {"able", "unable", "adsorbent", "apple", "tart", "computer", "cat", "great", "allowable"};

but they all return empty lists. I am checking for all parts of speech (POS) for the word:

private static final POS[] POS_ARRAY = {POS.ADJECTIVE, POS.ADVERB, POS.NOUN, POS.VERB};
private IIndexWord[] getAllPOSForBaseWord(String baseWord) {
    IIndexWord[] returnValue = new IIndexWord[4];
    for (int i = 0; i < returnValue.length; i++) {
        returnValue[i] = dict.getIndexWord(baseWord, POS_ARRAY[i]);
    }
    return returnValue;
}

I used this same approach to find synonyms but checked if the pointer type is related to/hypernym/etc... and had success with that implementation.

Other info:

The dict variable is an IDictionary object from (edu.mit.jwi.IDictionary)


Solution

  • I think you got wrong relatedMap. I have changed your code like this and successfully:

    public List<String> getAntonyms(String baseWord) {
        List<String> synonymList = new ArrayList<>();
        IIndexWord[] baseWordPOS = getAllPOSForBaseWord(baseWord);
        for (IIndexWord iIndexWord : baseWordPOS) {
            if (iIndexWord == null) {
                continue;
            }
            for (IWordID wordID : iIndexWord.getWordIDs()) {
                IWord word = dict.getWord(wordID);
    
                Map<IPointer, List<IWordID>> relatedMap = word.getRelatedMap();
                for (Map.Entry<IPointer, List<IWordID>> entry : relatedMap.entrySet()) {
                    IPointer iPointer = entry.getKey();
                    if (iPointer.equals(Pointer.ANTONYM)) {
                        List<IWordID> iWordIDs = entry.getValue();
                        for (IWordID iWordID : iWordIDs) {
                            IWord iWord = dict.getWord(iWordID);
                            ISynset synset = iWord.getSynset();
                            for (IWord w : synset.getWords()) {
                                synonymList.add(ConvertToPolyFormat(w.getLemma()));
                            }
                        }
                    }
                }
            }
        }
        return synonymList.stream()
                .distinct()
                .filter(s -> !s.equals(baseWord))
                .collect(Collectors.toList());
    }