Está en la página 1de 39

29/8/2019 Inferencia_Difusa_v1.

Lógica difusa (Fuzzy logic)

Modelos de inferencia en lógica difusa


A continuación veremos dos tipos de inferencia:

el modelo de Mamdani y
el modelo de TSK (Takagi, Sugeno y Kang).

Modelo de Inferencia de Mamdani


Overview y terminología
Como sabemos Fuzzy Logic es una metodología basada en la idea de que la "veracidad" de algo se puede expresar en un continuo. Esto
quiere decir que algo no es verdadero o falso de manera puntual, sino que más bien las cosas en realidad se deben concebir como
parcialmente verdaderas o parcialmente falsas.

El método de inferencia difusa de Mandami es posiblemente es el método más ampliamente utilizado, propuesto por Ebrahim Mamdani
en 1975. El proceso se realiza en cuatro pasos:

1. Fuzificación de las variables de entrada.


2. Evaluación de las reglas.
3. Agregación de las salidas de las reglas.
4. Defuzificación.

La inferencia difusa puede definirse como el proceso que consiste en obtener un valor de salida o resultado para un(os) valor(es) de
entrada empleando como punto de partida la teoría de conjuntos difusos. Para este propósito se utilizan las reglas difusas. Una regla
difusa, también conocidad como regla de producción difusa if-then, es expresada simbólicamente como:

IF <proposición difusa> THEN <proposición difusa>

localhost:8888/notebooks/prueba101/IA-1/Inferencia_Difusa_v1.1.ipynb 1/39
29/8/2019 Inferencia_Difusa_v1.1

Donde puede ser una proposición difusa atómica o compuesta, esto es, una variable en combinación con una variable lingüística.
Podemos definir una proposición sencilla de este tipo mediante:

p: IF X es A THEN Y es B

El antecedente y consecuente de una regla puede tener múltiples partes. Veremos a continuación cómo se trabaja con estos formatos de
reglas. En los sistemas de reglas clásicos, si el antecedente es cierto, el consecuente es también cierto.

En sistemas fuzzy donde el antecedente es difuso, todas las reglas se ejecutan parcialmente, y el consecuente es cierto en cierto grado,
esto es, si el antecedente es cierto con cierto grado de pertenencia, el consecuente es cierto también el cierto grado.

x
Veamos a continuación un ejemplo de uso empleando tres reglas. Estas reglas usan como variables lingüísticas (financiación del
y z X A1 , A2 , A3
proyecto), (plantilla del proyecto) y (riesgo). Los conjuntos definidos sobre el dominio de son (inadecuado, marginal,
adecuado), sobre el dominio de con Y B1 , B2 Z C1 , C2 C3
(pequeña, grande) y sobre el universo del discurso de son y (bajo, normal y
alto)

Como ya indicamos, un sistema de control difuso vincula variables difusas utilizando un conjunto de reglas. Estas reglas son simplemente
asignaciones que describen cómo una o más variables difusas se relacionan con otras variables difusas. Estos se expresan en términos
de una declaración IF-THEN; la parte IF se llama antecedente y la parte ENTONCES es la consecuente. La matemática exacta
relacionada con cómo se usa una regla para calcular el valor del consecuente basado en el valor del antecedente está fuera del alcance
de este documento.

Deshabilitar los mensajes de advertencias (warnings)

In [0]: 1 import warnings


2 warnings.filterwarnings("ignore")

Instalar la librería de lógica difusa

localhost:8888/notebooks/prueba101/IA-1/Inferencia_Difusa_v1.1.ipynb 2/39
29/8/2019 Inferencia_Difusa_v1.1

In [2]: 1 !pip install -U scikit-fuzzy

Requirement already up-to-date: scikit-fuzzy in /usr/local/lib/python3.6/dist-packages (0.4.1)


Requirement already satisfied, skipping upgrade: networkx>=1.9.0 in /usr/local/lib/python3.6/dist-packages (fro
m scikit-fuzzy) (2.3)
Requirement already satisfied, skipping upgrade: numpy>=1.6.0 in /usr/local/lib/python3.6/dist-packages (from s
cikit-fuzzy) (1.16.4)
Requirement already satisfied, skipping upgrade: scipy>=0.9.0 in /usr/local/lib/python3.6/dist-packages (from s
cikit-fuzzy) (1.3.1)
Requirement already satisfied, skipping upgrade: decorator>=4.3.0 in /usr/local/lib/python3.6/dist-packages (fr
om networkx>=1.9.0->scikit-fuzzy) (4.4.0)

In [0]: 1 import numpy as np


2 import skfuzzy as fuzz
3 import matplotlib.pyplot as plt

Universos de discurso
x = financiación del proyecto, valores reales de 1 a 100 por ciento
y = plantilla del proyecto, valores reales de 1 a 100 por ciento y
z = riesgo, valores reales de 1 a 100 por ciento
In [0]: 1 x = np.arange(0, 101, 1)
2 y = np.arange(0, 101, 1)
3 z = np.arange(0, 101, 1)

Conjuntos difusos

x y
Los conjuntos definidos sobre el dominio de son A1, A2, A3 (inadecuado, marginal, adecuado), sobre el dominio de y son B1, B2
z
(pequeña, grande) y sobre el universo del discurso de son C1, C2 y C3 (bajo, normal y alto).

Reglas:
Regla 1: IF x IS A3 OR y IS B1 THEN z IS C1
Regla 2: IF x IS A2 AND y IS B2 THEN z IS C2
localhost:8888/notebooks/prueba101/IA-1/Inferencia_Difusa_v1.1.ipynb 3/39
29/8/2019 Inferencia_Difusa_v1.1

Regla 3: IF x IS A1 THEN z IS C3

Procedimiento

1. Fuzificación.
El primer paso consiste en tomar los valores crisp de las entradas (financiacion-del-proyecto y plantilla-del-proyecto) y determinar el grado
de pertenencia de estas entradas a los conjuntos difusos asociados.

El valor crisp naturalmente estará limitado en el universo del discurso de la variable. En nuestro caso, x e y estarán limitadas al universo
X Y
del discurso de e respectivamente.

In [0]: 1 A1 = fuzz.trapmf(x, [0, 0, 25, 45]) # inadecuado,


