Некоторые ли кластеры HPC кэшируют только один результат при запуске Stanford CoreNLP? - PullRequest
0 голосов
/ 17 мая 2019

Я использую библиотеку Stanford CoreNLP для проекта Java. Я создал класс под названием StanfordNLP и создал два разных объекта и инициализировал конструкторы с разными строками в качестве параметров. Я использую тег POS для получения последовательностей прилагательного-существительного. Тем не менее, вывод программы показывает только результаты первого объекта. Каждый объект StanfordNLP был инициализирован с отдельной строкой, но каждый объект возвращает те же результаты, что и первый объект. Я новичок в Java, поэтому не могу сказать, есть ли проблема с моим кодом или проблема с кластером HPC, на котором он работает.

Вместо того, чтобы возвращать список строк из метода класса StanfordNLP, я попытался использовать метод получения. Я также попытался установить для первого объекта StanfordNLP значение null, чтобы он не ссылался ни на что, после чего создал другие объекты. Ничего не работает.

/* in main */
List<String> pos_tokens0 = new ArrayList<String>();
List<String> pos_tokens1 = new ArrayList<String>();

String text0 = "Mary little lamb white fleece like snow"
StanfordNLP snlp0 = new StanfordNLP(text0);
pos_tokens0 = snlp0.process();

String text1 = "Everywhere little Mary went fluffy lamb ate green grass"
StanfordNLP snlp1 = new StanfordNLP(text1);
pos_tokens1 = snlp1.process();


/* in StanfordNLP.java */
public class StanfordNLP {

    private static List<String> pos_adjnouns = new ArrayList<String>();
    private String documentText = "";

    public StanfordNLP() {}
    public StanfordNLP(String text) { this.documentText = text; }

    public List<String> process() {     
        Properties props = new Properties();
        props.setProperty("annotators", "tokenize, ssplit, pos, lemma, ner, depparse");
        props.setProperty("coref.algorithm", "neural");
        StanfordCoreNLP pipeline = new StanfordCoreNLP(props);    
        Annotation document = new Annotation(documentText);
        pipeline.annotate(document);

        List<CoreMap> sentences = document.get(SentencesAnnotation.class);
        List<String[]> corpus_temp = new ArrayList<String[]>();
        int count = 0;

        for(CoreMap sentence: sentences) {
            for (CoreLabel token: sentence.get(TokensAnnotation.class)) {
                String[] data = new String[2];
                String word = token.get(TextAnnotation.class);
                String pos = token.get(PartOfSpeechAnnotation.class);
                count ++;

                data[0] = word;
                data[1] = pos;         
                corpus_temp.add(data);
            }           
        }

        String[][] corpus = corpus_temp.toArray(new String[count][2]);

        // corpus contains string arrays with a word and its part-of-speech.
        for (int i=0; i<(corpus.length-3); i++) { 
            String word = corpus[i][0];
            String pos = corpus[i][1];
            String word2 = corpus[i+1][0];
            String pos2 = corpus[i+1][1];

            // find adjectives and nouns (eg, "fast car")
            if (pos.equals("JJ")) {         
                if (pos2.equals("NN") || pos2.equals("NNP") || pos2.equals("NNPS")) {
                    word = word + " " + word2;
                    pos_adjnouns.add(word);
                }
            }
        }
        return pos_adjnouns;
}

Ожидаемый результат для pos_tokens0 - "маленький ягненок, белая шерсть". Ожидаемый результат для pos_tokens1 - "маленькая Мэри, пушистый ягненок, зеленая трава". Но фактический результат для обеих переменных - «маленький ягненок, белая шерсть».

Есть идеи, почему это может происходить? Я запустил простой файл jar Java с main.java и myclass.java на HPC и не могу повторить эту проблему. Таким образом, не похоже, что у HPC есть проблемы с несколькими объектами одного класса.

1 Ответ

0 голосов
/ 17 мая 2019

Проблема заключается в том, что ваша переменная pos_adjnouns равна static, поэтому она используется всеми экземплярами StanfordNLP….Попробуйте удалить ключевое слово static и посмотрите, все ли будет работать так, как вы ожидаете.

Но все равно это не правильно, поскольку у вас будет переменная экземпляра и при нескольких вызовах process(), вещибудет продолжать добавляться в список pos_adjnouns.Вы должны сделать еще две вещи:

  1. Сделать pos_adjnouns переменную метода в методе process()
  2. И наоборот, инициализация конвейера StanfordCoreNLP стоит дорого, поэтому вы должны переместить этоиз метода process() и сделайте это в конструкторе класса.Вероятно, было бы лучше, если бы все было в точности наоборот, и чтобы конструктор инициализировал конвейер, а для метода process() было бы взято String для анализа.
...