欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

完整的模糊推理系统介绍以及matlab中从零实现(下篇)

程序员文章站 2024-03-25 08:22:52
...

模糊推理系统从零实现

完整的模糊推理系统介绍以及matlab中从零实现(上篇)中,我们对一个完整的模糊推理系统所涉及到的知识点做了一个细致地展述。
进而,我们可以根据实际需要设计一个属于自己的模糊推理系统。主要涉及到以下几个方面的参数设置。

  1. 系统的输入输出变量
  2. 变量对应的语义变量,即分类
  3. 每个语义变量都需要一个隶属度函数与之对应
  4. 推理规则

本文的模糊推理系统的输入,输出以及相应规则设定如下

  1. 系统输入为两个,分别为商品评价(差、中、好、极好)、用户购买意愿(弱、中、强、很强)。输入范围都是[0 10]
  2. 系统输出为用户行为,购买与否。用[0 1]区间的数值表示。大于0.5则为购买。
  3. 模糊规则考虑为
  • rule1: IF 购买意愿很强 THEN ACtion=买
  • rule2: IF 商品评价极好且购买意愿为不为弱 THEN Action=买
  • rule3: IF 商品评价为差 THEN Action=不买
  • rule4: IF 如果商品评价不为差且购买意愿强 THEN Action=买
    完整的模糊推理系统介绍以及matlab中从零实现(下篇)
    最终的目的是建成如上的一个推理系统

基本命令介绍

在调用doc fuzzy得到的文档窗口后,对Fuzzy Inference System Modeling中的functions做一个仔细地阅读,不难发现。
matlab在安装工具箱Fuzzy的基础上,给定了几个模糊推理系统:tipper等
因此,我们可以直接通过tipper=readfis('tipper')调用得到这个完整的系统。还可以通过命令plotfis(tipper)showfis(tipper)对其进行分析。
完整的模糊推理系统介绍以及matlab中从零实现(下篇)
我们可以看到它有两个输入和一个输出,并且分别具有不同的语义变量和隶属度函数。通过showrule(tipper)可以看到它设置的规则为

'1. If (service is poor) or (food is rancid) then (tip is cheap) (1) ’
'2. If (service is good) then (tip is average) (1) ’
‘3. If (service is excellent) or (food is delicious) then (tip is generous) (1)’

创建一个新的FIS

事实上,我们可以将工具箱自带的tipper做进一步优化。添加更多的输入,更完整的规则等。而这一点,在我们成功实现一个自己的系统后很容易做到。
我们通过fis=newfis(name)命令生成一个空的fis,并且在初始化的过程中,fis的类型,逻辑运算等都选择为默认值。
完整的模糊推理系统介绍以及matlab中从零实现(下篇)
可以发现,生成的基本fis中,模糊规则前件的对应min对应max,再将前件的隶属度同后件的隶属度函数比较取较小者。结合不同规则得到的输出隶属度值,取面积最大的情形,最后通过centorid,即面积重心的去模糊方法得到输出的数值。
完整的模糊推理系统介绍以及matlab中从零实现(下篇)

在大多数时候,我们是不需要更改这些基础设定的。我们所需要做的就是,添加输入输出,语义变量以及隶属度函数,并且设定好相应的规则即可。如果需要对这些基础设定作出更改。可以通过命令setfig()进行改动。具体的可以参考该命令的帮助文档。

设定输入、输出

  1. 所用到的添加变量函数命令fis=addvar(fis,varType,varName,varBounds),即设定参数的类型:输入or输出,输入的名称和区间。
    因此,我们设定输入输出分别为:
    • fis=addvar(fis,‘input’,‘Attitude’,[0 10])
    • fis=addvar(fis,‘input’,‘Comment’,[0 10])
    • fis=addvar(fis,‘output’,‘Action’,[0 1])
      此时,我们可以看到系统的参数增加了。
      完整的模糊推理系统介绍以及matlab中从零实现(下篇)
      与之对应的命令是fis = rmvar(fis,varType,varIndex)用于移除设定好的输入输出变量。
  2. 添加隶属度函数命令
    命令:fis = addmf(fis,varType,varIndex,mfName,mfType,mfParams),形参含义如下表
形参 含义
varType 参数类型,输入或输出
varIndex 参数标号,第几个输入或输出
mfName 隶属度函数名称,即语义变量
mfType 选用哪种隶属度函数
mfParams 隶属度函数生产参数

shopper=addmf(shopper,‘input’,1,‘weak’,‘gaussmf’,[1 0]);
shopper=addmf(shopper,‘input’,1,‘medium’,‘gaussmf’,[1 3.33]);
shopper=addmf(shopper,‘input’,1,‘strong’,‘gaussmf’,[1 6.77]);
shopper=addmf(shopper,‘input’,1,‘very strong’,‘gaussmf’,[1 10]);

