English 中文 Español Deutsch 日本語 Português
Введение в теорию нечеткой логики

Введение в теорию нечеткой логики

MetaTrader 5Примеры | 3 сентября 2015, 10:10
17 560 14
MetaQuotes
MetaQuotes

Введение

Свое начало математическая теория нечетких множеств (fuzzy sets) и сама нечеткая логика (fuzzy logic) ведет с 1965 года. Ее отцом-основателем является профессор Лотфи Заде (Lotfi Zadeh) из университета Беркли, именно он в своей статье «Fuzzy Sets» в журнале Information and Control и ввел оба этих понятия. Данный математический аппарат позволил ввести в такую точную науку, как математика, нечеткие (размытые) понятия, которыми оперирует любой человек, и заложил основу принципиально новым методам решения задач на основе мягких вычислений. Все эти нововведения, при правильном их использовании, могут значительно облегчить процесс решения задач классификации, создания экспертных систем и построения нейронных сетей.

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


1. Теория нечетких множеств и нечеткой логики

Новая теория Лотфи Заде в некотором роде расширяет привычные нам границы математической логики и теории множеств. Математическая логика способна работать только со строго формализованными данными, а принадлежность объекта к тому или иному множеству определяется лишь двумя понятиями, то есть само понятие "принадлежность" — дискретная величина, способная принимать два значения:

  • "1" — если объект принадлежит тому или иному множеству;
  • "0" — если не принадлежит.

В своей теории нечетких множеств Лотфи Заде отошел от дискретного понятия "принадлежности" и ввел новое — "степень принадлежности", а привычные "множества" были заменены на "нечеткие множества".


1.1. Основные термины и определения

Определение 1. Нечетким множеством (fuzzy set) на универсальном множестве называется совокупность пар , где — степень принадлежности элемента нечеткому множеству.

Определение 2. Степень принадлежности — это число из диапазона [0, 1]. Чем выше степень принадлежности, тем в большей мере элемент универсального множества соответствует свойствам данного нечеткого множества. Так, если степень принадлежности равна 0, то данный элемент абсолютно не соответствует множеству, а если равна 1, то можно говорить, наоборот, о полном соответствии. Эти два случая являются краевыми и в отсутствии иных вариантов представляли бы из себя обычное множество. Наличие всех остальных вариантов и есть ключевое отличие нечеткого множества.

Определение 3. Функцией принадлежности (membership function) называется функция, которая позволяет вычислить степень принадлежности произвольного элемента универсального множества нечеткому множеству. Следовательно, область значений функций принадлежности должна принадлежать диапазону [0, 1]. В большинстве случаев функция принадлежности — это монотонная непрерывная функция.

Определение 4. Лингвистической (нечеткой) переменной (linguistic variable) называется переменная, значениями которой могут быть слова или словосочетания некоторого естественного или искусственного языка. Именно из лингвистических переменных и состоят нечеткие множества. При определении нечеткого множества количество и характер нечетких переменных субъективны для каждой отдельной задачи.

Определение 5. Терм–множеством (term set) называется множество всех возможных значений, которые способна принимать лингвистическая переменная.

Определение 6. Термом (term) называется любой элемент терм–множества. В теории нечетких множеств терм формализуется нечетким множеством с помощью функции принадлежности. Функция принадлежности для каждого термина индивидуальна и зачастую уникальна. Существуют различные методы построения этих функций: прямые, косвенные и методы относительных частот. В их основе зачастую лежат характерные точки функции принадлежности или эмпирические данные эксперта данной предметной области.

Пример:

Определим некоторую лингвистическую переменную с названием "Возраст". По определению "Возраст" — период, ступень в развитии и росте человека, животного, растения. Минимальное значение этой переменной равно 0, то есть человеку не исполнилось и года. В качестве максимального значения возьмем 80. В зависимости от конкретного возраста человека мы можем дать оценку: "новорожденный", "юный", "молодой", "среднего", "старый", "пожилой" и так далее. Этот список может вместить в себя довольно большое количество элементов. Он будет являться терм-множеством для нашей лингвистической переменной, а его элементами — термами.

На рисунке ниже приведен пример нечеткой переменной "Возраст", для которой задали терм-множество только из трех термов: "Юный", "Средний", "Старый". Каждый из термов имеет свою функцию принадлежности.