2 A2 = fuzz.trimf(x, [31, 50, 69]) # marginal,
3 A3 = fuzz.trapmf(x, [55, 75, 100, 100]) # adecuado
4
5 # Plantilla del proyecto en personas
6 B1 = fuzz.trapmf(y, [0, 0, 24, 64]) # pequeña,
7 B2 = fuzz.trapmf(y, [26, 74, 100, 100]) # grande
8
9 # Porcentaje de riesgo
10 C1 = fuzz.trapmf(z, [0, 0, 16, 24]) # bajo,
11 C2 = fuzz.trapmf(z, [16, 28, 65, 80]) # normal
12 C3 = fuzz.trapmf(z, [70, 80, 100, 100]) # alto

localhost:8888/notebooks/prueba101/IA-1/Inferencia_Difusa_v1.1.ipynb 4/39
29/8/2019 Inferencia_Difusa_v1.1

In [6]: 1 # Visualizar estos universos y funciones de membresía (membership functions)


2 fig, (ax0, ax1, ax2) = plt.subplots(nrows=3, figsize=(8, 9))
3
4 # grafica los puntos correspondientes a los conjuntos difusos de la financiación del proyecto
5 ax0.plot(x, A1, 'b', linewidth=1.5, label='inadecuado')
6 # grafica los puntos
7 ax0.plot(x, A2, 'g', linewidth=1.5, label='marginal')
8 # grafica los puntos
9 ax0.plot(x, A3, 'r', linewidth=1.5, label='adecuado')
10 ax0.set_title('Financiacion del proyecto')
11 ax0.legend()
12
13 # grafica los puntos correspondientes a los conjuntos difusos de la plantilla del proyecto
14 ax1.plot(y, B1, 'b', linewidth=1.5, label='pequeña')
15 # grafica los puntos
16 ax1.plot(y, B2, 'g', linewidth=1.5, label='grande')
17 ax1.set_title('Plantilla del proyecto')
18 ax1.legend()
19
20 # grafica los puntos correspondientes a los conjuntos difusos del riesgo del proyecto
21 ax2.plot(z, C1, 'b', linewidth=1.5, label='bajo')
22 # grafica los puntos
23 ax2.plot(z, C2, 'g', linewidth=1.5, label='normal')
24 # grafica los puntos
25 ax2.plot(z, C3, 'r', linewidth=1.5, label='alto')
26 ax2.set_title('Riesgo del proyecto')
27 ax2.legend()

Out[6]: <matplotlib.legend.Legend at 0x7fbddfffc9b0>

localhost:8888/notebooks/prueba101/IA-1/Inferencia_Difusa_v1.1.ipynb 5/39
29/8/2019 Inferencia_Difusa_v1.1

En nuestro caso vamos a suponer que un experto asigna a x un valor del 35 % (financiacion-proyecto) y a y un valor de 60 % (plantilla-
proyecto).

x
Como se puede ver estos valores Crisp se corresponden con los valores de pertenecia de A1 y A2 (en el caso de ) con 0.5 y 0.2, y con
los valores de B1 y B2 (en el caso de y) con 0.1 y 0.7 respectivamente. De este modo cada entrada se fuzzifica sobre todas las funciones
de pertenencia utilizadas en la reglas difusas.

localhost:8888/notebooks/prueba101/IA-1/Inferencia_Difusa_v1.1.ipynb 6/39
29/8/2019 Inferencia_Difusa_v1.1

In [0]: 1 presupuesto = 35
2 plantilla = 60

localhost:8888/notebooks/prueba101/IA-1/Inferencia_Difusa_v1.1.ipynb 7/39
29/8/2019 Inferencia_Difusa_v1.1

In [8]: 1 # Visualizar estos universos y funciones de membresía (membership functions)


2 fig, (ax0, ax1, ax2) = plt.subplots(nrows=3, figsize=(8, 9))
3
4 # grafica los puntos correspondientes a los conjuntos difusos de la financiación del proyecto
5 ax0.plot(x, A1, 'b', linewidth=1.5, label='inadecuado')
6 # grafica los puntos
7 ax0.plot(x, A2, 'g', linewidth=1.5, label='marginal')
8 # grafica los puntos
9 ax0.plot(x, A3, 'r', linewidth=1.5, label='adecuado')
10 ax0.vlines(presupuesto, 0, 1, color='chocolate', linewidth=2.5, label='presupuesto=35')
11 ax0.set_title('Financiacion del proyecto')
12 ax0.legend()
13
14 # grafica los puntos correspondientes a los conjuntos difusos de la plantilla del proyecto
15 ax1.plot(y, B1, 'b', linewidth=1.5, label='pequeña')
16 # grafica los puntos
17 ax1.plot(y, B2, 'g', linewidth=1.5, label='grande')
18 ax1.vlines(plantilla, 0, 1, color='chocolate', linewidth=2.5, label='plantilla=60')
19 ax1.set_title('Plantilla del proyecto')
20 ax1.legend()
21
22 # grafica los puntos correspondientes al riesgo del proyecto
23 ax2.plot(z, C1, 'b', linewidth=1.5, label='bajo')
24 # grafica los puntos
25 ax2.plot(z, C2, 'g', linewidth=1.5, label='normal')
26 # grafica los puntos
27 ax2.plot(z, C3, 'r', linewidth=1.5, label='alto')
28 ax2.set_title('Riesgo del proyecto')
29 ax2.legend()

Out[8]: <matplotlib.legend.Legend at 0x7fbddd685860>

localhost:8888/notebooks/prueba101/IA-1/Inferencia_Difusa_v1.1.ipynb 8/39
29/8/2019 Inferencia_Difusa_v1.1

2. Evaluación de Reglas
Tomamos las entradas anteriores y se aplican a los antecedentes de las reglas difusas. Si una regla tiene múltiples antecedentes, se
utiliza el operador AND u OR para obtener un único número que represente el resultado de la evaluación. Este número (el valor de
verdad) se aplica al consecuente. Para evaluar la disjución (operador OR) habitualmente se emplea la T-Conorma estándar (máximo),
definida como hemos visto como: µA∪B (x) = max[µA (x), µB (x)]
. De igual forma, para el AND se usa habitualmente la T-Norma estándar
del mínimo.

