Idee für Spracherkennungsgrammatik

  • C#
  • .NET (FX) 1.0–2.0

Es gibt 1 Antwort in diesem Thema. Der letzte Beitrag () ist von faxe1008.

    Idee für Spracherkennungsgrammatik

    Hi,

    Ich arbeite gerade an einem Raspberry PI gestützten Amazon Echo "Imitat". Hab einfach Lautsprecher & Mikro an den Pi gehängt und da läuft eben eine Spracherkennung drauf.
    Jetzt gelange ich allerdings langsam an einen Punkt wo ich weiß das die Wartbarkeit des Codes mit jedem weiteren Befehl abnimmt, was natürlich nicht Sinn der Sache sein kann.

    Habe mir dazu folgendes überlegt (handelt sich um ein Python Projekt, aber die Vorgehensweise ist sprachenunabhängig): Ich bastele ein einfaches Plugin-System dass einfach alle Module aus dem /commands Ordner lädt die eine Implementierung des ICommand Interfaces haben. Das funktioniert auch soweit.

    Jetzt zur eigentlichen Frage: wie gestalte ich die Spracherkennung möglichst flexibel, d.h. sie reagiert sowohl auf "play song xyz" oder "start song xyz" hört? Habe mir dazu überlegt eine Grammatik zu implementieren die aus Verben und Subjekten besteht, die jeweils Synonyme & Deklinationen beinhaltet. Außerdem verfügt Sie natürlich über WildCards die im Falle von oben das "xyz" erkennen würden oder eben jeden anderen Namen. Hier liegt der Hund auch schon begraben - Ich kann nicht abschätzen wie viele Wörter maximal in einer Wildcard sein können, z.B. Songnamen können 1 Wort oder auch 10 haben. Zudem kommt natürlich das Problem das man dazu neigt Füllwörter wie "the", "a" usw. zu nutzen beim Sprechen.

    Bisherige Implementierung, die die Reihenfolge der Kommandobestandteile berücksichtigt (Ja es ist Python, aber das soll nur das Prinzip zeigen):

    Quellcode

    1. class ICommand():
    2. words = []
    3. parameters = []
    4. def recognize(self, rec_text):
    5. rec_text_fragments = rec_text.split()
    6. for word in self.words:
    7. fragment = None
    8. while not word.recognize(fragment):
    9. if len(rec_text_fragments) > 0:
    10. fragment = rec_text_fragments.pop(0)
    11. else:
    12. return False
    13. if isinstance(word, WildCard):
    14. self.parameters.append(fragment)
    15. return True
    16. def execute(self):
    17. pass


    Hat hierzu jemand eine gute Idee?

    8-) faxe1008 8-)
    Da sich keiner gemeldet hat, habe ich mal was gebastelt, was bisher alle Anforderungen erfüllt:

    Quellcode

    1. ​def recognize(self, rec_text):
    2. rec_text_fragments = rec_text.split()
    3. for x in range(0, len(self.words)):
    4. word = self.words[x]
    5. fragment = ''
    6. if isinstance(word, WildCard):
    7. # last expression in rule, put rest of rec_Text_fragments in one wildcard
    8. if x == len(self.words)-1:
    9. self.parameters.append(' '.join(rec_text_fragments))
    10. break
    11. else:
    12. next_keyword = self.words[x+1]
    13. while not next_keyword.recognize(rec_text_fragments[0]):
    14. fragment = fragment + ' ' + rec_text_fragments.pop(0)
    15. if len(rec_text_fragments) == 0 : return False
    16. self.parameters.append(fragment.lstrip())
    17. else:
    18. while not word.recognize(fragment):
    19. if len(rec_text_fragments) > 0:
    20. fragment = rec_text_fragments.pop(0)
    21. else:
    22. return False
    23. return True


    Idee ist dass bei einer Regel ​VERB WILDCARD OBJECT solange Textfragmente in die Wildcard geschmissen werden bis ein akzeptiertes Objekt gefunden wird. Wenn es eine Regel der Form ​VERB WILDCARD ist wird einfach alles bis zum Ende in die Wildcard gegeben.

    8-) faxe1008 8-)