Рассмотрим случай, когда возраст человека равен 30 годам, что на рисунке будет соответствовать перпендикуляру, проведенному из точки (30, 0). Эта прямая будет пересекать все три функции принадлежности в точках:

  1. (30, 0) — точка пересечения графика "Возраст 30 лет" и графика "Старый".
  2. (30, 0.29) — точка пересечения графика "Возраст 30 лет" и графика "Средний".
  3. (30, 0.027) — точка пересечения графика "Возраст 30 лет" и графика "Юный".

Нечеткое множество "Возраст"

Из координат этих трех точек можно сделать вывод, что человека в 30 лет никак нельзя назвать старым, а если выбирать между юным и средним возрастом, то преобладает второе. Степень принадлежности к терму "Средний" равна 0.29, что довольно мало, и в действительности для человека в 30 лет куда лучше подошел бы иной терм, например "Молодой".

Определение 7. Дефаззификацией (defuzzification) называется процедура преобразования нечеткого множества в четкое число. На данный момент выделяют более двадцати методов, причем их результаты могут весьма значимо отличаться друг от друга. Следует отметить, что лучшие результаты дает дефаззификации по методу центра тяжести (center of gravity).


1.2. Нечеткая логика

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

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

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

Ход построения модели можно разделить на три основных этапа:

  1. Определение входных и выходных параметров модели.
  2. Построение базы знаний.
  3. Выбор одного из методов нечеткого логического вывода.

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

Если условие (посылка) правила, то заключение правила.

Условие правила характеризует текущее состояние объекта, а заключение — то, как это условие повлияет на объект. Общий вид условий и заключений нельзя выделить, так как они определяются нечетким логическим выводом.

Каждое правило в системе имеет вес — данный параметр характеризует значимость правила в модели. Весовые коэффициенты присваиваются правилу в диапазоне [0, 1]. Во многих примерах нечетких моделей, которые можно встретить в литературе, данные веса не указаны, но это не означает, что их нет, в действительности для каждого правила из базы в таком случае вес фиксирован и равен единице. Условия и заключения для каждого правила могут быть двух видов:

  1. простое — в нем участвует одна нечеткая переменная;
  2. составное — участвуют несколько нечетких переменных.

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


1.3. Нечеткий логический вывод Мамдани

Нечеткий логический вывод по алгоритму Мамдани выполняется по нечеткой базе знаний:


Значения входных и выходной переменной в ней заданы нечеткими множествами.

Эту базу также можно записать как:

где:

  • — вектор входных переменных;
  • выходная переменная;
  • вектор значений входных переменных в j-м правиле, j=0,1,2...m;
  • — вектор значений выходной переменной;
  • вес j-го правила, j=0,1,2...m.

Введем новое обозначение: — функция принадлежности входной или выходной нечеткой переменной v нечеткому терму t.

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

— данная функция будет характеризовать результат работы j-го правила из базы знаний;

где — операция из s-нормы (t-нормы), т.е. из множества реализаций логической операции ИЛИ (И). Наиболее часто используются следующие реализации: для операции ИЛИ — нахождение максимума и для операции И — нахождение минимума.

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

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

Далее необходимо:

  1. "срезать" функции принадлежности на уровне ;
  2. объединить полученные нечеткие множества.

Иными словами, используя термины нечеткой логики, произвести импликацию и агрегацию условий. Импликация моделируется двумя методами: нахождением минимума или произведения множеств, агрегация — нахождением максимума или суммы множеств.

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


1.4. Нечеткий логический вывод Сугено

Нечеткий логический вывод по алгоритму Сугено выполняется по нечеткой базе знаний:


База знаний Сугено аналогична базе знаний Мамдани за исключением заключений правил , которые задаются не нечеткими термами, а линейной функцией от входов:

Правила в базе знаний Сугено являются своего рода переключателями с одного линейного закона "входы - выход" на другой, тоже линейный. Границы подобластей размытые, следовательно, одновременно могут выполняться несколько линейных законов, но с различными степенями.

Эту базу также можно записать как:

где:

  • — вектор входных переменных.
  • — выходная переменная.
  • — вектор значений входных переменных в j-м правиле, j=0,1,2...m.
  • — коэффициент при свободном члене в линейной функции для выходного значения в j-м правиле, j=0,1,2...m.
  • — коэффициент при i-м члене в линейной функции для выходного значения в j-м правиле, j=0,1,2...m, i=0,1,2...n.
  • вес j-го правила, j=0,1,2...m.

Введем новое обозначение: — функция принадлежности входной или выходной нечеткой переменной v нечеткому терму t.

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

— данная функция будет характеризовать результат работы j-го правила из базы знаний;