localhost:8888/notebooks/prueba101/IA-1/Inferencia_Difusa_v1.1.ipynb 9/39
29/8/2019 Inferencia_Difusa_v1.1

Finalmente el resultado de la evaluación del antecedente se alpica al consecuente, aplicando un recorte o escalado según el valor de
verdad del antecedente. El método más comunmente utilizado es el recorte (clipping) que corta el consecuente con el valor de verdad del
antecedente. El escalado proporciona un valor más preciso, preservando la forma original del conjunto difuso

localhost:8888/notebooks/prueba101/IA-1/Inferencia_Difusa_v1.1.ipynb 10/39
29/8/2019 Inferencia_Difusa_v1.1

In [9]: 1 # Necesitamos la activación de nuestras funciones de membresía difusas en


2 # estos valores.
3 # Los valores exactos de 35 y 60 no existen en nuestros universos...
4 # ¡Para esto es para lo que existe fuzz.interp_membership!
5 xA1 = fuzz.interp_membership(x, A1, presupuesto)
6 print("Verificación de membresía de x = %2f con A1 (inadecuado) = %2f" % (presupuesto, xA1))
7 xA2 = fuzz.interp_membership(x, A2, presupuesto)
8 print("Verificación de membresía de x = %2f con A2 (marginal) = %2f" % (presupuesto, xA2))
9 xA3 = fuzz.interp_membership(x, A3, presupuesto)
10 print("Verificación de membresía de x = %2f con A3 (adecuado) = %2f" % (presupuesto, xA3))
11
12 yB1 = fuzz.interp_membership(y, B1, plantilla)
13 print("Verificación de membresía de y = %2f con B1 (pequeña) = %2f" % (plantilla, yB1))
14 yB2 = fuzz.interp_membership(y, B2, plantilla)
15 print("Verificación de membresía de y = %2f con B2 (grande) = %2f" % (plantilla, yB2))
16
17 # Ahora tomamos nuestras reglas y las aplicamos.
18 # La regla 1 se refiere a IF x is A3 OR y is B1 THEN z is C1
19 # El operador OR significa que tomamos el máximo de estos dos valores.
20 active_rule1 = np.fmax(xA3, yB1)
21
22 # Ahora aplicamos esto recortando la parte superior de la salida correspondiente
23 # a la función de membresía con `np.fmin`
24 zC1 = np.fmin(active_rule1, C1) # eliminado por completo a 0
25
26 # Para la regla 2 IF x is A2 AND y is B2 THEN z is C2
27 # El operador AND significa que tomamos el mínimo de estos dos valores.
28 active_rule2 = np.fmin(xA2, yB2)
29
30 # Ahora aplicamos esto recortando la parte superior de la salida correspondiente
31 # a la función de membresía con `np.fmin`
32 zC2 = np.fmin(active_rule2, C2) # eliminado por completo a 0
33
34 # Para la regla 3, IF x is A1 THEN z is C3
35 # con una propina alta
36 active_rule3 = np.fmin(xA1, C3)
37 zC3 = active_rule3
38
39 z0 = np.zeros_like(z)
40

Verificación de membresía de x = 35.000000 con A1 (inadecuado) = 0.500000

localhost:8888/notebooks/prueba101/IA-1/Inferencia_Difusa_v1.1.ipynb 11/39
29/8/2019 Inferencia_Difusa_v1.1

Verificación de membresía de x = 35.000000 con A2 (marginal) = 0.210526


Verificación de membresía de x = 35.000000 con A3 (adecuado) = 0.000000
Verificación de membresía de y = 60.000000 con B1 (pequeña) = 0.100000
Verificación de membresía de y = 60.000000 con B2 (grande) = 0.708333

Regla 1

Regla 1: IF x IS A3 OR y IS B1 THEN z IS C1 → (SI x es adecuado ENTONCES z es bajo)

localhost:8888/notebooks/prueba101/IA-1/Inferencia_Difusa_v1.1.ipynb 12/39
29/8/2019 Inferencia_Difusa_v1.1

In [10]: 1 # Visualizar estos universos y funciones de membresía (membership functions)


2 fig, (ax0, ax1, ax2) = plt.subplots(nrows=3, figsize=(8, 9))
3
4 # grafica los puntos
5 ax0.plot(x, A1, 'b', linewidth=1.5, label='inadecuado')
6 # grafica los puntos
7 ax0.plot(x, A2, 'g', linewidth=1.5, label='marginal')
8 # grafica los puntos
9 ax0.plot(x, A3, 'r', linewidth=3.5, label='adecuado')
10 ax0.vlines(presupuesto, 0, 1, color='chocolate', linewidth=2.5, label='presupuesto=35')
11 ax0.set_title('Financiacion del proyecto')
12 ax0.legend()
13
14 # linestyles : {'solid', 'dashed', 'dashdot', 'dotted'}
15
16 # grafica los puntos
17 ax1.plot(y, B1, 'b', linewidth=3.5, label='pequeña')
18 # grafica los puntos
19 ax1.plot(y, B2, 'g', linewidth=1.5, label='grande')
20 ax1.vlines(plantilla, 0, 1, color='chocolate', linewidth=2.5, label='plantilla=60')
21 ax1.hlines(yB1,min(y),plantilla, color='black', linewidth=1.5, linestyles='dashed')
22 ax1.set_title('Plantilla del proyecto')
23 ax1.legend()
24
25 # grafica los puntos correspondientes al riesgo del proyecto y al consecuente de la regla 1
26 ax2.plot(z, C1, 'b', linewidth=1.5, label='bajo')
27 # grafica los puntos
28 ax2.plot(z, C2, 'g', linewidth=1.5, label='normal')
29 # grafica los puntos
30 ax2.plot(z, C3, 'r', linewidth=1.5, label='alto')
31 ax2.fill_between(z, z0, zC1, facecolor='g', alpha=0.5)
32 ax2.plot(z, C1, 'g', linewidth=0.5, linestyle='--')
33 ax2.set_title('Riesgo del proyecto')
34 ax2.legend()

Out[10]: <matplotlib.legend.Legend at 0x7fbddd555f98>

localhost:8888/notebooks/prueba101/IA-1/Inferencia_Difusa_v1.1.ipynb 13/39
29/8/2019 Inferencia_Difusa_v1.1

Regla 2