对于输入1的四个语义变量设定相应的隶属度函数。同样地,我们也可以设定输入2(商品评价)和输出的语义变量和对应的隶属度函数
完整的模糊推理系统介绍以及matlab中从零实现(下篇)
完整的模糊推理系统介绍以及matlab中从零实现(下篇)
完整的模糊推理系统介绍以及matlab中从零实现(下篇)

规则矩阵输入

在模糊推理系统中,推理规则设定是通过对规则矩阵R的元素进行相应的设定,并调用命令fis=addrule(fis,RuleMatrix)实现。
对于一个m个输入,n个输出,k条规则的系统规则矩阵R的规模大小为k×(m+n+2)k\times(m+n+2)其中一行元素分别对应一条规则。

每个行向量中的前m个元素表示m个输入的语义变量的标识
m+1到m+n之间的元素表示输出语义变量的标识
倒数第二个表示该规则的权重
最后一个元素表示逻辑前件的逻辑运算符,其中and表示为1,or表示为2

rule2: IF 商品评价极好且购买意愿为不为弱 THEN Action=买为例,
R(2,:)=[-1 4 2 1 1]细心的同学会发现R(2,1)前面有个负号,之所以会有这个负号,是因为在规则2的逻辑前件中有个不为,因此需要加个负号。
最终,我们可以得到规则矩阵R如下
R=[40211142110111131211]\left[\begin{array}{ccc|c|c}4&0&2&1&1\\-1&4&2&1&1\\0&1&1&1&1\\3&-1&2&1&1\end{array}\right]
调用命令shopper=addrule(shopper,ruleMatrix);showrule(shopper,'Format','symbolic');可以发现与预想的一致

'1. (Attitude == very strong) => (Action=买) (1) ’
‘2. (Attitude~=weak) & (Comment == very good) => (Action=买) (1)’
'3. (Comment == bad) => (Action=不买) (1) ’
'4. (Attitude == strong) & (Comment~=bad) => (Action=买) (1) ’
完整的模糊推理系统介绍以及matlab中从零实现(下篇)
这时候,是不是和我们直接调用的样例fistipper很像了呢

系统评价

此时,我们已经构建好了一个模糊推理系统。可以传入一定的参数进行分析。
假设商品评价和购买意愿都为7,那么该用户选择购买的可能性为多少呢?
完整的模糊推理系统介绍以及matlab中从零实现(下篇)
从上图看还是比较合理的,但是当我们把输入改为[2 4]时,按照我们的思维,该用户不会选择购买的可能性更大。可结果却差异较大
完整的模糊推理系统介绍以及matlab中从零实现(下篇)
之所以会出现这种情况,是因为我们的规则设立并不是很合理。所以,在模糊推理系统设定中,推理规则的设定也很重要

系统调整

为了修改我们的系统,使之更加合理。或者将别人建立好的系统做一定的修改,以满足更多的需求。我们可能需要对系统的输入输出以及他们对应的语义变量隶属度函数等进行调整。

  1. 我们可以通过rmvar()移除一些输入或输出,也可以通过advar()添加一些新的输入输出变量。
  2. 并且通过addmf()rmmf()对隶属度函数进行增删。同时,可以调用mfedit()对隶属度函数做一个可视化的调整
    完整的模糊推理系统介绍以及matlab中从零实现(下篇)
  3. 如果要对规则做出调整。那么我们可以先试着分析哪条规则设置存在不合理性。这时候,可以调用ruleview()来可视化每条规则逻辑运算。
    完整的模糊推理系统介绍以及matlab中从零实现(下篇)

从这个图可以大概分析,规则2关于Attitude和规则4关于Comment的设定可能存在一定的不合理性。因此我们需要进一步修改规则设定。有两种操作方法

  • 将原来的规则矩阵删除,重新设定规则矩阵。fisname.rule=[]
  • 也可以通过ruleedit()进行可视化界面下的规则设定
    完整的模糊推理系统介绍以及matlab中从零实现(下篇)
    系统评价也就是根据不同输入下,得到的输出结果是否符合逻辑进行评价。并针对所出现的问题作出相应的改变。
    目前我个人认为好的模糊系统应该能够有好的规则设定。这比隶属度函数等的设定更加重要

系统导入导出

matlab中可以将自己创建的FIS进行保存。通过调用命令writefis(),具体的参数设定可以参考帮助文档。

附录

附上shopper完整地实现代码。只是在规则设定方面没有做太多的考究。

