예제 #1
0
def generate_MFs(inp, outp):
    """
    Generates input MFs from input data in the form: {'var': {'ling':[Xvals_MF1], 'ling':[Xvals_MF2], ...},
                                                      'var': {'ling':[Xvals_MF1], 'ling':[Xvals_MF2], ...}, ... } 
                                                
    """
    
    inParams = copy.deepcopy(inp)
    outParams = copy.deepcopy(outp)

    for var in inParams:
        #x_min = min([min(inParams[var][ling]) for ling in inParams[var]])
        #x_max = max([max(inParams[var][ling]) for ling in inParams[var]])

        #x = np.arange(x_min,x_max,float((x_max-x_min)/100.0)) #generage x values for MF
        for ling in inParams[var]: #for each MF
        
            #if len(inParams[var][ling])   == 3: y = fuzz.trimf( x, inParams[var][ling]) #if 3 values -> triangular
            #elif len(inParams[var][ling]) == 4: y = fuzz.trapmf(x, sorted(inParams[var][ling])) #if 4 values -> trapezoidal
            inParams[var][ling] = fuzzyOps.paramsToMF(inParams[var][ling])
        
    for var in outParams:
        #x_min = min([min(outParams[var][ling]) for ling in outParams[var]])
        #x_max = max([max(outParams[var][ling]) for ling in outParams[var]])

        #x = np.arange(x_min,x_max,float((x_max-x_min)/100.0)) #generage x values for MF
        for ling in outParams[var]: #for each MF
            #if len(outParams[var][ling])   == 3: y = fuzz.trimf( x, outParams[var][ling]) #if 3 values -> triangular
            #elif len(outParams[var][ling]) == 4: y = fuzz.trapmf(x, sorted(outParams[var][ling])) #if 4 values -> trapezoidal
            outParams[var][ling] = fuzzyOps.paramsToMF(outParams[var][ling])#[x,y]        
        
    return inParams, outParams
예제 #2
0
def generate_MFs(inp, outp):
    """
    Generates input MFs from input data in the form: {'var': {'ling':[Xvals_MF1], 'ling':[Xvals_MF2], ...},
                                                      'var': {'ling':[Xvals_MF1], 'ling':[Xvals_MF2], ...}, ... } 
                                                
    """

    inParams = copy.deepcopy(inp)
    outParams = copy.deepcopy(outp)

    for var in inParams:
        #x_min = min([min(inParams[var][ling]) for ling in inParams[var]])
        #x_max = max([max(inParams[var][ling]) for ling in inParams[var]])

        #x = np.arange(x_min,x_max,float((x_max-x_min)/100.0)) #generage x values for MF
        for ling in inParams[var]:  #for each MF

            #if len(inParams[var][ling])   == 3: y = fuzz.trimf( x, inParams[var][ling]) #if 3 values -> triangular
            #elif len(inParams[var][ling]) == 4: y = fuzz.trapmf(x, sorted(inParams[var][ling])) #if 4 values -> trapezoidal
            inParams[var][ling] = fuzzyOps.paramsToMF(inParams[var][ling])

    for var in outParams:
        #x_min = min([min(outParams[var][ling]) for ling in outParams[var]])
        #x_max = max([max(outParams[var][ling]) for ling in outParams[var]])

        #x = np.arange(x_min,x_max,float((x_max-x_min)/100.0)) #generage x values for MF
        for ling in outParams[var]:  #for each MF
            #if len(outParams[var][ling])   == 3: y = fuzz.trimf( x, outParams[var][ling]) #if 3 values -> triangular
            #elif len(outParams[var][ling]) == 4: y = fuzz.trapmf(x, sorted(outParams[var][ling])) #if 4 values -> trapezoidal
            outParams[var][ling] = fuzzyOps.paramsToMF(
                outParams[var][ling])  #[x,y]

    return inParams, outParams
