Génération de texte en russe par des modèles

Quand je commençais à peine à travailler sur mon jeu de texte, j'ai décidé que l'une de ses principales caractéristiques devait être de belles descriptions artistiques des actions des personnages. En partie, je voulais «sauvegarder», car je ne savais pas comment le planifier. La sauvegarde n'a pas fonctionné, mais il s'est avéré une bibliothèque Python ( github , pypi ) pour générer des textes, en tenant compte de la dépendance des mots et de leurs caractéristiques grammaticales.

Par exemple, à partir du modèle:
[Héros] [passé | héros] devant une cour discrète et soudain [remarqua | héros] des enfants jouant. Ils couraient avec des épées en bois, des bâtons et des masques de monstres. Soudain, un des joueurs s'est arrêté, a mis [jouet | hero.weapon | vn] [hero.weapon | vn] , a crié: “ [I | hero] [grand | hero] [Hero] ! Obtenez-le! " - et se précipita vers la "bête". Ils sont tombés au sol, ont sauté leurs bras et leurs jambes, puis se sont levés, ont enlevé leurs masques et ont ri. [Grunted | hero] et [lui-même | hero] [Hero] , mais [ start | hero] ne sont pas allés voir le petit.
Nous pouvons obtenir le texte suivant (les mots changeants sont en gras):
Hallr passa devant une cour discrète et remarqua soudain des enfants jouant. Ils couraient avec des épées en bois, des bâtons et des masques de monstres. Soudain, un des joueurs s'est arrêté, a sorti une épée dorée jouet , a crié: « Je suis un grand Hallr ! Obtenez-le! " - et se précipita vers la "bête". Ils sont tombés au sol, ont sauté leurs bras et leurs jambes, puis se sont levés, ont enlevé leurs masques et ont ri. Hallr lui-même gloussa , mais ne sortit pas vers le petit.
Ou comme ça:
Fievara passa devant une cour discrète et remarqua soudain des enfants qui jouaient. Ils couraient avec des épées en bois, des bâtons et des masques de monstres. Soudain, l'un des joueurs s'est arrêté, a sorti un jouet catarrhe , a crié: « Je suis le grand Fievara ! Obtenez-le! " - et se précipita vers la "bête". Ils sont tombés au sol, ont sauté leurs bras et leurs jambes, puis se sont levés, ont enlevé leurs masques et ont ri. Fievara elle-même grogna , mais ne sortit pas vers le petit.

Réservations de couple
Clause de non-responsabilité 1 . Je ne suis pas linguiste et la bibliothèque a été écrite «pour travailler», et non «pour correspondre exactement à toutes les règles de la langue». Par conséquent, je m'excuse à l'avance pour les inexactitudes dans la terminologie ou une interprétation incomplète des règles de la langue russe.

Clause de non-responsabilité 2 . La bibliothèque a été développée il y a environ 5 ans, maintenant des moyens alternatifs de génération de texte pourraient apparaître (ou atteindre un état normal). Par exemple, quelque chose d'intéressant peut être dans le logiciel de localisation.

Sur la complexité de la génération de texte


La langue russe est complexe sous de nombreux aspects. En particulier, les mots ont un grand nombre de formes morphologiques. Par exemple, les adjectifs peuvent avoir une forme complète et courte, variant selon le sexe, le nombre, le cas, l'animation et le degré de comparaison. Le choix d'une forme spécifique dépend d'autres mots de la phrase. Nous disons «belle femme», mais «bel homme». Le mot «beau» dans ce cas dépend des mots «homme» / «femme» - sa forme est déterminée par le sexe du mot principal.

Par conséquent, les difficultés commencent lorsque nous essayons de contacter quelqu'un en fonction de son sexe. Lors de la compilation de textes pour des sites Web, des lettres, des jeux, il faut soit proposer une formulation très soignée (en évitant le sexe de l'utilisateur), écrire plusieurs textes à la fois, ou utiliser des langages de balisage de divers degrés de polyvalence.

Je voulais quelque chose de plus qu'une simple dépendance du sexe du joueur, et même pour que les utilisateurs eux-mêmes puissent ajouter de nouveaux textes (et l'utilisateur "moyen" est assez analphabète, comme nous le savons tous :-)). Par conséquent, ne trouvant pas le bon logiciel, j'ai décidé de le faire moi-même.