Regla 2: IF x IS A2 AND y IS B2 THEN z IS C2 → (SI x es marginal ENTONCES z es normal)

localhost:8888/notebooks/prueba101/IA-1/Inferencia_Difusa_v1.1.ipynb 14/39
29/8/2019 Inferencia_Difusa_v1.1

In [11]: 1 # Visualizar estos universos y funciones de membresía (membership functions)


2 fig, (ax0, ax1, ax2) = plt.subplots(nrows=3, figsize=(8, 9))
3
4 # grafica los puntos
5 ax0.plot(x, A1, 'b', linewidth=1.5, label='inadecuado')
6 # grafica los puntos
7 ax0.plot(x, A2, 'g', linewidth=3.5, label='marginal')
8 # grafica los puntos
9 ax0.plot(x, A3, 'r', linewidth=1.5, label='adecuado')
10 ax0.vlines(presupuesto, 0, 1, color='chocolate', linewidth=2.5, label='presupuesto=35')
11 ax0.hlines(xA2,min(x),presupuesto, color='black', linewidth=1.5, linestyles='dashed')
12 ax0.set_title('Financiacion del proyecto')
13 ax0.legend()
14
15 # grafica los puntos
16 ax1.plot(y, B1, 'b', linewidth=1.5, label='pequeña')
17 # grafica los puntos
18 ax1.plot(y, B2, 'g', linewidth=3.5, label='grande')
19 ax1.vlines(plantilla, 0, 1, color='chocolate', linewidth=2.5, label='plantilla=60')
20 ax1.hlines(yB2,min(y),plantilla, color='black', linewidth=1.5, linestyles='dashed')
21 ax1.set_title('Plantilla del proyecto')
22 ax1.legend()
23
24 # grafica los puntos correspondientes al riesgo del proyecto y al consecuente de la regla 2
25 ax2.plot(z, C1, 'b', linewidth=1.5, label='bajo')
26 # grafica los puntos
27 ax2.plot(z, C2, 'g', linewidth=1.5, label='normal')
28 # grafica los puntos
29 ax2.plot(z, C3, 'r', linewidth=1.5, label='alto')
30 ax2.fill_between(z, z0, zC2, facecolor='g', alpha=0.5)
31 ax2.plot(z, C2, 'g', linewidth=0.5, linestyle='--')
32 ax2.set_title('Riesgo del proyecto')
33 ax2.legend()

Out[11]: <matplotlib.legend.Legend at 0x7fbddd42d710>

localhost:8888/notebooks/prueba101/IA-1/Inferencia_Difusa_v1.1.ipynb 15/39
29/8/2019 Inferencia_Difusa_v1.1

Regla 3

Regla 3: IF x IS A1 THEN z IS C3 → (SI x es inadecuado ENTONCES z es alto)

localhost:8888/notebooks/prueba101/IA-1/Inferencia_Difusa_v1.1.ipynb 16/39
29/8/2019 Inferencia_Difusa_v1.1

In [12]: 1 # Visualizar estos universos y funciones de membresía (membership functions)


2 fig, (ax0, ax1, ax2) = plt.subplots(nrows=3, figsize=(8, 9))
3
4 # grafica los puntos del conjunto difuso Financiación del proyecto
5 ax0.plot(x, A1, 'b', linewidth=3.5, label='inadecuado')
6 # grafica los puntos
7 ax0.plot(x, A2, 'g', linewidth=1.5, label='marginal')
8 # grafica los puntos
9 ax0.plot(x, A3, 'r', linewidth=1.5, label='adecuado')
10 ax0.vlines(presupuesto, 0, 1, color='chocolate', linewidth=2.5, label='presupuesto=35')
11 ax0.hlines(xA1,min(x),presupuesto, color='black', linewidth=1.5, linestyles='dashed')
12 ax0.set_title('Financiacion del proyecto')
13 ax0.legend()
14
15 # grafica los puntos correspondientes al riesgo del proyecto y al consecuente de la regla 3
16 ax2.plot(z, C1, 'b', linewidth=1.5, label='bajo')
17 # grafica los puntos
18 ax2.plot(z, C2, 'g', linewidth=1.5, label='normal')
19 # grafica los puntos
20 ax2.plot(z, C3, 'r', linewidth=1.5, label='alto')
21 ax2.fill_between(z, z0, zC3, facecolor='g', alpha=0.5)
22 ax2.plot(z, C3, 'g', linewidth=0.5, linestyle='--')
23 ax2.set_title('Riesgo del proyecto')
24 ax2.legend()

Out[12]: <matplotlib.legend.Legend at 0x7fbddd291f98>

localhost:8888/notebooks/prueba101/IA-1/Inferencia_Difusa_v1.1.ipynb 17/39
29/8/2019 Inferencia_Difusa_v1.1

3. Agregación de las salidas


La agregación es el proceso de unificación de las salidas de todas las reglas; es decir, se combinan las funciones de pertenencia de todos
los consecuentes previamente recortados o escalados, combinando para obtener un único conjunto difuso por cada variable de salida.
Visualización de la agregación de consecuentes

localhost:8888/notebooks/prueba101/IA-1/Inferencia_Difusa_v1.1.ipynb 18/39
29/8/2019 Inferencia_Difusa_v1.1

In [13]: 1 # Visualizar estos


2 fig, ax0 = plt.subplots(figsize=(8, 3))
3
4 ax0.fill_between(z, z0, zC1, facecolor='b', alpha=0.5)
5 ax0.plot(z, C1, 'b', linewidth=0.5, linestyle='--', )
6 ax0.fill_between(z, z0, zC2, facecolor='g', alpha=0.5)
7 ax0.plot(z, C2, 'g', linewidth=0.5, linestyle='--')
8 ax0.fill_between(z, z0, zC3, facecolor='r', alpha=0.5)
9 ax0.plot(z, C3, 'r', linewidth=0.5, linestyle='--')
10 ax0.set_title('Salida de actividad de membresía')
11
12 # Apagar los ejes superior / derecho
13 for ax in (ax0,):
14 ax.spines['top'].set_visible(False)
15 ax.spines['right'].set_visible(False)
16 ax.get_xaxis().tick_bottom()
17 ax.get_yaxis().tick_left()
18
19 plt.tight_layout()

