Created
January 7, 2014 19:33
-
-
Save hinnerk/8305396 to your computer and use it in GitHub Desktop.
n-gram Zerlegung aus einem Programmierkurs für Erwachsene aus dem Jahre 2010.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python2.7 | |
from operator import itemgetter | |
import sys, pickle, os | |
def normalisiere_text(text): | |
""" | |
1. Buchstaben sollen zu Kleinbuchstaben werden | |
2. Nicht-Buchstabn sollen entfernt werden | |
>>> normalisiere_text("tesTtest123test") | |
'testtesttest' | |
""" | |
normalisierter_text = "" | |
buchstaben = "abcdefghijklmnopqrstuvwxyz" | |
for x in text: | |
x = x.lower() | |
if x in buchstaben: | |
normalisierter_text += x | |
return normalisierter_text | |
def zerlege_text(text): | |
""" zerlegt text in 5-gramme | |
>>> zerlege_text("testestestestestes") | |
['teste', 'estes', 'stest', 'teste', 'estes', 'stest', 'teste', 'estes', 'stest', 'teste', 'estes', 'stest', 'teste', 'estes', 'stes', 'tes', 'es', 's'] | |
""" | |
ngramme = [] | |
textumfang = len(text) | |
for pos in range(textumfang): | |
ngram = text[pos:pos+3] | |
if len(ngram) == 3: | |
ngramme.append(ngram) | |
return ngramme | |
def zaehle_ngramme(ngramme): | |
""" zahle ngramme in einer liste | |
>>> zaehle_ngramme(["test","test","tset"]) | |
{'test': 2, 'tset': 1} | |
""" | |
zaehler = {} | |
for ngramm in ngramme: | |
zaehler[ngramm] = zaehler.get(ngramm, 0) + 1 | |
return zaehler | |
def sortiere_ngramme(gezaehlte_ngramme): | |
""" ein dictionary {ngramm: 23} wird umgeformt | |
und als sortierte Liste zurueckgegeben | |
>>> sortiere_ngramme({'tset': 1, 'test': 2}) | |
[('test', 2), ('tset', 1)] | |
""" | |
ngramm_liste = [(x, gezaehlte_ngramme[x]) for x in gezaehlte_ngramme] | |
# Schwartzian transformation | |
ngramm_liste.sort(key=itemgetter(1), reverse=True) | |
return ngramm_liste | |
def liste_ngramme(ngramm_liste, num): | |
""" gibt liste mit num haeufigsten | |
n-grammen zurueck | |
>>> liste_ngramme([('test',2),('tset',1)],1) | |
['test'] | |
""" | |
return [x[0] for x in ngramm_liste[0:num]] | |
def datei_zu_ngramm(datei, anzahl_ngramme): | |
""" datei wird gelesen, in ngramme zerlegt | |
und eine liste der haeufigsten ngramme | |
wird zurueckgegeben | |
>>> datei_zu_ngramm("doctest.txt", 2) | |
['ester', 'teste'] | |
""" | |
f = open(datei) | |
rohtext = f.read() | |
text = normalisiere_text(rohtext) | |
ngramme = zerlege_text(text) | |
gezaehlt = zaehle_ngramme(ngramme) | |
sortiert = sortiere_ngramme(gezaehlt) | |
return liste_ngramme(num=anzahl_ngramme, ngramm_liste=sortiert) | |
def vergleiche_dateien(datei, ngramme, anzahl_ngramme, vergleich): | |
""" vergleicht die haeufigsten ngramme | |
zweiter dateien | |
>>> vergleiche_dateien("deutsch1.txt", ['nicht', 'ianne'], 2, 2) | |
True | |
>>> vergleiche_dateien("deutsch1.txt", ["teste", "blabl"], 2, 2) | |
False | |
""" | |
ngramme_neu = datei_zu_ngramm(datei, anzahl_ngramme) | |
s1 = set(ngramme_neu) | |
s2 = set(ngramme) | |
return len(s1.intersection(s2)) >= vergleich | |
def lernen(datei, sprache): | |
""" | |
speichert daten sprachabhaengig auf festplatte | |
>>> lernen("deutsch1.txt", "deutsch") | |
>>> os.path.isfile("sprachen.dat") | |
True | |
""" | |
sprachen = {} | |
# daten aus datei laden, wen datei existiert | |
if os.path.isfile("sprachen.dat"): | |
sprachen.update(pickle.load(open("sprachen.dat"))) | |
# 50 ngramme pro sprache werden gespeichert | |
ngramme = datei_zu_ngramm(datei, 50) | |
# ueberschreibt gelernte daten fuer diese sprache | |
sprachen[sprache] = ngramme | |
pickle.dump(sprachen, open("sprachen.dat", "wb")) | |
def vergleiche(datei): | |
""" vergleiche datei mit gespeicherten daten | |
# doctest hier einfuegen | |
""" | |
gelernt = pickle.load(open("sprachen.dat")) | |
sprachen = [] | |
for sprache in gelernt: | |
if vergleiche_dateien(datei, gelernt[sprache], 50, 10): | |
sprachen.append(sprache) | |
return sprachen | |
def main(): | |
""" | |
zwei dateien (als kommandozeilenoption) auswerten | |
""" | |
if sys.argv[1] == "lerne": | |
lernen(sys.argv[3], sys.argv[2]) | |
elif len(sys.argv) == 2: | |
sprachen = vergleiche(sys.argv[1]) | |
if len(sprachen) == 0: | |
print "Unbekannte Sprache" | |
else: | |
print "Text koennte sein: %s" % " ,".join(sprachen) | |
else: | |
print "lernen: %s lerne <dateiname>" % sys.argv[0] | |
print "vergleich: %s dateiname" % sys.argv[0] | |
if __name__ == "__main__": | |
# unsere Funktion | |
main() | |
# our doctest | |
#import doctest | |
#doctest.testmod() | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment