Engee 文档
Notebook

决策模糊推理系统

此示例演示创建模糊推理系统的过程。 此类系统以模糊集、其隶属函数和决策规则的形式将人类推理和专家知识形式化。

安装和连接库

要创建模糊推理系统,让我们使用名为FuzzyLogic的Julia编程语言库。 要在Engee中安装它,您需要执行以下代码。:

In [ ]:
Pkg.add(["FuzzyLogic"])
In [ ]:
Pkg.add("FuzzyLogic")

连接已安装的FuzzyLogic库:

In [ ]:
using FuzzyLogic

建立模糊推理系统

下面的代码使用@mamfis宏构建Mamdani模糊推理系统。 该系统包括输入和输出变量的隶属度函数的定义。

在代码的开头,我们声明了tipper函数,它有两个参数:service和food。 这些变量表示将用于估计餐厅访客想要离开的小费的输入数据。

对于服务变量,我们使用高斯隶属函数定义三个模糊集:

*差,中心为0,标准偏差为1.5
*良好,中心为5,标准偏差为1.5
*优秀的中心为10,标准偏差为1.5

对于食物变量,我们使用梯形隶属函数定义两个模糊集。:

*腐臭(腐烂)与坐标(-2,0,1,3)
*美味与坐标(7,9,10,12)

Tip变量有三个由三角隶属函数定义的模糊集:
*便宜(小)与坐标(0,5,10)
*坐标平均值(10,15,20)
*慷慨与坐标(20,25,30)

接下来,定义了模糊逻辑的规则,将服务质量和食物与提示联系起来。 例如,如果服务很差或食物不合格,小费就会很低,如果服务很好并且食物质量令人满意,小费就会平均,等等。

In [ ]:
fis = @mamfis function tipper(service, food)::tip
    service := begin
      domain = 0:10
      poor = GaussianMF(0.0, 1.5)
      good = GaussianMF(5.0, 1.5)
      excellent = GaussianMF(10.0, 1.5)
    end

    food := begin
      domain = 0:10
      rancid = TrapezoidalMF(-2, 0, 1, 3)
      delicious = TrapezoidalMF(7, 9, 10, 12)
    end

    tip := begin
      domain = 0:30
      cheap = TriangularMF(0, 5, 10)
      average = TriangularMF(10, 15, 20)
      generous = TriangularMF(20, 25, 30)
    end

    service == poor || food == rancid --> tip == cheap
    service == good --> tip == average
    service == excellent || food == delicious --> tip == generous
end
Out[0]:
tipper

Inputs:
-------
service ∈ [0, 10] with membership functions:
    poor = GaussianMF{Float64}(0.0, 1.5)
    good = GaussianMF{Float64}(5.0, 1.5)
    excellent = GaussianMF{Float64}(10.0, 1.5)

food ∈ [0, 10] with membership functions:
    rancid = TrapezoidalMF{Int64}(-2, 0, 1, 3)
    delicious = TrapezoidalMF{Int64}(7, 9, 10, 12)


Outputs:
--------
tip ∈ [0, 30] with membership functions:
    cheap = TriangularMF{Int64}(0, 5, 10)
    average = TriangularMF{Int64}(10, 15, 20)
    generous = TriangularMF{Int64}(20, 25, 30)


Inference rules:
----------------
(service is poor ∨ food is rancid) --> tip is cheap
service is good --> tip is average
(service is excellent ∨ food is delicious) --> tip is generous


Settings:
---------
- MinAnd()
- MaxOr()
- MinImplication()
- MaxAggregator()
- CentroidDefuzzifier(100)

以函数形式使用模糊推理系统的示例 fis:

In [ ]:
fis(service=2, food=4)
Out[0]:
1-element Dictionaries.Dictionary{Symbol, Float64}
 :tip │ 7.788531995027619

使用以下方法生成独立于库的函数 compilefis:

