-
Notifications
You must be signed in to change notification settings - Fork 1
/
capitulo4.qmd
391 lines (250 loc) · 34.9 KB
/
capitulo4.qmd
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
---
execute:
eval: false
code-block-bg: true
code-block-border-color: red
code-block-border-left: "#31BAE9"
code-line-numbers: true
code-block-font-size: 14
---
# Lógica Difusa
## Contexto y conceptos clave
La lógica difusa tiene un origen que se remonta a la antigua Grecia con Aristóteles, quien ya proponía la idea de grados de verdad o falsedad. Sin embargo, su desarrollo significativo ocurrió en el siglo XVIII, con filósofos como David Hume y Charles Sander Pierce, quienes exploraron conceptos como el razonamiento basado en la experiencia y la idea de vaguedad en lugar de la dicotomía cierto-falso.
El verdadero punto de inflexión llegó en 1962 con Lotfi Zadeh, quien cuestionó la rigidez de las matemáticas tradicionales frente a la imprecisión y las verdades parciales. Su trabajo en la Universidad de California en Berkeley condujo al concepto de conjuntos difusos, que generalizan los conjuntos tradicionales para trabajar con expresiones imprecisas, una noción inspirada en una discusión sobre la belleza de sus respectivas esposas.
Desde entonces, la lógica difusa ha encontrado aplicaciones prácticas en campos como el control de sistemas, la ingeniería y la inteligencia artificial. Ebrahim Mandani y Lauritz Peter Holmbland desarrollaron sistemas de control difuso prácticos en los años 70, mientras que en Japón se produjo un rápido avance en el uso de la lógica difusa en una amplia gama de aplicaciones, desde sistemas de transporte hasta electrodomésticos inteligentes.
La importancia de la lógica difusa radica en su capacidad para modelar la incertidumbre y la imprecisión en la toma de decisiones, permitiendo sistemas más adaptables y eficientes en numerosas aplicaciones. Se fundamenta en los conjuntos difusos y un sistema de inferencia basado en reglas, lo que ofrece una manera elegante de abordar problemas con información vaga o incompleta. En contraste con la lógica tradicional, que emplea conceptos absolutos, la lógica difusa permite grados variables de pertenencia a los conjuntos, imitando así el razonamiento humano.
Se definen a continuación los principales conceptos:
- **Lógica Difusa**: es un sistema matemático que modela funciones no lineales, que convierte unas entradas en salidas acorde con los planteamientos lógicos que usan el razonamiento aproximado.
- **Lógica Difusa en Inteligencia Artificial**: método de razonamiento de máquina similar al pensamiento humano, que puede procesar información incompleta o incierta, característico de muchos sistemas expertos. Con la lógica difusa o borrosa se puede gobernar un sistema por medio de reglas de “sentido común” las cuales se refieren a cantidades indefinidas. En general, la lógica difusa se puede aplicar tanto a sistemas de control como para modelar cualquier sistema continuo de ingeniería, física, biología o economía.
- **Conjuntos difusos**: son conjuntos que permiten la representación de la imprecisión y la incertidumbre. A diferencia de los conjuntos tradicionales, donde un elemento pertenece o no pertenece al conjunto de manera precisa, en los conjuntos difusos un elemento puede pertenecer al conjunto en diferentes grados. Por ejemplo, en lugar de definir un conjunto "alto" como una altura mayor a 180 cm, se podría definir de manera difusa, permitiendo grados de "altitud" para alturas que no son completamente altas o completamente bajas.
- **Sistema de Inferencia Difuso**: es el componente de la lógica difusa que utiliza reglas lingüísticas para mapear las entradas difusas a salidas difusas. Estas reglas se expresan en la forma "SI...ENTONCES...", donde se especifica cómo se relacionan las variables de entrada con las de salida. Por ejemplo, una regla en un sistema de control de climatización podría ser: "SI la temperatura es FRÍA y la humedad es ALTA, ENTONCES aumentar la calefacción".
- **Fuzzificación**: es el proceso de convertir entradas nítidas o precisas en valores difusos. Por ejemplo, en un sistema de control de velocidad de un automóvil, la entrada "velocidad del vehículo" puede ser fuzzificada para representar grados de "lento", "medio" o "rápido", en lugar de valores exactos de velocidad.
- **Defuzzificación**: es el proceso inverso de fuzzificación, donde se convierten las salidas difusas en valores nítidos o precisos. Después de que el sistema de inferencia difuso ha producido una salida difusa basada en las reglas y las entradas, la defuzzificación asigna un valor preciso a esa salida difusa.
- **Funciones de Pertenencia**: son funciones matemáticas que describen la membresía de un elemento a un conjunto difuso. Estas funciones determinan cómo se distribuyen los grados de pertenencia dentro del conjunto difuso. Algunas funciones comunes son las funciones triangulares, trapezoidales y gaussianas, que modelan diferentes formas de incertidumbre.
- **Variable lingüística**: es una variable cuyos valores se expresan en términos lingüísticos o en palabras en lugar de valores numéricos precisos. Estos términos lingüísticos se utilizan para describir la incertidumbre o la imprecisión asociada con la variable y pueden incluir etiquetas como "bajo", "medio" y "alto" en lugar de valores numéricos específicos. Al utilizar términos lingüísticos en lugar de valores numéricos precisos, los sistemas difusos pueden manejar de manera más efectiva la información subjetiva y no lineal existente en el mundo real.
### Operaciones sobre conjuntos difusos
Las operaciones sobre conjuntos difusos son operaciones matemáticas que se realizan sobre conjuntos difusos para obtener nuevos conjuntos difusos. Las operaciones sobre conjuntos difusos se pueden clasificar en dos categorías principales:
- **Operaciones Unarias**: se aplican a un solo conjunto difuso y generan un nuevo conjunto difuso como resultado. Algunas de las operaciones unarias más comunes son:
- `Negación`: la negación de un conjunto difuso *A*, denotada como $¬A$, se obtiene complementando la función de pertenencia de *A*. En otras palabras, para todo elemento *x* en el universo de discurso, $\mu ¬A(x) = 1 - \mu A(x)$.
- `Inversión`: la inversión de un conjunto difuso *A* se obtiene invirtiendo la función de pertenencia de *A*. En otras palabras, para todo elemento *x* en el universo de discurso, $\mu A^{x} = [1 - \mu A(x)]^n$, donde *n* es un parámetro que controla la forma de la inversión.
- `Concentración`: la concentración de un conjunto difuso *A*, denotada como *C(A)*, se obtiene estrechando la función de pertenencia de A alrededor de sus valores máximos. En otras palabras, para todo elemento x en el universo de discurso, $\mu C(A)(x) = f(\mu A(x))$, donde *f* es una función creciente que acerca los valores de $\mu A(x)$ a 1.
- `Dilatación`: La dilatación de un conjunto difuso *A*, denotada como *D(A)*, se obtiene ampliando la función de pertenencia de *A*. En otras palabras, para todo elemento *x* en el universo de discurso, $\mu D(A)(x) = g(\mu A(x))$, donde *g* es una función decreciente que aleja los valores de $\mu A(x)$ de 1.
- **Operaciones Binarias**: se aplican a dos conjuntos difusos y generan un nuevo conjunto difuso como resultado. Algunas de las operaciones binarias más comunes son:
- `Intersección`: la intersección de dos conjuntos difusos *A* y *B*, denotada como $A ∩ B$, se obtiene como el conjunto difuso que contiene solo los elementos que pertenecen tanto a *A* como a *B*. En otras palabras, para todo elemento x en el universo de discurso, $\mu A∩B(x) = min(\mu A(x), µB(x))$.
- `Unión`: La unión de dos conjuntos difusos *A* y *B*, denotada como $A ∪ B$, se obtiene como el conjunto difuso que contiene todos los elementos que pertenecen a *A*, a *B* o a ambos. En otras palabras, para todo elemento *x* en el universo de discurso, $\mu A∪B(x) = max(\mu A(x), \mu B(x))$.
- `Complemento`: ll complemento de un conjunto difuso *A*, denotado como $A^C$, se obtiene como el conjunto difuso que contiene todos los elementos que no pertenecen a *A*. En otras palabras, para todo elemento *x* en el universo de discurso, $\mu A^C(x) = 1 - \mu A(x)$.
- `Composición`: la composición de dos conjuntos difusos *A* y *B*, denotada como *A* o *B*, se obtiene como el conjunto difuso que representa la "relación" entre *A* y *B*. La definición precisa de la composición depende del tipo de conjuntos difusos y la aplicación específica.
**Propiedades de las Operaciones sobre Conjuntos Difusos**
Las operaciones sobre conjuntos difusos generalmente satisfacen ciertas propiedades matemáticas que garantizan su consistencia y aplicabilidad. Algunas de las propiedades comunes son:
- `Asociatividad`: la asociación de las operaciones define el orden en que se realizan las operaciones. Por ejemplo, para la intersección: $(A ∩ B) ∩ C = A ∩ (B ∩ C)$
- `Conmutatividad`: el orden de los operandos no afecta el resultado de la operación. Por ejemplo, para la unión: $A ∪ B = B ∪ A$
- `Distributividad`: la distribución de una operación sobre otra define cómo se combinan las operaciones. Por ejemplo, para la distribución de la unión sobre la intersección: $A ∪ (B ∩ C) = (A ∪ B) ∩ (A ∪ C)$
- `Absorción`: la absorción de una operación por otra define cómo un elemento neutro afecta el resultado
#### T-normas y T-conormas
Las **T-normas** y **T-conormas** son operadores fundamentales que permiten combinar información difusa y obtener un resultado difuso. Estas operaciones juegan un papel esencial en la intersección y unión de conjuntos difusos.
- **T-normas**: es una función binaria que combina dos valores difusos en un nuevo valor difuso. Se representa como T(a, b), donde a y b son valores difusos entre 0 y 1. Las T-normas se caracterizan por las siguientes propiedades:
- Monotonicidad: T(a1, b1) ≤ T(a2, b2) si a1 ≤ a2 y b1 ≤ b2.
- Conmutatividad: T(a, b) = T(b, a).
- Asociatividad: T(T(a1, a2), b) = T(a1, T(a2, b)).
- Neutralidad: T(a, 1) = a para todo a entre 0 y 1.
Las *T-normas* más destacadas son: - `Producto T-norma`: $T(a, b) = a * b$. Es la T-norma más común y representa la "intersección" difusa - `Mínima T-norma`: $T(a, b) = min(a, b)$. Representa la "mínima" entre dos valores difusos - `Diferencia limitada (o de Lukasiewick)`: $T(a, b) = max(0, a + b - 1)$.
- **T-conormas**: es una función binaria que combina dos valores difusos en un nuevo valor difuso. Se representa como C(a, b), donde a y b son valores difusos entre 0 y 1. Las T-conormas se caracterizan por las siguientes propiedades:
- Monotonicidad: C(a1, b1) ≥ C(a2, b2) si a1 ≤ a2 y b1 ≤ b2.
- Conmutatividad: C(a, b) = C(b, a).
- Asociatividad: C(C(a1, a2), b) = C(a1, C(a2, b)).
- Neutralidad: C(a, 0) = a para todo a entre 0 y 1.
Las *T-conormas* más destacadas son: - `Producto T-conorma`: $C(a, b) = a + b - a * b$. Es la T-conorma más común y representa la "unión" difusa - `Máxima T-norma`: $T(a, b) = max(a, b)$. Representa la "máxima" entre dos valores difusos - `Suma limitada (o de Lukasiewick)`: $T(a, b) = min(a + b, 1)$.
A continuación diferentes ejemplos para facilitar la interpretación de estos conceptos:
*Producto T-norma (a = 0.7, b = 0.5)*
> Considera un sistema que evalúa la idoneidad de un candidato para un trabajo basado en dos criterios: habilidades técnicas y habilidades de comunicación. Cada criterio se evalúa en una escala de 0 a 1, donde 0 representa ninguna habilidad y 1 representa habilidades excepcionales. Se tienen así lo siguientes valores para cada criterio:
> - a = 0.7 representa la calificación de habilidades técnicas del candidato (70% sobre 100%)
> - b = 0.5 representa la calificación de habilidades de comunicación del candidato (50% sobre 100%)
> Interpretación: aplicando la Producto T-norma (T(0.7, 0.5) = 0.35) indica que la idoneidad general del candidato, considerando tanto habilidades técnicas como de comunicación, es del 35%. Esto sugiere que la idoneidad general del candidato es menor que sus calificaciones individuales de habilidades, reflejando la naturaleza "intersectada" de la T-norma.
*Mínimo T-norma (a = 0.8, b = 0.3)*
> Imagina un sistema que evalúa el riesgo de una inversión financiera basado en dos factores: volatilidad del mercado y estabilidad económica. Cada factor se evalúa en una escala de 0 a 1, donde 0 representa ningún riesgo y 1 representa alto riesgo. Se tienen así lo siguientes valores para cada criterio:
> - a = 0.8 representa la calificación de volatilidad del mercado (80% sobre 100%)
> - b = 0.3 representa la calificación de estabilidad económica (30% sobre 100%)
> Interpretación: aplicando la Mínimo T-norma (T(0.8, 0.3) = 0.3) indica que el riesgo general de la inversión, considerando tanto factores de mercado como económicos, es del 30%. Esto sugiere que el riesgo general está determinado por el factor de calificación más baja (estabilidad económica), reflejando la naturaleza "mínima" de la T-norma.
*Producto T-Conorma (a = 0.4, b = 0.7)*
> Considera un sistema que evalúa el éxito potencial de una campaña de marketing basado en dos factores: conocimiento de marca y atractivo del producto. Cada factor se evalúa en una escala de 0 a 1, donde 0 representa ningún potencial y 1 representa alto potencial. Se tienen así lo siguientes valores para cada criterio:
> - a = 0.4 representa la calificación de conocimiento de marca (40% sobre 100%)
> - b = 0.7 representa la calificación de atractivo del producto (70% sobre 100%)
> Interpretación: aplicando el Producto T-conorma (C(0.4, 0.7) = 0.82) indica que el éxito potencial general de la campaña, considerando tanto factores de marca como de producto, es del 82%. Esto sugiere que el potencial general es mayor que las calificaciones individuales, reflejando la naturaleza de "unión" de la T-conorma
*Máximo T-conorma (a = 0.6, b = 0.8)*
> Imagina un sistema que evalúa la efectividad de un tratamiento médico experimental basado en dos criterios: reducción del dolor y mejora de la movilidad. Cada criterio se evalúa en una escala de 0 a 1, donde 0 representa ninguna mejora y 1 representa una mejora significativa. Se tienen así lo siguientes valores para cada criterio:
> - a = 0.6 representa la reducción del dolor obtenida con el tratamiento (60% de mejora)
> - b = 0.8 representa la mejora de la movilidad lograda con el tratamiento (80% de mejora)
> Interpretación: aplicando el máximo T-conorma (C(0.6, 0.8) = 0.8) indica que la efectividad general del tratamiento, considerando tanto la reducción del dolor como la mejora de la movilidad, es del 80%. Esto sugiere que la efectividad general está determinada por el factor de calificación más alto (mejora de la movilidad), reflejando la naturaleza de "máximo" de la T-conorma.
### Funciones de membresía y modelamiento difuso
#### Funciones de membresía
La **función de membresía** representa la asociación entre un elemento y un conjunto difuso, asignando un grado de pertenencia a dicho elemento en relación con el conjunto difuso. En otras palabras, una función de membresía describe cómo un elemento pertenece a un conjunto difuso en un continuo que va desde 0 (no pertenencia) hasta 1 (pertenencia total).
Imaginemos que medimos la temperatura de una vivienda y queremos analizar el nivel de frío. De forma difusa se podría definir una función de membresía como la presentada en la imagen:
![Ejemplo Funciones Membresia](imagenes/capitulo4/funcion_membresia_ejemplo.png){#fig-funcion_membresia_ejemplo}
Existen diferentes funciones de membresía, las más destacadas son:
- **Triangular**: esta función de membresía se caracteriza por tener una forma triangular. Tiene tres parámetros principales: *a*, *b* y *c*, que definen los límites del triángulo en el eje *x* donde *a* es el punto de inicio del triángulo, *b* es el punto medio y *c* es el punto final. La función aumenta linealmente desde 0 hasta 1, alcanzando su máximo en *𝑏* y luego disminuye linealmente hasta 0. Es ampliamente utilizada debido a su simplicidad y facilidad de interpretación.
- **Trapezoidal**: la función de membresía trapezoidal tiene cuatro parámetros principales: *a*, *b*, *c* y *d*, que definen los límites del trapecio en el eje *x*. La función aumenta linealmente desde 0 hasta 1 entre *a* y *b*, permanece constante en 1 entre *b* y *c*, y luego disminuye linealmente hasta 0 entre *c* y *d*. Esta función es útil cuando se necesita modelar conjuntos con rangos más amplios o cuando se requiere un grado de pertenencia constante en un intervalo.
- **Gaussiana**: la función de membresía gaussiana tiene una forma de campana y se utiliza comúnmente para representar variables que tienen una distribución normal. Esta función tiene dos parámetros principales: $\mu$, que representa la media de la distribución y $\sigma$ que controla su anchura de la distribución. A medida que *x* se aleja de $\mu$ el grado de pertenencia disminuye gradualmente. La función gaussiana es útil para modelar conjuntos con distribuciones simétricas y para suavizar transiciones entre conjuntos difusos.
- **Sigmoidal**: se utiliza para representar relaciones no lineales entre variables. Esta función tiene tres parámetros principales: *a*, *b* y *c*, que controlan la pendiente y la posición de la curva sigmoidal. A medida que *x* aumenta desde *a* hasta *b* el grado de pertenencia aumenta gradualmente. Luego, a medida que *x* aumenta desde *b* hasta *c* el grado de pertenencia disminuye gradualmente. La función sigmoidal es útil para modelar relaciones complejas entre conjuntos difusos y es especialmente importante en problemas de inferencia difusa y control difuso.
![Funciones Membresia](imagenes/capitulo4/funciones_membresia.png){#fig-funciones_membresia}
#### Modelado difuso
El **modelado difuso** implica la creación de un sistema que puede interpretar y procesar información imprecisa o incierta mediante reglas lingüísticas. En este contexto, las reglas se componen de antecedentes y consecuentes.
- **Antecedentes**: son las condiciones o variables de entrada que se evalúan para determinar qué acciones o decisiones tomar. Estos antecedentes se expresan en términos lingüísticos, como "temperatura fría" o "velocidad rápida".
El antecedente se expresa mediante una función de pertenencia difusa $\mu_A(x)$, donde *A* es el nombre del antecedente y *x* es el valor de la variable de entrada. Así, si *A* es la temperatura y *x* es el valor de la temperatura en grados Celsius entonces $\mu_A(x)$ podría representar el grado de pertenencia de *x* a la categoría "frío", "templado" o "caliente".
- **Consecuentes**: son las acciones o decisiones que se toman en respuesta a las condiciones evaluadas en los antecedentes. Estos consecuentes también se expresan en términos lingüísticos y representan las salidas del sistema difuso. En el ejemplo del sistema de control de clima, los consecuentes podrían ser ajustes en el sistema de calefacción, ventilación o aire acondicionado.
Existen diferentes modelamientos de consecuentes, los más destacados son:
- `Mamdani`: los consecuentes de las reglas difusas se expresan como funciones de pertenencia difusas. Estas funciones representan la contribución de cada regla al resultado final del sistema difuso. Por lo general, estas funciones son conjuntos difusos que se solapan entre sí, lo que significa que una regla puede contribuir parcialmente al resultado final del sistema. Por ejemplo, si tenemos un conjunto de reglas difusas del tipo *SI temperatura es fría Y humedad es alta ENTONCES activar calefacción*, el consecuente para esta regla podría expresarse como una función de pertenencia difusa $\mu_C(y)$, donde *y* es el valor de la salida. Así, esta función de pertenencia podría representar la intensidad de la calefación.
- `Sugeno`: los consecuentes de las reglas difusas se expresan como funciones lineales de la forma $y = ax + b$, donde *x* es el valor de la entrada e *y* es el valor de la salida. En lugar de producir conjuntos difusos como en el enfoque de Mamdani, las reglas Sugeno generan un valor numérico preciso como resultado; lo que hace que el enfoque de Sugeno sea más adecuado para aplicaciones donde se requiere una salida numérica clara y no una respuesta lingüística. Así, continuando con el ejemplo anterior, *SI temperatura es fría Y humedad es alta ENTONCES activar calefacción con intensidad 0.7*, el consecuente para esta regla podría expresarse como $y=0.7x$.
- `Tsukamoto`: los consecuentes se expresan como funciones de pertenencia escalonadas. Estas funciones asignan un grado de pertenencia a diferentes conjuntos difusos de salida en función de la evaluación de los antecedentes. El enfoque de Tsukamoto es útil cuando se necesita un sistema de control que pueda adaptarse a cambios en las condiciones de entrada de manera suave y gradual.
::: {style="text-align:center;"}
$$ y = \frac{{\sum_{i=1}^{n} \mu_{A_i}(x_i) \cdot \text{V}_i}}{{\sum_{i=1}^{n} \mu_{A_i}(x_i)}} $$
:::
donde $y$ es el valor de salida, $\mu_A(x)$ es la función de pertenencia difusa del antecedente $A_i$ evaluada en el valor de entrada, $V_i$ es el valor asociado al consecuente para el antecedente $A_i$ y *n* es el número de antecedentes en la regla
Esta fórmula calcula el valor de salida *𝑦* como una combinación ponderada de los valores asociados $V_i$ para cada antecedente, donde los pesos están determinados por las funciones de pertenencia de los antecedentes. La suma de las funciones de pertenencia de los antecedentes normaliza el resultado, asegurando que esté en el rango adecuado.
> Estas fórmulas proporcionan una manera matemática de expresar los antecedentes y consecuentes en un sistema de lógica difusa, lo que permite modelar y controlar sistemas basados en reglas lingüísticas y condiciones difusas.
La salida de un sistema difuso es, por tanto, un conjunto difuso. En cambio, los sistemas de control se relacionan con el mundo externo a través de valores exactos lo que implica, a la hora de hacer inferencia, es necesario realizar un proceso de **defuzzificación**. Así, los principales métodos de defuzzificación son:
- `Centroide`: calcula el centro de gravedad del conjunto difuso ponderado. Consiste en encontrar el punto en el eje de salida donde el área bajo la curva del conjunto difuso es dividida en dos áreas iguales. Matemáticamente, el valor de salida *y* se calcula como
::: {style="text-align:center;"}
$$ y = \frac{{\sum_{i=1}^{n} u_i \cdot x_i}}{{\sum_{i=1}^{n} u_i}} $$
:::
- `Máximo Valor de Membresía`: selecciona el valor de salida con el grado de membresía más alto. Es decir, el valor de salida es el punto en el conjunto difuso donde la membresía es máxima. Así, $y = max(u(x)$
- `Media de los Máximos`: se calcula la media de todos los puntos en el conjunto difuso donde el grado de membresía es máximo. Es útil cuando hay múltiples picos en el conjunto difuso
- `Primera Máxima y Última Máxima`: se selecciona el primer y último punto de máximo grado de membresía, respectivamente, como valores de salida
- `Bisectriz`: este método divide el conjunto difuso en dos áreas de igual tamaño y toma el punto medio entre los dos puntos de intersección de la bisectriz con el conjunto difuso
## Ejemplos prácticos
Para ilustrar un ejemplo de control de sistemas difuso, consideremos un sistema difuso simple para controlar la potencia de un calefactor basado en la temperatura ambiente. Supongamos que queremos mantener la temperatura en una habitación alrededor de un valor de referencia.
**Definición de las Variables Difusas** - `Temperatura`: esta variable representa la temperatura medida en grados Celsius. Creamos una variable de entrada temperatura que abarca valores desde 0 hasta 100 grados Celsius. - `Potencia`: esta variable representa el nivel de potencia de la calefacción. Creamos una variable de salida potencia que también abarca valores desde 0 hasta 100.
**Funciones de Membresía** - `Temperatura`: se definen tres funciones de membresía para la temperatura: "fría", "templada" y "caliente". - `Potencia`: de igual forma, se definen tres funciones de membresía para la potencia de la calefacción: "baja", "media" y "alta".
**Reglas difusas** Se define el sistema de reglas difusas: - Si la temperatura es fría, entonces la potencia debe ser alta - Si la temperatura es alta, entonces la potencia debe ser baja - Si la temperatura es templada, entonces la potencia debe ser media
**Sistema de Control** Se crea un conjunto de reglas difusas a partir de cada una de las reglas definidas previsamente. Este conjunto de reglas representa el conocimiento difuso que guiará el comportamiento del sistema de control.
**Controlador Difuso** Se crea un controlador difuso que toma como argumento el sistema de control difuso creado anteriormente. Este controlador simula el comportamiento del sistema de control difuso y nos permite introducir valores de entrada (temperatura) para obtener el valor de salida (potencia) correspondiente.
**Simulación** Se simula un cambio en la temperatura estableciendo un valor para la variable de entrada temperatura en el controlador difuso. Luego, se calcula el valor de salida (nivel de potencia) utilizando el método compute() del controlador.
Finalmente, el código python:
``` python
import numpy as np
import skfuzzy as fuzz
from skfuzzy import control as ctrl
# Definición de las variables de entrada y salida
temperatura = ctrl.Antecedent(np.arange(0, 101, 1), 'temperatura')
potencia = ctrl.Consequent(np.arange(0, 101, 1), 'potencia')
# Definición de las funciones de membresía para la temperatura
temperatura['fría'] = fuzz.trimf(temperatura.universe, [0, 0, 50])
temperatura['templada'] = fuzz.trimf(temperatura.universe, [0, 50, 100])
temperatura['caliente'] = fuzz.trimf(temperatura.universe, [50, 100, 100])
# Definición de las funciones de membresía para la potencia
potencia['baja'] = fuzz.trimf(potencia.universe, [0, 0, 50])
potencia['media'] = fuzz.trimf(potencia.universe, [0, 50, 100])
potencia['alta'] = fuzz.trimf(potencia.universe, [50, 100, 100])
# Reglas difusas
regla1 = ctrl.Rule(temperatura['fría'], potencia['alta'])
regla2 = ctrl.Rule(temperatura['templada'], potencia['media'])
regla3 = ctrl.Rule(temperatura['caliente'], potencia['baja'])
# Sistema de control difuso
sistema_control = ctrl.ControlSystem([regla1, regla2, regla3])
controlador = ctrl.ControlSystemSimulation(sistema_control)
# Simulación de un cambio en la temperatura
controlador.input['temperatura'] = 25 # Temperatura medida en grados Celsius
# Computar el resultado
controlador.compute()
# Visualización del resultado
print("Nivel de potencia de la calefacción:", controlador.output['potencia'])
```
A continuación, se representan e interpretan la funciones de membresía antecedente y consecuente del sistema de control:
``` python
# Detalle de las funciones de membresía (antecedente y consecuente)
temperatura.view(sim=controlador)
```
``` python
potencia.view(sim=controlador)
```
## Fuzzy C-Means
Los algoritmos de clustering difuso, como el Fuzzy C-Means (FCM), son esenciales en la agrupación de datos donde la pertenencia de un punto a un clúster no es binaria, sino que se modela como un grado de pertenencia difuso. FCM asigna a cada punto un grado de pertenencia a todos los clústeres, lo que permite una representación más flexible de la estructura de los datos. En lugar de asignar cada punto a un único clúster, FCM asigna grados de pertenencia que indican la probabilidad de que un punto pertenezca a cada clúster. Esto es especialmente útil cuando los datos pueden pertenecer a múltiples clústeres simultáneamente, o cuando la frontera entre clústeres no es clara. La importancia de los algoritmos de clustering difuso radica en su capacidad para manejar la incertidumbre en los datos y proporcionar una agrupación más completa y flexible que los métodos tradicionales de clustering.
> A diferencia del algoritmo C-Means clásico, que trabaja con una partición dura, FCM realiza una partición suave del conjunto de datos. En tal partición los datos pertenecen en algún grado a todos los clusters.
El siguiente código muestra cómo hacer un C-Means difuso:
``` python
import pandas as pd
import numpy as np
import seaborn as sns
import matplotlib.pyplot as plt
import skfuzzy as fuzz
from sklearn import datasets
# Carga de datos de Iris desde scikit-learn
iris = datasets.load_iris()
X = iris.data # Características
y = iris.target # Etiquetas
# Gráfico de dispersión para visualizar los clusters originales según las dos primeras características (sépalo)
g = sns.scatterplot(x=X[:, 0], y=X[:, 1], hue=y, palette="Set2")
plt.title('Sépalo: longitud vs tamaño'), plt.xlabel('Longitud'), plt.ylabel('Ancho')
plt.show()
# Algoritmo Fuzzy C-Means
# Es necesario que los datos estén en un array 2D, por lo que se utiliza la función "reshape"
X2 = np.reshape(X.T, (X.shape[1], X.shape[0])) # Cambio de forma de los datos
# Aplicación del modelo Fuzzy C-Means
cntr, u, u0, d, jm, p, fpc = fuzz.cluster.cmeans(X2, c=3, m=2, error=0.005, maxiter=1000, init=None, seed=111)
```
Entre los parámetros que devuelve la función `fuzz.cluster.cmeans` se pueden citar: - `cntr` es el centro de los clusters - `u` es el grado de membresía - `u0` es la matriz inicial de membresía - `d` es la matriz de distancias euclidiana
``` python
# Centro de los clusters
cluster_centers_df = pd.DataFrame(cntr, columns=['Longitud Sépalo', 'Ancho Sépalo', 'Longitud Pétalo', 'Ancho Pétalo'],
index=['Cluster 1', 'Cluster 2', 'Cluster 3'])
cluster_centers_df
```
``` python
# Grados de membresía (probabilidad de pertenencia a cada cluster)
membership_df = pd.DataFrame(u.T, columns=['Cluster 1', 'Cluster 2', 'Cluster 3'])
membership_df.head()
```
``` python
# Gráfico de dispersión para visualizar los clusters obtenidos
g = sns.scatterplot(x=X[:, 0], y=X[:, 1], hue=np.argmax(u.T, axis=1), palette="Set2") # Asignación de colores según cluster
plt.title('Sépalo: longitud vs tamaño'), plt.xlabel('Longitud'), plt.ylabel('Ancho')
plt.show()
```
## Fuzzy Matching
El **Fuzzy Matching** es una técnica utilizada para comparar cadenas de texto y determinar su grado de similitud, incluso cuando hay diferencias ortográficas, tipográficas u otras variaciones entre ellas. Esta técnica identifica la probabilidad de que dos registros sean realmente coincidentes en función de si coinciden o no en diferentes identificadores. Los identificadores elegidos y el peso asignado constituyen la base de la *Concordancia Difusa*. Así, cuando los parámetros son demasiado amplios, se encontrarán más coincidencias, pero también aumentarán las posibilidades de "falsos positivos".
Existen diversas métricas a utilizar en Fuzzy Matching siendo la más destacada la `distancia de Levenshtein` pero existen otras como se indican a continuación:
- `Distancia de Levenshtein`: mide el número mínimo de operaciones necesarias para convertir una cadena en otra. Las operaciones incluyen inserción, eliminación o sustitución de caracteres
- `Distancia Damerau-Levenshtein`: similar a la distancia de Levenshtein, pero también considera la transposición de caracteres adyacentes como una operación válida
- `Distancia Jaro-Winkler`: diseñada para comparar cadenas de texto cortas, tiene en cuenta la frecuencia de los caracteres y la posición de las coincidencias comunes
- `Distancia del teclado`: evalúa la similitud entre dos cadenas basándose en la proximidad de las teclas en un teclado estándar
- `Distancia Kullback-Leibler`: utilizada en comparaciones de cadenas de texto que representan distribuciones de probabilidad
> La **concordancia difusa** es crucial para identificar similitudes entre registros, permitiendo la gestión eficiente de datos duplicados. La distancia de Levenshtein es fundamental en este proceso, al calcular la diferencia entre dos cadenas de caracteres, siendo especialmente útil para detectar errores ortográficos y variaciones en la escritura. Más sobre Distancia de Levenshtein en el siguiente enlace: <https://es.wikipedia.org/wiki/Distancia_de_Levenshtein>
### Ejemplo 1
``` python
from fuzzywuzzy import fuzz
# Función para comparar nombres completos
def comparar_nombres(nombre1, nombre2):
# Usamos el ratio completo para comparar nombres
ratio = fuzz.ratio(nombre1.lower(), nombre2.lower())
return ratio
# Ejemplo de comparación de nombres
nombre1 = "Juan Pérez"
nombre2 = "Juan Pérez Gómez"
nombre3 = "Pedro López"
nombre4 = "María Pérez Gómez"
print("Comparación de nombres completos:")
print(f"{nombre1} vs {nombre2}: {comparar_nombres(nombre1, nombre2)}")
print(f"{nombre1} vs {nombre3}: {comparar_nombres(nombre1, nombre3)}")
print(f"{nombre2} vs {nombre4}: {comparar_nombres(nombre2, nombre4)}")
```
### Ejemplo 2
``` python
# Función para comparar direcciones de vivienda
def comparar_direcciones(direccion1, direccion2):
# Usamos el ratio parcial para comparar direcciones
ratio = fuzz.partialratio(direccion1.lower(), direccion2.lower())
return ratio
# Ejemplo de comparación de direcciones
direccion1 = "123 Calle Principal, Madrid"
direccion2 = "245 Calle Principal, Madrid"
direccion3 = "456 Calle Secundaria, Ávila"
direccion4 = "123 Calle Principal, Ávila"
print("\nComparación de direcciones de vivienda:")
print(f"{direccion1} vs {direccion2}: {comparar_direcciones(direccion1, direccion2)}")
print(f"{direccion1} vs {direccion3}: {comparar_direcciones(direccion1, direccion3)}")
print(f"{direccion2} vs {direccion4}: {comparar_direcciones(direccion2, direccion4)}")
print(f"{direccion3} vs {direccion4}: {comparar_direcciones(direccion3, direccion4)}")
```
En la biblioteca **fuzzywuzzy**, las funciones `ratio()` y `partial_ratio()` se utilizan para calcular la similitud entre dos cadenas de texto. La diferencia principal radica en cómo se realiza la comparación y qué tan flexible es cada método en términos de coincidencia.
- `ratio()`: esta función calcula la similitud entre dos cadenas comparándolas en su totalidad. Compara las cadenas carácter por carácter y devuelve un valor que representa la similitud entre las dos cadenas en términos de coincidencia exacta. Es útil cuando se busca una coincidencia exacta entre las cadenas y se prefiere una comparación estricta.
- `partial_ratio()`: esta función calcula la similitud entre dos cadenas tomando en cuenta solo una parte de las mismas. Se utiliza para buscar subcadenas que coincidan parcialmente entre las cadenas de texto. Esto significa que puede ser más útil cuando se enfrenta a casos donde las cadenas pueden tener variaciones menores o cuando se desea encontrar coincidencias incluso si las cadenas difieren en longitud o tienen diferencias menores.
Entonces, para decidir cuál usar, considera la naturaleza de los datos y el nivel de flexibilidad para realizar la comparación. Suele usarse `ratio()` cuando se necesita una comparación estricta y quieras asegurarte de que las cadenas coincidan exactamente; mientras que `partial_ratio()` se emplea cuando se buscan coincidencias parciales o flexibles entre las cadenas (p.e: cuando solo importan importa una parte específica de las mismas).