exponenta event banner

Оптимизация параметров FIS с помощью k-кратной перекрестной проверки

В этом примере показано, как оптимизировать параметры системы нечеткого вывода (FIS) с помощью k-кратной перекрестной проверки. В этом примере используется оптимизация генетического алгоритма (GA).

Замена данных в настройке параметров FIS

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

Чтобы преодолеть проблему переполнения данных, можно остановить процесс настройки на ранней стадии на основе объективной оценки модели с помощью отдельного набора данных проверки. Однако такой набор проверочных данных может также увеличить смещение, если он не точно представляет проблемное пространство. Чтобы преодолеть смещение из набора данных проверки, обычно используется k-кратный подход перекрестной проверки. Здесь обучающие данные случайным образом перетасовываются и затем разделяются на k разделов, как показано на следующем рисунке. Для каждой итерации проверки обучения используется отдельный раздел для проверки, а остальные данные используются для тестирования. Поэтому каждый раздел данных используется один раз для проверки и k-1 раз для обучения.

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

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

Настройка FIS без K-кратной проверки

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

В этом примере используются следующие шесть атрибутов входных данных для прогнозирования атрибута выходных данных MPG с FIS.

  • Количество баллонов

  • Смещение

  • Лошадиная сила

  • Вес

  • Ускорение

  • Модельный год

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

[data,varName,trnX,trnY,testX,testY] = loadData;

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

fisin = constructFIS(data,varName);

Создайте набор параметров для настройки FIS. Набор опций по умолчанию использует GA для оптимизации.

options = tunefisOptions;

При наличии программного обеспечения Parallel Computing Toolbox™ можно повысить скорость процесса настройки, задав options.UseParallel кому true. Если у вас нет программного обеспечения Parallel Computing Toolbox, установите options.UseParallel кому false.

Чтобы продемонстрировать проблему переполнения данных, в этом примере для настройки правил используется максимум 100 поколений.

options.MethodOptions.MaxGenerations = 100;

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

runtunefis = false;

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

  • Ошибка обучения - среднеквадратичная ошибка (RMSE) между ожидаемым результатом обучения и фактическим результатом обучения, полученным из настроенной FIS.

  • Ошибка теста - RMSE между ожидаемым результатом теста и фактическим результатом теста, полученным из настроенной FIS.

  • Количество функций - общее количество оценок функции затрат для настройки FIS.

В этом примере для настройки FIS используйте только параметры правил.

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

if runtunefis    
    % Get rule parameter settings.
    [~,~,rule] = getTunableSettings(fisin);
    
    % Set default random number generator.    
    rng('default')    

    % Tune rule parameters.
    [outputFIS,optimData] = tunefis(fisin,rule,trnX,trnY,options);

    % Get the training error.
    trnErrNoKFold = optimData.tuningOutputs.fval
    
    % Calculate the test error.
    evalOptions = evalfisOptions("EmptyOutputFuzzySetMessage","none", ...
        "NoRuleFiredMessage","none","OutOfRangeInputValueMessage","none");
    actY = evalfis(outputFIS,testX,evalOptions);
    del = actY - testY;
    testErrNoKFold = sqrt(mean(del.^2))
    
    % Get the function count.
    fcnCountNoKFold = optimData.totalFcnCount
    
    save tuningWithoutKFoldValidation trnErrNoKFold testErrNoKFold fcnCountNoKFold
else
    % Load the pretrained results.
    results = load('tuningWithoutKFoldValidation.mat');
    trnErrNoKFold = results.trnErrNoKFold
    testErrNoKFold = results.testErrNoKFold
    fcnCountNoKFold = results.fcnCountNoKFold
end
trnErrNoKFold = 2.4952
testErrNoKFold = 2.8412
fcnCountNoKFold = 19210

Более высокое значение ошибки тестирования по сравнению с ошибкой обучения указывает на то, что обученная FIS более смещена к данным обучения.

Настройка параметров FIS с проверкой K-Fold

Можно использовать k-кратную перекрестную проверку при оптимизации параметров FIS путем установки options.KFoldValue до значения, большего или равного 2. В этом примере установите значение k-fold равным 4.

options.KFoldValue = 4;

Чтобы задать значение допуска, используемое для раннего остановки процесса k-кратной настройки, установите значение options.ValidationTolerance собственность. В этом примере задайте значение допуска 0,02. Это значение допуска настраивает k-кратный процесс настройки на остановку, если текущие затраты на проверку увеличиваются более чем на 2% от минимальных затрат на проверку, найденных до этого момента процесса настройки.

options.ValidationTolerance = 0.02;

Для шумного набора данных можно вычислить скользящее среднее стоимости проверки, установив значение options.ValidationWindowSize свойство имеет значение больше 1. В этом примере задайте размер окна проверки равным 2.

options.ValidationWindowSize = 2;

Ограничьте максимальное количество поколений в каждом процессе настройки 25, чтобы общее число поколений в 4-кратном процессе настройки было таким же, как в предыдущем случае.

options.MethodOptions.MaxGenerations = 25;

