/ / Mapuj słowo ngrams do liczenia w scala - scala, nlp, n-gram

Mapuj słowo ngrams do zliczeń scala - scala, nlp, n-gram

Próbuję stworzyć mapę, która przechodzi przez wszystkiengrams w dokumencie i liczy, jak często się pojawiają. Ngramy są zestawami n kolejnych słów w zdaniu (więc w ostatnim zdaniu (Ngrams, są) jest 2-gramowym, (są, zestawy) to kolejne 2-gramowe itd.) Mam już kod, który tworzy dokument z pliku i analizuje go w zdania. Mam także funkcję do zliczania ngrams w zdaniu ngramsInSentence, które zwraca Seq [Ngram].

Utknąłem syntaktycznie w kwestii tworzeniamapa moich liczników. Iteruję przez wszystkie ngrams w dokumencie w pętli for, ale nie wiem, jak zmapować ngrams do tego, jak często występują. „Jestem wyraźnie konceptualny na temat tego, czego potrzebuję!

def getNGramCounts(document: Document, n: Int): Counts = {
for (sentence <- document.sentences; ngram <- nGramsInSentence(sentence,n))
//I need code here to map ngram -> count how many times ngram appears in document
}

Typ Counts above, a także Ngram, są zdefiniowane jako:

type Counts = Map[NGram, Double]
type NGram = Seq[String]

Czy ktoś zna składnię mapowania ngrams z pętli for na liczbę, w jakiej występują? Daj mi znać, jeśli chcesz uzyskać więcej informacji na temat problemu.

Odpowiedzi:

2 dla odpowiedzi № 1

Jeśli poprawnie interpretuję twój kod, jest to dość powszechne zadanie.

def getNGramCounts(document: Document, n: Int): Counts = {
val allNGrams: Seq[NGram] = for {
sentence <- document.sentences
ngram <- nGramsInSentence(sentence, n)
} yield ngram

allNgrams.groupBy(identity).mapValues(_.size.toDouble)
}

The allNGrams zmienna zbiera listę wszystkich NGramów pojawiających się w dokumencie.
W końcu powinieneś się zwrócić Streams jeśli dokument jest duży i nie można trzymać całej sekwencji w pamięci.

Następujące groupBytworzy a Map[NGram, List[NGram]] który grupuje wartości według ich tożsamości (argument metody definiuje kryteria „identyfikacji zbiorczej”) i grupuje odpowiednie wartości na liście.

Wystarczy tylko zmapować wartości ( List[NGram]) do tego size aby uzyskać liczbę powtarzających się wartości każdego z nich NGram.


Przyjąłem za pewnik, że:

  1. NGram ma oczekiwaną poprawną implementację equals + hashcode
  2. document.sentences zwraca a Seq[...]. Jeśli nie, należy się spodziewać allNGrams należy do odpowiedniego typu kolekcji.

ZAKTUALIZOWANE na podstawie komentarzy

Błędnie założyłem, że groupBy(_) skróciłby wartość wejściową. Użyj identity zamiast tego funkcja.

Przekonwertowałem liczbę na Double


0 dla odpowiedzi nr 2

Doceń pomoc - mam teraz poprawny kod, korzystając z powyższych sugestii. Następujący zwraca pożądany wynik:

def getNGramCounts(document: Document, n: Int): Counts = {
val allNGrams: Seq[NGram] = (for(sentence <- document.sentences;
ngram <- ngramsInSentence(sentence,n))
yield ngram)
allNGrams.groupBy(l => l).map(t => (t._1, t._2.length.toDouble))
}