In [0]: 1 # Agregue las tres funciones de membresía de salida juntas


2 aggregated = np.fmax(zC1, np.fmax(zC2, zC3))
3 #aggregated

4. Defuzificación

localhost:8888/notebooks/prueba101/IA-1/Inferencia_Difusa_v1.1.ipynb 19/39
29/8/2019 Inferencia_Difusa_v1.1

El resultado final habitualmente es necesario expresarlo mediante un valor crisp. En esta etapa se toma como entrada el conjunto difuso
anteriormente obtenido para dar un valor de salida. Existen varios métodos de defuzificación, pero probablemente el más ampliamente
usado es el centroide; que calcula el punto donde una línea vertical divide el conjunto en dos areas con igual masa.

localhost:8888/notebooks/prueba101/IA-1/Inferencia_Difusa_v1.1.ipynb 20/39
29/8/2019 Inferencia_Difusa_v1.1

In [15]: 1 # Calcular el resultado defuzificado


2 riesgo = fuzz.defuzz(z, aggregated, 'centroide')
3 riesgo_activation = fuzz.interp_membership(z, aggregated, riesgo) # for plot
4 print("Resultado defuzificado calculado para el riesgo:", riesgo)
5
6 # Visualizar estos
7 fig, ax0 = plt.subplots(figsize=(8, 3))
8
9 ax0.fill_between(z, z0, zC1, facecolor='b', alpha=0.5)
10 ax0.plot(z, C1, 'b', linewidth=0.5, linestyle='--', )
11 ax0.fill_between(z, z0, zC2, facecolor='g', alpha=0.5)
12 ax0.plot(z, C2, 'g', linewidth=0.5, linestyle='--')
13 ax0.fill_between(z, z0, zC3, facecolor='r', alpha=0.5)
14 ax0.plot(z, C3, 'r', linewidth=0.5, linestyle='--')
15 ax0.plot([riesgo, riesgo], [0, riesgo_activation], 'k', linewidth=1.5, alpha=0.9)
16 ax0.set_title('Salida de actividad de membresía')
17
18 # Apagar los ejes superior / derecho
19 for ax in (ax0,):
20 ax.spines['top'].set_visible(False)
21 ax.spines['right'].set_visible(False)
22 ax.get_xaxis().tick_bottom()
23 ax.get_yaxis().tick_left()
24
25 plt.tight_layout()

Resultado defuzificado calculado para el riesgo: 63.5680162740337

localhost:8888/notebooks/prueba101/IA-1/Inferencia_Difusa_v1.1.ipynb 21/39
29/8/2019 Inferencia_Difusa_v1.1

Conclusión
Por lo que la conclusión con el Modelo de Mandami para la configuración de datos de entradas de financiación del proyecto del
35% y plantilla del proyecto del 60%, es que el riesgo asociado del proyecto es normal.

Modelo de inferencia TSK (Takagi, Sugeno y Kang).


En 1985, Takagi y Sugeno aportan a la teoría del control difuso un nuevo método llamado de Takagi-Sugeno-Kang (TSK), como
alternativa al método de Mamdani. Se trata de un método basado en reglas difusas pero en el que el consecuente no nos da un conjunto
difuso sino una serie de funciones lineales. Este modelo es útil para sistemas complejos y de dimensiones mayores que los que podemos
resolver por el método de Mamdani.

La principal diferencia que presenta el método TSK respecto al de Mamdani es que no es necesario realizar un proceso de
defuzzificación. Esto se debe al hecho de que no obtenemos ningún conjunto difuso sino un conjunto de funciones lineales. Así, en el
método TSK podemos obtener directamente el valor de salida de sistema.

Universos de discurso
x = financiación del proyecto, valores reales de 1 a 100 por ciento
y = plantilla del proyecto, valores reales de 1 a 100 por ciento y
z = riesgo, valores reales de 1 a 100 por ciento
In [0]: 1 x = np.arange(0, 101, 1)
2 y = np.arange(0, 101, 1)
3 z = np.arange(0, 101, 1)

Procedimiento

1. Fuzificación.
El primer paso como con Mandami, consiste en tomar los valores crisp de las entradas (financiacion-del-proyecto y plantilla-del-proyecto)
y determinar el grado de pertenencia de estas entradas a los conjuntos difusos asociados.

localhost:8888/notebooks/prueba101/IA-1/Inferencia_Difusa_v1.1.ipynb 22/39
29/8/2019 Inferencia_Difusa_v1.1

El valor crisp naturalmente estará limitado en el universo del discurso de la variable. En nuestro caso, x e y estarán limitadas al universo
X Y
del discurso de e respectivamente.

In [0]: 1 A1 = fuzz.trapmf(x, [0, 0, 25, 45]) # inadecuado,


2 A2 = fuzz.trimf(x, [31, 50, 69]) # marginal,
3 A3 = fuzz.trapmf(x, [55, 75, 100, 100]) # adecuado
4
5 # Plantilla del proyecto en personas
6 B1 = fuzz.trapmf(y, [0, 0, 24, 64]) # pequeña,
7 B2 = fuzz.trapmf(y, [26, 74, 100, 100]) # grande
8
9 # Porcentaje de riesgo
10 k1 = 10
11 k2 = 20
12 k3 = 50
13 C1 = fuzz.interp_membership([k1,k2,k3], [1,0,0], k1) # bajo,
14 C2 = fuzz.interp_membership([k1,k2,k3], [0,1,0], k2) # normal
15 C3 = fuzz.interp_membership([k1,k2,k3], [0,0,1], k3) # alto

localhost:8888/notebooks/prueba101/IA-1/Inferencia_Difusa_v1.1.ipynb 23/39
29/8/2019 Inferencia_Difusa_v1.1

In [18]: 1 # Visualizar estos universos y funciones de membresía (membership functions)


