Text auf Substantive prüfen

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
Liskaya
User
Beiträge: 4
Registriert: Sonntag 28. September 2014, 20:51

Hallo zusammen,

ich hab hier ein kleines Problem und bräuchte ein wenig Hilfe.
Die SuFu hat mir leider nicht wirklich geholfen :-(

Also folgendes, ich soll einen Chatbot entwickeln der als Studienberater dienen soll und ähnlich wie "ELIZA" agiert.
Er soll die Benutzereingaben auf Substantive prüfen, diese auf der Konsole ausgeben und dann eine geeignete Antwort geben, indem er die gefundenen Substantive mit den vorgegebenen Schlüsselwörtern abgleicht.

Grundidee: Alle großgeschriebenen Wörter aus der Eingabe filtern und Satzanfänge ignorieren.
Mein Problem ist es, dass ich keine Ahnung habe welchen Befehl ich dazu brauche. Genauer gesagt wie sähe ein Codeschnipsel aus, der bewirkt, dass von dem Satz "Hallo ich habe Probleme den richtigen Studiengang zu finden" nur "Probleme" und "Studiengang" übrig bleibt?

Danke schon mal :)

Lg Liskaya
BlackJack

@Liskaya: Welches Tutorial hast Du denn für die Python-Grundlagen durchgearbeitet?

Das `re`-Modul könnte hier hilfreich sein. Dazu gibt es ein Howto in der Python-Dokumentation.

Das was Du beschreibst hat übrigens nicht viel mit ELIZA zu tun. ELIZA ist ”nutzlos”.
Benutzeravatar
pillmuncher
User
Beiträge: 1484
Registriert: Samstag 21. März 2009, 22:59
Wohnort: Pfaffenwinkel

@Liskaya: Was machst du mit Sätzen wie: "Grundidee: Alle großgeschriebenen Wörter aus der Eingabe filtern und Satzanfänge ignorieren."? Nach meiner Einschätzung ist das Wort Grundidee durchaus ein Substantiv, weil es aber am Satzanfang steht, würdest du es ignorieren.

Wie BlackJack bin ich der Überzeugung, dass man einen Studienberater nach dem ELIZA-Prinzip nicht programmieren kann. Wenn es aber tatsächlich so etwas dummes wie ELIZA werden soll, dann denke ich, dass du das ganze viel zu kompliziert angehst. Der Witz bei ELIZA war ja, dass es absolut gar nichts über irgendetwas wusste, auch nichts über Satzbau oder Substantive. Um ein funktionierendes ELIZA zu schreiben, braucht man nur die Antwort in Kleinbuchstaben verwandeln und nachsehen, ob ein Wort aus einer Schlagwortliste darin vorkommt. Findet man keines, gibt man aus "Erzählen sie mehr.", "Aha." oder "Hm." und falls man eines findet, sagen wir "mutter", "familie", "studium" oder "professor", dann gibt man aus "Erzählen sie mir mehr über ihr/e/n Mutter/Familie/Studium/Professor". Das könnte dann so aussehen:

Code: Alles auswählen

keywords = {
    'mutter': 'Ihre Mutter',
    'professor': 'Ihren Professor',
    'familie': 'Ihre Familie',
    'studium': 'Ihr Studium',
    ...
}
Daraus lässt sich dann leicht eine neue Frage zimmern:

Code: Alles auswählen

for word, phrase in keywords.items():
    ...
    question = 'Erzählen Sie mir mehr über {}.'.format(phrase)
    ....
In specifications, Murphy's Law supersedes Ohm's.
Liskaya
User
Beiträge: 4
Registriert: Sonntag 28. September 2014, 20:51

Hallo zusammen danke für die antworten
BlackJack hat geschrieben:@Liskaya: Welches Tutorial hast Du denn für die Python-Grundlagen durchgearbeitet?
Ich bin gerade dabei das Buch "einstieg in python" durch zu arbeiten. Da ich das Buch allerdings erst seit Samstag habe bin ich natürlich noch nicht allzu weit.
Die erste Vorlesung zum Thema hatte ich am Freitag, diese war allerdings so gar nicht hilfreich, da der Professor die Zeit eher damit verschwendet hat, über den Erfinder von Python zu erzählen und ein kleines Zahlen-Ratespiel zu programmieren.

pillmuncher hat geschrieben:@Liskaya: Was machst du mit Sätzen wie: "Grundidee: Alle großgeschriebenen Wörter aus der Eingabe filtern und Satzanfänge ignorieren."? Nach meiner Einschätzung ist das Wort Grundidee durchaus ein Substantiv, weil es aber am Satzanfang steht, würdest du es ignorieren.
Theoretisch ist das dumm, klar. Wird aber in der Aufgabenstellung so verlangt :roll:


Ich habe es jetzt auf zwei Arten probiert aber das gewünschte Ergebnis habe ich noch immer nicht

Code: Alles auswählen

f = input("Studierender:")
liste = f
gross = re.findall("[A-ZÖÄÜ]", liste)
print(gross)
hierbei wird halt nur der Anfangsbuchstabe ausgegeben

Code: Alles auswählen

f = input("Studierender:")
list = f
gross = filter(lambda x: x[0].isupper(), liste)
print(gross)
Dieser Code hat als Ausgabe lediglich <filter object at 0x02C19B30>
jerch
User
Beiträge: 1669
Registriert: Mittwoch 4. März 2009, 14:19