Fonctionnalités de la bibliothèque


UTG (générateur de texte universel - pas un nom très modeste) vous permet de créer des modèles pour générer du texte avec les éléments suivants:

  • variables (par exemple nom du caractère);
  • dépendances des mots sur les variables (par exemple, un adjectif sur un nom);
  • Dépendances de certaines variables sur d'autres;
  • Propriétés explicites des mots et des variables (par exemple, vous pouvez spécifier que le nom du caractère est inséré dans la casse parent);

Lors de la génération de texte à partir d'un modèle:

  • Les propriétés nécessaires du mot principal sont transférées aux mots dépendants. Par exemple, le sexe d'un nom est transféré à l'adjectif.
  • La forme des mots dépendants est cohérente avec les chiffres (en tenant compte de la forme des mots dépendants).
  • Les prépositions sont modifiées si nécessaire (par exemple, à propos de moi / à propos de vous), le prétexte à cela doit être balisé.

En outre mis en œuvre:

  • Un dictionnaire pour stocker les mots nécessaires.
  • Un référentiel de modèles pour les stocker par type et choisir des modèles aléatoires.

La bibliothèque «connaît» l'existence des noms, adjectifs, pronoms, verbes, participes, nombres, prépositions et «citations» (texte immuable).

Les propriétés suivantes des mots sont prises en compte: partie du discours, cas, animation, nombre, sexe, forme verbale, temps, personne, type, catégorie d'adjectif, degré d'adjectif, catégorie de pronom, promesse, forme de préposition, forme d'adjectif, forme de participe, forme de nom ( en plus de la forme normale, les noms ont un dénombrable ).

Format de modèle et exemple d'utilisation


Regardons un modèle simple:
Hier [mob] [mordu | mob] [héros | ext] .
Selon les valeurs des variables, le modèle peut apparaître comme une telle phrase:
Hier, une hyène a mordu Hallre.
tel et tel:
Les lucioles ont mordu un fantôme hier.
Examinez le modèle plus en détail:

  • - texte brut.
  • [mob] - une variable, au lieu de laquelle le nom du monstre est substitué.
  • [|mob] - un mot dépendant d'une variable, une partie de ses propriétés changera en fonction des propriétés du nom du monstre (par exemple, un nombre). Le générateur de texte reconnaît automatiquement les propriétés du formulaire Word et essaie de les enregistrer (par exemple, le temps écoulé sera reconnu et enregistré, vous n'avez donc pas besoin de le spécifier).
  • [hero|] - une variable, au lieu de laquelle le nom du héros est substitué. Il est en outre indiqué que le nom devrait figurer dans le dossier d'accusation.

Plus d'exemples de modèles.
Quelques exemples techniques peuvent être trouvés dans les tests .

Si vous êtes intéressé par plus d'exemples, vous pouvez les voir sur le site Web de jouets. Un lien vers celui-ci peut être trouvé en fouillant dans mon profil, ou en écrivant à titre personnel.

Les mots variables et dépendants du modèle sont mis en évidence de manière identique et ont le format suivant:

  • [ - ouverture du support carré.
  • ou identificateur de variable dépendant du mot. Le générateur vérifie d'abord la présence d'une variable portant ce nom; s'il n'y en a pas, le mot est recherché dans le dictionnaire.
  • | - barre verticale - séparateur, nécessaire si nous spécifions des propriétés supplémentaires.
  • - la variable dont dépend la forme du mot peut être absente.
  • | - barre verticale - séparateur, nécessaire si nous spécifions des propriétés supplémentaires.
  • - une description de la forme requise du mot (casse, sexe, etc.). Une liste d'entre eux peut être trouvée sur les pages du projet dans github et pypi.
  • ] Est le crochet carré de fermeture.

Vous pouvez spécifier toutes les propriétés supplémentaires à votre guise, elles seront appliquées dans l'ordre de définition, par exemple:

[ 1| 2|,| 3|,,]

