I try to make a gist code work to later adapt it but I run into the problem of
Code: Select all
TypeError: 'dict_view' object isn't subscriptable
Code: Select all
from rr1 import *
income = Antecedent(frange(0, 3, 1))
debt = Antecedent(frange(0, 100, 1))
qualification = Consequent(frange(0, 100, 1))
# Defining membership functions
income_mf = {
'poor': [0, 0, 0.3, 1.0],
'average': [0.25, 0.5, 1.5, 1.5],
'good': [1.3, 1.6, 2, 2]
}
income.set_mf(income_mf)
debt_mf = {
'low': [0, 0, 10, 30],
'average': [0, 30, 50, 80],
'high': [50, 75, 100, 100]
}
debt.set_mf(debt_mf)
qualification_mf = {
'not_decent': [0, 0, 20, 50],
'decent': [0, 40, 60, 80],
'very_decent': [50, 80, 100, 100]
}
qualification.set_mf(qualification_mf)
# Defining rules for inference engine
expert_rules = {
('poor', 'low'): 'very_decent',
('average', 'low'): 'decent',
('good', 'low'): 'not_decent',
('poor', 'average'): 'very_decent',
('average', 'average'): 'decent',
('good', 'average'): 'not_decent',
('poor', 'high'): 'very_decent',
('average', 'high'): 'very_decent',
('good', 'high'): 'not_decent',
('poor'): 'very_decent',
('average'): 'decent',
('good'): 'not_decent',
('low'): 'not_decent',
('average'): 'decent',
('high'): 'very_decent'
}
# List for storing prediction and final result
prediction, result = [],[]
# Read csv file
# Fuzzify process: crisp set -> fuzzy set input
fuzzy_income = fuzzify(float(1.632), income.get_mf())
fuzzy_debt = fuzzify(float(39.375), debt.get_mf())
# Inference process (clipping)
fuzzy_qualification = inference((fuzzy_income, fuzzy_debt), expert_rules)
# Deffuzify: fuzzy set value -> crisp value
result_area = qualification.get_area(fuzzy_qualification)
calculate_result = defuzzify(result_area, fuzzy_qualification)
print (calculate_rerult)
this class rr1 is ;
Code: Select all
import math
# Classes of fuzzy system components,
# Antecedent for input/sensor, Consequent for output
def reduce(function, iterable, initializer=None):
it = iter(iterable)
if initializer is None:
value = next(it)
else:
value = initializer
for element in it:
value = function(value, element)
return value
class Antecedent:
def __init__(self, universe):
self.__universe = universe
def get_mf(self):
return self.__membership
def set_mf(self, mf):
self.__membership = mf
class Consequent:
def __init__(self, universe):
self.__universe = universe
def get_mf(self):
return self.__membership
def set_mf(self, mf):
self.__membership = mf
def get_area(self, labels):
result = []
for i in labels:
for key, value in self.__membership.items():
if i == key:
result.append([min(value), max(value)])
return result
# Utilities
def frange(x, y, jump):
assert x < y
while x < y:
yield x
x += jump
# Fuzzy membership function
def trapmf(x, point):
# a <= b <= c <= d is required
assert point[0] <= point[1] <= point[2] <= point[3]
if x <= point[0] and x >= point[3]:
return 0
elif point[0] < x < point[1]:
return round((x - point[0]) / (point[1] - point[0]), 3)
elif point[1] <= x <= point[2]:
return 1
elif point[2] < x <= point[3]:
return round(-(x - point[3]) / (point[3] - point[2]), 3)
# Fuzzify return a dictionary containing membership value of x, can be more than one
def fuzzify(x, mfx):
membership_value = {}
for key, value in mfx.items():
membership = trapmf(x, value)
# assign membership value with 0 if x it is not in the area (None)
membership_value[key] = trapmf(x, value) if membership != None else 0
return membership_value
# Clipping process, producing an result area of trapezoidal
def inference(antecedents, rules):
area = {}
p, q = antecedents[0], antecedents[1]
for i in p.items():
if i[1] > 0:
# Get rules with single key (income) -> qualification
label1 = rules.get((i[0]), None)
area[label1] = i[1]
for j in q.items():
if j[1] > 0:
# Get rules with single key (debt) -> qualification
label2 = rules.get((j[0]), None)
area[label2] = j[1]
# Get rules with double key (income, debt) -> qualification
label3 = rules.get((i[0], j[0]), None)
area[label3] = min(i[1], j[1])
return area
def defuzzify(x, mf):
result, divider = 0, 0
rand_point, sum_rand_point = [], []
for i in range(0, len(x)):
rand_point.append(list(frange(min(x[i]), max(x[i]), 4)))
sum_rand_point.append(reduce(lambda x, y: x + y, rand_point[i]))
divider += len(rand_point[i]) * mf.values()[i]
result += sum_rand_point[i] * mf.values()[i]
return result / divider