Repository: nltk/nltk

Issue:
nltk.collocations.QuadgramAssocMeasures() is missing
nltk.collocations only import BigramAssocMeasures and TrigramAssocMeasures from nltk.metrics, and QuadgramAssocMeasures is left out.



Discussion:
Thanks @BLKSerene for raising this! 

Try this (for now):

```
from nltk.metrics.association import QuadgramAssocMeasures
```

Meanwhile wait for a quick patch in the next version before you can do:

```
from nltk.collocations import QuadgramAssocMeasures
```

----

Yeah, that's a gotcha that has been [quite a while](https://stackoverflow.com/questions/34230592/nltk-quadgram-collocation-finder) and it's an easy fix. Lets do that.
@alvations @BLKSerene is this issue still open? And if the CI related issues are fixed, I'm going for this


Resolving patch:
diff --git a/nltk/collocations.py b/nltk/collocations.py
--- a/nltk/collocations.py
+++ b/nltk/collocations.py
@@ -37,7 +37,7 @@
 from nltk.probability import FreqDist
 from nltk.util import ngrams
 # these two unused imports are referenced in collocations.doctest
-from nltk.metrics import ContingencyMeasures, BigramAssocMeasures, TrigramAssocMeasures
+from nltk.metrics import ContingencyMeasures, BigramAssocMeasures, TrigramAssocMeasures, QuadgramAssocMeasures
 from nltk.metrics.spearman import ranks_from_scores, spearman_correlation
 
 
diff --git a/nltk/metrics/__init__.py b/nltk/metrics/__init__.py
--- a/nltk/metrics/__init__.py
+++ b/nltk/metrics/__init__.py
@@ -40,6 +40,7 @@
     NgramAssocMeasures,
     BigramAssocMeasures,
     TrigramAssocMeasures,
+    QuadgramAssocMeasures,
     ContingencyMeasures,
 )
 from nltk.metrics.spearman import (


Test patch:
diff --git a/nltk/test/collocations.doctest b/nltk/test/collocations.doctest
--- a/nltk/test/collocations.doctest
+++ b/nltk/test/collocations.doctest
@@ -16,6 +16,7 @@ measured using Pointwise Mutual Information.
     >>> from nltk.collocations import *
     >>> bigram_measures = nltk.collocations.BigramAssocMeasures()
     >>> trigram_measures = nltk.collocations.TrigramAssocMeasures()
+    >>> fourgram_measures = nltk.collocations.QuadgramAssocMeasures()
     >>> finder = BigramCollocationFinder.from_words(
     ...     nltk.corpus.genesis.words('english-web.txt'))
     >>> finder.nbest(bigram_measures.pmi, 10)  # doctest: +NORMALIZE_WHITESPACE
@@ -126,6 +127,12 @@ A closer look at the finder's ngram frequencies:
      ((',', 'do', 'not'), 1), (('I', 'am', '!'), 1), (('Sam', 'I', '!'), 1),
      (('Sam', 'I', 'am'), 1)]
 
+A similar interface is provided for fourgrams:
+
+    >>> finder_4grams = QuadgramCollocationFinder.from_words(tokens)
+    >>> scored_4grams = finder_4grams.score_ngrams(fourgram_measures.raw_freq)
+    >>> set(fourgram for fourgram, score in scored_4grams) == set(nltk.ngrams(tokens, n=4))
+    True
 
 Filtering candidates
 ~~~~~~~~~~~~~~~~~~~~
diff --git a/nltk/test/metrics.doctest b/nltk/test/metrics.doctest
--- a/nltk/test/metrics.doctest
+++ b/nltk/test/metrics.doctest
@@ -276,3 +276,18 @@ For trigrams, we have to provide more count information:
     True
     >>> tam.jaccard(n_w1_w2_w3, pair_counts, uni_counts2, N) > tam.jaccard(n_w1_w2_w3, pair_counts, uni_counts, N)
     True
+
+
+For fourgrams, we have to provide more count information:
+
+    >>> n_w1_w2_w3_w4 = 5
+    >>> n_w1_w2, n_w1_w3, n_w2_w3 = 35, 60, 40
+    >>> n_w1_w2_w3, n_w2_w3_w4 = 20, 10 
+    >>> pair_counts = (n_w1_w2, n_w1_w3, n_w2_w3)
+    >>> triplet_counts = (n_w1_w2_w3, n_w2_w3_w4)
+    >>> n_w1, n_w2, n_w3, n_w4 = 100, 200, 300, 400
+    >>> uni_counts = (n_w1, n_w2, n_w3, n_w4)
+    >>> N = 14307668
+    >>> qam = QuadgramAssocMeasures
+    >>> qam.raw_freq(n_w1_w2_w3_w4, pair_counts, triplet_counts, uni_counts, N) == 1. * n_w1_w2_w3_w4 / N
+    True