exponenta event banner

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

Основная проблема опрокидывания

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

Какова правильная сумма, чтобы дать чаевые своему официанту?

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

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

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

Nonfuzzy подход

Начните с простейших отношений. Предположим, что наконечник всегда равен 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

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

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

  • Если обслуживание плохое или еда прогорклая, чаевые дешевые

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

  • Если обслуживание отличное или еда вкусная, чаевые щедрые

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

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

Связанные темы