Substantive mit Python filtern
Du kannst mit einem Part-of-Speech-Tagger die Wortarten in einem Text bestimmen und anschließend dann nach Substantiven filtern. POS-Tagger gibt es als Teil größerer Frameworks (spaCy, nltk, textblob) oder standalone.
-
Pedroski55
- User
- Beiträge: 53
- Registriert: Freitag 25. Juli 2025, 00:20
Nichts einfacher wie das! Probieren wir mit diesem Text:
wortzahl =
"""Ein neues Jahr besteht aus insgesamt vier Jahreszeiten.
Frühling, Sommer, Herbst und Winter folgen nacheinander.
Das Jahr beginnt im Januar.
Im Januar und Februar ist es draußen noch sehr kalt und man muss sich warm anziehen, um nicht zu frieren und krank zu werden.
Der Frühling beginnt im März.
Dann steigen die Temperaturen und es wird wieder wärmer.
In den Monaten März, April und Mai ist Frühling.
Von Juni bis September findet der Sommer statt.
Der Sommer ist die heißeste Jahreszeit in Deutschland.
Viele Menschen fahren in dieser Zeit in den Urlaub.
Ab Mitte September bis November gibt es in Deutschland den Herbst.
Dann wird es draußen langsam kälter und man muss sich wieder wärmer anziehen.
Der November und Dezember sind die letzten Monate des Jahres.
Dann stellt sich der Winter ein.
Wenn es besonders kalt ist, kann es im Winter schneien."""
Code: Alles auswählen
import regex as re
# alle gesuchte Worter
worter = ['Jahr', 'Frühling', 'Sommer', 'Herbst', 'Winter']
# Dict um Zahlen zu speichern
wortzahl = {wort: 0 for wort in worter}
# speicher die Datei als Textdatei um sich das Leben bequem zu machen
dtext = '/home/peterr/temp/Deutschetexte/Dtext1.txt'
# falls der Text sehr gross ist benutze einen Generator
def zeilen_holen(text):
with open(text) as f:
for line in f:
yield line
# finde alle Buchstaben und nur Buchstaben
e = re.compile(r'\w+')
# entferne was nicht Buchstabe ist ,.; Leertaste usw
def entferne_zeichen(text):
res = e.findall(text)
return res
for l in zeilen_holen(dtext):
print(l)
linie_list = entferne_zeichen(l)
for wort in linie_list:
if wort in worter:
wortzahl[wort] +=1{'Jahr': 2, 'Frühling': 3, 'Sommer': 3, 'Herbst': 2, 'Winter': 3}
-
Pedroski55
- User
- Beiträge: 53
- Registriert: Freitag 25. Juli 2025, 00:20
Fiel mir grad ein:
Nun müsste man die obige Liste worter mit einer Liste aller Substantive. Die Internetseite hier hat eine solche Liste.
Bißchen webscraping und könnte man sich die holen.
Dann das Resultat nach Haufigkeit der Worter sortieren:
Dann einfach die ersten 200 von sortiert_dict abzweigen!
Nun müsste man die obige Liste worter mit einer Liste aller Substantive. Die Internetseite hier hat eine solche Liste.
Bißchen webscraping und könnte man sich die holen.
Dann das Resultat nach Haufigkeit der Worter sortieren:
Code: Alles auswählen
sortiert_dict = {key: value for key, value in sorted(wortzahl.items(), reverse=True, key=lambda item: item[1])}Code: Alles auswählen
häufige_worter = {}
if len(sortiert_dict) < 200:
häufige_worter = sortiert_dict
else:
count = 1
for key in sortiert_dict.keys():
häufige_worter[key] = sortiert_dict[key]
count +=1
if count > 200:
break- noisefloor
- User
- Beiträge: 4321
- Registriert: Mittwoch 17. Oktober 2007, 21:40
- Wohnort: WW
- Kontaktdaten:
Hallo,
@Vesemir: was hast du den schon probiert? Ich habe vor ein paar Jahren mal was mit nltk gemacht, das war eigentlich relativ einfach. Auf jeden Fall ist das besser und zuverlässiger, als sich low-tech irgendwas selber zusammen zu basteln. Zumal die Bibliotheken direkt noch den "Service" liefern, Einzahl und Mehrzahl zu erkennen und (wenn gewünscht) einem Nomen zuzuordnen.
Gruß, noisefloor
@Vesemir: was hast du den schon probiert? Ich habe vor ein paar Jahren mal was mit nltk gemacht, das war eigentlich relativ einfach. Auf jeden Fall ist das besser und zuverlässiger, als sich low-tech irgendwas selber zusammen zu basteln. Zumal die Bibliotheken direkt noch den "Service" liefern, Einzahl und Mehrzahl zu erkennen und (wenn gewünscht) einem Nomen zuzuordnen.
Gruß, noisefloor
@Pedroski55: auch wenn Du beratungsresistent bist, hier nochmal alle Kommentare, die auch schon bei Deinen anderen Beiträgen hier gelten: benutze kein extra Modul regex, wenn aus auch das ganz normale re-Modul aus der Standardbibliothek tut. Einbuchstabige Variablennamen sind schlecht, weil sie nichts aussagen, l ist besonders schlecht, weil man es leicht mit 1 oder I verwechseln kann. Was soll das d in dtext bedeuten?
Funktionen sollten einen Namen haben, der auch sagt, was die Funktion macht, `entferne_zeichen` macht aber was ganz anderes.
Wenn man etwas zählen will, dann gibt es dafür collections.Counter, das muß man nicht selbst programmieren.
Das ganze könnte also so aussehen:
Aber es gilt das, was noisefloor geschrieben hat: mit regulären Ausdrücken und Wortlisten kommt man nicht sehr weit, wenn man im deutschen Substantive finden will.
Funktionen sollten einen Namen haben, der auch sagt, was die Funktion macht, `entferne_zeichen` macht aber was ganz anderes.
Wenn man etwas zählen will, dann gibt es dafür collections.Counter, das muß man nicht selbst programmieren.
Das ganze könnte also so aussehen:
Code: Alles auswählen
import re
from collections import Counter
INPUT_FILENAME = '/home/peterr/temp/Deutschetexte/Dtext1.txt'
WORDS = ['Jahr', 'Frühling', 'Sommer', 'Herbst', 'Winter']
WORD_REGEX = re.compile(r"\w+")
def iter_words(filename):
with open(filename) as lines:
for line in lines:
for word in WORD_REGEX.findall(line):
yield word
def main():
words_count = Counter(
word
for word in iter_words(INPUT_FILENAME)
if word in WORDS
)
print("Die 10 häufigsten Wörter")
for word, count in words_count.most_common(10):
print(f"{word}: {count}")
if __name__ == "__main__":
main()- noisefloor
- User
- Beiträge: 4321
- Registriert: Mittwoch 17. Oktober 2007, 21:40
- Wohnort: WW
- Kontaktdaten:
@Vesemir: ein bisschen mehr Kontext wäre auch nicht schlecht. Ist das eine Hausaufgabe oder was ist der Hintergrund? Des Weiteren: Substantiven in der Grundform oder sind Variationen von Substantiven ein eigenes Substantiv? Die Beispiel von Pedroski55 erkennt zwar den Genitiv von Jahr in der 3. letzten Zeile, würde aber bei einer Vielzahl von Pluralen scheitern. Die Pluralbildung im deutschen ja auch ziemlich Komplex, weil es X Formen und Sonderformen gibt, ein paar Beispiele: Auto - Autos, Messer - Messer, Gabel - Gabeln, Haus - Häuser, Schiff - Schiffe, Hemd - Hemden, Atlas - Atlanten.
Wenn man das richtig / ordentlich machen will, kommst du an einer Bibliothek mit einem Stemmer und Lemmatizer für Deutsch nicht vorbei. Gibt's ja auch für Python. Ein etwas älterer, aber IMHO für den Einstieg immer noch guter Artikel ist https://nickyreinert.de/2020/2020-12-09 ... it-python/. Da findest du auch Hinweise auf Bibliotheken für Python.
Gruß, noisefloor
Wenn man das richtig / ordentlich machen will, kommst du an einer Bibliothek mit einem Stemmer und Lemmatizer für Deutsch nicht vorbei. Gibt's ja auch für Python. Ein etwas älterer, aber IMHO für den Einstieg immer noch guter Artikel ist https://nickyreinert.de/2020/2020-12-09 ... it-python/. Da findest du auch Hinweise auf Bibliotheken für Python.
Gruß, noisefloor
- __blackjack__
- User
- Beiträge: 14380
- Registriert: Samstag 2. Juni 2018, 10:21
- Wohnort: 127.0.0.1
- Kontaktdaten:
@Pedroski55: Ergänzend zu dem Beitrag von Sirius3: Kommentare sollten inhaltlich korrekt sein, denn sonst weiss man nicht ob der Kommentar oder der Code falsch ist, wenn die sich nicht einig sind. „# finde alle Buchstaben und nur Buchstaben“ stimmt beispielsweise nicht. Das findet mehr als nur Buchstaben. Das findet Zeichen die Worte oder Bestandteile von Worten sein können. Wenn man da einfach mal _alles_ anschaut worauf man den Ausdruck los lassen kann, dann findet man, dass es sich um 142.940 von 1.114.112 Zeichen handelt:
Anfang der Ausgabe:
Später in der Ausgabe kommen dann noch verschiedene Ziffern und Zahlendarstellungen, unter anderem römische Zahlen, und natürlich auch Silben oder ganze Worte in aus dem Bereich von asiatischen Schriften.
Die Funktion, in der der reguläre Ausdruck dann verwendet wird, ist ziemlich umständlich ausgedrückt, dafür dass das nur ein anderer Name für die konkrete `findall()`-Methode ist:
Das Argument von `hole_zeilen()` ist ein Dateiname, den sollte man deshalb nicht `text` nennen.
Beim öffnen von Textdateien sollte man immer explizit die Kodierung angeben.
``yield`` in einer simplen Schleife ist eigentlich keine Schleife, sondern ``yield from``.
Entweder `worte` oder `woerter`, aber bitte nicht `worter`. Noch übler ist `linie_list`. Denglisch, Grunddatentyp im Namen, und der deutschsprachige Teil ist inhaltlich falsch. Das ist keine Linie sondern eine Zeile. Oder passender, das sind Worte. Letztlich braucht man aber auch gar keinen Namen dafür wenn man nicht jedes kleine Zwischenergebnis an einen Namen bindet.
Um ein Wörterbuch mit Schlüsseln, die alle den selben Wert haben, zu erzeugen, haben Wörterbücher die `fromkeys()`-Methode:
Statt jedes Wort gegen die Liste zu prüfen, wäre es effizienter gegen die Schlüssel des Wörterbuchs zu prüfen.
Zwischenstand (ungetestet):
Code: Alles auswählen
#!/usr/bin/env python3
import re
import sys
import textwrap
def main():
all_word_characters = "".join(
re.findall(r"\w+", "".join(map(chr, range(sys.maxunicode + 1))))
)
print(len(all_word_characters), "von", sys.maxunicode + 1, "Zeichen:")
print(textwrap.fill(all_word_characters))
if __name__ == "__main__":
main()Code: Alles auswählen
142940 von 1114112 Zeichen:
0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyzª²³µ¹º¼
½¾ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõöøùúûüýþÿĀāĂ㥹
ĆćĈĉĊċČčĎďĐđĒēĔĕĖėĘęĚěĜĝĞğĠġĢģĤĥĦħĨĩĪīĬĭĮįİıIJijĴĵĶķĸĹĺĻļĽľĿŀŁłŃńŅņŇňʼnŊŋ
ŌōŎŏŐőŒœŔŕŖŗŘřŚśŜŝŞşŠšŢţŤťŦŧŨũŪūŬŭŮůŰűŲųŴŵŶŷŸŹźŻżŽžſƀƁƂƃƄƅƆƇƈƉƊƋƌƍƎƏƐƑ
ƒƓƔƕƖƗƘƙƚƛƜƝƞƟƠơƢƣƤƥƦƧƨƩƪƫƬƭƮƯưƱƲƳƴƵƶƷƸƹƺƻƼƽƾƿǀǁǂǃDŽDždžLJLjljNJNjnjǍǎǏǐǑǒǓǔǕǖǗ
ǘǙǚǛǜǝǞǟǠǡǢǣǤǥǦǧǨǩǪǫǬǭǮǯǰDZDzdzǴǵǶǷǸǹǺǻǼǽǾǿȀȁȂȃȄȅȆȇȈȉȊȋȌȍȎȏȐȑȒȓȔȕȖȗȘșȚțȜȝ
ȞȟȠȡȢȣȤȥȦȧȨȩȪȫȬȭȮȯȰȱȲȳȴȵȶȷȸȹȺȻȼȽȾȿɀɁɂɃɄɅɆɇɈɉɊɋɌɍɎɏɐɑɒɓɔɕɖɗɘəɚɛɜɝɞɟɠɡɢɣ
...Die Funktion, in der der reguläre Ausdruck dann verwendet wird, ist ziemlich umständlich ausgedrückt, dafür dass das nur ein anderer Name für die konkrete `findall()`-Methode ist:
Code: Alles auswählen
def worte_holen(text):
res = WORD_RE.findall(text)
return res
# =>
worte_holen = WORD_RE.findallBeim öffnen von Textdateien sollte man immer explizit die Kodierung angeben.
``yield`` in einer simplen Schleife ist eigentlich keine Schleife, sondern ``yield from``.
Entweder `worte` oder `woerter`, aber bitte nicht `worter`. Noch übler ist `linie_list`. Denglisch, Grunddatentyp im Namen, und der deutschsprachige Teil ist inhaltlich falsch. Das ist keine Linie sondern eine Zeile. Oder passender, das sind Worte. Letztlich braucht man aber auch gar keinen Namen dafür wenn man nicht jedes kleine Zwischenergebnis an einen Namen bindet.
Um ein Wörterbuch mit Schlüsseln, die alle den selben Wert haben, zu erzeugen, haben Wörterbücher die `fromkeys()`-Methode:
Code: Alles auswählen
wortanzahl = {wort: 0 for wort in worte}
# =>
wortanzahl = dict.fromkeys(worte, 0)Zwischenstand (ungetestet):
Code: Alles auswählen
#!/usr/bin/env python3
import re
from collections import Counter
def zeilen_holen(dateiname):
with open(dateiname, encoding="utf-8") as zeilen:
yield from zeilen
worte_holen = re.compile(r"\w+").findall
def main():
wortanzahl = Counter(
(substantiv, 0)
for substantiv in ["Jahr", "Frühling", "Sommer", "Herbst", "Winter"]
)
for zeile in zeilen_holen("/home/peterr/temp/Deutschetexte/Dtext1.txt"):
print(zeile)
wortanzahl.update(
wort for wort in worte_holen(zeile) if wort in wortanzahl
)
if __name__ == "__main__":
main()Who is General Failure and why is he reading my hard disk?
-
Pedroski55
- User
- Beiträge: 53
- Registriert: Freitag 25. Juli 2025, 00:20
"beratungsresistent" finde ich lustig! Du bist noch lernfähig!
Am Ende, und für mich, zählt nur, was funktioniert. Das Gute an Python ist, man kann es so oder so machen, wenn das Ergebnis dem entspricht, was man haben will!
Am Ende, und für mich, zählt nur, was funktioniert. Das Gute an Python ist, man kann es so oder so machen, wenn das Ergebnis dem entspricht, was man haben will!
- DeaD_EyE
- User
- Beiträge: 1340
- Registriert: Sonntag 19. September 2010, 13:45
- Wohnort: Hagen
- Kontaktdaten:
NLTK wäre auf jeden Fall eine Erleichterung. Damit kann man auch Wörterbücher herunterladen und Wörter zerlegen.
sourceserver.info - sourceserver.info/wiki/ - ausgestorbener Support für HL2-Server