예제 #3
0
def plotMF_OPT(MFstructIn, MFstructOut, varList, inRanges, outRanges, varMins=None, varMaxs=None):
    """
    Plot membership functions in optimization problem
    
    """
    inMFsMin, outMFsMin = None, None
    inMFsMax, outMFsMax = None, None
    inMFs, outMFs = deparameterize(list(MFstructIn), list(MFstructOut), list(varList))
    if not varMins == None:
        inMFsMin, outMFsMin = deparameterize(list(MFstructIn), list(MFstructOut), list(varMins))
    if not varMaxs == None:
        inMFsMax, outMFsMax = deparameterize(list(MFstructIn), list(MFstructOut), list(varMaxs))

    #plot
    #plt.close('all')
    #plt.clf() #start a fresh figure if one is open
    
    plt.figure(figsize=(10, 6))
    i = 1
    for inp in inMFs:
        plt.subplot(len(inMFs) + len(outMFs), 1, i)
        for mf in inMFs[inp]:
            vals = fuzzyOps.paramsToMF(inMFs[inp][mf])
            plt.plot(vals[0], vals[1], lw=2.0)
            if inMFsMin <> None:
                vals = fuzzyOps.paramsToMF(inMFsMin[inp][mf])
                plt.plot(vals[0], vals[1], '--', lw=0.8)
            if inMFsMax <> None:
                vals = fuzzyOps.paramsToMF(inMFsMax[inp][mf])
                plt.plot(vals[0], vals[1], ':', lw=0.8)
            plt.plot([inRanges[inp][0], inRanges[inp][0]], [0.,1.], '-k', lw=3.0)
            plt.plot([inRanges[inp][1], inRanges[inp][1]], [0.,1.], '-k', lw=3.0)
            plt.ylabel('INPUT'+ str(inRanges[inp]))
        i = i+1
        plt.yticks([0.0,1.0])
    for otp in outMFs:
        plt.subplot(len(inMFs) + len(outMFs), 1, i)
        for mf in outMFs[otp]:
            vals = fuzzyOps.paramsToMF(outMFs[otp][mf])
            plt.plot(vals[0], vals[1], lw=2.0)
            if outMFsMin <> None:
                vals = fuzzyOps.paramsToMF(outMFsMin[otp][mf])
                plt.plot(vals[0], vals[1], '--', lw=0.8, )
            if outMFsMax <> None:
                vals = fuzzyOps.paramsToMF(outMFsMax[otp][mf])
                plt.plot(vals[0], vals[1], ':', lw=0.8, )
            plt.plot([outRanges[otp][0], outRanges[otp][0]], [0.,1.], '-k', lw=3.0)
            plt.plot([outRanges[otp][1], outRanges[otp][1]], [0.,1.], '-k', lw=3.0)
            
            plt.ylabel('OUTPUT')
        i = i+1  
예제 #4
0
            elif point[2] < min(outRange):
                err = point[2] - min(outRange)
            elif point[2] > max(outRange):
                err = point[2] - max(outRange)
            truthRange = point[2]
            
        error.append([truthRange, outRange, err])
        
    return error   
    
if __name__ == '__main__':
    
    #testerror functions
    import matplotlib.pyplot as plt
    
    A = fuzzyOps.paramsToMF([6.,7.,8.])
    B = fuzzyOps.paramsToMF([5.5,7.4,8.7])
    C = fuzzyOps.paramsToMF([1.5,2.8,4.1])
    D = fuzzyOps.paramsToMF([12.,14.,16.])
    
    A_A_int = fuzErrorInt(A, A)
    A_B_int = fuzErrorInt(A, B)
    A_C_int = fuzErrorInt(A, C)
    A_D_int = fuzErrorInt(A, D)
    print "INT ERRORS:", A_A_int, A_B_int, A_C_int, A_D_int
    
    #A = fuzzyOps.paramsToMF([3.,4.,5.])
    #B = fuzzyOps.paramsToMF([3.5,4.2,5.7])
    #C = fuzzyOps.paramsToMF([1.5,2.8,4.1])
    #D = fuzzyOps.paramsToMF([16.,17.,19.])
    
