В этом примере показано, как смоделировать отношение между количеством автомобильных прохождений, сгенерированных от области и демографией области с помощью отнимающей кластеризации и настройки ANFIS.
Этот пример использует демографический и данные о прохождении из 100 аналитических зон трафика в графстве Ньюкасл, Делавэр. Набор данных содержит пять демографических факторов как входные переменные: население, количество жилых секций, владения транспортного средства, среднего дохода семьи и общей занятости. Данные содержат одну выходную переменную, количество автомобильных прохождений.
Загрузите данные об обучении и валидации.
load trafficData
Набор данных содержит 100 точек данных, 75 для обучения и 25 для валидации. Учебные входные данные (datain
) и входные данные валидации (valdatain
) у каждого есть пять столбцов, которые представляют входные переменные. Учебные выходные данные (dataout
) и выходные данные валидации (valdataout
) у каждого есть один столбец, который представляет выходную переменную.
Отобразите обучающие данные на графике.
subplot(2,1,1) plot(datain) legend("population","number of dwellings","vehicle ownership",... "median income","total employment","Location","northwest") title('Input Variables') xlabel('Data Point') subplot(2,1,2) plot(dataout) legend("number of trips") title("Output Variable") xlabel('Data Point')
Отнимающая кластеризация является быстрым алгоритмом с одной передачей для оценки количества кластеров и кластерных центров в наборе данных. Чтобы кластеризировать обучающие данные с помощью отнимающей кластеризации, используйте subclust
функция.
[C,S] = subclust([datain dataout],0.5);
В данном примере используйте кластерную область значений влияния 0.5
. Это значение указывает на область значений влияния кластера, когда вы рассматриваете пространство данных как единичный гиперкуб. Определение маленького кластерного радиуса обычно генерирует много небольших кластеров в данных, которые производят FIS со многими правилами. Определение большого кластерного радиуса обычно производит несколько больших кластеров в данных и приводит к меньшему количеству правил.
Каждая строка C
содержит позицию кластерного центра, идентифицированного кластеризирующимся алгоритмом. В этом случае алгоритм нашел три кластера в данных.
C
C = 3×6
1.8770 0.7630 0.9170 18.7500 1.5650 2.1830
0.3980 0.1510 0.1320 8.1590 0.6250 0.6480
3.1160 1.1930 1.4870 19.7330 0.6030 2.3850
Отобразите обучающие данные на графике наряду с кластерными центрами двух из входных переменных.
figure plot(datain(:,5),dataout(:,1),'.',C(:,5),C(:,6),"r*") legend("Data points","Cluster centers","Location","southeast") xlabel("Total Employment") ylabel("Number of Trips") title("Data and Cluster Centers")
Значения в S
покажите область значений влияния кластерных центров каждой размерности данных. Все кластерные центры имеют тот же набор S
значения.
S
S = 1×6
1.1621 0.4117 0.6555 7.6139 2.8931 1.4395
Используйте genfis
функция, чтобы сгенерировать нечеткую систему вывода (FIS) из данных с помощью отнимающей кластеризации.
Важное преимущество использования метода кластеризации, чтобы найти правила состоит в том, что результирующие правила более адаптируются в соответствии с входными данными, чем они находятся в FIS, сгенерированном без кластеризации. Эта адаптация сокращает общее количество правил, когда входные данные имеют высокую размерность.
Во-первых, создайте genfisOptions
набор опции для отнимающей кластеризации, задавая то же кластерное значение области значений влияния.
fisOpt = genfisOptions("SubtractiveClustering",... "ClusterInfluenceRange",0.5);
Сгенерируйте модель FIS с помощью обучающих данных и заданных опций.
fis = genfis(datain,dataout,fisOpt);
На основе размерностей обучающих данных ввода и вывода сгенерированный FIS имеет пять входных параметров и один выход. genfis
имена по умолчанию присвоений для входных параметров, выходных параметров и функций принадлежности.
Сгенерированный объект FIS является системой Sugeno первого порядка с тремя правилами.
showrule(fis,"Format","symbolic")
ans = 3x132 char array
'1. (in1==in1cluster1) & (in2==in2cluster1) & (in3==in3cluster1) & (in4==in4cluster1) & (in5==in5cluster1) => (out1=out1cluster1) (1)'
'2. (in1==in1cluster2) & (in2==in2cluster2) & (in3==in3cluster2) & (in4==in4cluster2) & (in5==in5cluster2) => (out1=out1cluster2) (1)'
'3. (in1==in1cluster3) & (in2==in2cluster3) & (in3==in3cluster3) & (in4==in4cluster3) & (in5==in5cluster3) => (out1=out1cluster3) (1)'
Можно осмыслять каждое правило можно следующим образом: Если входные параметры к FIS (население, жилые секции, цифровые транспортные средства, поступают, и занятость) строго принадлежат своим представительным функциям принадлежности для кластера, то выход (цифра прохождений) должен принадлежать тому же кластеру. Таким образом, каждое правило кратко сопоставляет кластер во входном пространстве к тому же кластеру на выходном пробеле.
Каждая переменная ввода и вывода имеет три функции принадлежности, которые соответствуют трем идентифицированным кластерам. Параметры функций принадлежности ввода и вывода выведены на основе кластерных центров и кластерных областей значений влияния. Как пример, постройте функции принадлежности для первой входной переменной.
figure
plotmf(fis,"input",1)
Примените учебные входные значения к нечеткой системе и найдите соответствующие выходные значения.
fuzout = evalfis(fis,datain);
Вычислите среднеквадратическую ошибку (RMSE) выходных значений нечеткой системы по сравнению с ожидаемыми выходными значениями.
trnRMSE = norm(fuzout-dataout)/sqrt(length(fuzout))
trnRMSE = 0.5276
Подтвердите эффективность нечеткой системы с помощью данных о валидации.
valfuzout = evalfis(fis,valdatain); valRMSE = norm(valfuzout-valdataout)/sqrt(length(valfuzout))
valRMSE = 0.6179
Постройте выход модели против данных о валидации.
figure plot(valdataout) hold on plot(valfuzout,"o") hold off ylabel("Output value") legend("Validation data","FIS output","Location","northwest")
График показывает, что модель не предсказывает данные о валидации хорошо.
Чтобы улучшать производительность FIS, можно оптимизировать систему с помощью anfis
функция. Во-первых, попытайтесь использовать относительно короткий период подготовки (20 эпох), не используя данные о валидации, и затем протестируйте получившуюся модель FIS против данных о валидации.
opt = anfisOptions('InitialFIS',fis,... 'EpochNumber',20,... 'InitialStepSize',0.1); fis2 = anfis([datain dataout],opt);
ANFIS info: Number of nodes: 44 Number of linear parameters: 18 Number of nonlinear parameters: 30 Total number of parameters: 48 Number of training data pairs: 75 Number of checking data pairs: 0 Number of fuzzy rules: 3 Start training ANFIS ... 1 0.527607 2 0.513727 3 0.492996 4 0.499985 5 0.490585 6 0.492924 Step size decreases to 0.090000 after epoch 7. 7 0.48733 8 0.485037 9 0.480813 Step size increases to 0.099000 after epoch 10. 10 0.475097 11 0.469759 12 0.462516 13 0.451177 Step size increases to 0.108900 after epoch 14. 14 0.447856 15 0.444357 16 0.433904 17 0.433739 Step size increases to 0.119790 after epoch 18. 18 0.420408 19 0.420512 20 0.420275 Designated epoch number reached. ANFIS training completed at epoch 20. Minimal training RMSE = 0.420275
Оцените эффективность FIS и на обучающих данных и на данных о валидации.
fuzout2 = evalfis(fis2,datain); trnRMSE2 = norm(fuzout2-dataout)/sqrt(length(fuzout2))
trnRMSE2 = 0.4203
valfuzout2 = evalfis(fis2,valdatain); valRMSE2 = norm(valfuzout2-valdataout)/sqrt(length(valfuzout2))
valRMSE2 = 0.5894
Производительность модели показывает существенное улучшение относительно обучающих данных, но незначительно относительно данных о валидации. Постройте улучшенный выход модели против данных о валидации.
figure plot(valdataout) hold on plot(valfuzout,'o') plot(valfuzout2,'x') hold off ylabel('Output value') legend("Validation data",... "Initial FIS: RMSE = " + num2str(valRMSE), ... "Tuned FIS: RMSE = " + num2str(valRMSE2), ... "Location","northwest")
При настройке FIS можно обнаружить сверхподбор кривой, когда ошибка валидации начинает увеличиваться, в то время как учебная ошибка продолжает уменьшаться.
Чтобы проверять модель на сверхподбор кривой, используйте anfis
с данными о валидации, чтобы обучить модель в течение 200 эпох. Сначала сконфигурируйте опции обучения ANFIS путем изменения существующего anfisOptions
опция установлена. Задайте номер данных о валидации и эпох. Поскольку количество циклов обучения больше, подавите отображение учебной информации в Командном окне.
opt.EpochNumber = 200; opt.ValidationData = [valdatain valdataout]; opt.DisplayANFISInformation = 0; opt.DisplayErrorValues = 0; opt.DisplayStepSize = 0; opt.DisplayFinalResults = 0;
Обучите FIS.
[fis3,trnErr,stepSize,fis4,valErr] = anfis([datain dataout],opt);
Здесь:
fis3
объект FIS, когда учебная ошибка достигает минимума.
fis4
объект FIS снимка состояния, когда ошибка данных о валидации достигает минимума.
stepSize
история учебных размеров шага.
trnErr
RMSE использование обучающих данных.
valErr
RMSE использование данных о валидации в течение каждой учебной эпохи.
После того, как обучение завершается, подтвердите модель с помощью данных об обучении и валидации.
fuzout4 = evalfis(fis4,datain); trnRMSE4 = norm(fuzout4-dataout)/sqrt(length(fuzout4))
trnRMSE4 = 0.3405
valfuzout4 = evalfis(fis4,valdatain); valRMSE4 = norm(valfuzout4-valdataout)/sqrt(length(valfuzout4))
valRMSE4 = 0.5821
Ошибка с обучающими данными является самой низкой к настоящему времени, и ошибка с данными о валидации также немного ниже, чем прежде. Этот результат предлагает возможный сверхподбор кривой, который происходит, когда вы соответствуете нечеткой системе к обучающим данным так хорошо, что это больше не делает хорошее задание подбора кривой данным о валидации. Результатом является потеря общности.
Просмотрите улучшенный вывод модели. Постройте выход модели против данных о валидации.
figure plot(valdataout) hold on plot(valfuzout2,'o') plot(valfuzout4,'x') hold off ylabel('Output value') legend("Validation data",... "Tuned FIS: RMSE = " + num2str(valRMSE2), ... "Min val. error FIS: RMSE = " + num2str(valRMSE4), ... "Location","northwest")
Затем постройте учебную ошибку trnErr
.
figure plot(trnErr) title('Training Error') xlabel('Number of Epochs') ylabel('Error')
Этот график показывает, что учебная ошибка обосновывается приблизительно в 60-ю эпоху.
Постройте ошибку валидации valErr
.
figure plot(valErr) title('Validation Error') xlabel('Number of Epochs') ylabel('Error')
График показывает, что наименьшее значение ошибки данных о валидации происходит в эпоху 52. После этой точки это увеличивается немного как раз когда anfis
продолжает минимизировать ошибку против обучающих данных. Этот шаблон является знаком сверхподбора кривой. В зависимости от заданного ошибочного допуска, строя ошибку валидации может также указать на способность модели обобщить тестовые данные.