Da ich oben was von Chatbot gelesen habe, werfe ich mal noch das Problem in den Raum, das in Chats häufig ein anderer Schreibstil genutzt wird (häufig alles klein geschrieben, Nutzung von sonst nicht üblichen Kurzschreibweisen etc., sprich die Syntax weicht von der Hochsprache ab)
Damit verlagert sich das Problem wieder Richtung Inhaltsanalyse, und nunja darüber müssen noch viele Leute habilitieren, bis das wirklich was taugt ;)

@Liskaya:
Imho ist es für Dich wichtig, genau zu klären, was die Automatismen können sollen. Ansonsten wird das schnell zum Fass ohne Boden.
Benutzeravatar
/me
User
Beiträge: 3555
Registriert: Donnerstag 25. Juni 2009, 14:40
Wohnort: Bonn

Liskaya hat geschrieben:

Code: Alles auswählen

f = input("Studierender:")
liste = f
gross = re.findall("[A-ZÖÄÜ]", liste)
print(gross)
Der Ansatz ist da. Allerdings ist f ein völlig nichtssagender Name und warum der Inhalt noch mal an den Namen liste gebunden wird ist auch äußerst schleierhaft. Man sollte ohnehin keine Datentypen in den Namen des Bezeichner aufnehmen, vor allem, wenn der Datentyp dann nicht mal stimmt.

Aktuell suchst du nur nach genau einem Großbuchstaben. Du willst aber eigentlich einene Großbuchstaben der nach einer Wortgrenze beginnt und dann weitere Zeichen bis zur nächsten Wortgrenze. Die Wortgrenze bekommst du mit \b, die weiteren Zeichen mit \w (ergänzt um ein +, da es ja mehrere Zeichen sein dürfen). Um den Backslash jetzt nicht noch einmal explizit mit einem Backslash escapen zu müssen bietet sich die Verwendung eines Raw-Strings an.

Code: Alles auswählen

def find_words(text):
    return re.findall(r'\b([A-ZÄÖÜ]\w+)\b', text)
Das erste Wort musst du dir noch herausfiltern.
Liskaya
User
Beiträge: 4
Registriert: Sonntag 28. September 2014, 20:51

Vielen Dank euch allen :)
Das Problem ist nun gelöst aber aus Interesse frage ich nun noch warum dieser Schnipsel nur "<filter object at 0x02C19B30>" ausgibt. Habe ich etwas übersehen oder ist es gar nicht möglich das Problem damit zu lösen?

Code: Alles auswählen

f = input("Studierender:")
liste = f
gross = filter(lambda x: x[0].isupper(), liste)
print(gross)
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Liskaya hat geschrieben:...aber aus Interesse frage ich nun noch warum dieser Schnipsel nur "<filter object at 0x02C19B30>" ausgibt. Habe ich etwas übersehen oder ist es gar nicht möglich das Problem damit zu lösen?
``filter`` gibt Dir ein Iterator-Objekt zurück, also vereinfacht ausgedrückt ein Objekt, über welches Du z.B. in einer ``for``-Schleife iterieren kannst.
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
Benutzeravatar
/me
User
Beiträge: 3555
Registriert: Donnerstag 25. Juni 2009, 14:40
Wohnort: Bonn

Laut Dokumentation liefert filter dir einen Iterator.

Du kannst also einfach die Elemente durchlaufen.

Code: Alles auswählen

content = "Hallo ich habe Probleme den richtigen Studiengang zu finden"
for element in filter(lambda x: x[0].isupper(), content):
    print(element)
Wenn du die Elemente in einer Liste haben möchtest, dann mach einfach eine daraus.

Code: Alles auswählen

content = "Hallo ich habe Probleme den richtigen Studiengang zu finden"
print(list(filter(lambda x: x[0].isupper(), content)))
Falls du das irgendwo anders gesehen hast, dann war das Code für Python 2.x. Unter Python 2 hat filter direkt eine Liste zurückgeliefert.
Liskaya
User
Beiträge: 4
Registriert: Sonntag 28. September 2014, 20:51

/me hat geschrieben:
Falls du das irgendwo anders gesehen hast, dann war das Code für Python 2.x. Unter Python 2 hat filter direkt eine Liste zurückgeliefert.
Ja hatte ich auf der anderen Seite gefunden, wo jemand ein ähnliches Problem hatte. Ich hab allerdings nicht draufgeachtet obs für 2 oder 3 war. Aber wenns für 2 ist ergibt es natürlich Sinn, dass es nicht problemlos funktioniert hat.


Danke an euch alle für die schnelle Hilfe und die super Erklärungen!
Benutzeravatar
snafu
User
Beiträge: 6740
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Für Operationen, die über ein "Funktion(x) für alle x" hinausgehen, würde ich sowieso eher List Comprehensions (LCs) empfehlen. Die sind dann meistens einfacher zu schreiben und einfacher zu lesen. Ausgenommen sind Fälle, bei denen die Operation wirklich so komplex ist, dass eine LC zu umständlich wird und man die Operation tatsächlich in einer Funktion kapseln möchte. Im hier vorliegenden Anwendungsfall würde ich jedenfalls eine LC nehmen.
Antworten