Monkey Language

In real vorkommendem Text sind die meisten Wörter relativ kurz. Zunächst überraschend ist, dass zufällige Zeichenfolgen ("Monkeys on Typewriters") auch eine größere Häufigkeit von kurzen Wörtern aufweist. (Viel mehr zu diesen Zufallsprozessen gibt es in Krause und Zollmann, "Not so randomly typing monkeys" )

In [47]:
import numpy
import re
from random import choice
from numpy import bincount
import matplotlib.pyplot as plt
from pytree import read_trees
%matplotlib inline

LETTERS = '  abcdefghijklmnopqrstuvwxyz'

def monkeylanguage(n=10000):
    chars = []
    for i in xrange(n):
        chars.append(choice(LETTERS))
    return ''.join(chars).strip().split()
Wie sieht "Monkey language" aus?
In [33]:
monkeylanguage(200)
Out[33]:
['a',
 'zpebekvafndobvu',
 'pclevt',
 'qu',
 'yzfphrdadzxdanrawnrp',
 'qdclqtkoirzbhtrgbs',
 'jmhptucvcqiicbystuiwwmxy',
 'lofhbc',
 'ogg',
 'spw',
 'kghzcmsglp',
 'ztztind',
 'zpqsr',
 'nfkcywnuwqqptn',
 'tddgchxhm',
 'qrqps',
 'osrnjyaiwbtjwmsimkkhshonowxujkupl']

Wie sieht es mit der Verteilung der Längen aus?

In [38]:
worte = monkeylanguage()
laengen = sorted([len(w) for w in worte])
counts = bincount(laengen)
x_numbers = numpy.linspace(0,len(counts), len(counts))
plt.plot(x_numbers, counts)
plt.plot(x_numbers, 50*(numpy.exp(-x_numbers/(26/2.))))
plt.title('Monkey Language: Word length distribution');

Zum Vergleich nun Worte aus einem deutschen Korpus (Zahlen, Zeichensetzung und Worte mit Umlauten oder Sonderzeichen werden weggeworfen):

In [43]:
def corpus_words(fname):
    words = []
    for t in read_trees(fname):
        for n in t.terminals:
            words.append(n.word)
    return words
In [48]:
word_re = re.compile('^[a-zA-Z]+$')
worte = [x.lower() for x in corpus_words('/home/yannick/corpora/tuebadz-8.0-mit-NE.export4')
         if word_re.match(x)]
worte[:10]
/home/yannick/corpora/tuebadz-8.0-mit-NE.export4: cchardet detected encoding WINDOWS-1252
Out[48]:
['veruntreute',
 'die',
 'awo',
 'spendengeld',
 'staatsanwaltschaft',
 'flossen',
 'mark',
 'sammelgelder',
 'flutopfer',
 'in']
In [53]:
laengen = sorted([len(w) for w in worte])
counts = numpy.array(bincount(laengen))
x_numbers = numpy.linspace(0,len(counts), len(counts))
avg_len = (counts*x_numbers).sum()/counts.sum()
plt.plot(x_numbers, counts)
plt.plot(x_numbers, 300000*(numpy.exp(-x_numbers/(avg_len))))
plt.title('German Language: Word length distribution');

Wir sehen, dass die Exponentialfunktion die geometrische Verteilung bei Monkey Language gut einfängt, und bei den Worten aus der tageszeitung immer noch halbwegs passt, aber eher nicht so genau.