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 № 1Jeś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ć Stream
s jeśli dokument jest duży i nie można trzymać całej sekwencji w pamięci.
Następujące groupBy
tworzy 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:
NGram
ma oczekiwaną poprawną implementacjęequals
+hashcode
document.sentences
zwraca aSeq[...]
. 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))
}