Нечеткая и нефузкая логика

Базовая задача расчета чаевых

Чтобы проиллюстрировать значения нечеткой логики, рассмотрим как линейный, так и нечеткий подходы к следующей задаче:

Какова справедливая сумма чаевых для вашего официанта?

Во-первых, решим эту задачу обычным способом, записывая команды MATLAB ®, которые описывают линейные и кусочно-линейные зависимости. Затем рассмотрим ту же систему, использующую нечеткую логику.

Базовая задача расчета чаевых. Учитывая значение от 0 до 10, которое представляет качество сервиса в ресторане (где 10 превосходно), каковы должны быть советы?

Эта задача основана на чаевых, которые обычно практикуются в Соединенных Штатах. Средние чаевые за еду в США составляют 15%, хотя фактическое количество может варьироваться в зависимости от качества предоставляемой услуги.

Нефузкий подход

Начнем с самой простой зависимости. Предположим, что советы всегда равны 15% от общего счета.

service = 0:.5:10;
tip = 0.15*ones(size(service));
plot(service,tip)
xlabel('Service')
ylabel('Tip')
ylim([0.05 0.25])

Figure contains an axes. The axes contains an object of type line.

Эта связь не учитывает качество сервиса, поэтому вы должны добавить термин к уравнению. Поскольку сервис оценивается по шкале от 0 до 10, вы увеличение совета линейно с 5%, если сервис плох к 25%, если сервис превосходен. Теперь отношение выглядит как следующий график:

tip = (.20/10)*service+0.05;
plot(service,tip)
xlabel('Service')
ylabel('Tip')
ylim([0.05 0.25])

Figure contains an axes. The axes contains an object of type line.

Формула делает то, что вы хотите, и прямо вперед. Тем не менее, вы можете захотеть, чтобы советы также отражали качество пищи. Это расширение задачи определяется следующим образом.

Расширенная задача расчета чаевых. Учитывая два значений чисел от 0 до 10 (где 10 превосходно), которые соответственно представляют качество сервиса и качество еды в ресторане, каковы должны быть советы?

Теперь, когда вы добавили другую переменную, проверьте влияние формулы.

food = 0:.5:10;
[F,S] = meshgrid(food,service);
tip = (0.20/20).*(S+F)+0.05;
surf(S,F,tip)
xlabel('Service')
ylabel('Food')
zlabel('Tip')

Figure contains an axes. The axes contains an object of type surface.

В этом случае результаты выглядят удовлетворительно, но когда вы смотрите на них пристально, они кажутся неправильными. Предположим, что вы хотите, чтобы обслуживание было более важным фактором, чем качество еды. Укажите, что сервис составляет 80% от общего сорта чаевых, а еда составляет другие 20%.

servRatio = 0.8;
tip = servRatio*(0.20/10*S+0.05) + ...
	(1-servRatio)*(0.20/10*F+0.05);
surf(S,F,tip)
xlabel('Service')
ylabel('Food')
zlabel('Tip')

Figure contains an axes. The axes contains an object of type surface.

Реакция все еще слишком равномерно линейна. Предположим, что вы хотите получить более плавный ответ в середине, то есть вы хотите дать 15% советов в общем случае, но хотите также указать изменение, если услуга исключительно хороша или плоха. Этот фактор, в свою очередь, означает, что предыдущие линейные отображения больше не применяются. Вы по-прежнему можете использовать линейный расчет с кусочно-линейной конструкцией. Теперь вернемся к одномерной проблеме, рассматривая только сервис. Вы можете создать простое условное назначение советов с помощью логического индексирования.

tip = zeros(size(service));
tip(service<3) = (0.10/3)*service(service<3)+0.05;
tip(service>=3 & service<7) = 0.15;
tip(service>=7 & service<=10) = ...
	(0.10/3)*(service(service>=7 & service<=10)-7)+0.15;
plot(service,tip)
xlabel('Service')
ylabel('Tip')
ylim([0.05 0.25])

Figure contains an axes. The axes contains an object of type line.

Предположим, что вы расширяете этот подход до двух размерностей, где вы снова учитываете качество еды.

servRatio = 0.8;
tip = zeros(size(S));
tip(S<3) = ((0.10/3)*S(S<3)+0.05)*servRatio + ...
	(1-servRatio)*(0.20/10*F(S<3)+0.05);
tip(S>=3 & S<7) = (0.15)*servRatio + ...
	(1-servRatio)*(0.20/10*F(S>=3 & S<7)+0.05);
tip(S>=7 & S<=10) = ((0.10/3)*(S(S>=7 & S<=10)-7)+0.15)*servRatio + ...
    (1-servRatio)*(0.20/10*F(S>=7 & S<=10)+0.05);
surf(S,F,tip)
xlabel('Service')
ylabel('Food')
zlabel('Tip')

Figure contains an axes. The axes contains an object of type surface.

График выглядит неплохо, но функция на удивление сложна. Кому-то, кто не видел процесс первоначального проекта, даже непонятно как работает алгоритм.

Нечеткий логический подход

