Разделите предложение на фрагменты фиксированного размера, используя границу слова и POS - PullRequest
5 голосов
/ 10 февраля 2020

Я пытаюсь разбить предложение на фиксированные фрагментированные ключевые фразы на основе границы слова и POS (часть речи), используя Java (см. Обновленный код в конце этого поста)

1) Не принимать во внимание определенные POS

2) Некоторые POS не могут функционировать как ключевое слово root.

и выдавать следующий вывод:

**Root Keyword:** In
**Phrase:** None

**Root Keyword:** 2017
**Phrase:** None

**Root Keyword:** Joe Smith
**Phrase:** None

**Root Keyword:** announced
**Phrase 1:** In CD, NNP announced he was
**Phrase 2:** CD, NNP announced he was diagnosed
**Phrase 3:** NNP announced he was diagnosed with
**Phrase 4:** announced he was diagnosed with Lyme

**Root Keyword:** diagnosed
**Phrase 1:** CD, NNP announced he was diagnosed
**Phrase 2:** NNP announced he was diagnosed with
**Phrase 3:** announced he was diagnosed with Lyme
**Phrase 4:** he was diagnosed with Lyme disease

Последнее возможное слово для генерации фразы: болезнь

**Root Keyword:** disease
**Phrase 1:** he was diagnosed with Lyme disease

До сих пор я реализовал следующий код:

public class Sentence {


    public Sentence()
    {

    }


    ArrayList<Word> wordList = new ArrayList<Word>();

    public void addWord(Word word)
    {
        wordList.add(word);
    }

    public ArrayList<Word> getWordList() {
        return wordList;
    }

}

public class Word {

    public Word(String word, String pos) {

        this.word = word;
        this.pos = pos;
    }


    String word;
    String pos;
    ArrayList<String> phraseList = new ArrayList<String>();


    public String getWord() {
        return word;
    }

    public String getPos() {
        return pos;
    }


    public void setPhraseList(ArrayList<String> phraseList)
    {
        phraseList.addAll(phraseList);
    }

}

public void generatePhrases()
{


    Sentence sentence = new Sentence();
    sentence.addWord(new Word("In", "IN"));
    sentence.addWord(new Word("2017", "CD"));
    sentence.addWord(new Word(",", "PUNCT"));
    sentence.addWord(new Word("Joe Smith", "NNP"));
    sentence.addWord(new Word("announced", "VB"));
    sentence.addWord(new Word("he", "PRP"));
    sentence.addWord(new Word("was", "VBD"));
    sentence.addWord(new Word("diagnosed", "VBN"));
    sentence.addWord(new Word("with", "IN"));
    sentence.addWord(new Word("Lyme", "NN"));
    sentence.addWord(new Word("disease", "NN"));
    sentence.addWord(new Word(".", "PUNCT"));


    ArrayList<String> posListNotUsedAsRootKeyword = new ArrayList<String>();
    posListNotUsedAsRootKeyword.add("NNP");
    posListNotUsedAsRootKeyword.add("CD");


    ArrayList<String> posListNotCountedTowardMin = new ArrayList<String>();
    posListNotCountedTowardMin.add("VBD");
    posListNotCountedTowardMin.add("IN");
    posListNotCountedTowardMin.add("PRP");
    posListNotCountedTowardMin.add("TO");

    int minPhraseLength = 4; 
    int maxPhraseLength = 6;


    for (int wordCounter = 0; wordCounter < sentence.getWordList().size(); wordCounter++) {

        ArrayList<String> phraseList = new ArrayList<String>();


        Word word = sentence.getWordList().get(wordCounter);
        String wordAsStr = word.getWord();
        String pos = word.getPos();

        if (posListNotUsedAsRootKeyword.contains(pos) || posListNotCountedTowardMin.contains(pos)) {
            continue;
        }


        boolean phraseDesiredLength = false;

        String phrase = wordAsStr;
        int phraseCounter = wordCounter + 1;
        while (!phraseDesiredLength && phraseCounter < sentence.getWordList().size()) {

            Word phraseWord = sentence.getWordList().get(phraseCounter);
            String phraseWordAsStr = phraseWord.getWord();
            String phrasePOS = phraseWord.getPos();


            String appendPhrase = (posListNotUsedAsRootKeyword.contains(phrasePOS)) ? phrasePOS : phraseWordAsStr;
            phrase += " " + appendPhrase;

            if (StringX.countNumberOfWordsInStr(phrase) == minPhraseLength || StringX.countNumberOfWordsInStr(phrase) == maxPhraseLength) {

                phraseDesiredLength = true;
            }


            phraseCounter++;
        }


        System.out.println("PHRASE: " + phrase);

        phraseList.add(phrase);

    }

}

У меня в основном проблемы с генерацией фраз которые начинаются до root ключевого слова и заканчиваются после root ключевого слова (рекурсия?) и проверяют длину фразы == мин или максимальную длину фразы.

1 Ответ

0 голосов
/ 13 февраля 2020

У меня такое чувство, что вы делаете слишком много проверок для своей фразы, это сбивает с толку. У меня была бы база данных с типами ключей (VBD, IN, NNP, CD, TO ...) и связанными ключевыми словами, чтобы быть моим «словарем», тогда я бы оценил:

, если есть другие типы ключей, которые нежелательны, выполните проверки if для нужных,

, если есть еще желаемые типы клавиш, выполните проверки if для нежелательных.

Это сделает код короче. Тогда я бы go для пользовательского ввода текста, где они будут вводить что-то вроде:

Peter Griffin likes small white cats snoring on the couch.

Это предложение будет затем проанализировано в вашем generatePhrases(), где первый блок будет сортировать фразу в StringList, эта «сортировка» будет проверять каждое слово в словаре, чтобы определить его тип ключа и проверять этот тип ключа, если это необходимо, тогда я бы удалил из этого StringList ненужные фрагменты (NNP, CD, VBD, IN, PRP, TO), потому что у вас больше желаемых типов слов, поэтому нежелательная проверка выполняется быстрее.

String textinput = "Peter Griffin likes small white cats snoring on the couch";
String[] words = textinput.Split(" ");
StringList validwords = new StringList();

for (int i = 0; i < words.size(); i++){
    //do the SQL prepare thing, sqlite checks and all the good stuff...
    validword = "SELECT keytype FROM dictionary WHERE word = " + words[i] + 
    " AND keytype NOT IN ('NNP', 'CD', 'VBD', 'IN', 'PRP', 'TO')";

    validwords.add(validword);
}

if (validwords.size() >= 4) && (validwords.size() <= 6){
  system.out.println("Phrase: " + validwords.toString());
}

Так что у меня останется StringList с только нужными словами для моего ключевого предложения. , тогда я бы просто проверил, если длина StringList между 4 и 6, а затем просто конкатенировал слова из индексов с помощью метода StringList.toString().

Поскольку вы вводите текст в порядке это имеет смысл, вам не нужно проверять, имеет ли смысл Snoring couch cat Griffin small Peter, потому что он уже был бы упорядочен как Peter Griffin likes small white cats, так как это порядок вход.

...