{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# UD05 · Notebook 5 — Lógica difusa: el problema de las propinas\n", "\n", "**Objetivo**: implementar de principio a fin el ejemplo difuso de la teoría (§8.4) y comprobar\n", "en código las tres fases de un sistema de razonamiento impreciso: **fuzzificación**, **evaluación\n", "de reglas** y **desfuzzificación** (CE b).\n", "\n", "Es **práctica**: se trabaja en clase y no se entrega ni puntúa. Prepara las entregas de la unidad\n", "y la prueba escrita del RA5." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Antes de empezar\n", "\n", "```bash\n", "pip install scikit-fuzzy networkx\n", "```\n", "\n", "### `scikit-fuzzy`: dos versiones y una trampa\n", "\n", "La versión **0.4.2** ya **no arranca** en Python 3.12 o posterior: importa `imp` y `distutils`,\n", "eliminados del lenguaje. Instala la **0.5.0** (es lo que hace `pip install scikit-fuzzy`).\n", "\n", "En la 0.5.0 falla solo **`ControlSystem.view()`**, el dibujo del grafo del sistema, por un error\n", "de la librería. Los dibujos de cada variable (`servicio.view()`, `propina.view(sim=sim)`) **no**\n", "están afectados, y son los que se usan aquí. Si necesitas el grafo, párchealo:\n", "\n", "```python\n", "from skfuzzy.control.visualization import ControlSystemVisualizer\n", "\n", "_init_original = ControlSystemVisualizer.__init__\n", "\n", "def _init_parcheado(self, control_system):\n", " _init_original(self, control_system)\n", " self.ctrl = control_system\n", "\n", "ControlSystemVisualizer.__init__ = _init_parcheado\n", "```" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Fase 1 — Instalación y variables de entrada\n", "\n", "Define dos antecedentes —**servicio** y **comida**, universo 0-10— con tres funciones de\n", "pertenencia triangulares cada uno: `baja`/`media`/`alta` y `mala`/`media`/`buena`." ] }, { "cell_type": "code", "metadata": {}, "execution_count": null, "outputs": [], "source": [ "%pip install scikit-fuzzy networkx\n", "\n", "import numpy as np\n", "import skfuzzy as fuzz\n", "from skfuzzy import control as ctrl\n", "\n", "# TU CÓDIGO: define los dos Antecedent y sus funciones de pertenencia\n", "servicio = ...\n", "comida = ..." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Fase 2 — Variable de salida y reglas\n", "\n", "Define el consecuente **propina** (universo 0-25) con sus tres funciones de pertenencia, y las\n", "tres reglas de la teoría:\n", "\n", "1. servicio bajo **o** comida mala → propina baja\n", "2. servicio medio → propina media\n", "3. servicio alto **o** comida buena → propina alta" ] }, { "cell_type": "code", "metadata": {}, "execution_count": null, "outputs": [], "source": [ "# TU CÓDIGO: el Consequent y las tres Rule\n", "propina = ...\n", "regla1 = ...\n", "regla2 = ...\n", "regla3 = ..." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Fase 3 — Inferencia con el caso de la teoría\n", "\n", "Monta el sistema de control, simúlalo con **servicio 9,8** y **comida 6,5**, y obtén la propina." ] }, { "cell_type": "code", "metadata": {}, "execution_count": null, "outputs": [], "source": [ "# TU CÓDIGO\n", "sistema = ...\n", "sim = ...\n", "print(\"Propina:\", ...)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**✏️ Respuesta**: la teoría da **19,24 €** y a ti te saldrá una cifra parecida pero no idéntica,\n", "en torno a **19-20 €**. ¿Por qué?\n", "\n", "La **resolución de los universos** de entrada y salida afecta al resultado de la desfuzzificación\n", "por centro de gravedad: con `np.arange(0, 26, 1)` el universo de la propina tiene 26 puntos, y con\n", "más puntos el centro de gravedad se desplaza. Es el mismo fenómeno de **sensibilidad** del §9: un\n", "parámetro que parece un detalle técnico —cuántos puntos tiene el universo discreto— cambia la\n", "respuesta del sistema. Compruébalo: repite la fase con `np.arange(0, 26, 0.1)`.\n", "\n", "*(escribe aquí tu cifra, la del universo más fino, y la diferencia)*" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Fase 4 — Visualiza las funciones de pertenencia\n", "\n", "Dibuja las tres variables y el resultado de la inferencia. **Guarda las cuatro figuras**: son la\n", "evidencia de las fases de fuzzificación (las dos de entrada) y de desfuzzificación (la última, con\n", "la línea vertical del resultado)." ] }, { "cell_type": "code", "metadata": {}, "execution_count": null, "outputs": [], "source": [ "# TU CÓDIGO: dibuja las tres variables y el resultado de la inferencia\n", "..." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Fase 5 — Cambia el escenario\n", "\n", "Repite la Fase 3 con un **servicio de 3** (malo) y una **comida de 8** (buena)." ] }, { "cell_type": "code", "metadata": {}, "execution_count": null, "outputs": [], "source": [ "# TU CÓDIGO\n", "..." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**✏️ Respuesta**: ¿qué regla domina? ¿Es coherente el resultado con lo que esperarías de un\n", "cliente que recibió un trato mediocre pero comió muy bien?\n", "\n", "*(escribe aquí)*" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Fase 6 — Compara con un sistema de reglas «duro»\n", "\n", "Escribe la misma lógica con `if`/`elif` sobre umbrales fijos (p. ej. `servicio >= 8 → propina\n", "alta`) y compara la salida en varios casos, sobre todo **cerca de los umbrales**." ] }, { "cell_type": "code", "metadata": {}, "execution_count": null, "outputs": [], "source": [ "def propina_dura(servicio, comida):\n", " # TU CÓDIGO: la misma logica con umbrales fijos\n", " ...\n", "\n", "for s, c in [(9.8, 6.5), (5.0, 5.0), (5.1, 5.0), (4.9, 5.0)]:\n", " print(s, c, \"->\", propina_dura(s, c))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**✏️ Respuesta**: ¿qué le pasa al sistema duro cerca de los umbrales que no le pasa al difuso?\n", "¿En qué casos dan lo mismo las dos versiones y en cuáles no? Relaciónalo con la histéresis del\n", "notebook 8.\n", "\n", "*(escribe aquí)*" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Qué tienes que tener al terminar\n", "\n", "Las figuras y las explicaciones de las seis fases, en este mismo notebook.\n", "\n", "| Fase | Evidencia mínima |\n", "|---|---|\n", "| 1 | Las dos variables de entrada con sus funciones de pertenencia |\n", "| 2 | La variable de salida y las tres reglas |\n", "| 3 | La propina calculada para el caso de la teoría, y **por qué no sale exactamente la misma cifra** |\n", "| 4 | Las figuras de las funciones de pertenencia y del resultado |\n", "| 5 | Un escenario propio, con su resultado interpretado |\n", "| 6 | La comparación con un sistema de reglas «duro»: qué cambia en la respuesta |\n", "\n", "Las soluciones no se publican: se corrigen y comentan en clase." ] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "name": "python", "version": "3.12" } }, "nbformat": 4, "nbformat_minor": 5 }