SkFuzzy Giving "ValueError: Unexpected input: quality"

796 Views Asked by At

CODE SET BELOW WRITTEN IN PYTHON USING SKFUZZY FROM SCI-KIT LEARN:

import skfuzzy as fuzz
import numpy as np
from skfuzzy import control as ctrl
import matplotlib.pyplot as plt

# New Antecedent/Consequent objects hold universe variables and membership
# functions
quality = ctrl.Antecedent(np.arange(0, 11, 1),'quality')
service = ctrl.Antecedent(np.arange(0, 11, 1), 'service')
tip = ctrl.Consequent(np.arange(0, 26, 1), 'tip')

# Auto-membership function population is possible with .automf(3, 5, or 7)
quality.automf(5)
service.automf(5)

tip['lower'] = fuzz.gaussmf(tip.universe,5,2)
tip['low'] = fuzz.gaussmf(tip.universe,10,2)
tip['average'] = fuzz.gaussmf(tip.universe,15,2)
tip['high'] = fuzz.gaussmf(tip.universe,20,1)
tip['higher'] = fuzz.gaussmf(tip.universe,23,0.5)


rule1 = ctrl.Rule(((quality['poor'] | quality['mediocre']) and (service['poor'] | service['mediocre'])), tip['lower'])
rule2 = ctrl.Rule(((quality['average'] | quality['mediocre']) and (service['poor'] | service['mediocre'])), tip['low'])
rule3 = ctrl.Rule(((quality['average'] | quality['decent']) and (service['mediocre'] | service['average'])), tip['average'])
rule4 = ctrl.Rule(((quality['decent'] | quality['good']) and (service['poor'] | service['mediocre'])), tip['average'])
rule5 = ctrl.Rule(((quality['decent'] | quality['good']) and (service['decent'] | service['mediocre'])), tip['high'])
rule6 = ctrl.Rule(((quality['decent'] | quality['good']) and (service['decent'] | service['good'])), tip['higher'])


tipping_ctrl = ctrl.ControlSystem([rule1, rule2, rule3, rule4, rule5, rule6])

tipping = ctrl.ControlSystemSimulation(tipping_ctrl)


tipping.input['service'] = 10
tipping.input['quality'] = 10
tipping.compute()

print(tipping.output['tip'])
tip.view(sim=tipping)

GIVES FOLLOWING ERROR UPON EXECUTION OF THE CODE-SET. ERROR IS A VALUE ERROR, UNSURE WHY I AM GETTING THIS? IS IT BECAUSE OF THE WAY I HAVE ENTERED THE RULE SET?:

Traceback (most recent call last):
  File "/Users/gaurangsmacbookpro/Desktop/Gaurang/PYTHON_CODE/FuzzyLogic/employee_salary.py", line 60, in <module>
    tipping.input['quality'] = 10
  File "/usr/local/lib/python3.8/site-packages/skfuzzy/control/controlsystem.py", line 168, in __setitem__
    raise ValueError("Unexpected input: " + key)
ValueError: Unexpected input: quality

CAN SOMEONE PLEASE TELL ME WHAT I HAVE DONE WRONG HERE? KIND OF OUT OF IDEAS.

4

There are 4 best solutions below

1
On

check input values with value() before execute and arrange the code in order to do.

0
On

Try defining your input membership functions automatically instead of using automf().

E.g.

quality['poor'] = fuzz.gaussmf(quality.universe, 1, 5)
quality['mediocre'] = fuzz.gaussmf(quality.universe, 5, 10)
etc.
0
On

Its difficult to figure out what exactly is wrong working with skfuzzy. I have faced similar challenges for diverse occasions.

The rules definition is where fuzzy registers the antecedents into memory. Not the fuzzification step. Follow below steps to ensure your antecedents get registered.

  • Permute the occurrences of or and and with | and & respectively.

  • You can check if your antecedent and consequence variables have been registered by checking with below code

for Input Variables

<code>
    for inp_var in problem.input.sim.ctrl.antecedents:
        print(inp_var)
</code>

for Output Variables

<code>
    for out_var in problem.input.sim.ctrl.consequents:
        print(out_var)
</code>
    
  • Try this for just one rule and check the one parameters (could be | and and) that work for your use case.
0
On

Your code is absolutely fine but by using and instead of &, you are telling it to take only one antecedent. Find below the edited program which now works perfectly. Copy it or you may edit your original code and you should be fine.

import skfuzzy as fuzz
import numpy as np
from skfuzzy import control as ctrl
import matplotlib.pyplot as plt

# New Antecedent/Consequent objects hold universe variables and membership
# functions
quality = ctrl.Antecedent(np.arange(0, 11, 1),'quality')
service = ctrl.Antecedent(np.arange(0, 11, 1), 'service')
tip = ctrl.Consequent(np.arange(0, 26, 1), 'tip')

# Auto-membership function population is possible with .automf(3, 5, or 7)
quality.automf(5)
service.automf(5)

tip['lower'] = fuzz.gaussmf(tip.universe,5,2)
tip['low'] = fuzz.gaussmf(tip.universe,10,2)
tip['average'] = fuzz.gaussmf(tip.universe,15,2)
tip['high'] = fuzz.gaussmf(tip.universe,20,1)
tip['higher'] = fuzz.gaussmf(tip.universe,23,0.5)


rule1 = ctrl.Rule(((quality['poor'] | quality['mediocre']) & (service['poor'] | 
service['mediocre'])), tip['lower'])
rule2 = ctrl.Rule(((quality['average'] | quality['mediocre']) & (service['poor']   
| service['mediocre'])), tip['low'])
rule3 = ctrl.Rule(((quality['average'] | quality['decent']) & 
(service['mediocre'] | service['average'])), tip['average'])
rule4 = ctrl.Rule(((quality['decent'] | quality['good']) & (service['poor'] | 
service['mediocre'])), tip['average'])
rule5 = ctrl.Rule(((quality['decent'] | quality['good']) & (service['decent'] | 
service['mediocre'])), tip['high'])
rule6 = ctrl.Rule(((quality['decent'] | quality['good']) & (service['decent'] | 
service['good'])), tip['higher'])


tipping_ctrl = ctrl.ControlSystem([rule1, rule2, rule3, rule4, rule5, rule6])

tipping = ctrl.ControlSystemSimulation(tipping_ctrl)


tipping.input['service'] = 10
tipping.input['quality'] = 10
tipping.compute()

print(tipping.output['tip'])
tip.view(sim=tipping)