2 fig, (ax0, ax1, ax2) = plt.subplots(nrows=3, figsize=(8, 9))
3
4 # grafica los puntos
5 ax0.plot(x, A1, 'b', linewidth=1.5, label='inadecuado')
6 # grafica los puntos
7 ax0.plot(x, A2, 'g', linewidth=1.5, label='marginal')
8 # grafica los puntos
9 ax0.plot(x, A3, 'r', linewidth=1.5, label='adecuado')
10 ax0.set_title('Financiacion del proyecto')
11 ax0.legend()
12
13 # grafica los puntos
14 ax1.plot(y, B1, 'b', linewidth=1.5, label='pequeña')
15 # grafica los puntos
16 ax1.plot(y, B2, 'g', linewidth=1.5, label='grande')
17 ax1.set_title('Plantilla del proyecto')
18 ax1.legend()
19
20 # grafica los puntos
21
22 C = [C1, C2, C3]
23 labels = ['bajo', 'normal', 'alto']
24 colors = ['b', 'r', 'g']
25 xvals = [k1, k2, k3]
26
27 for xv, yc, label, color in zip(xvals, C, labels, colors):
28 ax2.vlines(xv, 0, yc, label=label, color=color)
29 ax2.set_ylabel('Fuzzy membership')
30 #ax2.set_xlabel('Universe variable (Power motor)\n')
31 ax2.set_xlim(0.0, 100.1)
32 ax2.set_ylim(-0.1, 1.1)
33 ax2.set_title('Riesgo del proyecto')
34 ax2.legend()

Out[18]: <matplotlib.legend.Legend at 0x7fbddd099ac8>

localhost:8888/notebooks/prueba101/IA-1/Inferencia_Difusa_v1.1.ipynb 24/39
29/8/2019 Inferencia_Difusa_v1.1

En nuestro caso vamos a suponer que un experto asigna a x un valor del 35 % (financiacion-proyecto) y a y un valor de 60 % (plantilla-
proyecto).

x
Como se puede ver estos valores Crisp se corresponden con los valores de pertenecia de A1 y A2 (en el caso de ) con 0.5 y 0.2, y con
los valores de B1 y B2 (en el caso de y) con 0.1 y 0.7 respectivamente. De este modo cada entrada se fuzzifica sobre todas las funciones
de pertenencia utilizadas en la reglas difusas.

localhost:8888/notebooks/prueba101/IA-1/Inferencia_Difusa_v1.1.ipynb 25/39
29/8/2019 Inferencia_Difusa_v1.1

In [0]: 1 presupuesto = 35
2 plantilla = 60

localhost:8888/notebooks/prueba101/IA-1/Inferencia_Difusa_v1.1.ipynb 26/39
29/8/2019 Inferencia_Difusa_v1.1

In [20]: 1 # Visualizar estos universos y funciones de membresía (membership functions)


2 fig, (ax0, ax1, ax2) = plt.subplots(nrows=3, figsize=(8, 9))
3
4 # grafica los puntos
5 ax0.plot(x, A1, 'b', linewidth=1.5, label='inadecuado')
6 # grafica los puntos
7 ax0.plot(x, A2, 'g', linewidth=1.5, label='marginal')
8 # grafica los puntos
9 ax0.plot(x, A3, 'r', linewidth=1.5, label='adecuado')
10 ax0.vlines(presupuesto, 0, 1, color='chocolate', linewidth=2.5, label='presupuesto=35')
11 ax0.set_title('Financiacion del proyecto')
12 ax0.legend()
13
14 # grafica los puntos
15 ax1.plot(y, B1, 'b', linewidth=1.5, label='pequeña')
16 # grafica los puntos
17 ax1.plot(y, B2, 'g', linewidth=1.5, label='grande')
18 ax1.vlines(plantilla, 0, 1, color='chocolate', linewidth=2.5, label='plantilla=60')
19 ax1.set_title('Plantilla del proyecto')
20 ax1.legend()
21
22 # grafica los puntos
23 C = [C1, C2, C3]
24 labels = ['bajo', 'normal', 'alto']
25 colors = ['b', 'r', 'g']
26 xvals = [k1, k2, k3]
27
28 for xv, yc, label, color in zip(xvals, C, labels, colors):
29 ax2.vlines(xv, 0, yc, label=label, color=color)
30 ax2.set_ylabel('Fuzzy membership')
31 #ax2.set_xlabel('Universe variable (Power motor)\n')
32 ax2.set_xlim(0.0, 100.1)
33 ax2.set_ylim(-0.1, 1.1)
34 ax2.set_title('Riesgo del proyecto')
35 ax2.legend()

Out[20]: <matplotlib.legend.Legend at 0x7fbddcf54f28>

localhost:8888/notebooks/prueba101/IA-1/Inferencia_Difusa_v1.1.ipynb 27/39
29/8/2019 Inferencia_Difusa_v1.1

2. Evaluación de Reglas
Tomamos las entradas anteriores y se aplican a los antecedentes de las reglas difusas. Si una regla tiene múltiples antecedentes, se
utiliza el operador AND u OR para obtener un único número que represente el resultado de la evaluación. Este número (el valor de
verdad) se aplica al consecuente. Para evaluar la disjución (operador OR) habitualmente se emplea la T-Conorma estándar (máximo),
definida como hemos visto como: µA∪B (x) = max[µA (x), µB (x)]
. De igual forma, para el AND se usa habitualmente la T-Norma estándar
del mínimo.

localhost:8888/notebooks/prueba101/IA-1/Inferencia_Difusa_v1.1.ipynb 28/39
29/8/2019 Inferencia_Difusa_v1.1

Finalmente el resultado de la evaluación del antecedente se alpica al consecuente, aplicando un recorte o escalado según el valor de
verdad del antecedente. El método más comunmente utilizado es el recorte (clipping) que corta el consecuente con el valor de verdad del
antecedente. El escalado proporciona un valor más preciso, preservando la forma original del conjunto difuso

localhost:8888/notebooks/prueba101/IA-1/Inferencia_Difusa_v1.1.ipynb 29/39
29/8/2019 Inferencia_Difusa_v1.1

In [21]: 1 # Necesitamos la activación de nuestras funciones de membresía difusas en