예제 #5
0
def plotMF_OPT(MFstructIn,
               MFstructOut,
               varList,
               inRanges,
               outRanges,
               varMins=None,
               varMaxs=None):
    """
    Plot membership functions in optimization problem
    
    """
    inMFsMin, outMFsMin = None, None
    inMFsMax, outMFsMax = None, None
    inMFs, outMFs = deparameterize(list(MFstructIn), list(MFstructOut),
                                   list(varList))
    if not varMins == None:
        inMFsMin, outMFsMin = deparameterize(list(MFstructIn),
                                             list(MFstructOut), list(varMins))
    if not varMaxs == None:
        inMFsMax, outMFsMax = deparameterize(list(MFstructIn),
                                             list(MFstructOut), list(varMaxs))

    #plot
    #plt.close('all')
    #plt.clf() #start a fresh figure if one is open

    plt.figure(figsize=(10, 6))
    i = 1
    for inp in inMFs:
        plt.subplot(len(inMFs) + len(outMFs), 1, i)
        for mf in inMFs[inp]:
            vals = fuzzyOps.paramsToMF(inMFs[inp][mf])
            plt.plot(vals[0], vals[1], lw=2.0)
            if inMFsMin <> None:
                vals = fuzzyOps.paramsToMF(inMFsMin[inp][mf])
                plt.plot(vals[0], vals[1], '--', lw=0.8)
            if inMFsMax <> None:
                vals = fuzzyOps.paramsToMF(inMFsMax[inp][mf])
                plt.plot(vals[0], vals[1], ':', lw=0.8)
            plt.plot([inRanges[inp][0], inRanges[inp][0]], [0., 1.],
                     '-k',
                     lw=3.0)
            plt.plot([inRanges[inp][1], inRanges[inp][1]], [0., 1.],
                     '-k',
                     lw=3.0)
            plt.ylabel('INPUT' + str(inRanges[inp]))
        i = i + 1
        plt.yticks([0.0, 1.0])
    for otp in outMFs:
        plt.subplot(len(inMFs) + len(outMFs), 1, i)
        for mf in outMFs[otp]:
            vals = fuzzyOps.paramsToMF(outMFs[otp][mf])
            plt.plot(vals[0], vals[1], lw=2.0)
            if outMFsMin <> None:
                vals = fuzzyOps.paramsToMF(outMFsMin[otp][mf])
                plt.plot(
                    vals[0],
                    vals[1],
                    '--',
                    lw=0.8,
                )
            if outMFsMax <> None:
                vals = fuzzyOps.paramsToMF(outMFsMax[otp][mf])
                plt.plot(
                    vals[0],
                    vals[1],
                    ':',
                    lw=0.8,
                )
            plt.plot([outRanges[otp][0], outRanges[otp][0]], [0., 1.],
                     '-k',
                     lw=3.0)
            plt.plot([outRanges[otp][1], outRanges[otp][1]], [0., 1.],
                     '-k',
                     lw=3.0)

            plt.ylabel('OUTPUT')
        i = i + 1
예제 #6
0
 def feedforward(self, inputs):
     """
     ------INPUTS------
     
     inputs : dict
         the set of outputs from previous nodes in form 
         {nodeName: value, nodeName: value, ...} (or inputs for input 
         nodes)   
     """
     #INPUT FEED FORWARD (fuzzify inputs)
     for inp in self.layer1:
         try:
             if inp in inputs: #check if input is given
                 if not isinstance(inputs[inp], list):
                     MF = fuzzOps.paramsToMF([inputs[inp]]) #get fuzzy MF for singleton
                     self.layer1[inp] = MF
                 else: 
                     self.layer1[inp] = inputs[inp]
             else: 
                 print "Not all inputs given!!!" 
                 self.layer3[self.layer3.keys()[0]] = None #set system output to None
         except:
             raise StandardError("NEFPROX input error!")
     
     #RULE FEED FORWARD (gets min (t-norm) firing strength of weights/MFterms and inputs)
     for rule in self.layer2: #for each rule
         for inp in self.connect1to2[rule]: #for each input in antecedent 
             fs = max(fuzz.fuzzy_and(self.inputMFs[inp][0], self.inputMFs[inp][1],
                                     self.layer1[inp[0]][0], self.layer1[inp[0]][1])[1])
             self.connect1to2[rule][inp] = fs
         self.layer2[rule] = min([self.connect1to2[rule][inp] for inp in self.connect1to2[rule]])
 
     #OUTPUT FEED FORWARD (apply minimum of firing strength and output MF (reduce output MF), then aggregate)
     outMFs = []
     for rule in self.connect2to3: #for each rule
         cons = self.connect2to3[rule].keys()[0]  #get consequent for single output
         if self.layer2[rule] > 0.0: #only for active rules (save time)
             outMF = copy.deepcopy(self.outputMFs[cons][:2])
             outMF[1] = np.asarray([ min(self.layer2[rule], outMF[1][i]) for i in range(len(outMF[1])) ])
                         #apply minimum of firing strength and output MF (reduce output MF)
             self.connect2to3[rule][cons] = outMF
             outMFs.append(outMF)
         else: #for inactive rules, applied MF is 0.0 for all 
             self.connect2to3[rule][cons] = [np.asarray([0.0, 0.0]), np.asarray([0.0,0.0])]
             
     #once all rules are reduced with MFs aggregate
     if len(outMFs) > 0: #check for no rules fired
         while len(outMFs) > 1: #get maximum (union) of all MFs (aggregation)
             outMFs0 = outMFs.pop(0)
             outMFs[0][0], outMFs[0][1] = fuzz.fuzzy_or(outMFs0[0], outMFs0[1], 
                                                         outMFs[0][0], outMFs[0][1])
         
         if   self.defuzz == None: pass
         elif self.defuzz == 'centroid': outMFs[0] = fuzz.defuzz(outMFs[0][0],outMFs[0][1],'centroid')
         elif self.defuzz == 'bisector': outMFs[0] = fuzz.defuzz(outMFs[0][0],outMFs[0][1],'bisector')
         elif self.defuzz == 'mom':      outMFs[0] = fuzz.defuzz(outMFs[0][0],outMFs[0][1],'mom')               #mean of maximum
         elif self.defuzz == 'som':      outMFs[0] = fuzz.defuzz(outMFs[0][0],outMFs[0][1],'som')               #min of maximum
         elif self.defuzz == 'lom':      outMFs[0] = fuzz.defuzz(outMFs[0][0],outMFs[0][1],'lom')               #max of maximum
         
         self.layer3[cons[0]] = outMFs[0]
         
     else:#if no rules fire, then output is None
     
         if self.defuzz == None:
             self.layer3[cons[0]] = [[0.0,0.0],[0.0,0.0]] #result 0.0 in fuzzy MF form
         else:
             self.layer3[cons[0]] = 0.0 #result 0.0 as crisp if some defuzz method specified
         
     return True
