Para la parte linguistica del proyecto de generación automática de lenguaje, he encontrado dos paquetes interesantes en ruby: ruby linguistics y ruby wordnet.
Ruby linguistics comprende una serie de utilidades para manejar palabras de forma «linguistica»: permite cosas como estas:
- pluralizar una palabra: «box».en.plural # => «boxes»
- añadir artículo indefinido: «book».en.a # => «a book»
- generar el gerundio: «runs».en.present_participle # => «running»
- calcular ordinales de números: 5.en.ordinal # => «5th»
- escribir un número en letra: 5.en.numwords # => «five»
- cuantificar objetos: «cow».en.quantify(5) # => «several cows» || «cow».en.quantify( 1005 ) # => «thousands of cows»
- infinitivos: «leaving».en.infinitive # => «leave»
- generar conjunciones:
animals = %w{dog cow ox chicken goose goat cow dog rooster llama pig goat dog cat cat dog cow goat goose goose ox alpaca}
puts «The farm has: » + animals.en.conjunction
Produce:
The farm has: four dogs, three cows, three geese, three goats,two oxen, two cats, a chicken, a rooster, a llama, a pig, and an alpaca
Los ejemplos están tomados de la página del proyecto dónde hay más ejemplos.
Ruby wordnet es un interfaz ruby a Wordnet, una base de datos de palabras organizada de forma semántica. En esta base de datos las palabras se agrupan en synsets (conjuntos de palabras sinónimas) que se relacionan entre ellas con las siguientes relaciones:
- Hiperonimia e hiponimia: una palabra es hipónima de otra si posée los rasgos semánticos de otra más general.
- Holonimia y meronimia: si una palabra es parte de otra (ventana es una parte de una casa).
- Términos coordinados: dos palabras son términos coordinados si comparten un hiperónimo.
He hecho una prueba simple con linguistics y wordnet que pongo aquí cómo ejemplo. En este caso se busca el synset de unas palabras («happiness», «young» y «man») y se eligen aleatoriamente las palabras de cada synset para formar el mensaje resultado:
require ‘rubygems’
require ‘linguistics’
require ‘wordnet’
Linguistics::use( :en )
puts «Your future»
happiness_synonyms = «happiness».en.synset(1,:noun).synonyms
happiness_word = happiness_synonyms[rand(happiness_synonyms.length)]
young_synonyms = «young».en.synset(1,:adjective).synonyms
young_word = young_synonyms[rand(young_synonyms.length)]
man_synonyms = «man».en.synset(1,:noun).synonyms
man_word = man_synonyms[rand(man_synonyms.length)]
message = «I wish you #{happiness_word}, #{young_word} #{man_word}.»
puts message
Una prueba muy sencilla, pero que para poder ejecutarlo hay que resolver un par de problemillas:
- Para instalar wordnet para ruby (gem install wordnet) hay que tener instalado previamente wordnet (en ubuntu, es simplemente sudo apt-get install wordnet) y el binding de berkeley db para ruby (en ubuntu, sudo apt-get install libdb-ruby1.8). Después de instalar, hay que migrar la base de datos wordnet a berkeley db, con un script incluido en ruby wordnet (./convertdb.rb)
- Ruby linguistics, al menos en la versión que tengo instalada, la 1.0.5 (gem install Linguistics) está anticuado. Hay que sustituir la función lookupSynsets por lookup_synsets en el fichero wordnet.rb.
La ejecución de este programilla genera frases cómo esta:
I wish you felicity, offspring man.
I wish you happiness, young man.
I wish you happiness, offspring adult male.
Todavía muy simple para lo que quiero conseguir, pero parece que estas librerías pueden ser útiles.