Система нечёткого вывода для принятия решений
В данном примере демонстрируется процесс создания системы нечёткого вывода. Такие системы формализуют человеческие рассуждения и экспертные знания в виде нечётких множеств, их функций принадлежности и решающих правил.
Установка и подключение библиотек
Чтобы создать систему нечёткого вывода воспользуемся библиотекой языка программирования Julia, которая называется FuzzyLogic. Для её установки в Engee требуется выполнить следующую кодовую ячейку:
Pkg.add(["FuzzyLogic"])
Pkg.add("FuzzyLogic")
Подключение установленной библиотеки FuzzyLogic:
using FuzzyLogic
Построение системы нечёткого вывода
В коде ниже осуществляется построение системы нечёткого вывода Мамдани (Mamdani fuzzy inference system) с помощью макроса @mamfis. Эта система включает в себя определение функций принадлежности (membership functions) для входных и выходных переменных.
В начале кода мы объявляем функцию tipper, которая принимает два аргумента: service (обслуживание) и food (еда). Эти переменные представляют собой входные данные, которые будут использоваться для оценки чаевых, которые посетитель ресторана хочет оставить.
Для переменной service мы определяем три нечётких множества с помощью гауссовских функций принадлежности:
- poor (плохое) с центром 0 и стандартным отклонением 1.5
- good (хорошее) с центром 5 и стандартным отклонением 1.5
- excellent (отличное) с центром 10 и стандартным отклонением 1.5
Для переменной food мы определяем два нечётких множества с помощью трапециевидных функций принадлежности:
- rancid (протухшее) с координатами (-2, 0, 1, 3)
- delicious (вкусное) с координатами (7, 9, 10, 12)
Переменная tip (чаевые) имеет три нечётких множества, заданных треугольными функциями принадлежности:
- cheap (небольшие) с координатами (0, 5, 10)
- average (средние) с координатами (10, 15, 20)
- generous (щедрые) с координатами (20, 25, 30)
Далее определяются правила нечёткой логики, связывающие качество обслуживания и еды с чаевыми. Например, если обслуживание плохое или еда некачественная, чаевые будут низкими, если обслуживание хорошее, а качество еды удовлетворительное, чаевые будут средними и так далее.
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
Пример использования системы нечёткого вывода в виде функции fis
:
fis(service=2, food=4)
Генерация функции не зависящей от библиотеки, с помощью compilefis
:
fis_ex = compilefis(fis)
Функцию, полученную с помощью кодогенерации, можно записать в файл. Для этого переменная fis_ex
имеющая формат Expr
, конвертируется в формат String
, для дальнейшей записи:
text_function = string(fis_ex)
Запись функции в строковом формате в файл:
f = open("fis.jl","w") # создание файла
write(f, text_function) # запись в файл
close(f) # закрытие файла
Определение функции tipper
, в рабочем пространстве Engee с помощью функции include
из созданного файла:
include("fis.jl")
Использование функции из файла формата .jl.
tipper(2, 3)
Полученную функцию можно использовать в других проектах, не подключая библиотеку FuzzyLogic.
Визуализация функций принадлежности
Подключение библиотеки для визуализации графиков:
using Plots
Отображение функций принадлежности для переменной service
:
plot(fis, :service)
Отображение функций принадлежности для переменной food
:
plot(fis, :food)
Отображение функций принадлежности для переменной tip
:
plot(fis, :tip)
Построение поверхности отклика
Если система нечёткого вывода имеет 2 входа, то можно построить её поверхность отклика. Это поверхность, отображающая, как выходные данные изменяются в зависимости от входных данных:
# Определяем векторы
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)
Вывод
В данном примере были расмотрены функции библиотеки FuzzyLogic. С помощью них была построена система нечёткого вывода, которая позволяет моделировать и обрабатывать неопределённые и неточные данные, используя нечёткую логику. В контексте принятия решений и вычислений система нечёткого вывода формализует человеческие рассуждения и экспертные знания, позволяя принимать более гибкие и адаптивные решения в условиях неопределенности по сравнению с традиционными методами.