예제 #7
0
    def backpropagate(self, error, LR, data, inRanges, outRanges):
        """
        ------INPUTS------
        """
        
        
        #BACKPROP THROUGH OUTPUT NODE:
        if not isinstance(data, list):
            dataFuzz = fuzzOps.paramsToMF[[data]] #get fuzzy version of data for FS
        else: 
            dataFuzz = copy.deepcopy(data)
            data = fuzz.defuzz(data[0], data[1], 'centroid') #get crisp version of data
        
        for rule in self.connect2to3:    #for each rule to output connectionMF
            if self.layer2[rule] > 0.0:   #if rule is firing > 0.0
                outKey = self.connect2to3[rule].keys()[0] #get connection (outName,ling)
                fs = max(fuzz.fuzzy_and(self.outputMFs[outKey][0], self.outputMFs[outKey][1],
                                        dataFuzz[0], dataFuzz[1])[1])
                    #get "firing strength" of individual MF (result of MF for data: W(R,y_i)(t_i))

                #GET CONSTRAINTS: 
                #Triangular: MFs must overlap (or touch other MFs)
                [minP, maxP] = outRanges[outKey[0]]
                if len(self.outputMFs[outKey][2]) == 2:
                    raise StandardError("haven't programmed this")
                if len(self.outputMFs[outKey][2]) == 3:
                    all_params = [self.outputMFs[ling][2] for ling in self.outputMFs]
                    all_params.sort(key=lambda x: x[1]) #sort params by orderer of b value

                    min_ps = all_params[max(0, all_params.index(self.outputMFs[outKey][2]) - 1)] #get MF just < the one changing
                    if min_ps == self.outputMFs[outKey][2]: 
                        min_op = [minP, minP, minP]   #adjust if MF is minimum one 

                    max_ps = all_params[min(len(all_params) - 1, all_params.index(self.outputMFs[outKey][2]) + 1)]#get MF just > the one changing
                    if max_ps == self.outputMFs[outKey][2]: 
                        max_op = [maxP, maxP, maxP]  #adjust if MF is maximum one
                else: 
                    raise StandardError("haven't programmed this")

                if fs > 0: #for W(R,y_i)(t_i) > 0
                    if len(self.outputMFs[outKey][2]) == 2: #gaussian MF adjustment
                        raise StandardError("haven't programmed this")
                        
                    elif len(self.outputMFs[outKey][2]) == 3: #triangular MF adjustment
                        [a,b,c] = self.outputMFs[outKey][2][:] #get params
                        del_b = LR*error*(c - a)*self.layer2[rule]*(1-fs)
                        del_a = LR*(c - a)*self.layer2[rule] + del_b
                        del_c = -1*LR*(c - a)*self.layer2[rule] + del_b
                        b = min( max(b+del_b, min_ps[1]), max_ps[1] ) #bound b by nearest b's
                        a = min(b, min( max(a+del_a, min_ps[0]), min_ps[2] )) #bound a by nearest a and c and keep a < b
                        c = max(b, min( max(c+del_c, max_ps[0]), max_ps[2] )) #bound c by nearest a and c and keep c > b
                        self.outputMFs[outKey][2] = [a,b,c] #update params

                    elif len(self.outputMFs[outKey][2]) == 4: #trapezoidal MF adjustment
                        raise StandardError("haven't programmed this")

                else: #for W(R,y_i)(t_i) = 0
                    if len(self.outputMFs[outKey][2]) == 2: #gaussian MF adjustment
                        raise StandardError("haven't programmed this")
                        
                    elif len(self.outputMFs[outKey][2]) == 3: #triangular MF adjustment
                        [a,b,c] = self.outputMFs[outKey][2][:] #get params
                        del_b = LR*error*(c - a)*self.layer2[rule]*(1-fs)
                        del_a = np.sign(data-b)*LR*(c - a)*self.layer2[rule] + del_b
                        del_c = np.sign(data-b)*LR*(c - a)*self.layer2[rule] + del_b
                        b = min( max(b+del_b, min_ps[1]), max_ps[1] ) #bound b by nearest b's
                        a = min(b, min( max(a+del_a, min_ps[0]), min_ps[2] )) #bound a by nearest a and c and keep a < b
                        c = max(b, min( max(c+del_c, max_ps[0]), max_ps[2] )) #bound c by nearest a and c and keep c > b
                        self.outputMFs[outKey][2] = [a,b,c] #update params

                    elif len(self.outputMFs[outKey][2]) == 4: #trapezoidal MF adjustment
                        raise StandardError("haven't programmed this")
                        

                newMF = fuzzOps.paramsToMF(self.outputMFs[outKey][2]) #get updated MF
                self.outputMFs[outKey][0] = newMF[0]    #update MF
                self.outputMFs[outKey][1] = newMF[1]    #update MF
        
        #BACKPROP THROUGH RULE NODES:
        for rule in self.layer2:
            #get Rule Error: E_R = o_R(1-o_R) * sum(2*W(R,y)(t_i) - 1) * abs(error)
            # note: only one output node:
            outKey = self.connect2to3[rule].keys()[0] #get connection (outName,ling)
            fs = max(fuzz.fuzzy_and(self.outputMFs[outKey][0], self.outputMFs[outKey][1],
                                dataFuzz[0], dataFuzz[1])[1])
            E_R = self.layer2[rule]*(1-self.layer2[rule]) * (2*fs-1) * abs(error) #rule error
            
            for input in self.connect1to2[rule]:
                o_x = fuzz.defuzz(self.layer1[input[0]][0], self.layer1[input[0]][1], 'centroid') #crisp version of input
                
                if self.connect1to2[rule][input] > 0.0: #if FS from that input > 0

                    if fs > 0: #for W(R,y_i)(t_i) > 0
                        if len(self.outputMFs[outKey][2]) == 2: #gaussian MF adjustment
                            raise StandardError("haven't programmed this")
                            
                        elif len(self.outputMFs[outKey][2]) == 3: #triangular MF adjustment
                        
                            [a,b,c] = self.inputMFs[input][2][:] #get params
                            del_b = LR*E_R*(c - a)*(1-self.connect1to2[rule][input])*np.sign(o_x - b)
                            del_a = -LR*E_R*(c - a)*(1-self.connect1to2[rule][input])+del_b
                            del_c = LR*E_R*(c - a)*(1-self.connect1to2[rule][input])+del_b
                            #print 'LR', LR, 'E_R', E_R, 'c-a', c-a, '1-W(x,R)(ox)', (1-self.connect1to2[rule][input])
                            #print 'rule dels:', [del_a, del_b, del_c]
                            self.inputMFs[input][2] = [min(self.inputMFs[input][2][0]+del_a, self.inputMFs[input][2][1]+del_b), 
                                                       self.inputMFs[input][2][1]+del_b,
                                                       max(self.inputMFs[input][2][2]+del_c, self.inputMFs[input][2][1]+del_b) ] #update params                            
                        
                        elif len(self.outputMFs[outKey][2]) == 4: #trapezoidal MF adjustment
                            raise StandardError("haven't programmed this")
                            
                        newMF = fuzzOps.paramsToMF(self.inputMFs[input][2]) #get updated MF
                        self.inputMFs[input][0] = newMF[0]    #update MF
                        self.inputMFs[input][1] = newMF[1]    #update MF