где — операция из s-нормы (t-нормы), т.е. из множества реализаций логической операции ИЛИ (И). В нечетком логическом выводе Сугено наиболее часто используются следующие реализации треугольных норм: вероятностное ИЛИ как s-норма и произведение как t-норма.

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

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


2. Библиотека нечеткой логики FuzzyNet

На практике создание и работа даже с очень простой нечеткой моделью — весьма непростая задача, однако имеется множество различных программных средств и библиотек, которые существенно ее упрощают. Рассмотрим на примерах тестовых скриптов из библиотеки FuzzyNet для MQL5 процесс создания и работы с двумя нечеткими моделями.


2.1. Проектирование систем типа Мамдани

Первый пример — скрипт Tips_Sample_Mamdani.mq5 из библиотеки FuzzyNet для MQL5. В нем реализована нечеткая модель для вычисления чаевых, которые посетителю заведения предпочтительнее оставить, опираясь на свою оценку качества обслуживания и еды. Данная система имеет два нечетких логических входа, один выход, базу знаний из трех правил и систему логического вывода типа Мамдани.

Входными параметрами будут нечеткие переменные "еда" (food) и "сервис" (service), обе переменные оцениваются по шкале от 0 до 10 — это их минимальные и максимальные значения. Переменная "еда" состоит из двух термов: "невкусная" (rancid), "вкусная" (delicious). Переменная "сервис" будет состоять из трех нечетких термов: "плохой" (poor), "хороший" (good), "отличный" (excellent).

На выходе получим нечеткую переменную "чаевые" (tips). Определим диапазон значений оставляемых чаевых от 5 до 30% процентов от суммы в чеке и заведем для этой переменной три терма: "маленькие" (cheap), "средние" (average), "большие" (generous).

База знаний этой системы будет состоять из трех правил:

  1. Если (сервис плохой) или (еда невкусная), то чаевые маленькие.
  2. Если (сервис хороший), то чаевые средние.
  3. Если (сервис отличный) или (еда вкусная), то чаевые большие.

Теперь, имея общие представления о системе, рассмотрим процесс ее создания:

  1. Подключим файл MamdaniFuzzySystem.mqh из библиотеки FuzzyNet для MQL5:
    #include <Math\FuzzyNet\MamdaniFuzzySystem.mqh>
    Данный файл позволяет создавать системы типа Мамдани и работать с ними.

  2. Теперь мы можем создать пустую систему Мамдани и далее ее наполнять:
    MamdaniFuzzySystem *fsTips=new MamdaniFuzzySystem();
  3. Создадим первую входную переменную "сервис". При создании нечетких переменных в качестве параметров для конструктора указывается сначала имя переменной в виде строки, затем ее минимальное и максимальное значение.
    FuzzyVariable *fvService=new FuzzyVariable("service",0.0,10.0);
  4. Добавим в нее нечеткие термы. В качестве параметров конструктор нечетких терминов принимает первым параметром имя в виде строки, а вторым — соответствующую ему функцию принадлежности.
    fvService.Terms().Add(new FuzzyTerm("poor", new TriangularMembershipFunction(-5.0, 0.0, 5.0)));
    fvService.Terms().Add(new FuzzyTerm("good", new TriangularMembershipFunction(0.0, 5.0, 10.0)));
    fvService.Terms().Add(new FuzzyTerm("excellent", new TriangularMembershipFunction(5.0, 10.0, 15.0)));
    Функции принадлежности в данном примере для всех термов представлены в виде треугольной функции.

  5. Теперь уже готовую и сформированную нечеткую переменную добавляем в нашу систему:
    fsTips.Input().Add(fvService);
  6. Аналогично реализуем второй вход для системы с переменной "еда", только термины для этой переменной будут иметь трапециевидную функцию принадлежности.
    FuzzyVariable *fvFood=new FuzzyVariable("food",0.0,10.0);
    fvFood.Terms().Add(new FuzzyTerm("rancid", new TrapezoidMembershipFunction(0.0, 0.0, 1.0, 3.0)));
    fvFood.Terms().Add(new FuzzyTerm("delicious", new TrapezoidMembershipFunction(7.0, 9.0, 10.0, 10.0)));
    fsTips.Input().Add(fvFood);
  7. Поскольку система имеет логический вывод Мамдани, ее входные и выходные значения будет определяться одними и теми же способами. Поэтому по аналогии создадим выход:
    FuzzyVariable *fvTips=new FuzzyVariable("tips",0.0,30.0);
    fvTips.Terms().Add(new FuzzyTerm("cheap", new TriangularMembershipFunction(0.0, 5.0, 10.0)));
    fvTips.Terms().Add(new FuzzyTerm("average", new TriangularMembershipFunction(10.0, 15.0, 20.0)));
    fvTips.Terms().Add(new FuzzyTerm("generous", new TriangularMembershipFunction(20.0, 25.0, 30.0)));
    fsTips.Output().Add(fvTips);
  8. Создадим нечеткие правила, которые в совокупности будут представлять базу знаний нашей системы. Для создания правила необходимо вызвать метод ParseRule от объекта, который представляет нашу систему, и в качестве параметра передать ему простое строковое представление нечеткого правила:
    MamdaniFuzzyRule *rule1 = fsTips.ParseRule("if (service is poor) or (food is rancid) then (tips is cheap)");
    MamdaniFuzzyRule *rule2 = fsTips.ParseRule("if (service is good) then (tips is average)");
    MamdaniFuzzyRule *rule3 = fsTips.ParseRule("if (service is excellent) or (food is delicious) then (tips is generous)");

    Написание нечетких правил строго типизировано и не допускает использование неключевых слов. Ключевыми словами являются: "if", "then", "is", "and", "or", "not", "(" , ")", "slightly", "somewhat", "very", "extremely". Последние четыре ключевых слова являются лингвистическими квантификаторами. Также к ключевым словам относятся все имена переменных, терминов и функций, имеющихся в вашей системе. Лингвистическими квантификаторами увеличивают или, наоборот, уменьшают значимость нечетких термов или линейных функций Сугено. Реализация лингвистических квантификаторов:

    1. "slightly" — "едва", заменяет результат посылки на ее кубический корень. Сильно уменьшает значимость.
    2. "somewhat" — "отчасти", заменяет результат посылки на ее квадратный корень. Уменьшает значимость.
    3. "very" — "очень", возводит результат посылки во вторую степень. Увеличивает значимость.
    4. "extremely" — "экстремально", возводит результат посылки в третью степень. Сильно увеличивает значимость.

  9. Осталось лишь добавить правила в систему:
    fsTips.Rules().Add(rule1);
    fsTips.Rules().Add(rule2);
    fsTips.Rules().Add(rule3);

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