В целом, вы хотите захватить суть этой задачи, оставив в стороне все факторы, которые могут быть произвольными. Если вы составите список того, что действительно имеет значение в этой проблеме, вы можете закончить со следующими описаниями правил.

Правила задачи расчета чаевых - коэффициент обслуживания

  • Если сервис плох, то чаевые малы

  • Если сервис хорош, то чаевые средние

  • Если сервис превосходен, то чаевые щедрые

Порядок, в котором здесь представлены правила, произволен. Неважно, какие правила стоят на первом месте. Чтобы включить эффект качества продуктов на чаевые, добавьте следующие два правила.

Задача расчета чаевых правила - пищевой фактор

  • Если еда - тухлая, то чаевые малы

  • Если еда восхитительна, то чаевые щедрые

Можно объединить два разных списка правил в один список из трех таких правил.

Задача расчета чаевых правила - как сервисные, так и продовольственные факторы

  • Если сервис плох, или еда является прогорклой, то чаевые малы

  • Если сервис хорош, то чаевые средние

  • Если сервис превосходен, или еда восхитительна, тогда чаевые будут большими

Эти три правила являются ядром вашего решения, и они соответствуют правилам для нечеткой логической системы. Когда вы придаете математический смысл лингвистическим переменным (что такие средние чаевые, для примера), у вас есть полная система нечеткого вывода. Методология нечеткой логики должна также учитывать:

  • Как все правила объединяются?

  • Как математически определить, что такое средний чаевые?

Решение задачи

Следующий график представляет нечеткую логическую систему, которая решает задачу расчета чаевых.

gensurf(readfis('tipper'))

Figure contains an axes. The axes contains an object of type surface.

Этот график был сгенерирован тремя правилами, которые учитывали как сервисные, так и пищевые факторы.

Наблюдения Рассмотрим некоторые наблюдения о примере до сих пор. Вы нашли кусочно-линейное соотношение, которое решило задачу. Это сработало, но вывести было проблематично, и когда вы записывали его как код, это было непросто интерпретировать. И наоборот, нечеткая логическая система основана на некоторых операторах здравого смысла. Кроме того, вы смогли добавить в список еще два правила, которые повлияли на форму общего выхода, не отменяя того, что уже было сделано.

Более того, при помощи нечетких логических правил поддержание структуры алгоритма развязывается по довольно чистым линиям. Понятие средней чаевые могут меняться изо дня в день, город к городу, страна к стране. Однако базовая логика одинаковая: если сервис хорош, советы должны быть средними.

Повторная калибровка Метода Вы можете быстро повторно калибровать метод путем простого сдвига нечеткого набора, который определяет среднее значение, не переписывая нечеткие логические правила.

Можно сдвинуть списки кусочно-линейных функций, но существует большая вероятность трудной перекалибровки.

В следующем примере кусочно-линейная задача расчета чаевых переписывается, чтобы сделать ее более общей. Он выполняет ту же функцию, что и прежде, только теперь константы могут быть легко изменены.

lowTip = 0.05;
averTip = 0.15;
highTip = 0.25;
tipRange = highTip-lowTip;
badService = 0;
okayService = 3; 
goodService = 7;
greatService = 10;
serviceRange = greatService-badService;
badFood = 0;
greatFood = 10;
foodRange = greatFood-badFood;

% If service is poor or food is rancid, tip is cheap
if service<okayService
    tip = (((averTip-lowTip)/(okayService-badService)) ...
        *service+lowTip)*servRatio + ...
        (1-servRatio)*(tipRange/foodRange*food+lowTip);

% If service is good, tip is average
elseif service<goodService
    tip = averTip*servRatio + (1-servRatio)* ...
        (tipRange/foodRange*food+lowTip);

% If service is excellent or food is delicious, tip is generous
else
    tip = (((highTip-averTip)/ ...
        (greatService-goodService))* ...
        (service-goodService)+averTip)*servRatio + ...
        (1-servRatio)*(tipRange/foodRange*food+lowTip);
end

Как и во всем коде, чем больше общности, которая вводится, тем меньше точности становится алгоритм. Можно улучшить ясность, добавив больше комментариев или, возможно, переписав алгоритм немного более очевидными способами. Но кусочно-линейная методология - не оптимальный способ решить этот вопрос.

Если вы удаляете все из алгоритма, кроме трех комментариев, то остались именно те нечеткие логические правила, которые вы ранее записали.

  • Если сервис плох, или еда является прогорклой, советы малы

  • Если сервис хорош, советы средние

  • Если сервис превосходен, или еда восхитительна, советы будут большими

Нечеткая логика использует язык, который вам понятен и который также имеет смысл для компьютера, поэтому это успешный метод для преодоления разрыва между людьми и машинами.

Делая уравнения максимально простыми (линейными), вы делаете вещи более простыми для машины, но более сложными для вас. Однако ограничением больше не является компьютер - это ваша ментальная модель того, что делает компьютер. Нечеткая логика позволяет машине работать с вашими настройками, а не наоборот.

Похожие темы