2 # estos valores.
3 # Los valores exactos de 35 y 60 no existen en nuestros universos...
4 # ¡Para esto es para lo que existe fuzz.interp_membership!
5 xA1 = fuzz.interp_membership(x, A1, presupuesto)
6 print("Verificación de membresía de x = %2f con A1 (inadecuado) = %2f" % (presupuesto, xA1))
7 xA2 = fuzz.interp_membership(x, A2, presupuesto)
8 print("Verificación de membresía de x = %2f con A2 (marginal) = %2f" % (presupuesto, xA2))
9 xA3 = fuzz.interp_membership(x, A3, presupuesto)
10 print("Verificación de membresía de x = %2f con A3 (adecuado) = %2f" % (presupuesto, xA3))
11
12 yB1 = fuzz.interp_membership(y, B1, plantilla)
13 print("Verificación de membresía de y = %2f con B1 (pequeña) = %2f" % (plantilla, yB1))
14 yB2 = fuzz.interp_membership(y, B2, plantilla)
15 print("Verificación de membresía de y = %2f con B2 (grande) = %2f" % (plantilla, yB2))
16
17 # Ahora tomamos nuestras reglas y las aplicamos.
18 # La regla 1 se refiere a IF x is A3 OR y is B1 THEN z is C1
19 # El operador OR significa que tomamos el máximo de estos dos valores.
20 active_rule1 = np.fmax(xA3, yB1)
21
22 # Ahora aplicamos esto recortando la parte superior de la salida correspondiente
23 # a la función de membresía con `np.fmin`
24 zC1 = np.fmin(active_rule1, C1) # eliminado por completo a 0
25
26 # Para la regla 2 IF x is A2 AND y is B2 THEN z is C2
27 # El operador AND significa que tomamos el mínimo de estos dos valores.
28 active_rule2 = np.fmin(xA2, yB2)
29
30 # Ahora aplicamos esto recortando la parte superior de la salida correspondiente
31 # a la función de membresía con `np.fmin`
32 zC2 = np.fmin(active_rule2, C2) # eliminado por completo a 0
33
34 # Para la regla 3, IF x is A1 THEN z is C3
35 # con una propina alta
36 active_rule3 = np.fmin(xA1, C3)
37 zC3 = active_rule3
38
39 z0 = np.zeros_like(z)
40

Verificación de membresía de x = 35.000000 con A1 (inadecuado) = 0.500000

localhost:8888/notebooks/prueba101/IA-1/Inferencia_Difusa_v1.1.ipynb 30/39
29/8/2019 Inferencia_Difusa_v1.1

Verificación de membresía de x = 35.000000 con A2 (marginal) = 0.210526


Verificación de membresía de x = 35.000000 con A3 (adecuado) = 0.000000
Verificación de membresía de y = 60.000000 con B1 (pequeña) = 0.100000
Verificación de membresía de y = 60.000000 con B2 (grande) = 0.708333

Regla 1

Regla 1: IF x IS A3 OR y IS B1 THEN z IS C1 → (SI x es adecuado ENTONCES z es bajo)

localhost:8888/notebooks/prueba101/IA-1/Inferencia_Difusa_v1.1.ipynb 31/39
29/8/2019 Inferencia_Difusa_v1.1

In [22]: 1 # Visualizar estos universos y funciones de membresía (membership functions)


2 fig, (ax0, ax1, ax2) = plt.subplots(nrows=3, figsize=(8, 9))
3
4 # grafica los puntos
5 ax0.plot(x, A1, 'b', linewidth=1.5, label='inadecuado')
6 # grafica los puntos
7 ax0.plot(x, A2, 'g', linewidth=1.5, label='marginal')
8 # grafica los puntos
9 ax0.plot(x, A3, 'r', linewidth=3.5, label='adecuado')
10 ax0.vlines(presupuesto, 0, 1, color='chocolate', linewidth=2.5, label='presupuesto=35')
11 ax0.set_title('Financiacion del proyecto')
12 ax0.legend()
13
14 # grafica los puntos
15 ax1.plot(y, B1, 'b', linewidth=3.5, label='pequeña')
16 # grafica los puntos
17 ax1.plot(y, B2, 'g', linewidth=1.5, label='grande')
18 ax1.vlines(plantilla, 0, 1, color='chocolate', linewidth=2.5, label='plantilla=60')
19 ax1.hlines(yB1,min(y),plantilla, color='black', linewidth=1.5, linestyles='dashed')
20 ax1.set_title('Plantilla del proyecto')
21 ax1.legend()
22
23 # grafica los puntos correspondientes al riesgo del proyecto y al consecuente de la regla 1
24 C = [C1, C2, C3]
25 labels = ['bajo', 'normal', 'alto']
26 colors = ['b', 'r', 'g']
27 xvals = [k1, k2, k3]
28
29 for xv, yc, label, color in zip(xvals, C, labels, colors):
30 ax2.vlines(xv, 0, yc, label=label, color=color)
31 ax2.set_ylabel('Fuzzy membership')
32 ax2.vlines(k1, 0, zC1, color='black', linewidth=3.5)
33 #ax2.set_xlabel('Universe variable (Power motor)\n')
34 ax2.set_xlim(0.0, 100.1)
35 ax2.set_ylim(-0.1, 1.1)
36 ax2.set_title('Riesgo del proyecto')
37 ax2.legend()

Out[22]: <matplotlib.legend.Legend at 0x7fbddce64c18>

localhost:8888/notebooks/prueba101/IA-1/Inferencia_Difusa_v1.1.ipynb 32/39
29/8/2019 Inferencia_Difusa_v1.1

Regla 2

Regla 2: IF x IS A2 AND y IS B2 THEN z IS C2 → (SI x es marginal ENTONCES z es normal)

localhost:8888/notebooks/prueba101/IA-1/Inferencia_Difusa_v1.1.ipynb 33/39
29/8/2019 Inferencia_Difusa_v1.1

In [23]: 1 # Visualizar estos universos y funciones de membresía (membership functions)