2.2. Проектирование систем типа Сугено

Примером реализации системы типа Сугено будет скрипт для вычисления необходимого управления системой круиз-контроля автомобиля. Этот скрипт описан в файле Cruise_Control_Sample_Sugeno.mq5 библиотеки FuzzyNet для MQL5 и является одним из примеров применения нечетких моделей для решения задач автоматического управления.

Именно для таких одномерных задач в системах автоматического управления (САУ) и нашла наибольшее распространение нечеткая логика. Постановка этих задач звучит примерно так: некий объект в момент времени находится в состоянии "A", необходимо, чтобы за время он пришел в состояние "B". Для решения задач такого типа весь временной участок разбивают на частей, находят шаг по времени, равный , и далее САУ необходимо вырабатывать управление в каждой точке , где i=0,1,2...n.

С данной задачей легко справляются различные ПИД-регуляторы, но у них есть один существенный недостаток — они не могут выработать, скажем так, "плавное" управление. То есть если построить систему круиз-контроля автомобиля на основе ПИД-регулятора, при изменении скорости эта система выведет вас на заданную, но при этом могут быть различные рывки и толчки. Нечеткий регулятор сможет выполнить все гораздо плавнее и комфортнее с точки зрения человека.

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

  • разность между скоростью автомобиля в данный момент и скоростью, установленной в системе круиз-контроля;
  • как быстро эта разность уменьшается (увеличивается).

Итак, первый входной параметр "ошибка скорости" (SpeedError) будет принимать значения от -20 до 20 км/ч и иметь три терма: "уменьшилась" (slower), "не изменилась" (zero), "увеличилась" (faster). Все три терма будут иметь треугольную функцию принадлежности. Второй вход — "производная по ошибке скорости" (SpeedErrorDot) с диапазоном от -5 до 5 и нечеткими термами "уменьшилась" (slower), "не изменилась" (zero), "увеличилась" (faster) также с треугольной функцией принадлежности.

Поскольку наша модель имеет систему логического вывода Сугено, выходное значение "ускорение" (Accelerate) не будет иметь максимального и минимального значения, а вместо нечетких терминов будут линейные комбинации входных переменных, которые также будут иметь имена: "не изменять" (zero), "увеличить" (faster), "уменьшить" (slower), "поддерживать" (func). Распишем все четыре линейные комбинации. Для этого обозначим переменные SpeedError как , SpeedErrorDot как , а Accelerate как , тогда получим уравнения:

  1. zero: ;
  2. faster: ;
  3. slower: ;
  4. func: .

