Skip to content

Zipf's law

ests.visualizers.zipf(), ests.visualizers.zipf_theory()

Description

Plotting Zipf's law from a counter of the frequencies of words.

Definition

Zipf's law (the rank-frequency law) is an empirical regularity of the distribution of the frequencies of words in a natural language: if all the words of a language, or of a long enough text, are ordered by descending frequency, the frequency of the n-th word of the list is roughly inversely proportional to its number n, the rank of the word. The second most frequent word occurs about half as often as the first, the third a third as often, and so on.

Parameters

Parameter Type Default Description
counter Counter - Counter of the frequencies of words
num_words int None Number of the most frequent words
num_labels int 10 Number of the words labelled on the plot
log bool True Use a logarithmic scale
show_theory bool False Plot the theoretical Zipf's law
alpha float 1.5 Exponent α of the theoretical Zipf's law, greater than zero
show_fit bool False Plot the Zipf-Mandelbrot fit \(f(r) = C / (r + q)^s\) of fit_zipf_mandelbrot
ax Axes None Axes of matplotlib for the plot; if not given, a new figure is created

The function returns the Axes with the plot; a num_words greater than the number of word types does not extend the curves beyond the data, and an empty counter raises SourceError. zipf_theory(size, num_ranks, alpha, ax) plots the theoretical curve alone, \(f(r) = size \cdot r^{-\alpha}\) for the ranks from 1 to num_ranks.

Usage example

The lemmas of Marianela by Galdós from Project Gutenberg.

Example

Code:

from collections import Counter
from urllib.request import urlopen

from ests import WordsExtractor
from ests.visualizers import zipf

url = "https://www.gutenberg.org/cache/epub/17340/pg17340.txt"
text = urlopen(url).read().decode("utf-8")
text = text[text.index("\n", text.index("*** START OF")) : text.index("*** END OF")]
counts = Counter(WordsExtractor(use_lexemes=True, lowercase=True, filter_nums=True).extract(text))

ax = zipf(counts, num_labels=10, show_theory=True, alpha=1.0, show_fit=True)
ax.figure.savefig("zipf.png")

Result:

ests

On logarithmic axes the frequencies of the lemmas fall along a straight line; the Zipf-Mandelbrot fit, \(s = 1.14\) with a shift \(q = 1.77\), follows them closer than the theoretical law with \(\alpha = 1\) at the head of the list.