├── Benchmarks ├── HSI_Index.mat ├── SSE_Index.mat └── SandP_Index.mat ├── createMembershipFunction.m ├── createMembershipFunctionContinuousRFNN.m ├── costCalculation.m ├── evaluateMFForStateNetworkOutput.m ├── objectiveFunction.m ├── createGaussianMembershipFunction.m ├── generateGaussianFuzzyRulesUsingCoverage.m ├── generateTriangleFuzzyRulesUsingCoverage.m ├── createGeneralizedBellshapeMembershipfunction.m ├── calculateMembershipValues.m ├── createGaussian2MembershipFunction.m ├── calculatingTestError.m ├── README.md └── main.m /Benchmarks/HSI_Index.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Hamid-Nasiri/VMD-MFRFNN/HEAD/Benchmarks/HSI_Index.mat -------------------------------------------------------------------------------- /Benchmarks/SSE_Index.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Hamid-Nasiri/VMD-MFRFNN/HEAD/Benchmarks/SSE_Index.mat -------------------------------------------------------------------------------- /Benchmarks/SandP_Index.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Hamid-Nasiri/VMD-MFRFNN/HEAD/Benchmarks/SandP_Index.mat -------------------------------------------------------------------------------- /createMembershipFunction.m: -------------------------------------------------------------------------------- 1 | function mf = createMembershipFunction (nMembership) 2 | 3 | type = 'trimf' ; 4 | mf = []; 5 | fsb = linspace (0, 1, nMembership); 6 | step = fsb(2); 7 | fsb = [-step fsb 1+step]; 8 | for i = 1:nMembership 9 | param = [fsb(i) fsb(i+1) fsb(i+2)]; 10 | mf = [mf ; fismf(type, param)]; 11 | end 12 | 13 | end -------------------------------------------------------------------------------- /createMembershipFunctionContinuousRFNN.m: -------------------------------------------------------------------------------- 1 | function mf = createMembershipFunctionContinuousRFNN(nMembership) 2 | 3 | mf = []; 4 | 5 | if nMembership == 2 6 | type = "trapmf"; 7 | params = [0 0 1 2]; 8 | mf = [mf ; fismf(type, params)]; 9 | params = [1 2 3 3]; 10 | mf = [mf ; fismf(type, params)]; 11 | elseif nMembership == 3 12 | type = "trapmf"; 13 | params = [0 0 1 2]; 14 | mf = [mf ; fismf(type, params)]; 15 | type = "trimf"; 16 | params = [1 2 3]; 17 | mf = [mf ; fismf(type, params)]; 18 | type = "trapmf"; 19 | params = [2 3 4 4]; 20 | mf = [mf ; fismf(type, params)]; 21 | end 22 | 23 | end 24 | -------------------------------------------------------------------------------- /costCalculation.m: -------------------------------------------------------------------------------- 1 | %% Calculate Cost of currentIndividual and Update Its W 2 | 3 | s = zeros(nStates,1); 4 | s(1) = 1; 5 | 6 | RS_Big = zeros(nData, nRules_Output*nStates); 7 | 8 | for t=1:nData 9 | 10 | %% Find Output 11 | % Compute Cartesian Product R x S 12 | [R, S] = meshgrid(rbarOutput(:,t),s); 13 | RS = R(:) .* S(:); 14 | RS_Big(t,:) = RS; 15 | 16 | %% Find Next State 17 | 18 | [R2, S2] = meshgrid(rbarState(:,t),s); 19 | RS2 = R2(:) .* S2(:); 20 | nextState = RS2' * currentIndividual.V(:); 21 | 22 | nextState = (nextState*(nStates-1)) + 1; 23 | 24 | % This Script Calculate S 25 | evaluateMFForStateNetworkOutput; 26 | 27 | end 28 | 29 | lastState = nextState; 30 | W = lsqminnorm(RS_Big, targetOutput); 31 | currentIndividual.W = reshape(W,nStates,nRules_Output); 32 | predictedOutput = RS_Big * currentIndividual.W(:); 33 | currentIndividual.Cost = sqrt(immse(predictedOutput,targetOutput)); 34 | -------------------------------------------------------------------------------- /evaluateMFForStateNetworkOutput.m: -------------------------------------------------------------------------------- 1 | if nStates == 1 2 | s(1) = 1; 3 | elseif nStates == 2 4 | s(1) = trapmf(nextState,[0 0 1 2]); 5 | s(2) = trapmf(nextState,[1 2 3 3]); 6 | elseif nStates == 3 7 | s(1) = trapmf(nextState,[0 0 1 2]); 8 | s(2) = trimf(nextState, [1 2 3]); 9 | s(3) = trapmf(nextState,[2 3 4 4]); 10 | elseif nStates == 5 11 | s(1) = trapmf(nextState,[0 0 1 2]); 12 | s(2) = trimf(nextState, [1 2 3]); 13 | s(3) = trimf(nextState, [2 3 4]); 14 | s(4) = trimf(nextState, [3 4 5]); 15 | s(5) = trapmf(nextState,[4 5 6 6]); 16 | elseif nStates == 10 17 | s(1) = trapmf(nextState,[0 0 1 2]); 18 | s(2) = trimf(nextState, [1 2 3]); 19 | s(3) = trimf(nextState, [2 3 4]); 20 | s(4) = trimf(nextState, [3 4 5]); 21 | s(5) = trimf(nextState, [4 5 6]); 22 | s(6) = trimf(nextState, [5 6 7]); 23 | s(7) = trimf(nextState, [6 7 8]); 24 | s(8) = trimf(nextState, [7 8 9]); 25 | s(9) = trimf(nextState, [8 9 10]); 26 | s(10) = trapmf(nextState,[9 10 11 11]); 27 | else 28 | s(1) = trapmf(nextState, [0 0 1 2]); 29 | for i = 2:nStates-1 30 | s(i) = trimf(nextState, [i-1 i i+1]); 31 | end 32 | s(nStates) = trapmf(nextState,[nStates-1 nStates nStates+1 nStates+1]); 33 | end -------------------------------------------------------------------------------- /objectiveFunction.m: -------------------------------------------------------------------------------- 1 | function out = objectiveFunction (V) 2 | 3 | global nStates; 4 | global nData; 5 | global nRules_Output; 6 | global rbarOutput; 7 | global rbarState; 8 | global currentIndividual; 9 | global targetOutput; 10 | 11 | currentIndividual.V = V; 12 | 13 | s = zeros(nStates,1); 14 | s(1) = 1; 15 | RS_Big = zeros(nData, nRules_Output*nStates); 16 | for t=1:nData 17 | 18 | %% Find Output 19 | % Compute Cartesian Product R x S 20 | [R, S] = meshgrid(rbarOutput(:,t),s); 21 | RS = R(:) .* S(:); 22 | RS_Big(t,:) = RS; 23 | 24 | %% Find Next State 25 | 26 | [R2, S2] = meshgrid(rbarState(:,t),s); 27 | RS2 = R2(:) .* S2(:); 28 | nextState = RS2' * currentIndividual.V(:); 29 | nextState = (nextState*(nStates-1)) + 1; 30 | evaluateMFForStateNetworkOutput 31 | 32 | end 33 | 34 | W = lsqminnorm(RS_Big, targetOutput); 35 | currentIndividual.W = reshape(W,nStates,nRules_Output); 36 | predictedOutput = RS_Big * currentIndividual.W(:); 37 | currentIndividual.Cost = sqrt(immse(predictedOutput,targetOutput)); 38 | out = currentIndividual.Cost; 39 | 40 | end -------------------------------------------------------------------------------- /createGaussianMembershipFunction.m: -------------------------------------------------------------------------------- 1 | function mf = createGaussianMembershipFunction(nMembership) 2 | 3 | mf = []; 4 | type = "gaussmf"; 5 | if nMembership == 2 6 | params = [0.4247 0 ; 0.4247 1]; 7 | elseif nMembership == 3 8 | params = [0.2123 0; 0.2123 0.5; 0.2123 1]; 9 | elseif nMembership == 4 10 | params = [0.1416 0; 0.1416 0.3333; 0.1416 0.6667; 0.1416 1]; 11 | elseif nMembership == 5 12 | params = [0.1062 0; 0.1062 0.25; 0.1062 0.5; 0.1062 0.75; 0.1062 1]; 13 | elseif nMembership == 6 14 | params = [0.08493 0; 0.08493 0.2; 0.08493 0.4; 0.08493 0.6; 15 | 0.08493 0.8; 0.08493 1]; 16 | elseif nMembership == 7 17 | params = [0.07078 0; 0.07078 0.1667; 0.07078 0.3333; 0.07078 0.5; 18 | 0.07078 0.6667; 0.07078 0.8333; 0.07078 1]; 19 | elseif nMembership == 8 20 | params = [0.06067 0;0.06067 0.1429; 0.06067 0.2857; 21 | 0.06067 0.4286; 0.06067 0.5714; 0.06067 0.7143; 22 | 0.06067 0.8571; 0.06067 1]; 23 | elseif nMembership == 9 24 | params = [0.05308 0; 0.05308 0.125; 0.05308 0.25; 0.05308 0.375; 25 | 0.05308 0.5; 0.05308 0.625; 0.05308 0.75; 0.05308 0.875; 26 | 0.05308 1]; 27 | 28 | end 29 | for i = 1:nMembership 30 | mf = [mf ; fismf(type, params(i,:))]; 31 | end 32 | 33 | end 34 | -------------------------------------------------------------------------------- /generateGaussianFuzzyRulesUsingCoverage.m: -------------------------------------------------------------------------------- 1 | 2 | fprintf('Generating Gaussian Fuzzy Rules Using Coverage\n'); 3 | 4 | trainInputShuffled = trainInput; 5 | mf = []; 6 | if nDimensions == 1 7 | % Create a rule for first data 8 | mf = fismf('gaussmf',[ruleSigma, trainInputShuffled(1)]); 9 | for ii = 2:nData 10 | % Check Coverage 11 | membershipValue = evalmf(mf,trainInputShuffled(ii)); 12 | membershipValueSUM = sum(membershipValue); 13 | if membershipValueSUM < coverageThreshold 14 | % Create new Rule 15 | mf = [mf ; fismf('gaussmf',[ruleSigma, trainInputShuffled(ii)])]; 16 | end 17 | end 18 | elseif nDimensions > 1 19 | % Create a rule for first data 20 | for ii = 1:nDimensions 21 | mf = [mf fismf('gaussmf',[ruleSigma, trainInputShuffled(1,ii)])]; 22 | end 23 | for ii = 2:nData 24 | % Check Coverage 25 | membershipValue = []; 26 | for jj = 1:nDimensions 27 | membershipValue = [membershipValue evalmf(mf(:,jj),trainInputShuffled(ii,jj))]; 28 | end 29 | membershipValueProduct = 1; 30 | for jj = 1:nDimensions 31 | membershipValueProduct = membershipValueProduct .* membershipValue(:,jj); 32 | end 33 | membershipValueSUM = sum(membershipValueProduct); 34 | if membershipValueSUM < coverageThreshold 35 | % Create new Rule 36 | newRuleMf = []; 37 | for jj = 1:nDimensions 38 | newRuleMf = [newRuleMf fismf('gaussmf',[ruleSigma, trainInputShuffled(ii,jj)])]; 39 | end 40 | mf = [mf ; newRuleMf]; 41 | end 42 | end 43 | end 44 | 45 | -------------------------------------------------------------------------------- /generateTriangleFuzzyRulesUsingCoverage.m: -------------------------------------------------------------------------------- 1 | 2 | fprintf('Generating Triangle Fuzzy Rules Using Coverage\n'); 3 | 4 | trainInputShuffled = trainInput; 5 | mf = []; 6 | if nDimensions == 1 7 | % Create a rule for first data 8 | mf = fismf('trimf',[trainInputShuffled(1)-ruleSigma trainInputShuffled(1) trainInputShuffled(1)+ruleSigma]); 9 | for ii = 2:nData 10 | % Check Coverage 11 | membershipValue = evalmf(mf,trainInputShuffled(ii)); 12 | membershipValueSUM = sum(membershipValue); 13 | if membershipValueSUM < coverageThreshold 14 | % Create new Rule 15 | mf = [mf ; fismf('trimf',[trainInputShuffled(ii)-ruleSigma trainInputShuffled(ii) trainInputShuffled(ii)+ruleSigma])]; 16 | end 17 | end 18 | elseif nDimensions > 1 19 | % Create a rule for first data 20 | for ii = 1:nDimensions 21 | mf = [mf fismf('trimf',[trainInputShuffled(1,ii)-ruleSigma trainInputShuffled(1,ii) trainInputShuffled(1,ii)+ruleSigma])]; 22 | end 23 | for ii = 2:nData 24 | if mod(ii,500) == 0 25 | ii 26 | end 27 | % Check Coverage 28 | membershipValue = []; 29 | for jj = 1:nDimensions 30 | membershipValue = [membershipValue evalmf(mf(:,jj),trainInputShuffled(ii,jj))]; 31 | end 32 | membershipValueProduct = 1; 33 | for jj = 1:nDimensions 34 | membershipValueProduct = membershipValueProduct .* membershipValue(:,jj); 35 | end 36 | membershipValueSUM = sum(membershipValueProduct); 37 | if membershipValueSUM < coverageThreshold 38 | % Create new Rule 39 | newRuleMf = []; 40 | for jj = 1:nDimensions 41 | newRuleMf = [newRuleMf fismf('trimf',[trainInputShuffled(ii,jj)-ruleSigma trainInputShuffled(ii,jj) trainInputShuffled(ii,jj)+ruleSigma])]; 42 | end 43 | mf = [mf ; newRuleMf]; 44 | end 45 | end 46 | end 47 | -------------------------------------------------------------------------------- /createGeneralizedBellshapeMembershipfunction.m: -------------------------------------------------------------------------------- 1 | function mf = createGeneralizedBellshapeMembershipfunction(nMembership) 2 | 3 | %% Create membership functions using a combination of two Gaussian membership functions 4 | mf = []; 5 | type = "gbellmf"; 6 | if nMembership == 2 7 | params = [0.5 2.5 0; 8 | 0.5 2.5 1]; 9 | elseif nMembership == 3 10 | params = [0.25 2.5 0; 11 | 0.25 2.5 0.5; 12 | 0.25 2.5 1]; 13 | elseif nMembership == 4 14 | params = [0.1667 2.5 0; 15 | 0.1667 2.5 0.3333; 16 | 0.1667 2.5 0.6667; 17 | 0.1667 2.5 1]; 18 | elseif nMembership == 5 19 | params = [0.125 2.5 0; 20 | 0.125 2.5 0.25; 21 | 0.125 2.5 0.5; 22 | 0.125 2.5 0.75; 23 | 0.125 2.5 1]; 24 | elseif nMembership == 6 25 | params = [0.1 2.5 0; 26 | 0.1 2.5 0.2; 27 | 0.1 2.5 0.4; 28 | 0.1 2.5 0.6; 29 | 0.1 2.5 0.8; 30 | 0.1 2.5 1]; 31 | elseif nMembership == 7 32 | params = [0.08333 2.5 0; 33 | 0.08333 2.5 0.1667; 34 | 0.08333 2.5 0.3333; 35 | 0.08333 2.5 0.5; 36 | 0.08333 2.5 0.6667; 37 | 0.08333 2.5 0.8333; 38 | 0.08333 2.5 1]; 39 | elseif nMembership == 8 40 | params = [0.07143 2.5 0; 41 | 0.07143 2.5 0.1429; 42 | 0.07143 2.5 0.2857; 43 | 0.07143 2.5 0.4286; 44 | 0.07143 2.5 0.5714; 45 | 0.07143 2.5 0.7143; 46 | 0.07143 2.5 0.8571; 47 | 0.07143 2.5 1]; 48 | elseif nMembership == 9 49 | params = [0.0625 2.5 0; 50 | 0.0625 2.5 0.125; 51 | 0.0625 2.5 0.25; 52 | 0.0625 2.5 0.375; 53 | 0.0625 2.5 0.5; 54 | 0.0625 2.5 0.625; 55 | 0.0625 2.5 0.75; 56 | 0.0625 2.5 0.875; 57 | 0.0625 2.5 1]; 58 | end 59 | for i = 1:nMembership 60 | mf = [mf ; fismf(type, params(i,:))]; 61 | end 62 | 63 | end 64 | -------------------------------------------------------------------------------- /calculateMembershipValues.m: -------------------------------------------------------------------------------- 1 | 2 | muOutput = zeros(nFuzzySetsOutput, nData, nDimensions); 3 | muState = zeros(nFuzzySetsState, nData, nDimensions); 4 | rOutput = zeros(nRules_Output, nData); 5 | rState = zeros(nRules_State, nData); 6 | 7 | 8 | for ii=1:nDimensions 9 | muOutput(:,:,ii) = evalmf(mfOutput(:,ii),trainInput(:,ii)); 10 | muState(:,:,ii) = evalmf(mfState(:,ii),trainInput(:,ii)); 11 | end 12 | % Compute Cartesian Product of Rules 13 | 14 | if nDimensions == 2 && coverageRules == false 15 | for ii=1:nData 16 | [R1,R2] = meshgrid(muOutput(:,ii,1),muOutput(:,ii,2)); 17 | [S1,S2] = meshgrid(muState(:,ii,1),muState(:,ii,2)); 18 | rOutput(:,ii) = R1(:) .* R2(:); 19 | rState(:,ii) = S1(:) .* S2(:); 20 | end 21 | elseif nDimensions == 3 && coverageRules == false 22 | for ii=1:nData 23 | [R1,R2, R3] = meshgrid(muOutput(:,ii,1),muOutput(:,ii,2),muOutput(:,ii,3)); 24 | [S1,S2, S3] = meshgrid(muState(:,ii,1),muState(:,ii,2),muState(:,ii,3)); 25 | rOutput(:,ii) = R1(:) .* R2(:) .* R3(:); 26 | rState(:,ii) = S1(:) .* S2(:) .* S3(:); 27 | end 28 | elseif nDimensions == 4 && coverageRules == false 29 | for ii=1:nData 30 | [R1,R2, R3, R4] = ndgrid(muOutput(:,ii,1),muOutput(:,ii,2),muOutput(:,ii,3),muOutput(:,ii,4)); 31 | [S1,S2, S3, S4] = ndgrid(muState(:,ii,1),muState(:,ii,2),muState(:,ii,3),muState(:,ii,4)); 32 | rOutput(:,ii) = R1(:) .* R2(:) .* R3(:) .* R4(:); 33 | rState(:,ii) = S1(:) .* S2(:) .* S3(:) .* S4(:); 34 | end 35 | elseif nDimensions == 5 && coverageRules == false 36 | for ii=1:nData 37 | [R1,R2, R3, R4, R5] = ndgrid(muOutput(:,ii,1),muOutput(:,ii,2),muOutput(:,ii,3),muOutput(:,ii,4),muOutput(:,ii,5)); 38 | [S1,S2, S3, S4, S5] = ndgrid(muState(:,ii,1),muState(:,ii,2),muState(:,ii,3),muState(:,ii,4),muState(:,ii,5)); 39 | rOutput(:,ii) = R1(:) .* R2(:) .* R3(:) .* R4(:) .* R5(:); 40 | rState(:,ii) = S1(:) .* S2(:) .* S3(:) .* S4(:) .* S5(:); 41 | end 42 | elseif nDimensions == 1 && coverageRules == false 43 | rOutput = muOutput; 44 | rState = muState; 45 | elseif coverageRules == true 46 | rOutput(:,:) = 1; 47 | rState(:,:) = 1; 48 | for ii=1:nDimensions 49 | rOutput = rOutput .* muOutput(:,:,ii); 50 | rState = rState .* muState(:,:,ii); 51 | end 52 | end 53 | 54 | rbarOutput = rOutput ./ sum(rOutput); 55 | rbarState = rState ./ sum(rState); 56 | 57 | -------------------------------------------------------------------------------- /createGaussian2MembershipFunction.m: -------------------------------------------------------------------------------- 1 | function mf = createGaussian2MembershipFunction(nMembership) 2 | 3 | %% Create membership functions using a combination of two Gaussian membership functions 4 | mf = []; 5 | type = "gauss2mf"; 6 | if nMembership == 2 7 | params = [0.3397 -0.1 0.3397 0.1; 8 | 0.3397 0.9 0.3397 1.1]; 9 | elseif nMembership == 3 10 | params = [0.1699 -0.05 0.1699 0.05; 11 | 0.1699 0.45 0.1699 0.55 12 | 0.1699 0.95 0.1699 1.05]; 13 | elseif nMembership == 4 14 | params = [0.1132 -0.03333 0.1132 0.03333; 15 | 0.1132 0.3 0.1132 0.3667; 16 | 0.1132 0.6333 0.1132 0.7; 17 | 0.1132 0.9667 0.1132 1.033]; 18 | elseif nMembership == 5 19 | params = [0.08493 -0.025 0.08493 0.025; 20 | 0.08493 0.225 0.08493 0.275; 21 | 0.08493 0.475 0.08493 0.525; 22 | 0.08493 0.725 0.08493 0.775; 23 | 0.08493 0.975 0.08493 1.025]; 24 | elseif nMembership == 6 25 | params = [0.06795 -0.02 0.06795 0.02; 26 | 0.06795 0.18 0.06795 0.22; 27 | 0.06795 0.38 0.06795 0.42; 28 | 0.06795 0.58 0.06795 0.62; 29 | 0.06795 0.78 0.06795 0.82; 30 | 0.06795 0.98 0.06795 1.02]; 31 | elseif nMembership == 7 32 | params = [0.05662 -0.01667 0.05662 0.01667; 33 | 0.05662 0.15 0.05662 0.1833; 34 | 0.05662 0.3167 0.05662 0.35; 35 | 0.05662 0.4833 0.05662 0.5167; 36 | 0.05662 0.65 0.05662 0.6833; 37 | 0.05662 0.8167 0.05662 0.85; 38 | 0.05662 0.9833 0.05662 1.017]; 39 | elseif nMembership == 8 40 | params = [0.04853 -0.01429 0.04853 0.01429; 41 | 0.04853 0.1286 0.04853 0.1571; 42 | 0.04853 0.2714 0.04853 0.3; 43 | 0.04853 0.4143 0.04853 0.4429; 44 | 0.04853 0.5571 0.04853 0.5857; 45 | 0.04853 0.7 0.04853 0.7286; 46 | 0.04853 0.8429 0.04853 0.8714; 47 | 0.04853 0.9857 0.04853 1.014]; 48 | elseif nMembership == 9 49 | params = [0.04247 -0.0125 0.04247 0.0125; 50 | 0.04247 0.1125 0.04247 0.1375; 51 | 0.04247 0.2375 0.04247 0.2625; 52 | 0.04247 0.3625 0.04247 0.3875; 53 | 0.04247 0.4875 0.04247 0.5125; 54 | 0.04247 0.6125 0.04247 0.6375; 55 | 0.04247 0.7375 0.04247 0.7625; 56 | 0.04247 0.8625 0.04247 0.8875; 57 | 0.04247 0.9875 0.04247 1.012]; 58 | end 59 | for i = 1:nMembership 60 | mf = [mf ; fismf(type, params(i,:))]; 61 | end 62 | 63 | end 64 | -------------------------------------------------------------------------------- /calculatingTestError.m: -------------------------------------------------------------------------------- 1 | %% Calculate Cost of currentIndividual on Test Set 2 | 3 | s = zeros(nStates,1); 4 | s(1) = 1; 5 | 6 | nDataTest = size(testInput,1); 7 | 8 | muOutputTest = zeros(nFuzzySetsOutput, nDataTest, nDimensions); 9 | muStateTest = zeros(nFuzzySetsState, nDataTest, nDimensions); 10 | rOutputTest = zeros(nRules_Output, nDataTest); 11 | rStateTest = zeros(nRules_State, nDataTest); 12 | 13 | for ii=1:nDimensions 14 | muOutputTest(:,:,ii) = evalmf(mfOutput(:,ii),testInput(:,ii)); 15 | muStateTest(:,:,ii) = evalmf(mfState(:,ii),testInput(:,ii)); 16 | end 17 | % Compute Cartesian Product of Rules 18 | 19 | if nDimensions == 2 && coverageRules == false 20 | for ii=1:nDataTest 21 | [R1,R2] = meshgrid(muOutputTest(:,ii,1),muOutputTest(:,ii,2)); 22 | [S1,S2] = meshgrid(muStateTest(:,ii,1),muStateTest(:,ii,2)); 23 | rOutputTest(:,ii) = R1(:) .* R2(:); 24 | rStateTest(:,ii) = S1(:) .* S2(:); 25 | end 26 | elseif nDimensions == 3 && coverageRules == false 27 | for ii=1:nDataTest 28 | [R1,R2,R3] = meshgrid(muOutputTest(:,ii,1),muOutputTest(:,ii,2),muOutputTest(:,ii,3)); 29 | [S1,S2,S3] = meshgrid(muStateTest(:,ii,1),muStateTest(:,ii,2),muStateTest(:,ii,3)); 30 | rOutputTest(:,ii) = R1(:) .* R2(:) .* R3(:); 31 | rStateTest(:,ii) = S1(:) .* S2(:) .* S3(:); 32 | end 33 | elseif nDimensions == 4 && coverageRules == false 34 | for ii=1:nDataTest 35 | [R1,R2,R3,R4] = ndgrid(muOutputTest(:,ii,1),muOutputTest(:,ii,2),muOutputTest(:,ii,3),muOutputTest(:,ii,4)); 36 | [S1,S2,S3,S4] = ndgrid(muStateTest(:,ii,1),muStateTest(:,ii,2),muStateTest(:,ii,3),muStateTest(:,ii,4)); 37 | rOutputTest(:,ii) = R1(:) .* R2(:) .* R3(:) .* R4(:); 38 | rStateTest(:,ii) = S1(:) .* S2(:) .* S3(:) .* S4(:); 39 | end 40 | elseif nDimensions == 5 && coverageRules == false 41 | for ii=1:nDataTest 42 | [R1,R2,R3,R4,R5] = ndgrid(muOutputTest(:,ii,1),muOutputTest(:,ii,2),muOutputTest(:,ii,3),muOutputTest(:,ii,4),muOutputTest(:,ii,5)); 43 | [S1,S2,S3,S4,S5] = ndgrid(muStateTest(:,ii,1),muStateTest(:,ii,2),muStateTest(:,ii,3),muStateTest(:,ii,4),muStateTest(:,ii,5)); 44 | rOutputTest(:,ii) = R1(:) .* R2(:) .* R3(:) .* R4(:) .* R5(:); 45 | rStateTest(:,ii) = S1(:) .* S2(:) .* S3(:) .* S4(:) .* S5(:); 46 | end 47 | elseif nDimensions == 1 && coverageRules == false 48 | rOutputTest = muOutputTest; 49 | rStateTest = muStateTest; 50 | elseif coverageRules == true 51 | rOutputTest(:,:) = 1; 52 | rStateTest(:,:) = 1; 53 | for ii=1:nDimensions 54 | rOutputTest = rOutputTest .* muOutputTest(:,:,ii); 55 | rStateTest = rStateTest .* muStateTest(:,:,ii); 56 | end 57 | end 58 | 59 | rbarOutputTest = rOutputTest ./ sum(rOutputTest); 60 | rbarStateTest = rStateTest ./ sum(rStateTest); 61 | 62 | RS_Big = zeros(nDataTest, nRules_Output*nStates); 63 | for t=1:nDataTest 64 | 65 | %% Find Output 66 | % Compute Cartesian Product R x S 67 | [R, S] = meshgrid(rbarOutputTest(:,t),s); 68 | RS = R(:) .* S(:); 69 | RS_Big(t,:) = RS; 70 | 71 | %% Find Next State 72 | 73 | [R2, S2] = meshgrid(rbarStateTest(:,t),s); 74 | RS2 = R2(:) .* S2(:); 75 | nextState = RS2' * currentIndividual.V(:); 76 | 77 | nextState = (nextState*(nStates-1)) + 1; 78 | 79 | evaluateMFForStateNetworkOutput 80 | 81 | end 82 | 83 | predictedOutput = RS_Big * currentIndividual.W(:); 84 | scaledPredicted = predictedOutput .* (max(tempdata_test(:,TargetDimension))-min(tempdata_test(:,TargetDimension))) + min(tempdata_test(:,TargetDimension)); 85 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # VMD-MFRFNN 2 | 3 | ## Introduction 4 | 5 | **Multi-step-ahead stock price prediction using recurrent fuzzy neural network and variational mode decomposition** 6 | 7 | *Authors:* [Hamid Nasiri](https://www.linkedin.com/in/hamid-nasiri-b5555487/), [Mohammad Mehdi Ebadzadeh](https://www.linkedin.com/in/mehdi-ebadzadeh-28bb3b35/) 8 | 9 | *Abstract:* Financial time series prediction has attracted considerable interest from scholars, and several approaches have been developed. Among them, decomposition-based methods have achieved promising results. Most decomposition-based methods approximate a single function, which is insufficient for obtaining accurate results. Moreover, most existing research has concentrated on one-step-ahead forecasting that prevents market investors from making the best decisions for the future. This study proposes two novel multi-step-ahead stock price prediction methods based on different decomposition techniques, including discrete cosine transform (DCT), i.e., a linear transform, and variational mode decomposition (VMD), i.e., a non-linear transform. DCT-MFRFNN, a method based on DCT and multi-functional recurrent fuzzy neural network (MFRFNN), uses DCT to reduce fluctuations in the time series and simplify its structure and MFRFNN to predict the stock price. VMD-MFRFNN, an approach based on VMD and MFRFNN, brings together their advantages. VMD-MFRFNN consists of two phases. The input signal is decomposed to several intrinsic mode functions (IMFs) using VMD in the decomposition phase. In the prediction phase, each IMF is given to a separate MFRFNN for prediction, and predicted signals are summed to reconstruct the output. DCT-MFRFNN and VMD-MFRFNN use the particle swarm optimization (PSO) algorithm to train MFRFNN. In this research, for the first time, the gradient descent method is used to train MFRFNN. Three financial time series are used to evaluate the proposed methods. Experimental results indicate that VMD-MFRFNN surpasses other state-of-the-art methods. VMD-MFRFNN, on average, shows a decrease of 31.8% in RMSE compared to the MEMD-LSTM method. Also, DCT-MFRFNN outperforms MFRFNN and DCT-LSTM in all experiments, which reveals the favorable effect of DCT on MFRFNN’s performance. To assess the effectiveness of PSO in training VMD-MFRFNN, we compared its performance with twelve different metaheuristic approaches. PSO, on average, shows a decrease of 9.4% in MAPE compared to other metaheuristic methods. 10 | 11 | This repository contains MATLAB source code of the following paper: 12 | 13 | [Multi-step-ahead stock price prediction using recurrent fuzzy neural network and variational mode decomposition](https://www.sciencedirect.com/science/article/abs/pii/S1568494623008852) 14 | 15 | ## Source Code and Dataset 16 | 17 | To run the code simply execute `main.m` 18 | 19 | **Datasets:** 20 | The [`Benchmarks`](Benchmarks/) folder contains three financial time series datasets used for testing and evaluating the code. 21 | 22 | + `HSI_Index.mat` corresponds to HSI time series. 23 | + `SSE_Index.mat` corresponds to the SSE time series. 24 | + `SandP_Index.mat` corresponds to the SPX time series. 25 | 26 | ## Citation 27 | 28 | This repository accompanies the paper ["Multi-step-ahead stock price prediction using recurrent fuzzy neural network and variationa"](https://www.sciencedirect.com/science/article/abs/pii/S1568494623008852) by [Hamid Nasiri](https://www.linkedin.com/in/hamid-nasiri-b5555487/) and [Mohammad Mehdi Ebadzadeh](https://www.linkedin.com/in/mehdi-ebadzadeh-28bb3b35/), published in Applied Soft Computing journal. 29 | 30 | If you use either the code, datasets or paper, please consider citing the paper. 31 | 32 | ``` 33 | @article{nasiri2023multi, 34 | title={Multi-step-ahead stock price prediction using recurrent fuzzy neural network and variational mode decomposition}, 35 | author={Nasiri, Hamid and Ebadzadeh, Mohammad Mehdi}, 36 | journal={Applied Soft Computing}, 37 | pages={110867}, 38 | year={2023}, 39 | publisher={Elsevier} 40 | } 41 | ``` 42 | 43 | ## Contact Me 44 | 45 | If you have any questions, do not hesitate to reach me via [Linkedin](https://www.linkedin.com/in/hamid-nasiri-b5555487/) or email: h.nasiri@aut.ac.ir 46 | 47 | Thank you so much for your attention. 48 | -------------------------------------------------------------------------------- /main.m: -------------------------------------------------------------------------------- 1 | %%%**************************************************************************************** 2 | %%%* This is the source code for the paper "Multi-step-ahead Stock Price Prediction Using * 3 | %%%* Recurrent Fuzzy Neural Network and Variational Mode Decomposition" (VMD-MFRFFN) * 4 | %%%* Authors: Hamid Nasiri, Mohammad Mehdi Ebadzadeh * 5 | %%%**************************************************************************************** 6 | 7 | rng(1); % For reproducibility of results 8 | 9 | global nStates; 10 | global nData; 11 | global nRules_Output; 12 | global rbarOutput; 13 | global rbarState; 14 | global currentIndividual; 15 | global targetOutput; 16 | 17 | 18 | %% Load HSI Benchmark 19 | fprintf("Loading Hang Seng Index Dataset...\n"); 20 | maxNumberOfIMFS = 9; 21 | 22 | TargetDimension = 1; 23 | load('Benchmarks\\HSI_Index.mat'); 24 | % Test Data 25 | testOutputTemp = data(end-375:end,TargetDimension); 26 | 27 | % Train Data 28 | data = data(1:end-377,TargetDimension); 29 | 30 | finalPrediction = []; 31 | fprintf("Decomposing Train Data Using VMD...\n"); 32 | [imf,residual] = vmd(data,'NumIMF',maxNumberOfIMFS); 33 | fprintf("Decomposing Test Data Using VMD...\n"); 34 | [imf_test, residual_test] = vmd(testOutputTemp,'NumIMF',maxNumberOfIMFS); 35 | 36 | numberOfRules = [6 6 6 5 5 5 4 4 4]; 37 | 38 | for numberOfIMFS = 1:maxNumberOfIMFS 39 | 40 | data = imf(:,numberOfIMFS); 41 | data_test = imf_test(:,numberOfIMFS); 42 | 43 | tempdata = data; 44 | tempdata_test = data_test; 45 | data = (data - min(data)) ./ (max(data)-min(data)) ; 46 | data_test = (data_test - min(data_test)) ./ (max(data_test)-min(data_test)) ; 47 | 48 | trainInput = data(1:end-1,TargetDimension); 49 | targetOutput = data(2:end,TargetDimension); 50 | testInput = data_test(1:end-1,TargetDimension); 51 | testOutput = data_test(2:end,TargetDimension); 52 | 53 | 54 | % **************************************************** 55 | % * Parameters * 56 | % **************************************************** 57 | 58 | coverageRules = false; % Generating Fuzzy Rules Using Coverage? 59 | ruleSigma = 0.3; 60 | coverageThreshold = 0.2; 61 | nRules_Output = numberOfRules(numberOfIMFS); 62 | nRules_State = 2; 63 | nStates = 2; 64 | mfType = "trimf"; % trimf gaussmf gauss2mf gbellmf 65 | nFuzzySetsOutput = numberOfRules(numberOfIMFS); 66 | nFuzzySetsState = 2; 67 | PSO_SwarmSize = 25; 68 | PSO_MaxIteration = 2; 69 | nData = size(trainInput,1); 70 | nDimensions = size(trainInput,2); 71 | 72 | %% Create Fuzzy Rules 73 | if ~coverageRules 74 | if mfType == "gaussmf" 75 | mfOutput = createGaussianMembershipFunction(nFuzzySetsOutput); 76 | mfState = createGaussianMembershipFunction(nFuzzySetsState); 77 | elseif mfType == "trimf" 78 | mfOutput = createMembershipFunction(nFuzzySetsOutput); 79 | mfState = createMembershipFunction(nFuzzySetsState); 80 | elseif mfType == "gauss2mf" 81 | mfOutput = createGaussian2MembershipFunction(nFuzzySetsOutput); 82 | mfState = createGaussian2MembershipFunction(nFuzzySetsState); 83 | elseif mfType == "gbellmf" 84 | mfOutput = createGeneralizedBellshapeMembershipfunction(nFuzzySetsOutput); 85 | mfState = createGeneralizedBellshapeMembershipfunction(nFuzzySetsState); 86 | end 87 | mfOutput = repmat(mfOutput,1,nDimensions); 88 | mfState = repmat(mfState,1,nDimensions); 89 | else 90 | if ~exist('mf','var') 91 | if mfType == "gaussmf" 92 | generateGaussianFuzzyRulesUsingCoverage; 93 | elseif mfType == "trimf" 94 | generateTriangleFuzzyRulesUsingCoverage; 95 | end 96 | end 97 | mfOutput = mf; 98 | mfState = mf; 99 | nFuzzySetsOutput = length(mf); 100 | nFuzzySetsState = length(mf); 101 | 102 | nRules_Output = nFuzzySetsOutput; 103 | nRules_State = nFuzzySetsState; 104 | end 105 | 106 | fprintf("Calculating Membership Values...\n"); 107 | calculateMembershipValues; 108 | 109 | 110 | %% Initialization 111 | 112 | % W -> Weight of Output Network 113 | % V -> Weight of State Network 114 | currentIndividual.V = rand(nStates,nRules_State); 115 | currentIndividual.W = rand(nStates,nRules_Output); 116 | costCalculation; 117 | 118 | %% Training Network 119 | 120 | fprintf("Training Network Using PSO For IMF%d ...",numberOfIMFS); 121 | 122 | fun = @(x) objectiveFunction(x); 123 | lb = zeros(1,nRules_State*nStates); 124 | ub = ones(1,nRules_State*nStates); 125 | options = optimoptions('particleswarm','SwarmSize',PSO_SwarmSize,'Display','iter','MaxIterations',PSO_MaxIteration); %patternsearch fmincon 126 | [x, fval] = particleswarm(fun,nRules_State*nStates,lb,ub,options); 127 | 128 | currentIndividual.V = x; 129 | costCalculation 130 | calculatingTestError; 131 | 132 | finalPrediction = [finalPrediction ; scaledPredicted']; 133 | 134 | end 135 | 136 | predictedOutput = sum(finalPrediction); 137 | 138 | predictedOutput = predictedOutput'; 139 | testRMSE = sqrt(immse(predictedOutput,testOutputTemp(2:end))); 140 | testMAPE = mean(abs((predictedOutput-testOutputTemp(2:end))./testOutputTemp(2:end))*100); 141 | 142 | fprintf("One-step-ahead Prediction Results:\n"); 143 | fprintf("RMSE = %e\n",testRMSE); 144 | fprintf("MAPE = %e\n",testMAPE); 145 | --------------------------------------------------------------------------------