INTELIGENCIA EN REDES DE COMUNICACIONES

Anuncio
INTELIGENCIA EN REDES DE COMUNICACIONES
INMACULADA LUENGO LÓPEZ
Mª ESTHER MARTÍN REBOLLO
IRC
Práctica final
ÍNDICE
Introducción_______________________________________________3
Objetivo de la práctica _____________________________________3
Desarrollo de la práctica____________________________________4
Resultados obtenidos ______________________________________7
Aprendizaje _______________________________________________9
Código del programa______________________________________11
Bibliografía_______________________________________________15
Página 2 de 15
IRC
Práctica final
Introducción
En esta práctica hemos decidido implementar un programa en PROLOG
para adivinar animales a partir de preguntas que se le van haciendo al usuario.
La decisión de utilizar PROLOG para el desarrollo de esta práctica se
debe a que es un lenguaje sencillo que proporciona una sintaxis para la
construcción de sistemas expertos (en nuestro caso un sistema experto que
identifique a los animales a partir de sus características).
PROLOG es un lenguaje lógico declarativo que se basa en cláusulas de
Horn. Sus principales características son que se trata de una programación
dinámica, y tanto las reglas como los objetivos, son también datos; y la asunción
de un mundo cerrado, todo lo que no figura explícitamente como un hecho y
tampoco se puede deducir es falso. Otra característica es que el orden de las
cláusulas cambia el resultado final.
En esta práctica vamos a analizar el problema de un árbol de decisión con
aprendizaje.
Objetivo de la práctica
El fin de esta práctica ha sido desarrollar un programa en PROLOG que
adivine el animal que ha pensado el usuario mediante el empleo de una serie de
preguntas sobre las características del mismo a las que el jugador debe responder
afirmativa o negativamente.
Para ello, hemos definido un conjunto de reglas que debe verificar cada
uno de los animales que el programa conoce y, a partir de estas reglas, se le
formularán al usuario preguntas sobre las características que tiene el animal que
ha pensado.
También se ha contemplado la posibilidad de que el programa aprenda
nuevos animales, que el usuario podría introducir cuando el programa no
adivinase el animal que éste había pensado. Para ello se debe introducir, además
de dicho animal, una pregunta que lo diferencie del animal que ha respondido
erróneamente el programa.
Página 3 de 15
IRC
Práctica final
Desarrollo de la práctica
Para la implementación del programa deseado, en primer lugar nos
tendremos que plantear la estructura que va a tener nuestra lista de animales. Esta
estructura será un árbol, en el que en las hojas se encontraran los distintos
animales, y llegaremos a ellos por medios de las distintas características
diferenciadoras que tiene cada uno. Siendo una de las principales características
su clasificación en: reptiles, anfibios, mamíferos, aves y peces.
Para realizar esta clasificación se tienen que tener en cuenta que las
preguntas a realizar nos tienen que caracterizar una de las hojas frente a otra, y
así poder llegar a la hoja deseada sin ningún tipo de ambigüedad.
La lista de los animales que se han tenido en cuenta para el desarrollo de
esta práctica es: rana, salamandra, serpiente, tortuga, cocodrilo, jirafa, conejo,
hombre, oso, tigre, león, águila, pato, gallina, avestruz, pingüino, carpa y pez
espada.
En primer lugar, y para mostrar con mayor claridad el fundamento del
programa, mostramos el árbol que vamos a desarrollar:
Página 4 de 15
IRC
Práctica final
Página 5 de 15
IRC
Práctica final
Comenzamos analizando el código desarrollado. En primer lugar, vamos a
utilizar una función que se llamará sera(Animal), que determinará
principalmente el orden en el que se deben ir comprobando los distintos animales
(¿será una rana?...), de izquierda a derecha en la figura del árbol.
Para cada uno de los animales se realizarán las preguntas sobre las
características que debe cumplir, comenzando por el animal situado más a la
izquierda del árbol y por la pregunta del nodo raíz. Se seguirán verificando las
características para un mismo animal siempre que se responda afirmativamente a
las preguntas y se pasará a comprobar las características del animal siguiente (el
situado inmediatamente a la derecha del animal actual) cada vez que se responda
negativamente a una de las preguntas. De esta forma, cuando lleguemos a una
hoja del árbol el programa dará como solución un animal que cumpla todas las
preguntas anteriormente realizadas.
El animal que no cumpla ninguna de las características preguntadas será el
que está en la hoja situada más a la derecha del árbol, que en nuestro caso es el
pez espada, y no necesitará verificar ninguna condición, ya que simplemente es
el que no cumple ninguna de las anteriores.
Mediante estas reglas podremos realizar una primera clasificación de los
animales en anfibios, reptiles, mamíferos, aves y peces. Las características que
nos permiten clasificarlos dentro de estos grupos se harán aparte para que el
código del programa sea más claro y más general.
Ahora pasamos a comentar la función verificar(caracteristica) que ya
hemos nombrado anteriormente. En esta función decimos que si se cumple la
característica el resultado será true, y si no se cumple será fail, y pasamos a
llamar a la función preguntar(caracteristica).
En la función preguntar será donde realizaremos la pregunta sobre la
característica determinada a verificar y en la que almacenaremos la respuesta.
Según ésta sea afirmativa o negativa, avanzaremos hacia una u otra rama del
árbol. Esto lo implementaremos con la ayuda de la función assert, que nos
ayudara a ir almacenando las respuestas a las distintas características, para evitar
repetir al usuario preguntas ya realizadas anteriormente, como las relacionadas
con el tipo de animal (anfibio, reptil…), y así poder seguir avanzando en el árbol.
Debido a la utilización de la función assert en este punto, necesitaremos
que las funciones cumple y no_cumple, con las que la utilizamos sean
dinámicas. Además tendremos que borrar los valores almacenamos, con la ayuda
Página 6 de 15
IRC
Práctica final
de la función retract, una vez que hayamos mostrado al usuario el animal
adivinado, para lo que llamaremos a la función borrar en la parte principal del
programa. Si olvidásemos realizar este borrado, en la siguiente ejecución
comenzaríamos directamente dando como animal adivinado el obtenido en el
caso anterior, sin haber realizado ninguna pregunta.
Además una vez adivinado el animal, se nos ofrecerá la oportunidad de
seguir jugando, en lugar de tener que volver a ejecutar el programa.
Resultados obtenidos
Ahora vamos a probar el funcionamiento de nuestro programa. Vamos a
pensar un animal de los que conoce, por ejemplo la jirafa. El programa nos irá
haciendo preguntas recorriendo el árbol de la siguiente forma:
Página 7 de 15
IRC
Práctica final
Página 8 de 15
IRC
Práctica final
La captura del programa obtenida es la siguiente:
Podemos ver que el programa va haciendo las preguntas en el orden
indicado en el árbol hasta adivinar que el animal que se había pensado era la
jirafa.
Aprendizaje
Nos hemos planteado también la posibilidad de que el programa pueda
aprender nuevos animales. Para implementarlo, hemos empleado la función
asserta que nos permite introducir nuevas reglas al principio de la base de datos.
El programa sólo podrá aprender cuando no acierte el animal que había
pensado el usuario. Por lo tanto, lo primero que tenemos que hacer una vez
identificado el animal por el programa es preguntarle si hemos acertado dicho
animal. De no ser así, tendremos que preguntarle al usuario cuál era el animal
que había pensado y que nos indique una característica de éste que permita al
programa diferenciarlo del animal que el había ofrecido como solución. Una vez
conocidos el animal y una característica que lo distinga, lo añadimos mediante la
función asserta. Esta nueva regla se tratará de igual forma que las definidas de
forma explícita en el programa.
Página 9 de 15
IRC
Práctica final
Veamos un ejemplo de aprendizaje de nuestro programa. Para ello, hemos
pensado en el mono, que no está incluido en la base de datos del programa. La
captura del programa es la siguiente:
Ahora podemos comprobar que ha insertado mono en la base de datos:
Página 10 de 15
IRC
Práctica final
Y además, que puede identificar este animal del ofrecido anteriormente
como solución:
En mayor inconveniente que tiene el método que hemos seguido es que ya
no nos permite realizar las preguntas en el orden inicial, pero no es demasiado
importante porque sigue adivinando correctamente los animales inicialmente
introducidos.
Código del programa
/* ADIVINO EL ANIMAL EN EL QUE ESTAS PENSANDO
Para empezar el juego, teclea: " ?- start."
*/
/*Comienza el juego*/
/*Para implementar el juego partiremos de un árbol en el que tendremos
todos los animales que podemos adivinar y las relaciones entre ellos*/
start :nl,
write('PARA ADIVINAR EL ANIMAL EN EL QUE ESTAS PENSANDO, '),
nl,
write('RESPONDE A LAS SIGUIENTES PREGUNTAS'),
nl,
nl,
sera(Animal),
/*En primer lugar llamamos a la función hipótesis.
Página 11 de 15
IRC
Práctica final
Con esta función empezaremos en el nodo raíz e iremos avanzando
en el árbol */
/*Cuando lleguemos a una hoja del árbol, habremos encontrado la
respuesta*/
nl,
nl,
write('****************************************'),
nl,
write('Creo que el animal es '),
write(Animal),
nl,
write('****************************************'),
nl,
nl,
/*Aprendizaje de nuestro programa*/
/*Comprobamos si hemos acertado el animal*/
write('¿He acertado? (s/n) '),
read(Respuesta),
nl,
/*En el caso de no haber acertado, intentamos introducir una
regla para su aprendizaje*/
( (Respuesta == s)
->
borrar,
seguir_jugando ;
write('¿Qué animal es? '),
read(Respuesta1),
nl,
write('Dime una pregunta para '),
write(Respuesta1),
write(' que lo diferencie de '),
write(Animal),
write(': '),
read(Respuesta2),
nl,
nl,
asserta( (sera(Respuesta1) :- Animal, verificar(Respuesta2)) ) ,
borrar,
seguir_jugando).
/* Hipótesis de animales que se van a comprobar */
sera(rana) :- rana, !.
sera(salamandra) :- salamandra, !.
sera(serpiente) :- serpiente, !.
sera(tortuga) :- tortuga, !.
sera(cocodrilo) :- cocodrilo, !.
sera(jirafa) :- jirafa, !.
sera(conejo) :- conejo, !.
sera(hombre) :- hombre, !.
Página 12 de 15
IRC
Práctica final
sera(oso) :- oso, !.
sera(tigre) :- tigre, !.
sera(leon) :- leon, !.
sera(aguila) :- aguila, !.
sera(pato) :- pato, !.
sera(gallina) :- gallina, !.
sera(avestruz) :- avestruz, !.
sera(pinguino) :- pinguino, !.
sera(carpa) :- carpa, !.
sera(pez_espada):- pez_espada.
/* Reglas con las que identificaremos los distintos animales */
/*Anfibios*/
rana :- sangre_fria,
anfibio,
verificar(salta).
salamandra :- sangre_fria,
anfibio.
/*Reptiles*/
serpiente :- sangre_fria,
verificar(se_arrastra).
tortuga :- sangre_fria,
verificar(tiene_caparazon).
cocodrilo :- sangre_fria.
/*Mamíferos*/
jirafa :- mamifero,
herbivoro,
verificar(tiene_cuello_largo).
conejo :- mamifero,
herbivoro.
hombre :- mamifero,
omnivoro,
verificar(razona).
oso :- mamifero,
omnivoro.
tigre :- mamifero,
verificar(tiene_rayas).
leon :- mamifero.
/*Aves*/
Página 13 de 15
IRC
Práctica final
aguila :- ave,
voladora,
verificar(es_ave_rapaz).
pato :- ave,
voladora.
gallina :- ave,
verificar(es_domestico).
avestruz :- ave,
verificar(corre_veloz).
pinguino :- ave.
/*Peces*/
carpa :- verificar(vive_rio).
pez_espada.
/* Reglas con las que clasificaremos los animales en: anfibios,
reptiles, mamíferos, aves y peces */
/* Para ello utilizaremos la función verificar */
sangre_fria :- verificar(tiene_sangre_fria).
anfibio :- verificar(vive_tierra_y_agua).
mamifero :- verificar(tiene_pelo).
herbivoro :- verificar(es_herbivoro).
omnivoro :- verificar(es_omnivoro).
ave :- verificar(tiene_alas).
voladora :- verificar(vuela).
/* Función verificar, desde aquí llamaremos a la función que
preguntara por cada característica */
verificar(S) :(cumple(S)
->
true ;
(no_cumple(S)
->
fail ;
preguntar(S))).
/* Para avanzar por el árbol, se irán realizando preguntas con las
distintas características. Esto lo haremos con la función preguntar*/
preguntar(Pregunta) :write('¿Tiene el animal la siguiente característica: '),
write(Pregunta),
write('? (s/n) '),
Página 14 de 15
IRC
Práctica final
read(Respuesta),
nl,
/*Avanzamos en función de la respuesta a la característica, hacia
una rama u otra del árbol */
/*Con assert, guardamos el camino seguido */
( (Respuesta == s)
->
assert(cumple(Pregunta)) ;
assert(no_cumple(Pregunta)), fail).
seguir_jugando :/*Ofrecemos la oportunidad de volver a jugar otra vez*/
write('¿Quieres seguir jugando? '),
read(Respuesta3),
( (Respuesta3 == s)
->
start ;
nl,
nl,
write('ESPERO QUE HAYAS DISFRUTADO JUGANDO CONMIGO'),
nl,
nl,
write('ADIOS'),
nl).
/*Hace dinámicas las funciones que se van a añadir con assert*/
:- dynamic cumple/1,no_cumple/1,sera/1,verificar/1.
/* Borramos todos los valores almacenados con assert que indican el
camino seguido en el árbol */
borrar :- retract(cumple(_)),fail.
borrar :- retract(no_cumple(_)),fail.
borrar.
Bibliografía
-
Prolog
Francis Giannesini, Henry Kanoui y otros.
Ed. Addison-Wesley Iberoamericana, 1989
-
Manual online de swi-prolog
Jan Wielemaker
-
Principles of programming languages XXI
Wael Aboelsaadat
Página 15 de 15
Descargar