База знаний этой системы будет состоять из девяти правил:

  1. Если (ошибка уменьшилась) и (производная по ошибке уменьшилась), то ускорение увеличить.
  2. Если (ошибка уменьшилась) и (производная по ошибке не изменилась), то ускорение увеличить.
  3. Если (ошибка уменьшилась) и (производная по ошибке увеличилась), то ускорение не изменять.
  4. Если (ошибка не изменилась) и (производная по ошибке уменьшилась), то ускорение увеличить.
  5. Если (ошибка не изменилась) и (производная по ошибке не изменилась), то ускорение поддерживать.
  6. Если (ошибка не изменилась) и (производная по ошибке увеличилась), то ускорение уменьшить.
  7. Если (ошибка увеличилась) и (производная по ошибке уменьшилась), то ускорение увеличить.
  8. Если (ошибка увеличилась) и (производная по ошибке не изменилась), то ускорение уменьшить.
  9. Если (ошибка увеличилась) и (производная по ошибке увеличилась), то ускорение уменьшить.

Рассмотрим непосредственно ход создания системы:

  1. Подключим файл SugenoFuzzySystem.mqh из библиотеки FuzzyNet для MQL5:
    #include <Math\FuzzyNet\SugenoFuzzySystem.mqh>
    Данный файл позволяет создавать системы типа Сугено и работать с ними.

  2. Теперь мы можем создать пустую систему Сугено и далее ее наполнять:
    SugenoFuzzySystem *fsCruiseControl=new SugenoFuzzySystem();
  3. Входные переменные для системы Сугено создаются так же, как и для системы типа Мамдани.

    Создадим переменную "ошибка скорости" и добавим ее в систему:

    FuzzyVariable *fvSpeedError=new FuzzyVariable("SpeedError",-20.0,20.0);
    fvSpeedError.Terms().Add(new FuzzyTerm("slower",new TriangularMembershipFunction(-35.0,-20.0,-5.0)));
    fvSpeedError.Terms().Add(new FuzzyTerm("zero", new TriangularMembershipFunction(-15.0, -0.0, 15.0)));
    fvSpeedError.Terms().Add(new FuzzyTerm("faster", new TriangularMembershipFunction(5.0, 20.0, 35.0)));

    Создадим переменную "изменение ошибки скорости" и также добавим ее в систему:

    FuzzyVariable *fvSpeedErrorDot=new FuzzyVariable("SpeedErrorDot",-5.0,5.0);
    fvSpeedErrorDot.Terms().Add(new FuzzyTerm("slower", new TriangularMembershipFunction(-9.0, -5.0, -1.0)));
    fvSpeedErrorDot.Terms().Add(new FuzzyTerm("zero", new TriangularMembershipFunction(-4.0, -0.0, 4.0)));
    fvSpeedErrorDot.Terms().Add(new FuzzyTerm("faster", new TriangularMembershipFunction(1.0, 5.0, 9.0)));
  4. Создадим нечеткую переменную типа Сугено, которая будет являться выходом системы. При создании нечеткой переменной конструктор принимает лишь один параметр — ее имя. Далее в нее можно добавлять линейные функции, но прежде эти функции нужно определить, а для этого нужен массив коэффициентов типа double.

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

    В нашей системе две входные переменные, поэтому длины массивов коэффициентов не должны превышать трех. Объявим все четыре массива, на их основе сформируем описанные выше функции и добавим их в нечеткую переменную типа Сугено, а ее, в свою очередь, занесем в систему:
    SugenoVariable *svAccelerate=new SugenoVariable("Accelerate");
    double coeff1[3]={0.0,0.0,0.0};
    svAccelerate.Functions().Add(fsCruiseControl.CreateSugenoFunction("zero",coeff1));
    double coeff2[3]={0.0,0.0,1.0};
    svAccelerate.Functions().Add(fsCruiseControl.CreateSugenoFunction("faster",coeff2));
    double coeff3[3]={0.0,0.0,-1.0};
    svAccelerate.Functions().Add(fsCruiseControl.CreateSugenoFunction("slower",coeff3));
    double coeff4[3]={-0.04,-0.1,0.0};
    svAccelerate.Functions().Add(fsCruiseControl.CreateSugenoFunction("func",coeff4));
    fsCruiseControl.Output().Add(svAccelerate);
  5. По аналогии с системой Мамдани создадим все девять нечетких правил:
    SugenoFuzzyRule *rule1 = fsCruiseControl.ParseRule("if (SpeedError is slower) and (SpeedErrorDot is slower) then (Accelerate is faster)");
    SugenoFuzzyRule *rule2 = fsCruiseControl.ParseRule("if (SpeedError is slower) and (SpeedErrorDot is zero) then (Accelerate is faster)");
    SugenoFuzzyRule *rule3 = fsCruiseControl.ParseRule("if (SpeedError is slower) and (SpeedErrorDot is faster) then (Accelerate is zero)");
    SugenoFuzzyRule *rule4 = fsCruiseControl.ParseRule("if (SpeedError is zero) and (SpeedErrorDot is slower) then (Accelerate is faster)");
    SugenoFuzzyRule *rule5 = fsCruiseControl.ParseRule("if (SpeedError is zero) and (SpeedErrorDot is zero) then (Accelerate is func)");
    SugenoFuzzyRule *rule6 = fsCruiseControl.ParseRule("if (SpeedError is zero) and (SpeedErrorDot is faster) then (Accelerate is slower)");
    SugenoFuzzyRule *rule7 = fsCruiseControl.ParseRule("if (SpeedError is faster) and (SpeedErrorDot is slower) then (Accelerate is faster)");
    SugenoFuzzyRule *rule8 = fsCruiseControl.ParseRule("if (SpeedError is faster) and (SpeedErrorDot is zero) then (Accelerate is slower)");
    SugenoFuzzyRule *rule9 = fsCruiseControl.ParseRule("if (SpeedError is faster) and (SpeedErrorDot is faster) then (Accelerate is slower)");
  6. Добавим их в нашу систему:
    fsCruiseControl.Rules().Add(rule1);
    fsCruiseControl.Rules().Add(rule2);
    fsCruiseControl.Rules().Add(rule3);
    fsCruiseControl.Rules().Add(rule4);
    fsCruiseControl.Rules().Add(rule5);
    fsCruiseControl.Rules().Add(rule6);
    fsCruiseControl.Rules().Add(rule7);
    fsCruiseControl.Rules().Add(rule8);
    fsCruiseControl.Rules().Add(rule9);