In [ ]:
fis_ex = compilefis(fis)
Out[0]:
:(function tipper(service, food)
      poor = exp(-((service - 0.0) ^ 2) / 4.5)
      good = exp(-((service - 5.0) ^ 2) / 4.5)
      excellent = exp(-((service - 10.0) ^ 2) / 4.5)
      rancid = max(min((food - -2) / 2, 1, (3 - food) / 2), 0)
      delicious = max(min((food - 7) / 2, 1, (12 - food) / 2), 0)
      ant1 = max(poor, rancid)
      ant2 = good
      ant3 = max(excellent, delicious)
      tip_agg = collect(LinRange{Float64}(0.0, 30.0, 101))
      @inbounds for (i, x) = enumerate(tip_agg)
              cheap = max(min((x - 0) / 5, (10 - x) / 5), 0)
              average = max(min((x - 10) / 5, (20 - x) / 5), 0)
              generous = max(min((x - 20) / 5, (30 - x) / 5), 0)
              tip_agg[i] = max(max(min(ant1, cheap), min(ant2, average)), min(ant3, generous))
          end
      tip = ((2 * sum((mfi * xi for (mfi, xi) = zip(tip_agg, LinRange{Float64}(0.0, 30.0, 101)))) - first(tip_agg) * 0) - last(tip_agg) * 30) / ((2 * sum(tip_agg) - first(tip_agg)) - last(tip_agg))
      return tip
  end)

代码生成得到的函数可以写入文件。 为此,变量 fis_ex 具有格式 Expr,被转换为格式 String,以作进一步记录:

In [ ]:
text_function = string(fis_ex)
Out[0]:
"function tipper(service, food)\n    poor = exp(-((service - 0.0) ^ 2) / 4.5)\n    good = exp(-((service - 5.0) ^ 2) / 4.5)\n    excellent = exp(-((service - 10.0) ^ 2) / 4.5)\n    rancid = max(min((food - -2) / 2, 1, (3 - food) / 2), 0)\n    delicious = max(min((food - 7) / 2" ⋯ 444 bytes ⋯ ", min(ant2, average)), min(ant3, generous))\n        end\n    tip = ((2 * sum((mfi * xi for (mfi, xi) = zip(tip_agg, LinRange{Float64}(0.0, 30.0, 101)))) - first(tip_agg) * 0) - last(tip_agg) * 30) / ((2 * sum(tip_agg) - first(tip_agg)) - last(tip_agg))\n    return tip\nend"

将字符串格式的函数写入文件:

In [ ]:
f = open("fis.jl","w") # создание файла
write(f, text_function) # запись в файл
close(f) # закрытие файла

函数定义 tipper,在Engee工作区中使用函数 include 从创建的文件:

In [ ]:
include("fis.jl")
Out[0]:
tipper (generic function with 1 method)

使用来自a的函数。jl文件。

In [ ]:
tipper(2, 3)
Out[0]:
7.7885319950276175

生成的函数可以在其他项目中使用,而无需连接FuzzyLogic库。

成员函数的可视化

连接图形可视化库:

In [ ]:
using Plots

显示变量的成员函数 service:

In [ ]:
plot(fis, :service)
Out[0]:

显示变量的成员函数 food:

In [ ]:
plot(fis, :food)
Out[0]:

显示变量的成员函数 tip:

In [ ]:
plot(fis, :tip)
Out[0]:

构建响应表面

如果模糊输出系统具有2个输入,那么可以构造其响应面。 这是一个显示输出如何根据输入数据而变化的表面。:

In [ ]:
# Определяем векторы
s = collect(0:0.2:10) # Вектор s от 0 до 10
f = collect(0:0.2:10) # Вектор f от 0 до 10

# Создаем матрицы значений
tip_matrix = zeros(length(s), length(f))

# Заполняем матрицу значениями отклика
for (i, service) in enumerate(s)
    for (j, food) in enumerate(f)
        tip_matrix[i, j] = tipper(service, food)
    end
end

# Построение поверхности отклика
surface(s, f, tip_matrix, xlabel="Service", ylabel="Food", zlabel="Tip", title="Поверхность отклика", color=:inferno)
Out[0]:

结论

在此示例中,检查了FuzzyLogic库的功能。 它们用于构建模糊推理系统,允许您使用模糊逻辑对不确定和不准确的数据进行建模和处理。 在决策和计算的背景下,模糊推理系统将人类推理和专家知识形式化,与传统方法相比,允许在面对不确定性时做出更灵活和自适应的决策。