Dans la plupart des cas, les formats suivants suffisent:

  • [] - insère une variable sous forme normale (par exemple, un nom dans le cas nominatif du singulier).
  • [|] - insère une variable avec les propriétés spécifiées.
  • [|] - insère un mot, en le faisant correspondre avec une variable (par exemple, l'adjectif "beau" avec un nom en genre et en casse).
  • [||] - insérez un mot, en le faisant correspondre avec une variable et en spécifiant des propriétés supplémentaires.

Veuillez noter:

  • La spécification des propriétés des mots et des variables n'est valable qu'au lieu d'insertion. Par conséquent, pour obtenir l'expression «beau héros», nous devons indiquer explicitement le cas accusatif pour deux mots: [|hero|] [hero|] .
  • Le générateur de texte peut «deviner» les propriétés du mot par sa forme, par exemple, dans la phrase [hero] [|hero] vous pouvez omettre le temps du verbe.
  • Les propriétés spécifiées ultérieurement remplacent les propriétés spécifiées précédemment. Par exemple, dans la phrase [|hero] [hero|] , l'accusatif de l'adjectif ne sera pas établi, car il sera remplacé par le cas nominatif du héros variable.
  • Une liste des propriétés des mots peut être trouvée sur les pages de la bibliothèque dans github et pypi.

Exemple de code
Python 3 requis

L'installation

 pip install utg python -m unittest discover utg 

Code

 from utg import relations as r from utg import dictionary from utg import words from utg import templates from utg import constructors ####################################### #     ####################################### coins_forms = [#   '', '', '', '', '', '', #   '', '', '', '', '', '', #   (  , #     autofill_missed_forms) '', '', '', '', '', ''] # : ,   coins_properties = words.Properties(r.ANIMALITY.INANIMATE, r.GENDER.FEMININE) #      ,    coins_word = words.Word(type=r.WORD_TYPE.NOUN, forms=coins_forms, properties=coins_properties) #        . #      , #          : # - utg.data.WORDS_CACHES # - utg.data.INVERTED_WORDS_CACHES ############################## #     ############################## #       # (     utg.data.WORDS_CACHES[r.WORD_TYPE.VERB]) action_forms = (['', '', '', '', ''] + [''] * 15) # : ,   action_properties = words.Properties(r.ASPECT.PERFECTIVE, r.VOICE.DIRECT) action_word = words.Word(type=r.WORD_TYPE.VERB, forms=action_forms, properties=action_properties) #       (  ) action_word.autofill_missed_forms() ############################################## #       ############################################## test_dictionary = dictionary.Dictionary(words=[coins_word, action_word]) ################ #   ################ template = templates.Template() # externals —  ,      template.parse('[Npc] [|npc] [hero|] [coins] [|coins|].', externals=('hero', 'npc', 'coins')) ############################## #    ############################## hero_forms = ['', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', ''] # : ,   hero_properties = words.Properties(r.ANIMALITY.ANIMATE, r.GENDER.MASCULINE) hero = words.WordForm(words.Word(type=r.WORD_TYPE.NOUN, forms=hero_forms, properties=hero_properties)) npc_forms = ['', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', ''] # : ,   npc_properties = words.Properties(r.ANIMALITY.ANIMATE, r.GENDER.FEMININE) npc = words.WordForm(words.Word(type=r.WORD_TYPE.NOUN, forms=npc_forms, properties=npc_properties)) ########################## #   ########################## result = template.substitute(externals={'hero': hero, 'npc': npc, 'coins': constructors.construct_integer(125)}, dictionary=test_dictionary) ########################## #  ########################## result == '   125 .' 

À propos des dictionnaires


Comme vous l'avez peut-être remarqué, UTG nécessite la formation d'un dictionnaire. Cela se fait «à la main» puisqu'au moment du développement:

  • Je n'ai trouvé aucun dictionnaire morphologique qualitatif généralement accessible.
  • La bibliothèque de pymorphie était toujours la première version et plissait souvent les yeux (surtout avec le cas accusatif), c'est pourquoi j'ai dû l'abandonner.

Si vous souhaitez utiliser un générateur avec beaucoup de mots, avant de les entrer manuellement, essayez d'utiliser pymorphy2, ou recherchez un dictionnaire prêt à l'emploi et exportez-le.

Total


J'espère que la bibliothèque vous sera utile.

Si vous avez des idées pour son développement (ou mieux encore, un désir d'y participer) - écrivez dans un message personnel, faites des requêtes pull, postez des bugs sur le github.

Source: https://habr.com/ru/post/fr471278/


All Articles