2.3. Расчет систем типа Мамдани и Сугено

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

Что же именно нужно подавать на вход системы и в каком виде мы получим результат от нее?

Количество входных переменных для нечетких систем не ограниченно, каждый вход обязательно должен принимать какие-то значения, следовательно, мы должны иметь список, в котором будем хранить значения для каждого входа. Элементами этого списка должен быть сложный объект с двумя полями: первое — нечеткая переменная, а второе — числовое значение типа double. В файле Dictionary.mqh из библиотеки FuzzyNet на MQL5 реализован класс Dictionary_Obj_Double, позволяющий создавать такие объекты.

Сформируем входной список для нашей системы типа Мамдани:

CList *in=new CList;
Dictionary_Obj_Double *p_od_Service=new Dictionary_Obj_Double;
Dictionary_Obj_Double *p_od_Food=new Dictionary_Obj_Double;
p_od_Service.SetAll(fvService, Service);
p_od_Food.SetAll(fvFood, Food);
in.Add(p_od_Service);
in.Add(p_od_Food);

Здесь Service и Food — два входных параметра типа double.

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

Выход для системы типа Мамдани:

CList *result=new CList;
Dictionary_Obj_Double *p_od_Tips=new Dictionary_Obj_Double;

Теперь для каждой системы вызываем функцию Calculate, которая принимает один параметр — список входов, а возвращает список выходов. По индексу 0 из этого списка получим значения выхода системы, который представлен как объект класса Dictionary_Obj_Double. Используя методы Key и Value для данного объекта, можно получить переменную и ее результат соответственно.

Выполним расчет для системы Мамдани и выведем на экран полученное число при нечеткой выходной переменной fvTips:

result=fsTips.Calculate(in);
p_od_Tips=result.GetNodeAtIndex(0);
Alert("Tips, %: ",p_od_Tips.Value());

Проделаем то же самое с системой типа Сугено:

CList *in=new CList;
Dictionary_Obj_Double *p_od_Error=new Dictionary_Obj_Double;
Dictionary_Obj_Double *p_od_ErrorDot=new Dictionary_Obj_Double;
p_od_Error.SetAll(fvSpeedError,Speed_Error);
p_od_ErrorDot.SetAll(fvSpeedErrorDot,Speed_ErrorDot);
in.Add(p_od_Error);
in.Add(p_od_ErrorDot);
CList *result=new CList;
Dictionary_Obj_Double *p_od_Accelerate=new Dictionary_Obj_Double;
result=fsCruiseControl.Calculate(in);
p_od_Accelerate=result.GetNodeAtIndex(0);
Alert("Accelerate, %: ",p_od_Accelerate.Value()*100);


