Inteligencia artificial 1 TEMA 1 QUÉ ES LA INTELIGENCIA ARTIFICIAL Tema 1 Qué es la inteligencia artificial 1. Repaso histórico 2. Qué es la inteligencia artificial 3. Algunas características de los sistemas inteligentes 1. REPASO HISTÓRICO El término Inteligencia Artificial fue adoptado en el verano de 1956 en Darmouth en un encuentro que reunió a varios investigadores y que constituyó lo que después sería el núcleo central de la inteligencia artificial. Se estaban realizando multitud de trabajos en este campo, como ordenadores neuronales, programas que formalizasen el razonamiento matemático, programas que jugasen a las damas /y de hecho, se consiguió que jugase mejor que el autor del mismo). Toda esta evolución le auguraba a la inteligencia artificial previsiones optimistas, pero que se vinieron abajo en la década de los sesenta. El paso del laboratorio al entorno real no fue como se esperaba, por 3 razones principalmente: Los sistemas no disponían normalmente del entorno de la aplicación o éste resultaba muy pequeño. Muchos de los problemas que se intentaban resolver eran NP-complejos, es decir, mientras la cantidad de conocimiento resultaba pequeña, el programa se defendía bien, pero al aumentar, resultaba irresoluble. Algunas de las estructuras básicas que se utilizaban para generar una conducta inteligente tenían grandes limitaciones. Para resolver estos problemas, se comenzó a trabajar en algoritmos de búsqueda que disminuyera la complejidad de la aplicación, se intentó también aumentar el dominio de la aplicación y construir aplicaciones para entornos más reales. 2. QUÉ ES LA INTELIGENCIA ARTIFICIAL No existe una única definición de inteligencia artificial: Construcción de programas: La inteligencia artificial como campo de la informática que es, está dedicada a la construcción de programas. Conducta frente a razonamiento: Los objetivos de estos programas nos llevan a diferentes definiciones: por un lado querremos obtener una conducta determinada de los mismos (nos interesa el resultado) o conseguir una manera determinada de razonar (nos interesan más los medios); o por otro lado exigiremos que los programas sean correctos comparándolos con el rendimiento de las personas o con un ideal que denominaremos racionalidad. Esto nos abre a su vez, 4 nuevos enfoques: o Actuar como las personas: Una conducta es inteligente cuando tiene suficiente nivel como para confundir a un interlocutor humano. o Razonar como las personas: Interesa cómo se llega a un resultado determinado y se quiere que el proceso de razonamiento sea parecido al de las personas. o Razonar racionalmente: Pensar correctamente o de manera lógica. o Actuar racionalmente: Conseguir objetivos racionales Ciencia e ingeniería: Como además de programas podemos construir robots y diversos ingenios, el campo se ha de ver como una ingeniería, además 2 · Inteligencia artificial 1 experimental, pues con experimentos se utiliza la inteligencia artificial para estudiar la misma inteligencia artificial. Hay 4 hipótesis diferentes sobre inteligencia artificial, nosotros nos basaremos en la primera, pero haremos un breve estudio de cada una de ellas: 1. La hipótesis del sistema de símbolos físicos: Un sistema de símbolos físicos dispone de un conjunto de entidades (símbolos) que son patrones físicos. Además, existe un conjunto de procesos (operaciones) que operan sobre esas expresiones para producir expresiones nuevas; y además se basan en búsquedas heurísticas para resolver los problemas. Con todo ello tenemos 3 entidades: símbolos, operaciones y búsquedas que se interrelacionan y de la definición de estructuras simbólicas y operaciones y del desarrollo de estrategias para realizar búsquedas se nutre la inteligencia artificial. 2. Sistemas basados en modelos biológicos: Una red neuronal está formada por neuronas (unidades de procesamiento) y unas conexiones entre sí que tienen asociados unos pesos. Es decir, no hay símbolos y operaciones, sino pesos asociados a las estructuras que varían con la experiencia y además el conocimiento específico no se encuentra en un lugar determinado de la red, sino repartido por toda ella. 3. Sistemas emergentes: Se parte del hecho de que la solución a un problema no se obtiene de un único sistema individual, sino que emerge de las actividades de unos agentes independientes. Son modelos de cooperación social en el que el total no es la suma de los individuos, sino la respuesta de toda una masa que no se puede explicar por la simple suma individual. 4. Sistemas basados en las teorías de la acción situada y la inteligencia artificial corpórea: Las teorías de la acción situada argumentan que no se ha de ver la inteligencia artificial como un proceso de construcción y evaluación de modelos del mundo, sino como un proceso menos estructurado de actuar en el mundo y responder a los resultados obtenidos, se da más importancia a la habilidad de actuar que a la de explicar estas acciones. Los sistemas reactivos son aquellos que no tienen un estado interno y que simplemente reaccionan a los estímulos existentes en el entorno. Aunque como vemos existen distintos puntos de vista, la inteligencia artificial se dedica sobre todo a la construcción de programas mediante: Resolución de problemas y búsqueda Sistemas basados en el conocimiento Aprendizaje Inteligencia artificial distribuida 3. ALGUNAS CARACTERÍSTICAS DE LOS SISTEMAS INTELIGENTES 5 principalmente son las características de los sistemas inteligentes: 1. Usan información simbólica para razonar sobre hechos, conceptos abstractos y poder sacar conclusiones. 2. Utilizan descripciones del dominio de la aplicación: los sistemas deben conocer el entorno de la aplicación para saber como actuar y estudiar como evoluciona. 3. Utilizan datos incompletos, inexactos o incluso en conflicto: a veces la información que reciben y con la que deben operar tiene alguna de estas características y aun así, el sistema no debe bloquearse y buscar la solución adecuada, o, al menos, con un mínimo de incertidumbre. Inteligencia artificial 1 · 3 4. Utilizan métodos heurísticos: A veces el sistema nos da indicaciones de cómo buscar la solución, y no la solución misma. 5. Son adaptativos: Cuando el entorno cambia, el sistema también lo hace a fin de obtener un comportamiento adecuado. 4 · Inteligencia artificial 1 TEMA 2 RESOLUCIÓN DE PROBLEMAS Y BÚSQUEDA 1. INTRODUCCIÓN A LA RESOLUCIÓN DE PROBLEMAS Y BÚSQUEDA Para que un sistema pueda aplicar los algoritmos de búsqueda a un problema concreto, se debe modelizar su entorno de trabajo de manera que se pueda encontrar una solución final a partir de una situación inicial. Esta modelización va a trabajar sobre el entorno del sistema, las acciones que se pueden desarrollar en él, la definición del problema y la solución. Tema 2 Resolución búsqueda Problemas de satisfacción de restricciones Tenemos un conjunto de variables a las cuales hemos de asignar un valor. Un estado se define como un conjunto de asignaciones a unas cuantas variables y existen un conjunto de restricciones que las variables han de satisfacer, el problema está resuelto cuando todas las variables tienen un valor asignado y además satisfacen todas las restricciones. Este tipo de problemas es muy importante porque modelan problemas reales de la vida diaria. Por ejemplo, como situar 8 reinas en un tablero de ajedrez problemas y 1. Introducción a la resolución de problemas y búsqueda 2. Construcción de una solución 3. Estrategias de búsqueda no informada 4. Coste y función heurística 5. Grafos Y/O 6. Búsquedas con adversario: los juegos 7. Algoritmos genéticos Modelización del entorno en el que se mueve el sistema: Un sistema necesita conocer el entorno en el que se encuentra en un instante concreto, a eso se le denomina estado, y además debe saber cuáles son los estados posibles con los que trabajará el sistema. Por ejemplo en el problema denominado rompecabezas lineal tenemos una secuencia [3,4,1,2] en la que cada dígito sólo puede ser intercambiado por posiciones consecutivas en la secuencia. En este entorno, ya conocemos el estado inicial [3,4,1,2] y se pretende llegar a un estado final ordenado [4,3,2,1]. Modelización de las acciones del Espacio de estados correspondiente al rompecabezas lineal sistema: Con el fin de encontrar el camino hacia la solución a partir de la solución actual, necesitamos saber cuáles son las acciones que puede realizar el sistema y el efecto que tienen en su entorno. Las acciones se modelizan como transiciones entre estados, y el conjunto de todos los estados posibles y las acciones entre ellos se define como espacio de estados. El factor de ramificación es el número de acciones que se pueden aplicar en los estados de un problema. Encontrar una solución corresponde a realizar una búsqueda en este espacio de estados. Definición del problema: Se necesita obviamente la definición de aquello que queremos resolver. La función objetivo aplicada a un estado devuelve un valor booleano, que será cierto cuando satisface ciertos requerimientos (la solución es correcta) o falso si no lo es; A la secuencia de acciones desde el estado inicial hasta el estado objetivo se le denomina plan o camino. Solución: A veces solo nos interesa saber cual es el estado objetivo o si este existe, o en ocasiones conocer cómo se llega a él (por ejemplo el camino mas corto en coche entre dos poblaciones. Problemas de planificación Consiste en encontrar una secuencia de acciones (plan) que permita al sistema realizar una tarea concreta, la secuencia describe qué acciones se deben efectuar y en qué momento. Así podemos pensar que cada posible situación de los objetos en un estado y debemos llegar a un estado final determinado con cada objeto en la posición que nos interesa para modelar el estado objetivo. de Inteligencia artificial 1 · 5 sin que se maten. Tenemos 8 reinas a las que debemos asignarles una fila y una columna (inicialmente ninguna está colocada en el tablero), además las restricciones son que todas deben estar situadas en filas y columnas distintas y además en diagonales también diferentes. El problema quedará resuelto cuando todas las reinas tengan asignada una fila y columna en el tablero y además todas estas asignaciones cumplan las restricciones previas. 2. CONSTRUCCIÓN DE UNA SOLUCIÓN Árbol de búsqueda Ya definido el problema hemos de pasar a encontrar la solución. Sabemos que partimos de un estado inicial y queremos ir a un estado que satisfaga la función objetivo. La búsqueda corresponde a encontrar el camino que nos lleve de un punto al otro en el grafo que representa el espacio de estados. Un algoritmo de búsqueda construye el camino en pasos sucesivos. A cada nodo de los que disponemos le aplicamos los estados a los que pueden cambiar y sucesivamente vamos ampliando los nodos que podemos tomar para seguir aplicando estos cambios, solo pararemos cuando ya no existan más nodos a los que aplicar los cambios dado que se estén repitiendo o porque hayamos encontrado la solución. Así la raíz del árbol corresponde al estado inicial, los nodos del árbol constituyen estados, los arcos corresponden a acciones y las hojas del árbol corresponden a los estados terminales de los caminos. Así cuando recorremos las ramas del árbol desde el nodo inicial a una hoja estamos repasando un camino desde el estado inicial a uno Terminal pasando por todos los estados intermedios. Podemos comprobar todo esto con la figura lateral que representa el problema de pasar del estado [1,4,3,2] al estado ordenado [1,2,3,4] mediante la aplicación de 3 rotaciones posibles. Aunque el árbol de búsqueda es muy parecido al grafo de estados hay una diferencia importante entre ambos, y es que en éste último hay tantos nodos como estados hay, mientras que en el árbol esto no es así, hay estados que pueden no aparecer y otros pueden aparecer repetidos. Para implementar el árbol de búsqueda necesitamos varias cosas: Estructura de datos correspondiente a un nodo: Debe contener toda la información necesario para luego poder recuperar el camino y dar la solución final; lo mejor es poder reconstruir el camino desde la solución al nodo raíz, por lo que cada nodo debe guardar la información de quién es su nodo padre, así tendremos [identificador de estado, nodo-padre, operador-generador, otrainformación]. Debemos guardar información de los nodos que se han expandidos y de los que restan por expandir. En los nodos por expandir aplicaremos las operaciones necesarias, la cuestión está en como elegir el nodo siguiente al que toca expandirse y lo haremos mediante una cola con prioridades, la cuestión ahora estriba en decidir qué criterio se fija para la prioridad. Con todo ello el algoritmo para generar el árbol quedaría como sigue: funcion busqueda(problema, estrategia-de-busqueda, arbol-de-busqueda-inicial) devuelve solucion es arbol-de-busqueda := arbol-de-busqueda-inicial; solucion-encontrada := falso; mientras no (solucion-encontrada) y hay-nodos-por-expandir(arbol-de-busqueda) hacer nodo := seleccionar-nodo(arbol-de-busqueda); anadir-nodo-a-ya-expandidos(nodo, arbol-de-busqueda); si solucion(problema, nodo) 6 · Inteligencia artificial 1 entonces solucion-encontrada := cierto; sino nuevos-nodos := expandir(nodo, problema); anadir-nodos-a-por-expandir (nuevos-nodos,estrategia-debusqueda,arbol-de-busqueda); fsi; fmientras; si solucion-encontrada entonces devuelve solucion(arbol-de-busqueda, nodo); sino devuelve no-hay-solucion; fsi; ffuncion; La función recibe como parámetros 3 elementos: El problema que contiene la información correspondiente al estado inicial, la función objetivo y los operadores. La estrategia de búsqueda que representa todo aquello que se refiere a la elección de un nuevo nodo. El árbol inicial formado por un único nodo (el estado inicial). Así la estrategia es la función que determina cómo ordenar los nodos de la lista y no cómo se lleva a cabo la selección. El funcionamiento de la función será como sigue: 1. Se selecciona el nodo de los posibles que se encuentra en el árbol, el nodo que corresponde según la prioridad de inclusión en la lista de nodos. 2. Se pasa al conjunto de nodos ya expandidos. 3. Se procesa si es una solución o no. SI no lo es, debemos expandirlo con los operadores que tenemos a nuestra disposición y añadiremos los nuevos nodos obtenidos al árbol de búsqueda (la manera de añadirlos dependerá de la estrategia que se conciba). Hay una diferencia entre la teoría y la función que hemos recreado y es que en la teoría cuando se encontraba la solución, se detenía la búsqueda. Ahora no, aunque generemos la solución al crear un nuevo nodo, hasta que no esté seleccionado para comprobar si es la solución no se parará la función. Esto es así para que el algoritmo de búsqueda sea óptimo, es decir, para que el algoritmo no sólo encuentre la solución, sino que además sea la más óptima si es que puede existir más de una. Hemos de tener en cuenta que este funcionamiento no detalla la estrategia que hemos de utilizar para seleccionar el nodo que debemos expandir. Para ello debemos tener en cuenta varias propiedades y costes que vemos a continuación: Compleción: Un algoritmo de búsqueda es completo si cuando un problema tiene solución, el algoritmo la encuentra. Optimalidad: Un algoritmo es óptimo cuando en un problema con diferentes solucionas, siempre encuentra la de más “calidad”. Complejidad respecto a tiempo: El tiempo que tarda el algoritmo en encontrar la solución. Complejidad respecto a espacio: La memoria que necesita el algoritmo para encontrar la solución. Algoritmos todo-tiempo: Es todo-tiempo cuando siempre puede encontrar una solución para cualquier asignación de tiempo de computación. Otro aspecto que se nos escapa son los estados repetidos. Ya hemos dicho que en el árbol de búsqueda podían existir estados repetidos en los que obviamente los volvemos a incluir en el árbol de búsqueda, van a “comerse” recursos de computación. Pero claro, el comprobar si un nuevo estado ya ha aparecido anteriormente y ha sido tratado también consume recursos, por lo que hay que adquirir un compromiso entre el sobrecoste de esta comprobación y que el algoritmo pueda acabar. Existen tres alternativas para esta comprobación que presentamos ordenadas de menor a mayor coste: Inteligencia artificial 1 · 7 No permitir el retorno al estado de donde venimos, por lo que solo hay que comprobar el estado del que venimos, por lo que se puede llevar a un tiempo constante. No permitir generar caminos con ciclo: “Sólo” debemos comprobar que el nuevo estado no coincide con ninguno de los antecedentes del nodo, y tiene un coste lineal. No generar ningún estado que ya haya sido generado: Obliga a guardar todos los estados del árbol de búsqueda y compararlos, la complejidad es de orden O(s) donde s constituye el número de estados en el espacio de estados. Almacenar los nodos ya expandidos no es indispensable para representar el árbol de búsqueda, ni tampoco para poder reconstruir la solución, por lo que almacenarlos representará un coste adicional en memoria. Eso sí, cuantos más estados repetidos aparezcan, más útil resultará almacenarlos y utilizar el tiempo para comprobar que el estado no ha aparecido antes; por lo que la elección de un tipo u otro de solución a los estados repetidos, dependerá de la estructura del problema en sí. 3. ESTRATEGIAS DE BÚSQUEDA NO INFORMADA El esquema general del punto anterior no concreta qué nodo debemos expandir o lo que es equivalente, cómo hemos de ordenar los nodos en la lista de nodos por expandir. Ahora veremos unas posibles soluciones al problema con dos algoritmos de búsqueda: en anchura y en profundidad. La búsqueda en anchura corresponde a realizar un recorrido del grafo de estados por niveles. Formalmente, tenemos que el algoritmo espera a expandir un nodo de un nivel determinado hasta el momento en que todos los nodos del nivel anterior ya se han expandido. Así, el algoritmo accede a un nodo de nivel d y los nodos resultados de la expansión (nodos del nivel d+1) quedarán al final de la lista. Se desarrolla un recorrido sistemático por el árbol y la solución se encontrará cuando se llegue al nivel de profundidad en que esté la misma. La complejidad con respecto al tiempo es exponencial y en cuanto a memoria será de orden = (bd) nodos. La búsqueda en profundidad expande siempre los nodos que se encuentran en un nivel más profundo dentro del árbol de búsqueda. Sólo cuando se llega a un nodo al que no se le puede aplicar ningún operador, se elegirá un nodo de otro camino. Los nodos resultado de la expansión se añadirán en el esquema general de búsqueda, delante de los nodos ya expandidos. Una forma de mejorar este tipo de búsqueda es restringiendo que si la expansión de un nodo da como resultado un nodo igual al nodo-padre, a partir de ahí no se continúe expandiendo y se elija otro nodo para continuar la búsqueda. La ventaja de la búsqueda en profundidad respecto a la búsqueda en anchura es el menor coste respecto a memoria, el coste es lineal con respecto a la profundidad. El coste en tiempo es parecido al anterior O(bm). Para potenciar y mejorar este tipo de búsqueda en profundidad se han desarrollado métodos mejores: Búsqueda en profundidad limitada: Se fija la profundidad máxima a la que se puede llegar. Llegada ésta y no habiéndose encontrado la solución, se considera que no se puede aplicar el operador, y se va a buscar el nodo siguiente para continuar expandiendo, lo cual obliga a retroceder y buscar un nuevo camino. El coste en tiempo vendrá impuesto por el límite p siempre y cuando encontremos la solución O(bp), y la complejidad con respecto a espacio será lineal O(bp). Búsqueda iterativa con profundidad: Se realizan varias búsquedas con profundidad limitada, utilizando valores crecientes para este límite; así de no encontrarse la solución iniciamos de nuevo todo el árbol de búsqueda con un 8 · Inteligencia artificial 1 limite crecientemente mayor. El coste en memoria será O(bd). En cuanto a tiempo tendremos en cuenta que hay nodos que se expanden más de una vez y será O(bd). 4. COSTE Y FUNCIÓN HEURÍSTICA En muchas ocasiones, con encontrar la solución o con encontrar la solución que tiene menos nodos no es suficiente. Muchas veces requerimos el camino mínimo (menos nodos) o el camino con menor coste (cuando cada estado tiene asociado un peso de coste distinto); en estas condiciones otras funciones de búsqueda nos son necesarias: Búsqueda de coste uniforme En esta ocasión se utiliza para ordenar los nodos a expandir el coste del nodo al estado inicial del grafo. SI nos planteamos encontrar el camino más corto entre MontBlanc y Tarragona, la primera búsqueda en profundidad generará las 4 poblaciones que contactan con Montblac y elegirá la del valor más bajo Espulga. A continuación expandirá este nodo con su única solución Poblet, como sigue siendo el camino de coste más bajo (6+4=10), volverá a expandirlo con al única solución Tarragona (84), como resulta que ahora hay caminos de momento más cortos, expande estos nodos, aunque Tarragona ya es solución, pero seguirá expandiendo nodos restantes según el camino más corto desde el origen hasta que llegue a la solución final; así la búsqueda de coste uniforme resulta completa y óptima cuando la función de coste es siempre positiva. Mapa de carreteras Búsqueda con función heurística: búsqueda ávida El tipo de búsqueda anterior cuando tenemos un caso como el de la imagen lateral, resulta completamente ineficiente, ya que expandirá todos los nodos antes del único nodo que tiene la única solución; esto es así porque estamos evaluando costes desde el origen, sin saber que podemos estar alejándonos de la solución final al elegir el nodo de menor valor desde el inicio del grafo. Una función heurística es una función que intenta solucionar este problema y aplicada a un nodo estima el coste del mejor camino entre este nodo y un estado solución. La ordenación de nodos a elegir tendrá como criterio la búsqueda ávida (del primero mejor), por lo que una vez seleccionado un camino probablemente éste se irá siguiendo hasta la solución, aun no siendo esta la Mapa de carreteras mejor; tiene los problemas que tenía la búsqueda en profundidad, ya que no siempre encuentra la solución, o no es la mejor de las que puedan existir. Lo que haríamos en nuestro problema anterior sería asignar un valor a cada población (o nodo) según la distancia que le restase para llegar a Tarragona, y a partir de ahí elegir el de menor valor para ir expandiendo. Así podemos ver la solución encontrada para el problema anterior entre Montblanc y Tarragona, sin considerar el eje Poblet-Tarragona y con los valores que se les ha asignado con la función heurística a cada nodo; démonos cuenta que no se ha elegido el camino más corto, aunque sí se ha llegado a una solución más aceptable que con la búsqueda anterior. Búsqueda ineficiente Inteligencia artificial 1 · 9 Búsqueda con función heurística: Algoritmo A* El método anterior ya hemos visto que no resulta ni completo ni óptimo porque hay veces que entra en un bucle en el que ya no encuentra la solución. Como por otro lado la búsqueda de coste uniforme minimiza el coste del nodo origen hasta el nodo en curso y la función heurística mejora el encontrar el camino correcto, podemos unir lo mejor de cada casa y elegir la expansión de nodos (o el criterio de ordenación para su elección) con unir dos funciones: F(n) = g(n) + h(n) Estimación del coste del camino que va del estaco inicial a una solución pasando por el nodo actual n = Coste desde el estado inicial + Coste hasta la solución final. Una función heurística nunca sobreestima el coste y es admisible y completo. La no sobreestimación implica que el coste real siempre va a estar por encima del que damos a priori Así, utilizando el valor de los nodos en el mapa y el de la función heurística que definimos anteriormente (pero aquí no representamos), hayamos un valor medio para cada nodo y elegimos el valor de nodo más pequeño para seguir expandiendo, llegando, por fin, a la solución óptima. 5. GRAFOS Y/O Grafos y/o No todos los problemas se pueden modelar con árboles como los que hemos hecho hasta ahora, en los que elegimos siempre un camino que parte de cada nodo, y solo uno. Es posible que la solución venga de unir dos caminos obligatoriamente y es entonces cuando debemos representarlo a través de grafos y/o y con la notación gráfica que observamos en la figura lateral. Unido al grafo y/o tenemos el algoritmo AO*. Este algoritmo se construye con una función heurística asociada a cada nodo y al que hay que sumarle el valor de cada arista para completar el valor de todo el recorrido. Obviamente, los nodos “y” en el grafo deberán calcularse para la suma de las ramas que lo componen, dado que la solución pasa por recorrer todos los caminos y. EL algoritmo AO* funciona de la siguiente manera: El primer paso consiste en recorrer el mejor camino del grafo, determinar los nodos de este camino que se deben expandir, y seleccionar uno. Es la misma estimación que habíamos realizado anteriormente. Una vez seleccionado un nodo, lo expandimos y si tiene sucesores hemos de añadir sus sucesores al grafo y calcular para cada uno su función heurística. Si 10 · Inteligencia artificial 1 el nodo es Terminal, la función heurística es 0 y debemos marcar el nodo como resuelto. Una vez expandidos y evaluados los nuevos nodos, propagamos la información hacia atrás (revisión); esta revisión comienza por el nodo que acabamos de expandir y si su evaluación de coste cambia con al revisión, debemos avisar a los nodos antecesores directos. En general, tendremos una lista de nodos a revisar, cuando revisemos uno puede que su estimación del coste cambie; si esto ocurre consideramos sus antepasados porque el cambio del coste de un nodo hijo puede afectar al coste del nodo padre e incluso podemos provocar un cambio en las selecciones del mejor camino. Estas revisiones empiezan seleccionando un nodo de la lista y se recalcula el coste de todos los arcos que salen del nodo; esto se realiza tomando cada arco de tipo O y recalculando los valores de sus nodos; a la suma de los valores de las heurísticas se suman el valor de las aristas; en los arcos de tipo Y el coste será la suma de los costes de las aristas que componen el arco más la suma de todos los costes de los nodos que integran el mismo. Definimos el coste del nodo como el coste del arco mejor y después marcaremos como mejor camino aquel que corresponde al arco de menor coste; si todos los caminos de ese nodo están resueltos, marcamos el nodo como resuelto. Las revisiones finalizarán cuando la lista de nodos por revisar esté vacía. 6. BÚSQUEDA CON ADVERSARIO: LOS JUEGOS Las búsquedas con adversario son mucho más difíciles de resolver, dado que el contrincante intentará realizar aquellos movimientos que le son más favorables a él y, por ende, menos favorables para nosotros. A esta dificultad se añade que si queremos una solución en un tiempo razonable, utilizando la memoria disponible puede ser que no demos con la mejor solución, ya que la cantidad de nodos que deberíamos expandir en un árbol de búsqueda hasta llegar a una solución adecuada podría resultar excesivo. Pensemos, por ejemplo, en la expansión de un árbol para una partida de ajedrez en la que en cada posición nos encontramos habitualmente con unos 35 movimientos posibles. Para encontrar una solución adecuada estudiaremos las soluciones perfectas, las imperfectas y los elementos aleatorios (como por ejemplo un dado) que añaden más confusión y complejidad al desarrollo del problema. Dentro de las soluciones perfectas, cuando no se ha de considerar ningún elemento de suerte resulta similar a formalizar problemas de búsqueda como hemos hecho hasta ahora. Por tanto, modelizamos los estados, las acciones y el problema. Debemos pensar que el estado inicial no es el estado inicial del tablero al principio de la partida, sino que para cada uno de nuestros movimientos, deberemos iniciar un nuevo árbol de búsqueda y, por tanto, un nuevo estado inicial. La función objetivo la descompondremos en un test de fin (para saber si todavía se puede continuar jugando) y un test de utilidad (para ver hasta qué punto nuestro movimiento es bueno). Un algoritmo muy bueno para encontrar el mejor movimiento dentro de una partida, es el algoritmo de mínimax que se utiliza para un juego con dos jugadores en los que no interviene ningún elemento de suerte, ni tenemos restricciones de memoria ni tiempo. Vamos a modelizarlo a través del ejemplo de la página siguiente. Partimos del típico juego de tres en raya, donde al jugador X (que somos nosotros y claro, queremos ganar) nos toca poner una X. La función de utilidad nos devolverá un 1 si ganamos nosotros (somos el jugador max), nos devolverá un 0 si empatamos y un -1 si perdemos. Para esa misma jugada al otro jugador le interesa obtener la puntuación más baja para ganar. Hay que señalar que esta función de utilidad solo se puede aplicar a estados terminales, cuando ya no se puede poner o mover ninguna pieza más o cuando un jugador ha ganado. Siguiendo con el algoritmo desarrollamos el árbol para la jugada siguiente en el que hay 3 nodos (hay 3 posiciones vacías) pero donde todavía desconocemos el Inteligencia artificial 1 · 11 resultado de la función de utilidad porque no hemos llegado a un estado Terminal (en los nodos a, b y c de la imagen, ya aparece un resultado, pero es por un avance posterior. Pasamos a evaluar cada uno de los nuevos nodos pasando a una profundidad 2, que tampoco podemos evaluar con el algoritmo minimax, y pasamos de nuevo a otro nivel de profanidad donde ya obtenemos respuestas. El nodo j tiene valor 0 pero el k tiene valor 1 (hemos ganado) Entonces ya podemos evaluar los nodos superiores, el nodo d tiene valor 0 y el nodo e tiene valor 1 porque es el valor mínimo de sus nodos hijos. Ascendemos al nodo a que tiene ahora valor 0 porque es el valor mínimo de sus nodos hijos (recordemos que si fuésemos el jugador min, nos interesarían los valores mínimos en los nodos y la función de utilidad a aplicar sería el valor máximo de cada nodo hijo se aplica al padre). Esto mismo aplicaríamos a todos los nodos desde el a hasta el o. Y nos damos cuenta que aunque hay posiciones terminales de valor 1, debemos pensar que el contrincante va a hacer el mejor movimiento para sus intereses y, por tanto, no podemos contar con un error; de ahí que desde la posición de partida cualquiera de los 3 movimientos que podemos realizar (a, b y c) nos van a llevar a un empate. Existe una variación a este algoritmo y es la poda alfa-beta, para el que expondremos un juego artificial con el ejemplo que puede verse en la página siguiente. En este caso y partiendo del nodo a, obtenemos b, f y g que al no poder evaluarlos porque no son terminales, pasamos a una profundidad 2 (somos el jugador max y nos toca mover ficha) donde ya todos los nodos son terminales y podemos empezar a evaluar. El algoritmo comenzaría por b y obtendría un valor 5. Al pasar a f y obtener un valor 3 en el primer nodo hijo sabemos que ese es el valor que tomará el nodo padre, y como nos interesa el valor más grande en el primer nivel de profundidad y ya tenemos un valor 5 en el nodo b, nunca tomaríamos el nodo f, por lo tanto ya no evaluamos más nodos. En cambio, para el nodo j, como el primer valor de su hijo es 8, debemos seguir evaluando, el segundo es 6, tenemos que continuar y el último es 3, por lo que nos decidimos por mover 12 · Inteligencia artificial 1 ficha hacia el nodo b. Hemos de darnos cuenta que aunque tanto f como j tienen los mismos valores en sus nodos hijo, la posición de los mismos ha hecho que en el primero podamos realizar una poda y ahorrarnos la evaluación de dos nodos, mientras que en el segundo esto no ha sido posible. Las decisiones imperfectas se dan cuando no podemos llegar a estos estados terminales, debido a limitaciones de tiempo o memoria, y por tanto debemos tomar una decisión basándonos en desarrollos parciales de los árboles de búsqueda. Reconozcamos que el algoritmo minimax tiene un coste exponencial (para una profundidad p y un factor de ramificación r el coste es fr). Si aplicamos la poda, en el mejor de los casos podemos dividir por 2 este coste, y el mejor de los casos es tener los nodos ordenados de menor a mayor, pero claro, esto no es posible porque nosotros buscamos el valor de los nodos y para tenerlos ordenados ya tendríamos que haber hecho eso anteriormente. Por lo tanto solo nos queda una solución: no desarrollar todo el árbol de expansión y aplicar una función de evaluación heurística a las hojas del árbol. Eso sí, esta forma de actuar puede llevarnos a no elegir la mejor opción en un momento dado. Como no expandimos todo el árbol no podemos aplicar la función de utilidad y nos conformamos con la función heurística y claro, como el rendimiento del programa dependerá mucho de la función heurística, ésta debe reflejar las posibilidades de ganar. Cuando al juego se le añade un elemento de azar la cuestión se complica ligeramente. Pensemos por ejemplo en el parchis, tenemos 4 fichas (para no complicarlo ya están todas fuera de la salida) que podemos mover libremente contando con la puntuación de un dado que hemos tirado previamente. En este caso se tira el dado que nos puede dar 6 expansiones diferentes (6 nodos hijo) y a cada posible tirada le aplicamos el movimiento de las 4 fichas que tenemos. Como podemos ver en el árbol de expansión nuestras decisiones se deben circunscribir a la profundidad 2 del árbol. En la profundidad 1 tenemos las 6 tiradas y en la dos la aplicación de esas tiradas al movimiento de las fichas de tablero (de n11 a n64). La aplicación del algoritmo mínimax es igual pero atendiendo a las alternativas de profundidad 2. Inteligencia artificial 1 · 13 7. ALGORITMOS GENÉTICOS Función g(x) y su gráfica Son algoritmos de búsqueda estocásticos inspirados en los fenómenos naturales de herencia genética y en que lo mejor es lo que sobrevive. La analogía con el proceso biológico de la evolución dirige todos los pasos de los algoritmos genéticos, así consideraremos poblaciones de individuos representados por sus cromosomas (formados por genes) y dado un cromosoma consideraremos su cruce con otro cromosoma o su mutación. Este tipo de algoritmos permiten encontrar una solución a un problema dado, pero normalmente no encuentran la mejor solución del problema, sino que encuentran una que aproxima a la solución óptima. En primer lugar debemos codificar las diferentes alternativas que se tienen que considerar en la solución, así por ejemplo si queremos encontrar una solución que se aproxime mucho al máximo de la función lateral entre 0 y 16 (podemos ver la gráfica de la función en la figura lateral), podemos codificar la posible solución en 8 bits binarios. Hay que tener en cuenta que debemos codificar en una secuencia de símbolos de longitud finita. Además necesitamos una función que evalúe las diferentes alternativas de manera que la mejor alternativa posea el mejor valor, esta es la denominada función de evaluación. La función de evaluación en nuestro caso será pasar el bit obtenido al número real correspondiente y después aplicarle la función g(x) para obtener el resultado. Así en nuestro ejemplo hemos creado aleatoriamente 8 cromosomas codificados en bits binarios y al pasarles la función de evaluación hemos obtenido que el cromosoma más alto es el 5, como se puede ver en esta tabla: Cromosoma Evaluación 1 1,1217 2 1,0672 3 0,9405 4 0,9758 5 1,7107 6 0,9837 7 0,9480 8 1,004 Ahora pasamos a seleccionar ese cromosoma y comenzamos un proceso iterativo para crear una nueva población. Crear esta nueva población puede tener varias alternativas, en nuestro caso vamos a obtener las probabilidades (acumuladas) de que cada cromosoma forme parte también de la nueva población, esta probabilidad se obtiene como el cociente entre el resultado de la función de evaluación y el total de las evaluaciones, con lo que la tabla de probabilidades nos queda así: Cromosoma Probabilidad Acumulada Modificación de cromosomas 1 0,1281 0,1281 2 0,1219 0,2501 3 0,1074 0,3575 4 0,1115 0,4690 5 0,1954 0,6645 6 0,1123 0,7769 7 0,1083 0,8852 8 0,1147 1,0 A continuación se generan nuevos valores aleatorios a los que se les aplica también aleatoriamente una forma de cruce: simple, múltiple, mutación o inversión. Pasamos a valorar los nuevos cromosomas generados usando la misma función de evaluación anterior y volvemos a encontrar un máximo más máximo que el anterior para esta función g(x). Como podemos observar este método resulta adecuado para valorar problemas que no se ajustan a los métodos estudiados anteriormente. Podemos también utilizarlos cuando las funciones que queremos optimizar son complicadas o cuando la resolución del problema supone un coste muy elevado. También debemos tener en cuenta el tamaño de la población, en nuestro ejemplo era 8 pero debe ser siempre un número adecuado a la solución del problema que buscamos. 14 · Inteligencia artificial 1 TEMA 3 SISTEMAS BASADOS EN EL CONOCIMIENTO 1. INTRODUCCIÓN A LOS SISTEMAS BASADOS EN EL CONOCIMIENTO Los sistemas basados en el conocimiento resuelven los problemas utilizando de manera intensiva conocimiento del campo de aplicación. Así, la figura lateral subraya los principales módulos que integran estos sistemas: Base de conocimientos: Es el almacén de conocimientos del sistema. Subsistema de inferencia: Razona sobre las soluciones de los problemas. Interfaz con el usuario: Es la que permite que los usuarios finales puedan interactuar con el sistema. El aspecto formal (base de conocimientos) y el aspecto inferencial (subsistema de inferencia) a menudo se encuentran tan ligados que no resultan independientes y por lo tanto, no pueden formar módulos separados. Los sistemas basados en el conocimiento requieren una gran inversión de tiempo y recursos por lo que es fundamental saber si imprescindiblemente necesitamos resolver el problema por este sistema, es decir, debemos asegurarnos de no podemos resolver el problema por otros métodos estudiados y de que el conocimiento está bien estructurado y existen expertos que lo controlan. Tema 3 Sistemas basados conocimiento en 1. Introducción a los sistemas basados en el conocimiento 2. La representación del conocimiento 3. Sistemas basados en reglas 4. Sistemas con representación estructurada 5. Sistema de razonamiento basado en casos 6. Sistemas de razonamiento basado en modelos 7. Redes neurales Esquema tradicional de un sistema basado en el conocimiento Para resolver los problemas podemos intentar dos vías: o bien contamos con un experto, o bien contamos con técnicas de aprendizaje. Cuando contamos con un experto, que es el que sabe los problemas que se plantean y las técnicas adecuadas para resolverlos, éste evaluará los datos y podrá tratar con problemas mal definidos o con incertidumbre. El ingeniero del conocimiento en cambio, es experto en inteligencia artificial y en representación del conocimiento, así que seleccionará las herramientas adecuadas y ayudará al experto a formular el conocimiento necesario e implementarlo en una base de conocimientos eficiente. El modelo que debemos construir deberá satisfacer 3 funciones: El modelo deberá abstraer unos objetivos concretos por lo que la complejidad del problema se reduce. Nos ayudará a comprender las entidades y los procesos que permiten la construcción de la solución en el mundo real. Debe ayudarnos a predecir los distintos comportamientos del modelo en según distintas situaciones. Por otro lado, podemos contar con técnicas de aprendizaje que permiten construir modelos de un dominio a partir de un conjunto de ejemplos. Del estudio del resultado de estos ejemplos intentaremos inferenciar las posibles respuestas posteriores frente a otras situaciones. Por ejemplo, consideramos el caso de un sistema de diagnosis de un circuito digital con 3 entradas binarias, v1, v2 y v3 que nos calcula una salida también binaria v4. Para construir nuestro sistema podemos hacer pruebas con un circuito que funcione correctamente, probando distintos valores binarios en v1, v2 y v3 y anotando los resultados para poder predecirlos posteriormente. Los modelos basados en el conocimiento presentan limitaciones, ya que muchas veces los ejemplos de los que nos servimos son un subconjunto de los que pueden darse; así en nuestro circuito si en lugar de un sistema binario, pudiese tomar 30 valores cada salida, las combinaciones de los 3 circuitos son tan altas que no podemos probar todos los casos. el Inteligencia artificial 1 · 15 Por último debemos comprender que es necesario compartir el conocimiento, es decir construir mecanismos para traducir el conocimiento obtenido mediante diferentes formalismos de representación para que pueda ser aplicado posteriormente. Verificar y validar el modelo se hace casi imposible, dado que el comportamiento real respecto al modelo construido depende del conocimiento escondido en la base de conocimientos. 2. LA REPRESENTACIÓN DEL CONOCIMIENTO Tablero de ajedrez recortado Una determinada representación nos puede simplificar enormemente el proceso de encontrar la solución a un problema o bien nos puede impedir encontrarle una solución. Así, en el caso del tablero de ajedrez recortado, como el que se ve en la figura lateral, queremos cubrir con fichas de dominó de forma que no quede ninguna posición vacía y sin que se produzcan solapamientos ¿es esto posible? Una forma de representar el problema es probar todas las combinaciones posibles hasta encontrar una solución si es que existe; otra forma (otra representación) es tener en cuenta que cada ficha ocupará exactamente un recuadro blanco y uno negro, y teniendo en cuenta que tenemos 32 espacios blancos y 30 negros, la solución ya cae por su propio peso. Los niveles de formalismo de representación del conocimiento son: Nivel de conocimiento: Es el nivel que utiliza cualquier agente para interaccionar con su formalismo de representación del conocimiento; nos interesa saber aquello que sabe sin tener en cuenta cómo está implementado. Desde el punto de vista de que el sistema debe interaccionar con el usuario ha de ser posible expresar el conocimiento en distinto nivel de detalle. Así para un razonamiento general sobre el universo debemos ser capaces de dibujar el sistema solar y sus rotaciones, pero para unos físicos es necesario conocer las ecuaciones de los movimientos de los cuerpos en el espacio. Nivel lógico: Tenemos la codificación del conocimiento en sentencias concretas, es decir, su significado y su capacidad de expresión. Nivel de implementación: Se trata de cómo representar el conocimiento en un ordenador, qué estructuras de datos y que algoritmos son adecuados para su representación e inferencia. Corresponden por tanto, a la eficiencia de los procesos (en tiempo y espacio). En todo formalismo de representación del conocimiento se pueden distinguir dos aspectos: Aspecto formal: Corresponde a cómo se almacena la información cuando la tenemos representada de manera explícita, cual es el formalismo que se utiliza. Aspecto inferencial: Corresponde a cómo se obtiene la información que se encuentra en el sistema pero sólo de manera implícita. Así, en el caso de la lógica tendremos que el aspecto formal corresponde a cómo se forman las expresiones y como se construyen las fórmulas; mientras que el aspecto inferencial tratará los métodos que permiten demostrar un predicado. Un sistema puede incluir distintos tipos de conocimiento: Conocimiento de dominio: Conocimiento general sobre el campo de aplicación del sistema. Conocimiento estratégico: Cómo utilizar el conocimiento de dominio para resolver un determinado problema. 16 · Inteligencia artificial 1 Así en el diagnóstico médico, el conocimiento de dominio corresponde a lo relativo a enfermedades y el estratégico a cómo enfocar el caso concreto de un enfermo para encontrar un diagnóstico a su enfermedad. Otra posible división es: Conocimiento procedimental: Se encuentra ligado a una utilización concreta, pro ejemplo definir una función para calcular el factorial de un número. La función nos permite saber este conocimiento pero no podemos aplicar otros como saber qué número tiene factorial 150. Conocimiento declarativo: Es independiente de su uso; si expresamos la relación entre un número y su factorial mediante lógica proposicional, podemos utilizar el conocimiento de distintas maneras, tal como expresábamos en el apartado anterior. En la implementación de los mecanismos de inferencia aparecen problemas de búsqueda. Esto se debe porque la inferencia se hace para cumplir un objetivo y en el proceso de cumplirlo se nos presentarán a menudo distintas alternativas de las cuales debemos elegir una. Aquí entra en juego el conocimiento estratégico, que describe cómo utilizar el conocimiento de dominio para resolver un determinado problema, guiándonos en la búsqueda para acercarnos al objetivo lo más rápidamente posible. Se dice que los sistemas basados en el conocimiento son frágiles porque fuera de su domino de aplicación no funcionan bien y además no saben cual es la frontera de su conocimiento. Esto provoca la llamada “falta de sentido común”: en algunas ocasiones las respuestas del sistema son absurdas porque falta conocimiento que podríamos denominar elemental y que casi todo el mundo tiene asumidos. Algunos investigadores piensan que este problema puede resolverse elaborando bases de conocimiento mayores para conseguir comportamientos “inteligentes”. 3. SISTEMAS BASADOS EN REGLAS Los sistemas basados en reglas se aplican sobre todo a problemas de clasificación (identificación) y diagnosis. El conocimiento viene representado mediante hechos y reglas. Los hechos se corresponden a conocimiento sobre objetos y las reglas permiten establecer relaciones entre estos objetos del tipo: Si <premisa> entonces <conclusión> A partir de los hechos y las reglas, el sistema de inferencia concluirá sobre nuevos hechos o corroborará la certeza de unos hechos. En la figura lateral se puede observar la arquitectura básica de un sistema basado en reglas. Los elementos que la constituyen son: Sistema basado en reglas Base de reglas: Es donde se guarda toda la información general relativa al dominio de aplicación, por lo tanto estarán aquí todas las reglas necesarias para resolver los problemas que trata el sistema. Memoria de trabajo: Son todos los hechos que pueden ser relevantes para el problema concreto y temporal que se quiere resolver. Intérprete: Es el aspecto inferencial del sistema, permite deducir nuevos hechos a partir de la información existente en la memoria de trabajo y de las reglas de la base de reglas. El proceso a seguir es el siguiente: Inteligencia artificial 1 · 17 o o o Recuperación: Se seleccionan de la base de reglas las que se pueden aplicar (habitualmente más de una) que constituyen el llamado conjunto de conflicto. Refinamiento: Se debe seleccionar una regla del conjunto dado que habitualmente no se aplica más de una regla a la vez. Ejecución: Se aplica la regla seleccionada en el punto anterior. Una vez ejecutada se pasará de nuevo a la recuperación hasta que se consigue demostrar lo que se quería o bien el conjunto de conflicto se encuentra vacío y ya no podemos aplicar ninguna regla más. Para ayudar y dirigir la búsqueda (sobre todo elegir en cada momento la regla a aplicar más conveniente dentro del conjunto de conflicto), nos podemos ayudar de algunas estrategias: Orden textual: El orden en que aparecen las reglas en la base de reglas determina el orden de aplicación. Obstinancia: Impide que una regla se aplique más de una vez, quedando anulada una vez aplicada. Cuando una regla tiene variables o el conocimiento no es monótono, hay que tener cuidado con esta estrategia porque puede dar problemas. Recencia: Se seleccionan las reglas que se refieren a los hechos más recientes de la memoria de trabajo; para ello es necesario que los predicados de la base de hechos incluyan una marca de tiempo. Especificidad: Se seleccionarán las reglas que corresponden a objetos más específicos y particulares que generales. Para ello, cuanto más conjuntandos tenga una regla más específica es; es decir, preferiremos la regla que comienza por “si el suelo está mojado y no llueve entonces…” antes que “si el suelo está mojado…” cuando nos encontremos en el primer caso. El razonamiento para inferir nuevos hechos puede ser de dos tipos: Razonamiento hacia delante: Partiendo de la información disponible y aplicando las reglas adecuadamente, queremos llegar a un objetivo determinado. Razonamiento hacia atrás: Partimos del objetivo y aplicando los antecedentes de las distintas reglas queremos llegar al punto de partida. No todos los sistemas permiten estos dos tipos de inferencia, y siempre se elegirá uno u otro dependiendo de la base de la información de la que disponemos y buscando siempre la opción que presente el factor de ramificación más pequeño. 4. SISTEMAS CON REPRESENTACIÓN ESTRUCTURADA Dentro de los sistemas con representación estructurada, vamos a limitarnos al estudio de los marcos, que representan conceptos que definen situaciones o incluso representan las situaciones mismas. Desde el punto de vista formal un sistema de marcos es una red donde cada nodo representa un objeto (concepto o individuo) y los arcos corresponden a las relaciones que se pueden establecer entre los objetos; el parecido con el lenguaje orientado al objeto es máximo. A tal punto lelga, que una de las relaciones que se establece entre los objetos son las relaciones de subclase, superclase de instancia. Vemos en la figura lateral que el concepto coche es una subclase del concepto vehículo y “mi coche” es una instancia del concepto coche, siendo María (también una instancia) la propietaria del mismo. Encontramos dos tipos de campos: los de miembro (propios y modificables para cada instancia) y los propios (propios del marco y por lo tanto, que comparten todas las instancias), así todos los coches tendrán 4 ruedas en el Ejemplo de representación usando marcos 18 · Inteligencia artificial 1 ejemplo. Se pueden incluir en estos campos valores de un dominio cualquiera, referencias a otros marcos, restricciones sobre valores e incluso funciones, aunque este último caso es complejo pero ayuda a incluir conocimiento procedimental como si fuese declarativo. Los sistemas de marcos además tienen los llamados procedimientos demonios, que están siempre latentes a la espera de ser activados por alguna actuación; por ejemplo si al variar el valor de un campo ha de comprobarse que se encuentra en un rango determinado; o que al bajar el valor de un campo de una cifra determinada se active determinada función. La interrogación de un sistema de marcos suele realizarse para saber si un objeto cumple una propiedad determinada. El problema se reduce a encontrar el campo que responde a la pregunta. Cuando el campo no se encuentra en el propio objeto, y si no se encuentra se consultarán otros marcos de Herencia múltiple acuerdo con las relaciones de herencia: primero se mira la superclase del objeto, después la superclase de la superclase y así hasta encontrar el campo. Este mecanismo se complica cuando tenemos herencia múltiple, pues podemos obtener distintos resultados según el camino que decidamos seguir en la búsqueda. Así en el ejemplo de la figura lateral sobre herencia múltiple, nos podemos preguntar qué tipo de escritura tenía Bertrand Russell. Si hacemos una búsqueda en profundidad diremos que aburrida, mientras que si la búsqueda es en anchura, diremos que excelente. Debemos, por tanto, decidir un algoritmo de ordenación topológica que nos haga seguir siempre el mismo camino para un mismo caso dado. 5. SISTEMAS DE RAZONAMIENTO BASADOS EN CASOS El razonamiento basado en casos considera el conjunto de experiencias pasadas y resuelve las nuevas situaciones de manera parecida a como se resolvieron las anteriores. Para llevarlo a cabo, almacena experiencias previas y guarda la solución aplicada en cada caso. Cuando se le plantea una nueva situación, se buscará una parecida entre las que ya ha visto antes y que almacena en su base de casos. Se dice que este tipo de conocimiento es operacional ya que se utiliza en una situación concreta y para un caso concreto y esto nos aporta algunas ventajas: En determinados entornos donde el conocimiento general es demasiado abstracto y difícil de aplicar en situaciones concretas es mejor este sistema. Este sistema aprende de su propia experiencia al poder almacenar soluciones de nuevos casos. Reducen el proceso de modelización ya que no necesita un experto que defina todo el conocimiento sobre el dominio, sino únicamente un conjunto de experiencias concretas. Pero también tiene sus desventajas: No explora todo el espacio de soluciones porque no tiene todo el conocimiento del dominio, por lo que podemos encontrar soluciones que no son globalmente óptimas (pueden ser óptimos locales). La solución está sesgada por los casos que se encuentren en su base de casos. La estructura de los sistemas de razonamiento basados en casos puede ser variada aunque suelen reflejar lo expresado en la figura lateral de la página siguiente: Recuperación: Se recuperan los casos precedentes que son parecidos al caso que debemos resolver, y se selecciona lo mejor de éstos. Aunque inicialmente debiéramos recuperar el caso sobre la utilidad de la solución, como esto es muy complejo, se efectúa dicha recuperación sobre la base de las características que Inteligencia artificial 1 · 19 Funcionamiento del sistema basado en casos describen el caso. Calcularemos la similitud entre los casos de la base de casos y el que queremos resolver y nos quedaremos con el más parecido. Los casos en la base deben estar indexados para una más fácil recuperación por características. Reutilización: Se decide si la solución del caso seleccionado se puede aplicar directamente y, si no es así, se la adapta a la nueva situación. Para adaptarla a menudo tenemos unas reglas definidas de forma que sus antecedentes sean las posibles diferencias entre el caso a estudiar y el caso recuperado; así determinaremos exactamente las diferencias y aplicaremos las reglas necesarias. Revisión: Se aplica la solución al problema en curso y se evalúa, a veces es necesario revisarla. Retención: Se almacena el nuevo caso y su solución para poder utilizarla más adelante. En general, la eficiencia de este tipo de sistemas dependerá fuertemente de los casos que se incluyan en su base de casos, de la forma en que se recuperan y, por supuesto, de los mecanismos de adaptación. 6. SISTEMAS DE RAZONAMIENTO BASADO EN MODELOS Los sistemas basados en modelos relacionan causa-efecto sin entrar en los detalles de la relación, por lo que con un conocimiento superficial somos capaces de obtener respuestas correctas. Así un médico tras unos análisis de sangre es capaz de emitir un juicio diagnóstico, en este caso sin saber como progresa la enfermedad. Para esto es necesario un modelo detallado de la estructura del sistema y una descripción de los componentes. Es bastante parecido al sistema basado en reglas, con la salvedad que éste último se basa en el conocimiento profundo, mientras que el sistema basado en modelos se basa en el conocimiento superficial. Tres aspectos debemos tener en cuenta: Circuito correspondiente a un sumador binario El modelo: Hay que construir el modelo del aparato o del sistema, con una descripción de la estructura física y todos los componentes que lo conforman. En el ejemplo lateral de un sumador binario debemos considerar todo el circuito, las puertas que lo constituyen, las conexiones y todas las entradas y salidas. Las posibles causas: Hay que disponer de información de todo lo que puede fallar en el aparato. En el ejemplo debemos definir las posibles causas de error (en este caso las puertas y las conexiones entre ellas). Las observaciones: Debemos contar con un conjunto de medidas del sistema en distintos puntos que nos permitan determinar qué es lo que no funciona correctamente (se especifican todos los puntos donde podemos consultar los valores que toma a lo largo del circuito, entrada de puertas, salidas, etc). Así, cuando el sistema no funciona correctamente, habrá divergencias entre los valores observados y lo que el modelo predice. Cuando se encuentra con divergencias, se planteará hipótesis sobre lo que puede haber fallado y se contrastarán con las mediciones que se realizan hasta encontrar dónde se ha producido el error por comparación con el modelo. El problema es que el número de causas posibles es grande, en nuestro ejemplo si consideramos que el error se puede provocar en una de las 8 puertas que tenemos, los estados posibles son 28, es exponencial. 20 · Inteligencia artificial 1 7. REDES NEURONALES Las redes neuronales son un sistema de representación del conocimiento inspirado en las redes de neuronas de los seres vivos. Una red neuronal se representa mediante un grafo en el que los nodos son neuronas (unidades de computación) y los arcos son flujos de información (sinapsis). Los arcos tienen pesos asociados que indican el grado de conexión entre nodos y las neuronas tienen asociadas funciones de activación que indican en qué medida se propaga una inferencia hacia la salida. Red neuronal En la figura lateral tenemos una red neuronal con unos pesos asociados y unas entradas x y unas salidas y. El valor de las salidas dependen directamente (aunque a veces también existen sesgos) de los valores ocultos de los pesos asociados, se convierte la red neuronal en una especie de caja negra, en la que el número de neuronas, las conexiones y el peso asociados a ellas debemos conjeturarlos a partir de ejemplos conocidos de valores de entrada y salida. Para cada ejemplo de entrada calculamos valores de los pesos para aproximarnos al valor real de la salida (fase de propagación); cuando nos hemos acercado lo suficiente (fase de adaptación), repetimos el proceso para el siguiente ejemplo y cuando tenemos todos ajustados, ya podemos probar con valores reales y no de ejemplo. Las características que encontramos asociadas a las redes neuronales son las siguientes: No necesitamos un modelo analítico de lo que queremos representar, a partir de un conjunto de ejemplos construimos un modelo suficientemente preciso a partir de los datos. El conocimiento no aparece concentrado en una parte del sistema, sino que está repartido por toda la red, lo que le da gran robustez; aunque también constituye una desventaja pues los pesos no son interpretables, esto le da dificultad a la definición inicial del modelo y a las modificaciones posteriores. Inteligencia artificial 1 · 21 TEMA 4 INCERTIDUMBRE Y RAZONAMIENTO APROXIMADO Tema 4 Incertidumbre y razonamiento aproximado 1. Razonamiento con información incompleta 2. Sistemas difusos 1. RAZONAMIENTO CON INFORMACIÓN INCOMPLETA Pocas veces la información o conocimiento disponible sobre un dominio concreto es completa y precisa. A menudo nos encontramos con la poca fiabilidad de la información, con información incompleta, con imprecisión en la información debido al uso del lenguaje natural o con la agregación incluso de información conflictiva o contradictoria. Por tanto, la imprecisión es algo inherente al lenguaje de representación, mientras que la incertidumbre aparece cuando la información no es lo suficientemente completa o precisa. 2. SISTEMAS DIFUSOS Función de pertenencia Complementación Unión Los sistemas difusos son los sistemas basados en reglas que se definen en términos de conjuntos difusos, para que un determinado aparato siga un esquema de comportamiento determinado. Un ejemplo será el de un aparato para el control de la temperatura. Así, el aparato funcionará mediante reglas del tipo Si <premisa> entonces <conclusión>, pero en las que las premisas y las conclusiones corresponderán a conceptos vagos. Los conjuntos difusos generalizan los conjuntos clásicos (que a partir de ahora denominaremos nítidos), es decir, las operaciones que aplicaremos a los conjuntos difusos son generalizaciones de las que aplicamos a los nítidos. En los conjuntos nítidos la función característica para un elemento del dominio devuelve 1 si pertenece a él o 0 si no pertenece; pero en los conjuntos difusos esto no funciona así, es decir, un elemento puede pertenecer al dominio o no pertenecer o pertenecer de forma graduada. Así cuando a un posible elemento del dominio del conjunto difuso le aplicamos la función característica de pertenencia, puede devolver un 0 o un 1 o un valor entre ellos que define de forma graduada cómo ese elemento pertenece al conjunto difuso. Así, los conjuntos difusos permiten definir conceptos en los que no resulta fácil definir claramente un punto donde separar entre aquellos elementos que son del concepto y aquellos que no lo son. Por ejemplo, si definimos que a partir de 1,80 una persona es alta, ¿podemos decir que una persona que mida 1,79 es bajita? Claro que no, será más bajita una que mida 1,76 pero sin ser baja del todo. Así vemos en la imagen lateral una función de pertenencia a un sistema difuso, en la que por debajo de 1,70 ya no se entra en el concepto de ser alto, a partir de 1,80 sí, y entre 1,7 y 1,8 está graduada su pertenencia. Las funciones aplicables a los conjuntos difusos son: Complementación: Para tener en cuenta el complementario del conjunto difuso (en este caso los bajitos) tenemos obviamente en cuenta el conjunto inicial y debe cumplir las condiciones de contorno, monotonía e involución. Así en la imagen lateral podemos ver el complementario de la función altura definida anteriormente. Unión de dos conjuntos difusos: Debemos crear una nueva función de pertenencia a partir de las dos funciones de los conjuntos difusos originales. Se le exigen las condiciones de conmutatividad, asociatividad, monotonía y elemento neutro (0). Así podemos observar la función unión de los dos conjuntos difusos anteriores: altura y complementario de la altura. Intersección Intersección de dos conjuntos difusos: También cumple las condiciones de conmutatividad, asociatividad, monotonía y elemento neutro (1). 22 · Inteligencia artificial 1 Para la construcción de un sistema difuso, se ha de tener en Sistema difuso cuenta que el conjunto de reglas que hay en el sistema debe cubrir todo el dominio que queremos controlar o modelizar. Así si queremos tratar el sistema que controla la temperatura mediante un termostato, debemos tener en cuenta qué errores y qué incrementos de errores ha de ser capaz de tratar el sistema. Si por ejemplo tenemos el dominio de la aplicación que aparece en la figura lateral, debemos asegurarnos de tratar todos los casos posibles, particionando el dominio de la aplicación y asociando una regla a cada elemento de la partición. Con el fin de simplificar la construcción de la partición y asegurarnos de que estamos definiendo realmente una partición del dominio, lo más sencillo es construirla regularmente a partir de los dominios del error y del incremento del error; así comprobamos que no nos dejamos ninguna región sin tratar. Así particionamos en 5 porciones el dominio del error y el dominio del incremento del error, nos queda dividido en 25 regiones y debemos definir 12 reglas que son el número de regiones donde se encuentra el dominio del sistema difuso. Así si definimos la variable temperatura en 3 tramos: frío (<35), Sistema difuso tibio (30-40) y caliente (>40) con al función de pertenencia que vemos en la figura lateral; resulta conveniente que el dominio de aplicación esté dividido en regiones regulares y que podamos construir estas regiones fácilmente particionando el dominio de las variables de entrada. A partir de aquí debemos definir las 25 reglas, que como ejemplo exponemos: si el error es muy positivo y el incremento del error es bastante negativo, entonces… Ya hemos visto como definir una regla y un sistema difuso, a continuación exponemos como aplicar estas reglas dependiendo del valor de las variables de entrada: Cómo calcular el grado en que se satisface el antecedente de una regla: Corresponde al grado en que la regla se activará. Se calcula viendo la pertenencia de los valores de las variables a los conjuntos difusos que aparecen en el antecedente y después combinando las pertenencias de acuerdo con las conjunciones, disyunciones o complementos que aparecen en el antecedente. Qué se concluye de una regla cuando ésta solo se satisface en un cierto grado: Cuando el antecedente se satisface plenamente, la conclusión será la misma que tenemos en la aplicación de la regla, pero si no se satisface plenamente, la conclusión será una modificación de lo que aparece en la regla. Qué ocurre en un sistema cuando existe más de una regla que se cumple en un determinado grado: Aplicaremos el mismo proceso anterior a cada una de las reglas que existan. Para cada una de las reglas se obtendrá un conjunto difuso truncado (el de la conclusión truncada según la satisfacción del antecedente), del que posteriormente realizaremos su función unión. Nitidificación: Es un paso posterior, hemos obtenido como resultado anterior un conjunto difuso, pero a menudo no es una buena solución porque un sistema para funcionar requerirá como salida un valor real (nítido, como puede ser la intensidad que debemos proporcionar a un aparato o la velocidad a la que se moverá un robot). Una de las formas más sencillas de realizar este proceso es el llamado centro de masas, y se define como una medida de los valores del dominio, cada uno ponderado según su pertenencia al conjunto que estamos nitidificando. A continuación presentamos algunas indicaciones para construir los sistemas difusos, aunque no siempre son buenas y aplicables: El producto da resultados más cuidados que el mínimo. Dos funciones de pertenencia correspondientes a términos lingüísticos contiguos han de tener intersección no nula. Si la intersección es nula, habrá discontinuidad en la conclusión. Inteligencia artificial 1 · 23 Es bueno que las anchuras de dos funciones de pertenencia correspondientes a términos lingüísticos contiguos sean la misma, y es adecuado que el valor de pertenencia máximo de la intersección de estas funciones sea 0,5; esto da buenos comportamientos en los sistemas de control. En la inferencia es más fácil implementar un sistema que primero aplica las reglas y después combina las conclusiones (método Mamdani) que uno que primero combina las reglas y después aplica la regla resultante. Los sistemas con reglas disyuntivas son más usados que los de reglas conjuntivas. Un sistema complejo es mucho más difícil de modelar, ya que si tiene muchas variables es necesario definir muchísimas reglas. Recordemos que habrá que definir mn reglas para un sistema con n variables de entrada y m términos por variable. Se suele resolver con sistemas jerárquicos o multietapa, donde las entradas de una etapa son las salidas de la etapa anterior más alguna nueva variable, obteniendo en el último sistema jerárquico, en la última etapa, la solución al problema. Texto elaborado a partir de: Inteligencia artificial 1 Vicenç Torra i Reventós, Lluís Godo i Lacasa Febrero 2006