%生成一个商品购买意愿测试系统
%输入1:购买意愿[0 10]记为Attitude
%语义变量:弱 中 强 很强
%输入2:商品评价[0 10]记为Comment
%语义变量:差 中 好 极好
%输出1:购买行为Action=不买, Action=买
%结合实际,简单的定义四个规则
%rule1: IF 购买意愿很强 THEN ACtion=买
%rule2: IF 商品评价极好且购买意愿为不为弱 THEN Action=买
%rule3: IF 商品评价为差 THEN Action=不买
%rule4: IF 如果商品评价不为差且购买意愿强 THEN Action=买
%%%四个规则的逻辑表示形式
%rule1: if Attitude==very strong -> Action=买
%rule2: if comment==very good && attitude~=weak -> Action=买
%rule3: if comment==bad -> Action=不买
%rule4: if comment~=bad && attitude==strong -> Action=买
clear;
close all;
shopper = newfis('shopper');
%添加系统输入和输出
shopper=addvar(shopper,'input','Attitude',[0 10]);
shopper=addvar(shopper,'input','Comment',[0 10]);
shopper=addvar(shopper,'output','Action',[0 1]);
%添加系统输入输出的语义变量及隶属度函数
figure
shopper=addmf(shopper,'input',1,'weak','gaussmf',[1 0]);
shopper=addmf(shopper,'input',1,'medium','gaussmf',[1 3.33]);
shopper=addmf(shopper,'input',1,'strong','gaussmf',[1 6.77]);
shopper=addmf(shopper,'input',1,'very strong','gaussmf',[1 10]);
plotmf(shopper,'input',1)
title('关于购买意愿的隶属度函数')
showfis(shopper);
figure
shopper=addmf(shopper,'input',2,'bad','trimf',[0 0 3.33]);
shopper=addmf(shopper,'input',2,'medium','trimf',[0 3.33 6.67]);
shopper=addmf(shopper,'input',2,'good','trimf',[3.33 6.67 10]);
shopper=addmf(shopper,'input',2,'very good','trimf',[6.67 10 10]);
plotmf(shopper,'input',2)
title('关于商品评价的隶属度函数')
figure
shopper=addmf(shopper,'output',1,'不买','zmf',[0.5 0.5]);
shopper=addmf(shopper,'output',1,'买','smf',[0.5 0.5]);
plotmf(shopper,'output',1)
title('关于购买结果的隶属度函数')
ruleMatrix=[4 0 2 1 1;-1 4 2 1 1;0 1 1 1 1;3 -1 2 1 1];
shopper=addrule(shopper,ruleMatrix);
showrule(shopper,'Format','symbolic');
figure
plotfis(shopper);
%进行输入测试[7 8]
[output,fuzzifiedInputs,ruleOutputs,aggregatedOutput] = evalfis([7 8],shopper);
outputRange = linspace(shopper.output.range(1),shopper.output.range(2),length(aggregatedOutput))'; 
figure
subplot(211)
plot(outputRange,ruleOutputs,[output output],[0 1])
title('每个规则的输出')
legend('rule1','rule2','rule3','rule3')
xlabel('Action')
ylabel('Output Membership')
subplot(212)
plot(outputRange,aggregatedOutput,[output output],[0 1])
xlabel('Action')
ylabel('Output Membership')
legend('Aggregated output fuzzy set','Defuzzified output')
title('最终输出')
figure
ruleview(shopper)
% for i=1:4
%     hold on;
%     plot([fuzzifiedInputs(i),fuzzifiedInputs(i)],[0 1]);
% end

%更新规则后
%%%四个规则的逻辑表示形式
%rule1: if Attitude==very strong -> Action=买
%rule2: if comment==very good && attitude==strong -> Action=买
%rule3: if comment==bad -> Action=不买
%rule4: if comment==good && attitude==strong -> Action=买
shopper.rule=[];
ruleMatrix=[4 0 2 1 1;3 4 2 1 1;0 1 1 1 1;3 3 2 1 1];
shopper=addrule(shopper,ruleMatrix);
showrule(shopper,'Format','symbolic');
figure
plotfis(shopper);
%进行输入测试[7 8]
[output,fuzzifiedInputs,ruleOutputs,aggregatedOutput] = evalfis([2 4],shopper);
outputRange = linspace(shopper.output.range(1),shopper.output.range(2),length(aggregatedOutput))'; 
figure
subplot(211)
plot(outputRange,ruleOutputs,[output output],[0 1])
title('每个规则的输出')
legend('rule1','rule2','rule3','rule3')
xlabel('Action')
ylabel('Output Membership')
subplot(212)
plot(outputRange,aggregatedOutput,[output output],[0 1])
xlabel('Action')
ylabel('Output Membership')
legend('Aggregated output fuzzy set','Defuzzified output')
title('最终输出')
figure
ruleview(shopper)
相关标签: Matlab matlab