Package: inferfuzzy
InferfuzzyAutor:Leynier Gutiérrez GonzálezGrupo:C412Correo:l.gutierrez@estudiantes.matcom.uh.cuTutor:Dr. Yudivian Almeida,Universidad de La HabanaCódigo:https://github.com/leynier/inferfuzzyInferfuzzyes una biblioteca dePythonpara implementarSistemas de Inferencia Difusa.Características del Sistema de InferenciaLa biblioteca contiene implementados los métodos de inferenciaMamdaniyLarsen. Pero es posible implementar partiendo de una base común otros métodos de inferencia.Los métodos de inferencia reciben una función dedefuzzificación. La biblioteca contiene implementadasCentroide,Bisectriz,Máximo Central,Máximo más pequeñoyMáximo más grande.Durante el proceso de definición de los conjuntos difusos esto requieren una función de membresía que puede ser implementada o utilizar una de las disponibles en la biblioteca.Funciones de membresía implementadas enInferfuzzy:Función GammaFunción Lambda o TriangularFunción Pi o TrapezoidalFunción SFunción ZFunción GaussianaLaT-conormyT-normutilizadas en las reglas de inferencia, así como el método de agregación de los conjuntos son posibles de sobrescribir, por defecto, sonmínimo,máximoymáximorespectivamente.Es posible definir más de una variable de salida para el sistema de inferencia difusa implementado en la biblioteca.Estructura de la ImplementaciónLa implementación se sostiene sobre 7 clases fundamentales:MembershipBaseSetBaseVarBaseRulePredicateVarSetInferenceSystemMembershipEs la clase encargada de representar una función de membresía junto a los puntos (llamadositemsinternamente)classMembership:def__init__(self,function:Callable[[Any],Any],items:list):self.function=functionself.items=itemsdef__call__(self,value:Any):returnself.function(value)BaseSetEs la clase encargada de representar un conjunto difuso. Recibe como parámetros un objeto de tipoMembershiprepresentando la función de membresía del conjunto y un método de agregación.classBaseSet:def__init__(self,name:str,membership:Membership,aggregation:Callable[[Any,Any],Any],):self.name=nameself.membership=membershipself.aggregation=aggregationdef__add__(self,arg:"BaseSet"):memb=Membership(lambdax:self.aggregation(self.membership(x),arg.membership(x),),self.membership.items+arg.membership.items,)returnBaseSet(f"({self.name})_union_({arg.name})",memb,aggregation=self.aggregation,)BaseVarEs la clase encargada de representar una variable lingüística. Recibe como parámetros una función de unión, una función de intercepción y una lista de objetos de tipoBaseSetrepresentando los conjuntos difusos de la variable.classBaseVar:def__init__(self,name:str,union:Callable[[Any,Any],Any],inter:Callable[[Any,Any],Any],sets:Optional[List[BaseSet]]=None,):self.name=nameself.sets={set.name:setforsetinsets}ifsetselse{}self.union=unionself.inter=interdefinto(self,set:Union[BaseSet,str])->VarSet:set_name=set.nameifisinstance(set,BaseSet)elsesetifset_namenotinself.sets:raiseKeyError(f"Set{set_name}not found into var{self.name}")temp_set=self.sets[set_name]returnVarSet(self,temp_set,self.union,self.inter)BaseRuleEs la clase encargada de representar una regla de inferencia. Recibe como parámetro un objeto de tipoPredicaterepresentando el antecedente de la regla.classBaseRule:def__init__(self,antecedent:Predicate):self.antecedent=antecedentdef__call__(self,values:dict):raiseNotImplementedError()BaseRuleno contiene consecuencias porque las consecuencias de todos los tipos de reglas no son de la misma estructura. La claseRulehereda deBaseRuley representa las reglas en los que el sistema produce un conjunto o más como resultado.classRule(BaseRule):def__init__(self,antecedent:Predicate,consequences:List[VarSet]):super(Rule,self).__init__(antecedent)self.consequences=consequencesdefaggregate(self,set:BaseSet,value:Any)->BaseSet:raiseNotImplementedError()def__call__(self,values:dict):value=self.antecedent(values)return{consequence.var.name:self.aggregate(consequence.set,value,)forconsequenceinself.consequences}PredicateEs la clase encargada de representar a los antecedentes. De ella heredan cuatro clases:AndPredicate,OrPredicate,NotPredicateyVarSet. Las primeras tres para representar las relaciones lógicas de unión, intercepción y negación; y la última representa la inclusión de una variable en un determinado conjunto, siendo esta la clase básica para representar a los antecedentes.classPredicate:def__init__(self,union:Callable[[Any,Any],Any],inter:Callable[[Any,Any],Any],)->None:self.union=unionself.inter=interdef__call__(self,values:dict):raiseNotImplementedError()def__and__(self,other:"Predicate"):returnAndPredicate(self,other,self.union,self.inter)def__or__(self,other:"Predicate"):returnOrPredicate(self,other,self.union,self.inter)def__invert__(self):returnNotPredicate(self,self.union,self.inter)VarSetclassVarSet(Predicate):def__init__(self,var:"BaseVar",set:BaseSet,union:Callable[[Any,Any],Any],inter:Callable[[Any,Any],Any],):super(VarSet,self).__init__(union,inter)self.var=varself.set=setdef__call__(self,values:dict):returnself.set.membership(values[self.var.name])InferenceSystemEs la clase encargada de representar el sistema de inferencia. Recibe como parámetros las reglas y una función de defuzzificación y con el métodoinferpermite realizar la inferencia según los valores proveídos.classInferenceSystem:def__init__(self,rules:Optional[List[BaseRule]]=None,defuzz_func:Optional[Callable[[BaseSet],Any]]=None,):self.rules=rulesifruleselse[]self.defuzz_func=defuzz_funcdefinfer(self,values:dict,defuzz_func:Optional[Callable[[BaseSet],Any]]=None,)->Dict[str,Any]:ifnotself.rules:raiseException("Empty rules")ifself.defuzz_funcisNoneanddefuzz_funcisNone:raiseException("Defuzzification not found")func=self.defuzz_funcifdefuzz_funcisNoneelsedefuzz_funcset:Dict[str,BaseSet]=self.rules[0](values)forruleinself.rules[1:]:temp:Dict[str,BaseSet]=rule(values)forkeyintemp:set[key]+=temp[key]result:Dict[str,Any]={}forkeyinset:result[key]=func(set[key])returnresultEjemplo de como utilizar InferfuzzyComo ejemplo se utilizará el siguiente problema.Se desea inferir el por ciento de la cantidad de un determinado producto que se ha vendido en un día en un restaurante, cafetería, etc.Por ejemplo, el productoPollo, se desea conocer bajo determinadas condiciones que por ciento delPollosacado del almacén dispuesto para venderse ese día se termina vendiendo.Para la implementación se seleccionaron4variables lingüísticas. Las primeras3de entrada y la última de salida.Cantidad de platos o derivados del producto que se vende. Por ejemplo, retomando el ejemplo delPollo, si se venderíaPollo FritoyPollo Asado, la variable valdría2. A esta variable le llamaremosvariety.Baja:low <= 2. Función de Membresía: ZNormal:1 <= normal <= 5. Función de Membresía: GaussianaAlta:high >= 4. Función de Membresía: SPor ciento que representa la variablevarietydel total de platos o derivados de productos que se vende. Por ejemplo, si se vendePollo Frito,Pollo Asado,PescadoyCerdola variable valdría50. A esta variable se le llamarádiversity.Baja:low >= 70. Función de Membresía: GammaNormal:40 <= normal <= 80. Función de Membresía: LambdaAlta:high <= 50. Función de Membresía: LPor ciento de la utilización del local, si es100es que el local siempre está lleno, si es0es que no asiste ningún cliente al establecimiento. A esta variable se le llamaráclients.Baja:low <= 40. Función de Membresía: LNormal:30 <= normal <= 90. Función de Membresía: LambdaAlta:high >= 80. Función de Membresía: GammaPor ciento de la cantidad del producto que se vendió en el día, si es100fue se vendió todo al final del día, si es50fue que no se vendió la mitad de la cantidad. A esta variable se le llamarásales.Baja:low <= 60. Función de Membresía: LNormal:30 <= normal <= 90. Función de Membresía: LambdaAlta:high >= 90. Función de Membresía: GammaDeclaración de las variables lingüísticas y sus conjuntos difusos en Inferfuzzyvariety_var=Var("variety")variety_var+="low",ZMembership(1,2)variety_var+="normal",GaussianMembership(3,2)variety_var+="high",SMembership(4,6)diversity_percent_var=Var("diversity")diversity_percent_var+="low",GammaMembership(70,100)diversity_percent_var+="normal",LambdaMembership(40,60,80)diversity_percent_var+="high",LMembership(30,50)clients_percent_var=Var("clients")clients_percent_var+="low",LMembership(20,40)clients_percent_var+="normal",LambdaMembership(30,60,90)clients_percent_var+="high",GammaMembership(80,100)sales_percent_var=Var("sales")sales_percent_var+="low",LMembership(20,60)sales_percent_var+="normal",LambdaMembership(30,60,90)sales_percent_var+="high",GammaMembership(90,100)Gráficos de pertenencia de los conjuntos por cada variableReglas de InferenciavarietydiversityclientssaleslowlowlowlowlowlownormalnormallowlowhighhighlownormallowlowlownormalnormallowlownormalhighnormallowhighlowlowlowhighnormallowlowhighhighnormalnormallowlowlownormallownormalnormalnormallowhighhighnormalnormallowlownormalnormalnormalnormalnormalnormalhighnormalnormalhighlowlownormalhighnormallownormalhighhighnormalhighlowlowlowhighlownormalnormalhighlowhighhighhighnormallowlowhighnormalnormallowhighnormalhighhighhighhighlowlowhighhighnormallowhighhighhighnormalDeclaración de las Reglas de Inferencia en Inferfuzzymamdani=MamdaniSystem(defuzz_func=centroid_defuzzification,)mamdani+=(variety_var.into("low")&diversity_percent_var.into("low")&clients_percent_var.into("low")),sales_percent_var.into("low")mamdani+=(variety_var.into("low")&diversity_percent_var.into("low")&clients_percent_var.into("normal")),sales_percent_var.into("normal")mamdani+=(variety_var.into("low")&diversity_percent_var.into("low")&clients_percent_var.into("high")),sales_percent_var.into("high")mamdani+=(variety_var.into("low")&diversity_percent_var.into("normal")&clients_percent_var.into("low")),sales_percent_var.into("low")mamdani+=(variety_var.into("low")&diversity_percent_var.into("normal")&clients_percent_var.into("normal")),sales_percent_var.into("low")mamdani+=(variety_var.into("low")&diversity_percent_var.into("normal")&clients_percent_var.into("high")),sales_percent_var.into("normal")mamdani+=(variety_var.into("low")&diversity_percent_var.into("high")&clients_percent_var.into("low")),sales_percent_var.into("low")mamdani+=(variety_var.into("low")&diversity_percent_var.into("high")&clients_percent_var.into("normal")),sales_percent_var.into("low")mamdani+=(variety_var.into("low")&diversity_percent_var.into("high")&clients_percent_var.into("high")),sales_percent_var.into("normal")mamdani+=(variety_var.into("normal")&diversity_percent_var.into("low")&clients_percent_var.into("low")),sales_percent_var.into("low")mamdani+=(variety_var.into("normal")&diversity_percent_var.into("low")&clients_percent_var.into("normal")),sales_percent_var.into("normal")mamdani+=(variety_var.into("normal")&diversity_percent_var.into("low")&clients_percent_var.into("high")),sales_percent_var.into("high")mamdani+=(variety_var.into("normal")&diversity_percent_var.into("normal")&clients_percent_var.into("low")),sales_percent_var.into("low")mamdani+=(variety_var.into("normal")&diversity_percent_var.into("normal")&clients_percent_var.into("normal")),sales_percent_var.into("normal")mamdani+=(variety_var.into("normal")&diversity_percent_var.into("normal")&clients_percent_var.into("high")),sales_percent_var.into("normal")mamdani+=(variety_var.into("normal")&diversity_percent_var.into("high")&clients_percent_var.into("low")),sales_percent_var.into("low")mamdani+=(variety_var.into("normal")&diversity_percent_var.into("high")&clients_percent_var.into("normal")),sales_percent_var.into("low")mamdani+=(variety_var.into("normal")&diversity_percent_var.into("high")&clients_percent_var.into("high")),sales_percent_var.into("normal")mamdani+=(variety_var.into("high")&diversity_percent_var.into("low")&clients_percent_var.into("low")),sales_percent_var.into("low")mamdani+=(variety_var.into("high")&diversity_percent_var.into("low")&clients_percent_var.into("normal")),sales_percent_var.into("normal")mamdani+=(variety_var.into("high")&diversity_percent_var.into("low")&clients_percent_var.into("high")),sales_percent_var.into("high")mamdani+=(variety_var.into("high")&diversity_percent_var.into("normal")&clients_percent_var.into("low")),sales_percent_var.into("low")mamdani+=(variety_var.into("high")&diversity_percent_var.into("normal")&clients_percent_var.into("normal")),sales_percent_var.into("low")mamdani+=(variety_var.into("high")&diversity_percent_var.into("normal")&clients_percent_var.into("high")),sales_percent_var.into("high")mamdani+=(variety_var.into("high")&diversity_percent_var.into("high")&clients_percent_var.into("low")),sales_percent_var.into("low")mamdani+=(variety_var.into("high")&diversity_percent_var.into("high")&clients_percent_var.into("normal")),sales_percent_var.into("low")mamdani+=(variety_var.into("high")&diversity_percent_var.into("high")&clients_percent_var.into("high")),sales_percent_var.into("normal")De manera análoga sería para Larsen utilizando la claseLarsenSystem.ResultadosVarietyValue:10DiversityPercent:50ClientsPercent:50Mamdani:35.11%
Larsen32.82%

VarietyValue:2DiversityPercent:100ClientsPercent:100Mamdani:96.22%
Larsen100.00%

VarietyValue:4DiversityPercent:40ClientsPercent:100Mamdani:60.00%
Larsen60.00%Análisis de los ResultadosDe los resultados, se puede observar que los métodos de Mamdani y Larsen obtienen resultados similares. A primera vista no es posible validar si los resultados se asemejan a la realidad, para esto es imprescindible la colaboración de un experto en el tema para la correcta definición de las variables, la asignación de las funciones de membresía más correctas así́ como la definición de las reglas asociadas.ConclusionesEn este escrito se muestra las líneas generales de cómo utilizar Inferfuzzy, además de que muestra la capacidad de los sistemas de inferencia difusos para afrontar problemáticas donde la definición utilizando la lógica clásica no esté clara o que la solución utilizando esta sea demasiado engorrosa.ReferenciasSistemas de Control con Lógica Difusa: Métodos de Mamdani y de Takagi-Sugeno-Kang (TSK). Autor: Samuel Diciembre SanahujaTemas de Simulación. Autor: Dr. Luciano García GarridoFirst Course on Fuzzy Theory and Applications. Autor: Kwang H. Lee