Main Content

Model Suburban Commuting Using Subtractive Clustering

This example shows how to model the relationship between the number of automobile trips generated from an area and the demographics of the area using the genfis function. Demographic and trip data are from 100 traffic analysis zones in New Castle County, Delaware. Five demographic factors are considered: population, number of dwelling units, vehicle ownership, median household income, and total employment. Hence, the model has five input variables and one output variable.

Load and plot the data.


The mytripdata command creates several variables in the workspace. Of the original 100 data points, use 75 data points as training data (datin and datout) and 25 data points as checking data (as well as for test data to validate the model). The checking data input/output pair variables are chkdatin and chkdatout.

Generate a model from the data using subtractive clustering using the genfis command.

First, create a genfisOptions option set for subtractive clustering, specifying ClusterInfluenceRange range property. The ClusterInfluenceRange property indicates the range of influence of a cluster when you consider the data space as a unit hypercube. Specifying a small cluster radius usually yields many small clusters in the data, and results in many rules. Specifying a large cluster radius usually yields a few large clusters in the data, and results in fewer rules.

opt = genfisOptions('SubtractiveClustering','ClusterInfluenceRange',0.5);

Generate the FIS model using the training data and the specified options.

fismat = genfis(datin,datout,opt);

The genfis command uses a one-pass method that does not perform any iterative optimization. The model type for the generated FIS object is a first order Sugeno model with three rules.

Verify the model. Here, trnRMSE is the root mean squared error of the system generated by the training data.

fuzout = evalfis(fismat,datin);
trnRMSE = norm(fuzout-datout)/sqrt(length(fuzout))
trnRMSE = 0.5276

Next, apply the test data to the FIS to validate the model. In this example, the validation data is used for both checking and testing the FIS parameters. Here, chkRMSE is the root mean squared error of the system generated by the validation data.

chkfuzout = evalfis(fismat,chkdatin);
chkRMSE = norm(chkfuzout-chkdatout)/sqrt(length(chkfuzout))
chkRMSE = 0.6179

Plot the output of the model, chkfuzout, against the validation data, chkdatout.

hold on
hold off

The model output and validation data are shown as circles and solid blue line, respectively. The plot shows that the model does not perform well on the validation data.

At this point, you can use the optimization capability of anfis to improve the model. First, try using a relatively short training period (20 epochs) without using validation data, and then test the resulting FIS model against the testing data.

anfisOpt = anfisOptions('InitialFIS',fismat,'EpochNumber',20,...
fismat2 = anfis([datin datout],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

After the training is complete, validate the model.

fuzout2 = evalfis(fismat2,datin);
trnRMSE2 = norm(fuzout2-datout)/sqrt(length(fuzout2))
trnRMSE2 = 0.4203
chkfuzout2 = evalfis(fismat2,chkdatin);
chkRMSE2 = norm(chkfuzout2-chkdatout)/sqrt(length(chkfuzout2))
chkRMSE2 = 0.5894

The model has improved a lot with respect to the training data, but only a little with respect to the validation data. Plot the improved model output obtained using anfis against the testing data.

hold on
hold off

The model output and validation data are shown as circles and solid blue line, respectively. This plot shows that subtractive clustering with genfis can be used as a standalone, fast method for generating a fuzzy model from data, or as a preprocessor to determine the initial rules for anfis training. An important advantage of using a clustering method to find rules is that the resultant rules are more tailored to the input data than they are in a FIS generated without clustering. This result reduces the problem of an excessive propagation of rules when the input data has a high dimension.

Overfitting can be detected when the checking error starts to increase while the training error continues to decrease.

To check the model for overfitting, use anfis with validation data to train the model for 200 epochs.

First configure the ANFIS training options by modifying the existing anfisOptions option set. Specify the epoch number and validation data. Since the number of training epochs is larger, suppress the display of training information to the Command Window.

anfisOpt.EpochNumber = 200;
anfisOpt.ValidationData = [chkdatin chkdatout];
anfisOpt.DisplayANFISInformation = 0;
anfisOpt.DisplayErrorValues = 0;
anfisOpt.DisplayStepSize = 0;
anfisOpt.DisplayFinalResults = 0;

Train the FIS.

[fismat3,trnErr,stepSize,fismat4,chkErr] = anfis([datin datout],anfisOpt);


  • fismat3 is the FIS object when the training error reaches a minimum.

  • fismat4 is the snapshot FIS object when the validation data error reaches a minimum.

  • stepSize is a history of the training step sizes.

  • trnErr is the RMSE using the training data

  • chkErr is the RMSE using the validation data for each training epoch.

After the training completes, validate the model.

fuzout4 = evalfis(fismat4,datin);
trnRMSE4 = norm(fuzout4-datout)/sqrt(length(fuzout4))
trnRMSE4 = 0.3393
chkfuzout4 = evalfis(fismat4,chkdatin);
chkRMSE4 = norm(chkfuzout4-chkdatout)/sqrt(length(chkfuzout4))
chkRMSE4 = 0.5834

The error with the training data is the lowest thus far, and the error with the validation data is also slightly lower than before. This result suggests possible overfitting, which occurs when you fit the fuzzy system to the training data so well that it no longer does a good job of fitting the validation data. The result is a loss of generality.

View the improved model output. Plot the model output against the checking data.

hold on
hold off

The model output and validation data are shown as circles and solid blue line, respectively.

Next, plot the training error, trnErr.

title('Training Error')
xlabel('Number of Epochs')
ylabel('Training Error')

This plot shows that the training error settles at about the 60th epoch point.

Plot the checking error, chkErr.

title('Checking Error')
xlabel('Number of Epochs')
ylabel('Checking Error')

The plot shows that the smallest value of the validation data error occurs at the 52nd epoch. After this point it increases slightly even as anfis continues to minimize the error against the training data all the way to the 200th epoch. Depending on the specified error tolerance, the plot also indicates the ability of the model to generalize the test data.

You can also compare the output of fismat2 and fistmat4 against the validation data, chkdatout.

hold on

See Also


Related Topics