Заключение

Более подробно ознакомиться со скриптами, описанными выше, а также создать свою нечеткую модель вы можете, скачав библиотеку FuzzyNet для MQL5 или MQL4. Важно понимать, что построение "боевых" нечетких моделей — это довольно непростая работа, даже с использованием каких-либо вспомогательных библиотек, а каждая готовая модель требует обязательной доскональной проверки и настройки.


Список литературы и ссылки

  1. http://matlab.exponenta.ru/fuzzylogic/index.php — полная теория нечеткой логики и нечетких множеств, а также примеры их реализации средствами MATLAB.
  2. http://www.gotai.net/documents/doc-l-fl-001.aspx — введение в теорию, список примеров того, как и где реально применяется нечеткая логика.
  3. Сигеру Омату. Нейроуправление и его приложения — в данной книге есть отдельная глава про нечеткие нейрорегуляторы.
  4. Владимир Гостев. Нечеткие регуляторы в системах автоматического управления — более подробное и объемное описание нечетких регуляторов.
  5. Осовский С. Нейронные сети для обработки информации.
  6. Статья Андрея Масаловича: Нечеткая логика в бизнесе и финансах.
  7. http://nrsu.bstu.ru/introduction.html
Последние комментарии | Перейти к обсуждению на форуме трейдеров (14)
Vladimir Perervenko
Vladimir Perervenko | 20 сент. 2015 в 10:02
Yury Reshetov:

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

А посему столь низкий интерес к теме, поскольку спецы, компетентные только в одной из областей зачастую не могут освоить вторую. И то и другое требует немалого опыта.

Впрочем в машинном обучении, где начинающие по наивности полагают, что алгоритм "сам всё разрулит, достаточно только научиться скармливать ему данные", тоже оказывается, что разруливать придётся пользователю. Т.е. зачастую проще формализовать задачу самостоятельно, после чего применение алгоритмов машинного обучения уже не имеет никакого смысла и становится лишним.

Согласен.

Но экспериментировать нужно продолжать.

Удачи

ПС. Кстати, давно хотел спросить. Вы не хотели бы переложить свой продукт написанный на Ява на язык R? Тогда его можно было бы опробовать в "бою" на МТ4.

Так, мысли вслух

Alexander Fedosov
Alexander Fedosov | 20 сент. 2015 в 11:27
Vladimir Perervenko:

А как же правила? Посмотрим статью.

Удачи

Ну правила связи входных и выходных термов это само собой.
Yury Reshetov
Yury Reshetov | 20 сент. 2015 в 11:34
Vladimir Perervenko:

ПС. Кстати, давно хотел спросить. Вы не хотели бы переложить свой продукт написанный на Ява на язык R?

Вопрос не по адресу. Портацией под R занимается CRAN, а я к этой организации не имею никакого отношения. Более того, я R не знаю и тратить время на изучение не собираюсь, т.к. меня визуализация игр в цифири не интересует.

На данный момент пока стоит вопрос: стоит ли потратить время на освоение нечёткой логики или имеем дело с очередной уткой. Если почитать бахвальные статьи о нечёткой логике, то получается, что ей пользуется чуть ли не каждый уважающий себя финансист. Если посмотреть, каким инструментарием пользуются финансисты для принятия решений, то оказывается, что наиболее распространён Excel c разными пакетами, среди которых пакетов нечёткой логики явно не наблюдается.

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

СанСаныч Фоменко
СанСаныч Фоменко | 20 сент. 2015 в 14:39
Yury Reshetov:

Вопрос не по адресу. Портацией под R занимается CRAN, а я к этой организации не имею никакого отношения. Более того, я R не знаю и тратить время на изучение не собираюсь, т.к. меня визуализация игр в цифири не интересует.

На данный момент пока стоит вопрос: стоит ли потратить время на освоение нечёткой логики или имеем дело с очередной уткой. 

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

Ну, и что?

Проблема ведь не в этом!

Проблема в том, чтобы не скатиться в игру в цифирь, не уподобиться той мартышке, которая примеряла очки.

Основное правило статистики гласит: мусор на входе - мусор на выходе.

Как в мясорубку: что подал на вход, то и получил на выходе, но в другом виде.