2 fig, (ax0, ax1, ax2) = plt.subplots(nrows=3, figsize=(8, 9))
3
4 # grafica los puntos
5 ax0.plot(x, A1, 'b', linewidth=1.5, label='inadecuado')
6 # grafica los puntos
7 ax0.plot(x, A2, 'g', linewidth=3.5, label='marginal')
8 # grafica los puntos
9 ax0.plot(x, A3, 'r', linewidth=1.5, label='adecuado')
10 ax0.vlines(presupuesto, 0, 1, color='chocolate', linewidth=2.5, label='presupuesto=35')
11 ax0.hlines(xA2,min(x),presupuesto, color='black', linewidth=1.5, linestyles='dashed')
12 ax0.set_title('Financiacion del proyecto')
13 ax0.legend()
14
15 # linestyles : {'solid', 'dashed', 'dashdot', 'dotted'}
16
17 # grafica los puntos
18 ax1.plot(y, B1, 'b', linewidth=1.5, label='pequeña')
19 # grafica los puntos
20 ax1.plot(y, B2, 'g', linewidth=3.5, label='grande')
21 ax1.vlines(plantilla, 0, 1, color='chocolate', linewidth=2.5, label='plantilla=60')
22 ax1.hlines(yB2,min(y),plantilla, color='black', linewidth=1.5, linestyles='dashed')
23 ax1.set_title('Plantilla del proyecto')
24 ax1.legend()
25
26 # grafica los puntos correspondientes al riesgo del proyecto y al consecuente de la regla 2
27 C = [C1, C2, C3]
28 labels = ['bajo', 'normal', 'alto']
29 colors = ['b', 'r', 'g']
30 xvals = [k1, k2, k3]
31
32 for xv, yc, label, color in zip(xvals, C, labels, colors):
33 ax2.vlines(xv, 0, yc, label=label, color=color)
34 ax2.set_ylabel('Fuzzy membership')
35 ax2.vlines(k2, 0, zC2, color='black', linewidth=3.5)
36 #ax2.set_xlabel('Universe variable (Power motor)\n')
37 ax2.set_xlim(0.0, 100.1)
38 ax2.set_ylim(-0.1, 1.1)
39 ax2.set_title('Riesgo del proyecto')
40 ax2.legend()

Out[23]: <matplotlib.legend.Legend at 0x7fbddcd2f7b8>

localhost:8888/notebooks/prueba101/IA-1/Inferencia_Difusa_v1.1.ipynb 34/39
29/8/2019 Inferencia_Difusa_v1.1

Regla 3

Regla 3: IF x IS A1 THEN z IS C3 → (SI x es inadecuado ENTONCES z es alto)

localhost:8888/notebooks/prueba101/IA-1/Inferencia_Difusa_v1.1.ipynb 35/39
29/8/2019 Inferencia_Difusa_v1.1

In [24]: 1 # Visualizar estos universos y funciones de membresía (membership functions)


2 fig, (ax0, ax1, ax2) = plt.subplots(nrows=3, figsize=(8, 9))
3
4 # grafica los puntos
5 ax0.plot(x, A1, 'b', linewidth=3.5, label='inadecuado')
6 # grafica los puntos
7 ax0.plot(x, A2, 'g', linewidth=1.5, label='marginal')
8 # grafica los puntos
9 ax0.plot(x, A3, 'r', linewidth=1.5, label='adecuado')
10 ax0.vlines(presupuesto, 0, 1, color='chocolate', linewidth=2.5, label='presupuesto=35')
11 ax0.hlines(xA1,min(x),presupuesto, color='black', linewidth=1.5, linestyles='dashed')
12 ax0.set_title('Financiacion del proyecto')
13 ax0.legend()
14
15 # grafica los puntos correspondientes al riesgo del proyecto y al consecuente de la regla 3
16 C = [C1, C2, C3]
17 labels = ['bajo', 'normal', 'alto']
18 colors = ['b', 'r', 'g']
19 xvals = [k1, k2, k3]
20
21 for xv, yc, label, color in zip(xvals, C, labels, colors):
22 ax2.vlines(xv, 0, yc, label=label, color=color)
23 ax2.vlines(k3, 0, zC3, color='black', linewidth=3.5)
24 ax2.set_ylabel('Fuzzy membership')
25 #ax2.set_xlabel('Universe variable (Power motor)\n')
26 ax2.set_xlim(0.0, 100.1)
27 ax2.set_ylim(-0.1, 1.1)
28 ax2.set_title('Riesgo del proyecto')
29 ax2.legend()

Out[24]: <matplotlib.legend.Legend at 0x7fbddcbfd5c0>

localhost:8888/notebooks/prueba101/IA-1/Inferencia_Difusa_v1.1.ipynb 36/39
29/8/2019 Inferencia_Difusa_v1.1

3. Agregación de las salidas


La agregación es el proceso de unificación de las salidas de todas las reglas; es decir, se combinan las funciones de pertenencia de todos
los consecuentes previamente recortados o escalados, combinando para obtener un único conjunto difuso por cada variable de salida.
Visualización de la agregación de consecuentes

localhost:8888/notebooks/prueba101/IA-1/Inferencia_Difusa_v1.1.ipynb 37/39
29/8/2019 Inferencia_Difusa_v1.1

In [25]: 1 # Visualizar estos


2 fig, ax0 = plt.subplots(figsize=(8, 3))
3
4 C = [C1, C2, C3]
5 zCs = [zC1, zC2, zC3]
6 labels = ['bajo', 'normal', 'alto']
7 colors = ['b', 'r', 'g']
8 xvals = [k1, k2, k3]
9
10 for xv, yc, zC, label, color in zip(xvals, C, zCs, labels, colors):
11 ax0.vlines(xv, 0, yc, label=label, color=color)
12 ax0.vlines(xv, 0, zC, color='black', linewidth=3.5)
13 ax0.set_ylabel('Fuzzy membership')
14 #ax0.set_xlabel('Universe variable (Power motor)\n')
15
16 ax0.set_xlim(0.0, 100.1)
17 ax0.set_ylim(-0.1, 1.1)
18 ax0.set_title('Riesgo del proyecto')
19 ax0.legend()

Out[25]: <matplotlib.legend.Legend at 0x7fbde48342e8>

In [26]: 1 # Agregue las tres funciones de membresía de salida juntas


2 aggregated = np.fmax(zC1, np.fmax(zC2, zC3))
3 aggregated

Out[26]: 0.5

localhost:8888/notebooks/prueba101/IA-1/Inferencia_Difusa_v1.1.ipynb 38/39
29/8/2019 Inferencia_Difusa_v1.1

Conclusión
Por lo que la conclusión con el Modelo de TSK para la configuración de datos de entradas de financiación del proyecto del 35% y
plantilla del proyecto del 60%, es que el riesgo asociado del proyecto es alto.

In [ ]: 1

localhost:8888/notebooks/prueba101/IA-1/Inferencia_Difusa_v1.1.ipynb 39/39

También podría gustarte