12. Zipf-törvény

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!