Az utolsó feladat egy érdekes megfigyelésről szól, a Zipf-törvényről, melyről a Wikipedia a következőt írja: „A Zipf-törvény azt állítja, hogy egy természetes nyelv egyes részeiben egy szó előfordulási gyakorisága fordítottan arányos a gyakorisági (előfordulási) táblában levő rangjával. Így, a leggyakoribb szó közel kétszer gyakoribb, mint a második leggyakoribb szó, és háromszor gyakoribb, mint a harmadik helyen lévő, stb.”
Amennyiben e szabály fennáll egy szövegre, akkor a gyakorisági függvény grafikonja egyenes egy olyan koordinátarendszerben ábrázolva, melyben mindkét koordinátatengely beosztása logaritmikus. A feladat az lesz, hogy egy természetes szövegre ellenőrizzük e szabályt grafikusan, azaz rajzoljuk ki a gyakoriságokat loglog koordinátarendszerben. Teszteléshez néhány szövegminta található a http://sandbox.hlt.bme.hu/~gaebor/zipf/ oldalon. E szabályt tökéletesen megvalósítja a szövegminták közt található tokeletes.txt fájl. Kisebb minták vannak az ember tragédiájából és nagyobb méretű angol szövegek.
A program kódolásához ezúttal (afélév végére való tekintettel) nagy segítséget adunk, a program kódjának nagy részét mellékeljük, csak a hiányzó kódot kell pótolni. Hogy mit kell csinálni, az kitalálható a környezetből és a megjegyzésekből.
import matplotlib.pyplot as plt
import sys
def plot_zipf(filename):
"""
Kirajzolja a rang-gyakoriság grafikont
egy loglog koordinátarendszerben.
"""
d = {} # dictionary
with open(filename, "r") as f:
for line in f:
for word in line.strip().split(): # split into words
word = word.strip(',.-_?! ').lower() # deleting punctuation
#
# megszámoljuk a nemüres szavakat,
# a gyakoriságokat a d szótárba írjuk úgy, hogy
# a kulcs a szó legyen, és az érték a gyakorisága.
#
if word != '':
........# a nem üres szavak számolása
#
# kirajzoljuk a gyakoriságokat loglog skálázott koordinátarendszerben
# (rendezett adatok a szótár értékei alapján)
data = ........
plt.loglog(range(1, len(data)+1), data)
plt.show()
# a szótár konvertálása párok listájává, majd rendezése a
# a párok második eleme mint kulcs szerint, végül az első 10
# pár kiírása
print(sorted(d.items(), key=lambda x:x[1], reverse=True)[0:10])
def main():
filename = sys.argv[1]
plot_zipf(filename)
if __name__ == "__main__":
main()
A megírt programot parancssorból is teszteljük beküldés előtt!