Применительно к статье.

Ведь основной вопрос: для каких областей в трейдинге применима эта нечеткая логика?

Вот 40 лет назад  придумали модель ARMA. При этом четко оговорили целый ряд нюансов со стационарными и нестационарными рядами. Оказалось, что на финансовых рынках сделан шаг, но очень маленький с огромными опасностями по сторонам. А что автор нам сообщил о применимости нечеткой логики? Может я чего не уловил?  

Оболочка caret  из R включает более 150 пакетов из области машинного обучения. Ну, и что? О применимости на финансовых рынках каждого из пакетов этой оболочки известно достаточно много, но чтоб что-то заработать  приходится очень много поработать со входными данными, минимум 70% времени уходит на входные данные,  процентов 10% на применение собственно готового, отлаженного алгоритма. Остальное на технику торговли, включая управление рисками. Кстати среди пакетов оболочки caret отсутствует нечеткая логика.

Отсюда, основные усилия в области нечеткой логики (как и любых других математических инструментов) следует сосредоточить на формулировании условий ПРИМЕНИМОСТИ данного инструмента на финансовых рынках и частности на форексе. А на досуге, при желании и наличия времени, разобраться с внутренним устройством матметода.

 

ПС.

Просто для справки из R 

fuzzyFDRExact calculation of fuzzy decision rules for multiple testing
FuzzyLPFuzzy Linear Programming
FuzzyNumbersTools to Deal with Fuzzy Numbers
fuzzyRankTestsFuzzy Rank Tests and Confidence Intervals
FuzzyStatProbFuzzy Stationary Probabilities from a Sequence of Observations of an Unknown Markov Chain
FuzzyToolkitUoNType 1 Fuzzy Logic Toolkit
Yury Reshetov
Yury Reshetov | 20 сент. 2015 в 15:48
СанСаныч Фоменко:

Отсюда, основные усилия в области нечеткой логики (как и любых других математических инструментов) следует сосредоточить на формулировании условий ПРИМЕНИМОСТИ данного инструмента на финансовых рынках и частности на форексе. А на досуге, при желании и наличия времени, разобраться с внутренним устройством матметода.

Раскатали губу, однако.

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

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

Ежели посмотреть на нечёткую логику, как на некий автоматический регулятор типа ПИДов, который всего лишь сглаживает дерготню по сравнению со своим конкурентом, то фиг его знает, как это можно применить в трейдинге? Рынок регулировать - бабла маловато. На собственном депо только баланс управляемый, а эквити пляшет, куда ему вздумается. Но баланс нафиг не нужен - он для школоты. Может быть регулировать риски? Но тут процент от депо рулит нехило и без всякой дерготни, не говоря о том, что никаких правил сочинять не надо, т.к. он задаётся всего одной константой.

Фиг его знает, куда можно было бы эту самую нечёткую прикрутить?

Использование утверждений (assertions) при разработке программ на MQL5 Использование утверждений (assertions) при разработке программ на MQL5
В данной статье рассматриваются утверждения (assertions) в рамках языка MQL5. Даются два примера реализации механизма утверждений, а также приводятся общие рекомендации по применению утверждений.
Теория рынка Теория рынка
До сих пор не существует логически завершенной теории рынка, охватывающей все типы и разновидности рынков товаров и услуг, микро- и макро-рынков, наподобие Форекс. Статья повествует о сущности новой теории рынка, основанной на анализе прибыли, вскрывает закономерности изменения текущей цены, а также выявляет принцип работы механизма, позволяющего цене находить наиболее оптимальное свое значение путем образования цепи виртуальных цен, способных вырабатывать управляющие воздействия на саму цену. Выявлены механизмы образования и смены трендов на рынке.
Индикатор для построения графика "шпинделей" (веретён) Индикатор для построения графика "шпинделей" (веретён)
Статья рассматривает построение графика "шпинделей" (spindles) или, как их еще называют, "веретён", его использование в торговых стратегиях и советниках. Вначале обсудим появление графика, его построение и связь с графиком японских свечей. Далее проанализируем реализацию индикатора в программном коде на языке MQL5. Протестируем основанный на индикаторе эксперт и сформулируем торговую стратегию.
Price Action. Автоматизация торговли по паттерну "Поглощение" Price Action. Автоматизация торговли по паттерну "Поглощение"
В статье описывается создание советника для MetaTrader 4, торгующего по паттерну "Поглощение", включая принцип нахождения паттерна, правила установки отложенных и стоп-ордеров. Приведены результаты тестирования и оптимизации.