В этом примере показано, как смоделировать связь между количеством автомобильных поездок, сгенерированных из области, и демографией области с помощью вычитающей кластеризации и настройки ANFIS.
Этот пример использует демографические и туристические данные из 100 зон анализа трафика в округе Нью-Касл, штат Делавэр. Набор данных содержит пять демографических факторов в качестве переменных входов: население, количество жилых модулей, владение транспортными средствами, средний доход домохозяйства и общая занятость. Данные содержат одну выходную переменную, количество поездок автомобилей.
Загрузите данные обучения и валидации.
load trafficData
Набор данных содержит 100 точек данных, 75 для обучения и 25 для валидации. Обучающие входные данные (datain
) и валидация входных данных (valdatain
) каждый имеет пять столбцов, которые представляют входные переменные. Выходные данные обучения (dataout
) и валидация выходных данных (valdataout
) каждый имеет по одному столбцу, который представляет переменный выход.
Постройте график обучающих данных.
subplot(2,1,1) plot(datain) legend("population","number of dwelling units","vehicle ownership",... "median household 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
набор опций для вычитания кластеризации, задающий то же значение области значений влияния кластера.
opt = genfisOptions("SubtractiveClustering","ClusterInfluenceRange",0.5);
Сгенерируйте модель FIS с помощью обучающих данных и заданных опций.
fis = genfis(datain,dataout,opt);
Основываясь на размерностях входных и выходных обучающих данных, сгенерированный FIS имеет пять входов и один выход. genfis
присваивает имена по умолчанию для входов, выходов и функций принадлежности.
Сгенерированный объект FIS является системой Sugeno первого порядка с тремя правилами.
showrule(fis)
ans = 3x158 char array
'1. If (in1 is in1cluster1) and (in2 is in2cluster1) and (in3 is in3cluster1) and (in4 is in4cluster1) and (in5 is in5cluster1) then (out1 is out1cluster1) (1)'
'2. If (in1 is in1cluster2) and (in2 is in2cluster2) and (in3 is in3cluster2) and (in4 is in4cluster2) and (in5 is in5cluster2) then (out1 is out1cluster2) (1)'
'3. If (in1 is in1cluster3) and (in2 is in2cluster3) and (in3 is in3cluster3) and (in4 is in4cluster3) and (in5 is in5cluster3) then (out1 is out1cluster3) (1)'
Можно представить каждое правило следующим образом: Если входы в FIS (население, жилые модули, num транспортные средства, доход и занятость) сильно относятся к их представительным функциям членства для кластера, то выходные (num of trips) должны принадлежать одному и тому же кластеру. То есть каждое правило кратко преобразует кластер во входном пространстве в тот же кластер в выход пространстве.
Каждая входная и выходная переменная имеет три функции принадлежности, которые соответствуют трем идентифицированным кластерам. Параметры входных и выходных функций принадлежности получают на основе центров кластеров и областей значений влияния кластеров. В качестве примера постройте график функций принадлежности для первой входной переменной.
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 на соответствие данным валидации.
anfisOpt = anfisOptions('InitialFIS',fis,... 'EpochNumber',20,... 'InitialStepSize',0.1); fis2 = anfis([datain dataout],anfisOpt);
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.485036 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
набор опций. Укажите количество эпох и данных валидации. Поскольку количество циклов обучения больше, подавьте отображение обучающей информации в Командном окне.
anfisOpt.EpochNumber = 200; anfisOpt.ValidationData = [valdatain valdataout]; anfisOpt.DisplayANFISInformation = 0; anfisOpt.DisplayErrorValues = 0; anfisOpt.DisplayStepSize = 0; anfisOpt.DisplayFinalResults = 0;
Обучите FIS.
[fis3,trnErr,stepSize,fis4,valErr] = anfis([datain dataout],anfisOpt);
Здесь:
fis3
- объект FIS, когда ошибка обучения достигает минимума.
fis4
- объект FIS моментального снимка, когда ошибка данных валидации достигает минимума.
stepSize
- история размеров шагов обучения.
trnErr
- RMSE, использующий обучающие данные.
valErr
- RMSE, использующий данные валидации для каждой эпохи обучения.
После завершения обучения проверьте модель с помощью данных обучения и валидации.
fuzout4 = evalfis(fis4,datain); trnRMSE4 = norm(fuzout4-dataout)/sqrt(length(fuzout4))
trnRMSE4 = 0.3393
valfuzout4 = evalfis(fis4,valdatain); valRMSE4 = norm(valfuzout4-valdataout)/sqrt(length(valfuzout4))
valRMSE4 = 0.5834
Ошибка с обучающими данными является самой низкой до сих пор, и ошибка с данными валидации также немного ниже, чем ранее. Этот результат предполагает возможный сверхподбор кривой, которая происходит, когда вы подгоняете нечеткую систему к обучающим данным настолько хорошо, что это больше не дает хорошей работы по подбору кривой данных валидации. Результатом является потеря общности.
Просмотрите улучшенный выход модели. Постройте график выхода модели с данными валидации.
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
продолжает минимизировать ошибку по отношению к обучающим данным. Этот шаблон является признаком сверхподбора кривой. В зависимости от заданного допуска ошибки построение графика ошибки валидации может также указать на способность модели обобщать тестовые данные.