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!