Настройте FIS с k-кратной проверкой.

if runtunefis    
    % Set default random number generator.
    rng('default')
    
    % Tune the FIS.
    [outputFIS,optimData] = tunefis(fisin,rule,trnX,trnY,options);
    
    % Get the training error.
    trnErrWithKFold = optimData.tuningOutputs(end).fval
    
    % Calculate the test error.
    actY = evalfis(outputFIS,testX,evalOptions);
    del = actY - testY;
    testErrWithKFold = sqrt(mean(del.^2))
    
    % Get the function count.
    fcnCountWithKFold = optimData.totalFcnCount
    
    save tuningWithKFoldValidation trnErrWithKFold testErrWithKFold fcnCountWithKFold
else
    % Load the pretrained results.
    results = load('tuningWithKFoldValidation.mat');
    trnErrWithKFold = results.trnErrWithKFold
    testErrWithKFold = results.testErrWithKFold
    fcnCountWithKFold = results.fcnCountWithKFold
end
trnErrWithKFold = 2.7600
testErrWithKFold = 2.9082
fcnCountWithKFold = 5590

Постройте график различий ошибок от теста к обучению для обучения как с k-кратными случаями, так и без них.

figure
cats = categorical({'Without k-fold','With k-fold'});
cats = reordercats(cats,{'Without k-fold','With k-fold'});
data = [trnErrNoKFold testErrNoKFold testErrNoKFold-trnErrNoKFold; ...
    trnErrWithKFold testErrWithKFold testErrWithKFold-trnErrWithKFold];
b = bar(cats,data);
ylabel('Root mean squared error (RMSE)')
text(b(3).XEndPoints,b(3).YEndPoints,string(b(3).YData),'HorizontalAlignment','center',...
    'VerticalAlignment','bottom')
legend('Training error','Test error','Test-to-training error difference', ...
    'Location','northoutside')

Figure contains an axes. The axes contains 5 objects of type bar, text. These objects represent Training error, Test error, Test-to-training error difference.

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

disp(table(fcnCountNoKFold,fcnCountWithKFold, ...
    'VariableNames',["Without k-fold" "With k-fold"], ...
    'RowName',"Function counts"))
                       Without k-fold    With k-fold
                       ______________    ___________

    Function counts        19210            5590    

Поэтому k-кратная проверка уменьшает количество поколений в каждом цикле оптимизации GA, уменьшая переоборудование параметров FIS. Общие k-кратные результаты проверки могут быть дополнительно улучшены путем экспериментов с различными значениями k-кратности, допуска и размера окна.

В общем случае для оптимизации параметров FIS с k-кратной проверкой используйте следующий процесс:

  1. Начните с допуска проверки 0 и размера окна 1, которые обеспечивают минимальную k-кратную производительность.

  2. Увеличьте k-кратное значение для достижения желаемой производительности. Обычно используют k-кратное значение, меньшее или равное 10.

  3. Увеличьте значение допуска для достижения желаемой производительности.

  4. Увеличьте размер окна для достижения желаемой производительности.

  5. При необходимости выполните этапы 3 и 4 в петле.

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

Локальные функции

function [data,varName,trnX,trnY,testX,testY] = loadData

% Load the data. Each row of the dataset obtained from the repository represents 
% a different automobile profile. Data contains 7 columns, where the first six 
% columns contain the following input attributes.
%   - Number of cylinders
%   - Displacement
%   - Horsepower
%   - Weight
%   - Acceleration
%   - Model year
% The seventh column contains the output attribute, MPG.
[data,name] = loadGasData;

% Remove leading and trailing whitespace from the attribute names.
varName = strtrim(string(name));

% Create input and output data sets.
n = size(data,2);
x = data(:,1:n-1);
y = data(:,n);

% Create training and test data sets.
trnX = x(1:2:end,:);
trnY = y(1:2:end,:);
testX = x(2:2:end,:);
testY = y(2:2:end,:);

end

function fisin = constructFIS(data,varName)

% Create a Sugeno FIS.
fisin = sugfis;

% Add input and output variables to the FIS, where each variable represents
% one of the data attributes. For each variable, use the corresponding
% attribute name and range. To reduce the number of rules, use two MFs for
% each input variable, which results in 2^6=64 input MF combinations.
% Therefore, the FIS uses a maximum of 64 rules corresponding to the input
% MF combinations. Both input and output variables use default triangular
% MFs, which are uniformly distributed over the variable ranges.
dataRange = [min(data)' max(data)'];
numINputs = size(data,2)-1;
numInputMFs = 2;
numOutputMFs = numInputMFs^numINputs;
for i = 1:numINputs
    fisin = addInput(fisin,dataRange(i,:),'Name',varName(i),'NumMFs',numInputMFs);
end

% To improve data generalization, use 64 MFs for the output variable.
% Doing so allows the FIS to use a different output MF for each rule.
fisin = addOutput(fisin,dataRange(end,:),'Name',varName(end),'NumMFs',numOutputMFs);
fisin.Rules = repmat(fisrule,[1 numOutputMFs]);

end

См. также

|

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