├── KernelPCA ├── Kernel.m ├── KernelPCA.m ├── KernelPCAOption.m └── KernelPCAVisualization.m ├── README.md ├── data ├── TE.mat ├── banana.mat ├── circle.mat ├── diagnosis.mat └── helix.mat ├── demo_DR.m ├── demo_DR_Contirbution.m ├── demo_DR_Reconstruction.m ├── demo_FD.m ├── demo_FD_Diagnosis.m └── demo_kernel_function.m /KernelPCA/Kernel.m: -------------------------------------------------------------------------------- 1 | classdef Kernel < handle 2 | %{ 3 | Kernel function 4 | 5 | INPUT 6 | X data (n*d) 7 | Y data (m*d) 8 | 9 | OUTPUT 10 | K kernel matrix (n*m) 11 | 12 | ---------------------------------------------------------------------- 13 | 14 | type - 15 | 16 | linear : k(x,y) = x'*y 17 | polynomial : k(x,y) = (γ*x'*y+c)^d 18 | gaussian : k(x,y) = exp(-γ*||x-y||^2) 19 | sigmoid : k(x,y) = tanh(γ*x'*y+c) 20 | laplacian : k(x,y) = exp(-γ*||x-y||) 21 | 22 | 23 | degree - d 24 | offset - c 25 | gamma - γ 26 | 27 | ---------------------------------------------------------------------- 28 | 29 | Version 1.1, 11-MAY-2021 30 | Email: iqiukp@outlook.com 31 | ---------------------------------------------------------------------- 32 | %} 33 | 34 | properties 35 | type = 'gaussian' 36 | offset = 0 37 | gamma = 0.1 38 | degree = 2 39 | end 40 | 41 | methods 42 | function obj = Kernel(varargin) 43 | inputValue = varargin; 44 | nParameter = size(inputValue, 2)/2; 45 | supportedKernelFunc = {'linear', 'gaussian', 'polynomial', 'sigmoid', 'laplacian'}; 46 | for n = 1:nParameter 47 | parameter = inputValue{(n-1)*2+1}; 48 | value = inputValue{(n-1)*2+2}; 49 | if strcmp(parameter, 'type') 50 | if ~any(strcmp(value, supportedKernelFunc)) 51 | errorText = sprintf([ 52 | 'Unsupported kernel function.\n',... 53 | 'Use one of these kernel functions:\n', ... 54 | 'linear, gaussian, polynomial, sigmoid, laplacian.']); 55 | error(errorText) 56 | end 57 | end 58 | obj.(parameter) = value; 59 | end 60 | end 61 | 62 | function K = computeMatrix(obj, x, y) 63 | K = zeros(size(x, 1), size(y, 1)); 64 | % compute the kernel matrix 65 | switch obj.type 66 | case 'linear' % linear kernel function 67 | K = x*y'; 68 | 69 | case 'gaussian' % gaussian kernel function 70 | try 71 | K = exp(-obj.gamma*pdist2(x, y, 'squaredeuclidean')); 72 | catch 73 | sx = sum(x.^2, 2); 74 | sy = sum(y.^2, 2); 75 | xy = 2*x*y'; 76 | K = exp((bsxfun(@minus, bsxfun(@minus, xy, sx), sy'))*obj.gamma); 77 | end 78 | 79 | case 'polynomial' % polynomial kernel function 80 | K = (obj.gamma*x*y'+obj.offset).^double(obj.degree); 81 | 82 | case 'sigmoid' % sigmoid kernel function 83 | K = tanh(obj.gamma*x*y'+obj.offset); 84 | 85 | case 'laplacian' % laplacian kernel function 86 | K = exp(-obj.gamma*pdist2(x, y, 'cityblock')); 87 | end 88 | end 89 | end 90 | end -------------------------------------------------------------------------------- /KernelPCA/KernelPCA.m: -------------------------------------------------------------------------------- 1 | classdef KernelPCA < handle 2 | %{ 3 | Kernel Principal component analysis (KPCA) 4 | 5 | Version 2.2, 14-MAY-2021 6 | Email: iqiukp@outlook.com 7 | ------------------------------------------------------------------- 8 | %} 9 | 10 | properties 11 | data 12 | label 13 | numComponents 14 | explainedLevel 15 | kernelFunc = Kernel('type', 'gaussian', 'gamma', 0.5) 16 | lambda 17 | coefficient % principal component coefficients 18 | score % principal component scores. 19 | cumContribution % cumulative contribution rate 20 | newData % Transform the mapping data back to original space 21 | T2 22 | SPE 23 | T2Limit 24 | SPELimit 25 | numSPEAlarm 26 | numT2Alarm 27 | accuracySPE 28 | accuracyT2 29 | eigenvalueTolerance = 1e-8 % tolerance for eigenvalues 30 | alpha = 1 % hyperparameter of the ridge regression that learns the reconstruction 31 | theta = 0.7 % experience parameter of fault diagnosis 32 | significanceLevel = 0.95 33 | display = 'on' 34 | temporary 35 | diagnosis = [] 36 | runningTime 37 | end 38 | 39 | properties (Dependent) 40 | numSamples 41 | numFeatures 42 | end 43 | 44 | methods 45 | function obj = KernelPCA(parameter) 46 | name_ = fieldnames(parameter); 47 | for i = 1:size(name_, 1) 48 | obj.(name_{i, 1}) = parameter.(name_{i, 1}); 49 | end 50 | KernelPCAOption.checkInputForDiagnosis(obj); 51 | end 52 | 53 | function obj = train(obj, data) 54 | tStart = tic; 55 | obj.data = data; 56 | obj.label = ones(obj.numSamples, 1); 57 | 58 | % compute the kernel matrix 59 | K = obj.kernelFunc.computeMatrix(obj.data, obj.data); 60 | % centralize the kernel matrix 61 | unit = ones(obj.numSamples, obj.numSamples)/obj.numSamples; 62 | K_c = K-unit*K-K*unit+unit*K*unit; 63 | % compute the eigenvalues and eigenvectors 64 | [obj.coefficient, obj.lambda] = obj.computeEigenvalue(K_c); 65 | % 66 | obj.score = K_c* obj.coefficient(:, 1:obj.numComponents); 67 | obj.newData = obj.reconstruct; 68 | obj.temporary.K = K; 69 | obj.temporary.K_c = K_c; 70 | obj.temporary.unit = unit; 71 | obj.computeControlLimit; 72 | 73 | % compute accuracy 74 | T2AlarmIndex = find(obj.T2 > obj.T2Limit); 75 | SPEAlarmIndex = find(obj.SPE > obj.SPELimit); 76 | obj.numSPEAlarm = length(SPEAlarmIndex); 77 | obj.numT2Alarm = length(T2AlarmIndex); 78 | 79 | label_ = obj.label; 80 | label_(SPEAlarmIndex) = -1; 81 | obj.accuracySPE = sum(label_ == obj.label)/obj.numSamples; 82 | label_ = obj.label; 83 | label_(T2AlarmIndex) = -1; 84 | obj.accuracyT2 = sum(label_ == obj.label)/obj.numSamples; 85 | % 86 | obj.runningTime = toc(tStart); 87 | if strcmp(obj.display, 'on') 88 | KernelPCAOption.displayTrain(obj) 89 | end 90 | end 91 | 92 | function results = test(obj, data, varargin) 93 | % test the model from the given data 94 | tStart = tic; 95 | results.evaluation = 'off'; 96 | if nargin == 3 97 | results.evaluation = 'on'; 98 | testLabel = varargin{1}; 99 | end 100 | Kt = obj.kernelFunc.computeMatrix(data, obj.data); 101 | % centralize the kernel matrix 102 | unit = ones(size(data, 1), obj.numSamples)/obj.numSamples; 103 | Kt_c = Kt-unit*obj.temporary.K-Kt*obj.temporary.unit+unit*obj.temporary.K*obj.temporary.unit; 104 | % 105 | results.numSamples = size(data, 1); 106 | results.data = data; 107 | results.score = Kt_c*obj.coefficient(:, 1:obj.numComponents); 108 | 109 | % compute Hotelling's T2 statistic 110 | results.T2 = diag(results.score/diag(obj.lambda(1:obj.numComponents))*results.score'); 111 | % compute the squared prediction error (SPE) 112 | results.SPE = sum((Kt_c*obj.coefficient).^2, 2)-sum(results.score.^2 , 2); 113 | 114 | % compute accuracy 115 | results.T2AlarmIndex = find(results.T2 > obj.T2Limit); 116 | results.SPEAlarmIndex = find(results.SPE > obj.SPELimit); 117 | if strcmp(results.evaluation, 'on') 118 | label_ = ones(size(results.data, 1), 1); 119 | label_(results.SPEAlarmIndex) = -1; 120 | results.accuracySPE = sum(label_ == testLabel)/results.numSamples; 121 | label_ = ones(size(results.data, 1), 1); 122 | label_(results.T2AlarmIndex) = -1; 123 | results.accuracyT2 = sum(label_ == testLabel)/results.numSamples; 124 | end 125 | results.numSPEAlarm = length(results.SPEAlarmIndex); 126 | results.numT2Alarm = length(results.T2AlarmIndex); 127 | results.temporary.Kt = Kt; 128 | results.runningTime = toc(tStart); 129 | 130 | if strcmp(obj.display, 'on') 131 | KernelPCAOption.displayTest(results) 132 | end 133 | 134 | % fault diagnosis 135 | if strcmp(obj.diagnosis.switch, 'on') 136 | results = obj.diagnose(results); 137 | end 138 | end 139 | 140 | function newData = reconstruct(obj) 141 | % Transform the mapping data back to original space. 142 | % References 143 | % ---------- 144 | % Bakır G H, Weston J, Schölkopf B. Learning to find pre-images[J]. 145 | % Advances in neural information processing systems, 2004, 16: 449-456. 146 | 147 | K_1 = obj.kernelFunc.computeMatrix(obj.score, obj.score); 148 | K_1_ = K_1; 149 | for i = 1:obj.numSamples 150 | K_1(i, i) = K_1(i, i)+obj.alpha; 151 | end 152 | dual_coef = mldivide(K_1, obj.data); 153 | K_2 = K_1_; 154 | newData = K_2*dual_coef; 155 | end 156 | 157 | function [coefficient, lambda] = computeEigenvalue(obj, K_c) 158 | % compute the eigenvalues and eigenvectors 159 | rng('default') 160 | [V, D, ~] = svd(K_c/obj.numSamples, 'econ'); 161 | % ill-conditioned matrix 162 | if ~(isreal(V)) || ~(isreal(D)) 163 | V = real(V); 164 | D = real(D); 165 | end 166 | lambda_ = diag(D); 167 | obj.cumContribution = cumsum(lambda_/sum(lambda_)); 168 | 169 | if isempty(obj.numComponents) 170 | obj.numComponents = obj.numFeatures; 171 | else 172 | if obj.numComponents >= 1 173 | obj.numComponents = obj.numComponents; 174 | else 175 | obj.explainedLevel = obj.numComponents; 176 | obj.numComponents = find(obj.cumContribution >= obj.numComponents, 1, 'first'); 177 | end 178 | end 179 | lambda = lambda_; 180 | try 181 | coefficient = V./sqrt(obj.numSamples*lambda_)'; 182 | catch 183 | coefficient = zeros(obj.numSamples, obj.numSamples); 184 | for i = 1:obj.numSamples 185 | coefficient(:, i) = V(:, i)/sqrt(obj.numSamples*lambda_(i, 1)); 186 | end 187 | end 188 | end 189 | 190 | function computeControlLimit(obj) 191 | % compute the squared prediction error (SPE) 192 | temp1 = obj.temporary.K_c*obj.coefficient; 193 | temp2 = obj.temporary.K_c*obj.coefficient(:, 1:obj.numComponents); 194 | obj.SPE = sum(temp1.^2, 2)-sum(temp2.^2, 2); 195 | obj.T2 = diag(obj.score/diag(obj.lambda(1:obj.numComponents))*obj.score'); 196 | 197 | % compute the T2 limit (the F-Distribution) 198 | k = obj.numComponents*(obj.numSamples-1)/(obj.numSamples-obj.numComponents); 199 | obj.T2Limit = k*finv(obj.significanceLevel, obj.numComponents, obj.numSamples-obj.numComponents); 200 | 201 | % compute the SPE limit (the Chi-square Distribution) 202 | a = mean(obj.SPE); 203 | b = var(obj.SPE); 204 | g = b/2/a; 205 | h = 2*a^2/b; 206 | obj.SPELimit = g*chi2inv(obj.significanceLevel, h); 207 | end 208 | 209 | function results = diagnose(obj, results, varargin) 210 | % falut diagnosis 211 | tStart = tic; 212 | fprintf('\n') 213 | fprintf('*** Fault diagnosis ***\n') 214 | fprintf('Fault diagnosis start...\n') 215 | results.diagnosis = obj.diagnosis; 216 | data_ = results.data; 217 | results.diagnosis.data = data_(results.diagnosis.start:results.diagnosis.end, :); 218 | % contribution plots of train data 219 | if ~exist('.\data', 'dir') 220 | mkdir data; 221 | end 222 | file_ = dir('.\data\*.mat'); 223 | name_ = {file_(1:length(file_)).name}'; 224 | if ismember('diagnosis.mat', name_) 225 | load('.\data\diagnosis.mat', 'tmp_') 226 | tmp__ = KernelPCAOption.saveCheckObj(obj); 227 | if isequal(tmp__, tmp_) 228 | load('.\data\diagnosis.mat', 'T2CpsTrain', 'SPECpsTrain') 229 | else 230 | [T2CpsTrain, SPECpsTrain] = obj.computeContribution(results, 'train'); 231 | tmp_ = KernelPCAOption.saveCheckObj(obj); 232 | save('.\data\diagnosis.mat', 'T2CpsTrain', 'SPECpsTrain', 'tmp_') 233 | end 234 | else 235 | [T2CpsTrain, SPECpsTrain] = obj.computeContribution(results, 'train'); 236 | tmp_ = KernelPCAOption.saveCheckObj(obj); 237 | save('.\data\diagnosis.mat', 'T2CpsTrain', 'SPECpsTrain', 'tmp_') 238 | end 239 | 240 | % contribution plots of test data 241 | [T2CpsTest, SPECpsTest] = obj.computeContribution(results, 'test'); 242 | % normalize the contribution plots 243 | T2CpsTrainMu = mean(T2CpsTrain); 244 | T2CpsTrainStd = std(T2CpsTrain); 245 | 246 | try 247 | T2Cps = bsxfun(@rdivide, bsxfun(@minus, T2CpsTest, T2CpsTrainMu), T2CpsTrainStd); 248 | catch 249 | mu_array = repmat(T2CpsTrainMu, size(T2CpsTest,1), 1); 250 | st_array = repmat(T2CpsTrainStd, size(T2CpsTest,1), 1); 251 | T2Cps = (T2CpsTest-mu_array)./st_array; 252 | end 253 | SPECpsTrainMu = mean(SPECpsTrain); 254 | SPECpsTrainStd = std(SPECpsTrain); 255 | try 256 | SPECps = bsxfun(@rdivide, bsxfun(@minus, SPECpsTest, SPECpsTrainMu), SPECpsTrainStd); 257 | catch 258 | mu_array = repmat(SPECpsTrainMu, size(SPECpsTest,1), 1); 259 | st_array = repmat(SPECpsTrainStd, size(SPECpsTest,1), 1); 260 | SPECps = (SPECpsTest-mu_array)./st_array; 261 | end 262 | 263 | % store the results 264 | results.diagnosis.T2Cps = T2Cps; 265 | results.diagnosis.SPECps = SPECps; 266 | 267 | % 268 | T2Cps_ = mean(abs(T2Cps), 1); 269 | results.diagnosis.meanT2Cps = T2Cps_/sum(T2Cps_, 2); 270 | 271 | SPECps_ = mean(abs(SPECps), 1); 272 | results.diagnosis.meanSPECps = SPECps_/sum(SPECps_, 2); 273 | 274 | % 275 | [value, index] = sort(results.diagnosis.meanT2Cps, 'descend'); 276 | results.diagnosis.faultVariabeT2.value = value; 277 | results.diagnosis.faultVariabeT2.index = index; 278 | 279 | [value, index] = sort(results.diagnosis.meanSPECps, 'descend'); 280 | results.diagnosis.faultVariabeSPE.value = value; 281 | results.diagnosis.faultVariabeSPE.index = index; 282 | 283 | results.diagnosis.runningTime = toc(tStart); 284 | if strcmp(obj.display, 'on') 285 | KernelPCAOption.displayDiagnose(results) 286 | end 287 | end 288 | 289 | function [T2Cps, SPECps] = computeContribution(obj, result, type) 290 | 291 | % Compute the Contribution Plots (CPs) 292 | % 293 | % Reference 294 | % [1] Deng X, Tian X. A new fault isolation method based on unified 295 | % contribution plots[C]//Proceedings of the 30th Chinese Control 296 | % Conference. IEEE, 2011: 4280-4285. 297 | % ------------------------------------------------------------------- 298 | % Thanks for the code provided by Rui. 299 | % -------------------------------------------------------------------- 300 | 301 | data_ = obj.data; 302 | switch type 303 | case 'train' 304 | Kt = obj.temporary.K; 305 | Y = data_; 306 | case 'test' 307 | Kt = result.temporary.Kt; 308 | Y = result.diagnosis.data; 309 | end 310 | 311 | K = obj.temporary.K; 312 | M = size(data_, 1); 313 | [Mt, d] = size(Y); 314 | 315 | A_T2 = obj.coefficient(:, 1:obj.numComponents)*... 316 | diag(obj.lambda(1:obj.numComponents))^(-1)*... 317 | obj.coefficient(:, 1:obj.numComponents)'; 318 | 319 | A_SPE = obj.coefficient(:, 1:obj.numComponents)*... 320 | obj.coefficient(:, 1:obj.numComponents)'; 321 | newY = Y*obj.theta; 322 | 323 | % initialization 324 | Knew = zeros(Mt, M); 325 | Knew_d1 = zeros(1, M); 326 | Knew_d2 = zeros(Mt, M); 327 | T2Cps = zeros(Mt, d); 328 | SPECps = zeros(Mt, d); 329 | Knew_s = zeros(Mt, M); 330 | sigma = sqrt(1/2/obj.kernelFunc.gamma); 331 | 332 | % compute contribution of statistic 333 | for i = 1:Mt 334 | for j = 1:d 335 | for k = 1:M 336 | Knew(i, k) = Kt(i, k); 337 | Knew_d1(k) = Knew(i, k)*2*obj.theta*(newY(i, j)-data_(k, j))/(-sigma^2); % derivative 338 | Knew_d2(i, k) = -2*Knew_d1(k); 339 | end 340 | Knew_d1_s = Knew_d1-ones(1, M)*mean(Knew_d1); 341 | Knew_s(i, :) = Knew(i, :)-ones(1, M)*K/M-Knew(i, :)*ones(M) ... 342 | /M+ones(1, M)/M*K*ones(M)/M; 343 | % contribution of T2 344 | T2Cps(i, j) = Y(i, j)*(Knew_d1_s*A_T2*Knew_s(i, :)' ... 345 | +Knew_s(i, :)*A_T2*Knew_d1_s'); 346 | % contribution of SPE 347 | SPECps(i, j)= Y(i, j)*mean(Knew_d2(i, :))-Y(i, j) ... 348 | *(Knew_d1_s*A_SPE*Knew_s(i, :)'+Knew_s(i, :)*A_SPE*Knew_d1_s'); 349 | end 350 | end 351 | end 352 | 353 | function numSamples = get.numSamples(obj) 354 | numSamples= size(obj.data, 1); 355 | end 356 | 357 | function numFeatures = get.numFeatures(obj) 358 | numFeatures= size(obj.data, 2); 359 | end 360 | end 361 | end 362 | -------------------------------------------------------------------------------- /KernelPCA/KernelPCAOption.m: -------------------------------------------------------------------------------- 1 | classdef KernelPCAOption < handle 2 | 3 | methods(Static) 4 | function checkInputForDiagnosis(obj) 5 | tmp_.switch = 'off'; 6 | tmp_.start = []; 7 | tmp_.end = []; 8 | errorText = sprintf('Incorrected input for diagnosis.\n'); 9 | if isempty(obj.diagnosis) 10 | obj.diagnosis = tmp_; 11 | else 12 | if ~strcmp(obj.kernelFunc.type, 'gaussian') 13 | error('Only fault diagnosis of Gaussian kernel is supported.') 14 | end 15 | if ~isa(obj.diagnosis, 'double') 16 | error(errorText); 17 | end 18 | numInput = length(obj.diagnosis); 19 | switch numInput 20 | case 1 21 | tmp_.switch = 'on'; 22 | tmp_.start = obj.diagnosis(1); 23 | tmp_.end = tmp_.start; 24 | case 2 25 | if obj.diagnosis(1) > obj.diagnosis(2) 26 | error(errorText) 27 | end 28 | tmp_.switch = 'on'; 29 | tmp_.start = obj.diagnosis(1); 30 | tmp_.end = obj.diagnosis(2); 31 | otherwise 32 | error(errorText) 33 | end 34 | obj.diagnosis = tmp_; 35 | end 36 | end 37 | 38 | function tmp_ = saveCheckObj(kpca) 39 | names_ = fieldnames(kpca.kernelFunc); 40 | for i = 1:length(names_) 41 | tmp_.kernelFunc.(names_{i}) = (kpca.kernelFunc.(names_{i})); 42 | end 43 | tmp_.data = kpca.data; 44 | tmp_.numComponents = kpca.numComponents; 45 | tmp_.explainedLevel = kpca.explainedLevel; 46 | tmp_.eigenvalueTolerance = kpca.eigenvalueTolerance; 47 | tmp_.significanceLevel = kpca.significanceLevel; 48 | end 49 | 50 | function displayTrain(kpca) 51 | fprintf('\n') 52 | fprintf('*** KPCA model training finished ***\n') 53 | fprintf('running time = %.4f seconds\n', kpca.runningTime) 54 | fprintf('kernel function = %s \n', kpca.kernelFunc.type) 55 | fprintf('number of samples = %d \n', kpca.numSamples) 56 | fprintf('number of features = %d \n', kpca.numFeatures) 57 | fprintf('number of components = %d \n', kpca.numComponents) 58 | fprintf('number of T2 alarm = %d \n', kpca.numT2Alarm) 59 | fprintf('number of SPE alarm = %d \n', kpca.numSPEAlarm) 60 | fprintf('accuracy of T2 = %.4f%% \n', 100*kpca.accuracyT2) 61 | fprintf('accuracy of SPE = %.4f%% \n', 100*kpca.accuracySPE) 62 | end 63 | 64 | function displayTest(results) 65 | fprintf('\n') 66 | fprintf('*** KPCA model test finished ***\n') 67 | fprintf('running time = %.4f seconds\n', results.runningTime) 68 | fprintf('number of test data = %d \n', results.numSamples) 69 | fprintf('number of T2 alarm = %d \n', results.numT2Alarm) 70 | fprintf('number of SPE alarm = %d \n', results.numSPEAlarm) 71 | if strcmp(results.evaluation, 'on') 72 | fprintf('accuracy of T2 = %.4f%% \n', 100*results.accuracyT2) 73 | fprintf('accuracy of SPE = %.4f%% \n', 100*results.accuracySPE) 74 | end 75 | fprintf('\n') 76 | end 77 | 78 | function displayDiagnose(results) 79 | fprintf('Fault diagnosis finished.\n') 80 | fprintf('running time = %.4f seconds\n', results.diagnosis.runningTime) 81 | fprintf('start point = %d \n', results.diagnosis.start) 82 | fprintf('ending point = %d \n', results.diagnosis.end) 83 | tmp_T2 = results.diagnosis.faultVariabeT2.index; 84 | tmp_SPE = results.diagnosis.faultVariabeSPE.index; 85 | if length(tmp_T2) > 3 86 | numShow = 3; 87 | else 88 | numShow = length(tmp_T2); 89 | end 90 | fprintf('fault variables (T2) = %s \n', num2str(tmp_T2(1:numShow))) 91 | fprintf('fault variables (SPE) = %s \n', num2str(tmp_SPE(1:numShow))) 92 | fprintf('\n') 93 | end 94 | end 95 | end -------------------------------------------------------------------------------- /KernelPCA/KernelPCAVisualization.m: -------------------------------------------------------------------------------- 1 | classdef KernelPCAVisualization < handle 2 | %{ 3 | CLASS DESCRIPTION 4 | 5 | Visualization of trained KPCA model and test results. 6 | 7 | ----------------------------------------------------------------- 8 | 9 | Version 1.1, 14-MAY-2021 10 | Email: iqiukp@outlook.com 11 | ----------------------------------------------------------------- 12 | %} 13 | 14 | properties (Constant) 15 | positionForOne = [300 150 600 300] 16 | positionForTwo = [300 150 800 600] 17 | colorStatistics = [125, 45, 141]/255 18 | colorLimit = [213, 81, 36]/255 19 | colorFace = [213, 81, 36]/255 20 | colorScatter = [0, 114, 189;162, 20, 47]/255; 21 | colorContribution = [162, 20, 47]/255 22 | lineWidthStatistics = 2 23 | lineWidthBox = 1.1 24 | scatterSize = 36 25 | tickDirection = 'in' 26 | end 27 | 28 | methods 29 | function cumContribution(obj, kpca) 30 | dims_ = find(kpca.cumContribution > 0.99, 1, 'first'); 31 | cumContribution_ = kpca.cumContribution(1:dims_)*100; 32 | figure 33 | set(gcf, 'position', obj.positionForOne) 34 | hold on 35 | plot(cumContribution_,... 36 | 'color', obj.colorContribution,... 37 | 'LineStyle', '-', 'LineWidth', obj.lineWidthStatistics) 38 | xlim([1, length(cumContribution_)]); 39 | ylim([cumContribution_(1), 100]) 40 | posi = [kpca.numComponents, cumContribution_(kpca.numComponents)]; 41 | % connected line 42 | line([posi(1, 1), posi(1, 1)], [cumContribution_(1), posi(1, 2)],... 43 | 'color', 'k', 'LineStyle', '--', 'LineWidth', obj.lineWidthBox); 44 | line([1, posi(1, 1)], [posi(1, 2), posi(1, 2)],... 45 | 'color', 'k', 'LineStyle', '--', 'LineWidth', obj.lineWidthBox); 46 | % 47 | plot(posi(1, 1), posi(1, 2),... 48 | 'Marker', 'o',... 49 | 'MarkerSize', 8,... 50 | 'MarkerEdgeColor', obj.colorContribution,... 51 | 'MarkerFaceColor', obj.colorContribution); 52 | 53 | testStr = ['(', num2str(posi(1, 1)), ', ', num2str(posi(1, 2)), '%)']; 54 | text(posi(1, 1)*1.1, posi(1, 2)*0.95, testStr, 'FontWeight', 'bold') 55 | ytickformat('%d%%') 56 | xlabel('Component number') 57 | ylabel('Cumulative contributions') 58 | set(gca, 'LineWidth', obj.lineWidthBox, 'TickDir', obj.tickDirection) 59 | box(gca, 'on'); 60 | end 61 | 62 | function trainResults(obj, kpca) 63 | figure 64 | set(gcf, 'position', obj.positionForTwo) 65 | subplot(2, 1, 1) 66 | plot(kpca.SPELimit*ones(kpca.numSamples, 1),... 67 | 'color', obj.colorLimit,... 68 | 'LineStyle', '-',.... 69 | 'LineWidth', obj.lineWidthStatistics) 70 | hold on 71 | plot(kpca.SPE,... 72 | 'color', obj.colorStatistics,... 73 | 'LineStyle', '-',.... 74 | 'LineWidth', obj.lineWidthStatistics) 75 | legend({'SPE limit', 'SPE'}) 76 | xlabel('Samples') 77 | ylabel('SPE') 78 | set(gca, 'LineWidth', obj.lineWidthBox,... 79 | 'TickDir', obj.tickDirection, 'yscale','log') 80 | box(gca, 'on'); 81 | 82 | subplot(2, 1, 2) 83 | plot(kpca.T2Limit*ones(kpca.numSamples, 1),... 84 | 'color', obj.colorLimit,... 85 | 'LineStyle', '-',.... 86 | 'LineWidth', obj.lineWidthStatistics) 87 | hold on 88 | plot(kpca.T2,... 89 | 'color', obj.colorStatistics,... 90 | 'LineStyle', '-',.... 91 | 'LineWidth', obj.lineWidthStatistics) 92 | legend({'T2 limit','T2'}) 93 | xlabel('Samples') 94 | ylabel('T2') 95 | set(gca, 'LineWidth', obj.lineWidthBox,... 96 | 'TickDir', obj.tickDirection, 'yscale','log') 97 | box(gca, 'on'); 98 | end 99 | 100 | function testResults(obj, kpca, results) 101 | figure 102 | set(gcf, 'position', obj.positionForTwo) 103 | subplot(2, 1, 1) 104 | plot(kpca.SPELimit*ones(results.numSamples, 1),... 105 | 'color', obj.colorLimit,... 106 | 'LineStyle', '-',.... 107 | 'LineWidth', obj.lineWidthStatistics) 108 | hold on 109 | plot(results.SPE,... 110 | 'color', obj.colorStatistics,... 111 | 'LineStyle', '-',.... 112 | 'LineWidth', obj.lineWidthStatistics) 113 | legend({'SPE limit','SPE'}) 114 | xlabel('Samples') 115 | ylabel('SPE') 116 | set(gca, 'LineWidth', obj.lineWidthBox,... 117 | 'TickDir', obj.tickDirection, 'yscale','log') 118 | box(gca, 'on'); 119 | 120 | subplot(2, 1, 2) 121 | plot(kpca.T2Limit*ones(results.numSamples, 1),... 122 | 'color', obj.colorLimit,... 123 | 'LineStyle', '-',.... 124 | 'LineWidth', obj.lineWidthStatistics) 125 | hold on 126 | plot(results.T2,... 127 | 'color', obj.colorStatistics,... 128 | 'LineStyle', '-',.... 129 | 'LineWidth', obj.lineWidthStatistics) 130 | legend({'T2 limit','T2'}) 131 | xlabel('Samples') 132 | ylabel('T2') 133 | set(gca, 'LineWidth', obj.lineWidthBox,... 134 | 'TickDir', obj.tickDirection, 'yscale','log') 135 | box(gca, 'on'); 136 | end 137 | 138 | function score(obj, kpca) 139 | if kpca.numFeatures < 2 || kpca.numFeatures > 3 ... 140 | || kpca.numComponents < 2 || kpca.numComponents > 3 141 | error('This demonstration only supports visualization of 2D or 3D data.') 142 | end 143 | for i = 1:3 144 | colormap_(:, i) = linspace(obj.colorScatter(1,i),obj.colorScatter(2,i),kpca.numSamples); 145 | end 146 | 147 | % original data 148 | figure 149 | set(gcf, 'position', obj.positionForOne) 150 | subplot(1, 2, 1) 151 | switch kpca.numFeatures 152 | case 2 153 | scatter(kpca.data(:, 1), kpca.data(:, 2),... 154 | obj.scatterSize, colormap_, 'filled') 155 | 156 | case 3 157 | scatter3(kpca.data(:, 1), kpca.data(:, 2), kpca.data(:, 3),... 158 | obj.scatterSize, colormap_, 'filled') 159 | end 160 | colormap(gca, 'parula') 161 | set(gca, 'LineWidth', obj.lineWidthBox, 'TickDir', obj.tickDirection) 162 | box(gca, 'on'); 163 | title('Original data') 164 | 165 | % scores 166 | subplot(1, 2, 2) 167 | switch kpca.numComponents 168 | case 2 169 | scatter(kpca.score(:, 1), kpca.score(:, 2),... 170 | obj.scatterSize, colormap_, 'filled') 171 | 172 | case 3 173 | scatter3(kpca.score(:, 1), kpca.score(:, 2), kpca.score(:, 3),... 174 | obj.scatterSize, colormap_, 'filled') 175 | end 176 | set(gca, 'LineWidth', obj.lineWidthBox, 'TickDir', obj.tickDirection) 177 | box(gca, 'on'); 178 | title('Mapping data'); 179 | end 180 | 181 | function reconstruction(obj, kpca) 182 | if kpca.numFeatures < 2 || kpca.numFeatures > 3 ... 183 | || kpca.numComponents < 2 || kpca.numComponents > 3 184 | error('This demonstration only supports visualization of 2D or 3D data.') 185 | end 186 | 187 | for i = 1:3 188 | colormap_(:, i) = linspace(obj.colorScatter(1,i),obj.colorScatter(2,i),kpca.numSamples); 189 | end 190 | 191 | % original data 192 | figure 193 | set(gcf, 'position', obj.positionForOne) 194 | subplot(1, 2, 1) 195 | switch kpca.numFeatures 196 | case 2 197 | scatter(kpca.data(:, 1), kpca.data(:, 2),... 198 | obj.scatterSize, colormap_, 'filled') 199 | 200 | case 3 201 | scatter3(kpca.data(:, 1), kpca.data(:, 2), kpca.data(:, 3),... 202 | obj.scatterSize, colormap_, 'filled') 203 | end 204 | set(gca, 'LineWidth', obj.lineWidthBox, 'TickDir', obj.tickDirection) 205 | box(gca, 'on'); 206 | title('Original data') 207 | 208 | subplot(1, 2, 2) 209 | switch kpca.numFeatures 210 | case 2 211 | scatter(kpca.newData(:, 1), kpca.newData(:, 2),... 212 | obj.scatterSize, colormap_, 'filled') 213 | 214 | case 3 215 | scatter3(kpca.newData(:, 1), kpca.newData(:, 2), kpca.newData(:, 3),... 216 | obj.scatterSize, colormap_, 'filled') 217 | end 218 | set(gca, 'LineWidth', obj.lineWidthBox, 'TickDir', obj.tickDirection) 219 | box(gca, 'on'); 220 | title('Reconstructed data'); 221 | end 222 | 223 | function diagnosis(obj, results) 224 | figure 225 | set(gcf,'position', obj.positionForTwo) 226 | subplot(2, 1, 1) 227 | bar(results.diagnosis.meanSPECps,... 228 | 'FaceColor', obj.colorFace,... 229 | 'EdgeColor', 'k',... 230 | 'LineWidth', obj.lineWidthStatistics); 231 | xlabel('Variables') 232 | ylabel('SPE contributions') 233 | set(gca, 'LineWidth', obj.lineWidthBox, 'TickDir', obj.tickDirection) 234 | titleStr = ['Sampling points between ', num2str(results.diagnosis.start),... 235 | ' and ', num2str(results.diagnosis.end)]; 236 | title(titleStr) 237 | 238 | subplot(2, 1, 2) 239 | bar(results.diagnosis.meanT2Cps,... 240 | 'FaceColor', obj.colorFace,... 241 | 'EdgeColor', 'k',... 242 | 'LineWidth', obj.lineWidthStatistics); 243 | xlabel('Variables') 244 | ylabel('T2 contributions') 245 | set(gca, 'LineWidth', obj.lineWidthBox, 'TickDir', obj.tickDirection) 246 | title(titleStr) 247 | end 248 | end 249 | end -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |

2 | 3 |

4 | 5 |

Kernel Principal Component Analysis (KPCA)

6 | 7 |

MATLAB code for dimensionality reduction, fault detection, and fault diagnosis using KPCA

8 |

Version 2.2, 14-MAY-2021

9 |

Email: iqiukp@outlook.com

10 | 11 |
12 | 13 | [![View Kernel Principal Component Analysis (KPCA) on File Exchange](https://www.mathworks.com/matlabcentral/images/matlab-file-exchange.svg)](https://ww2.mathworks.cn/matlabcentral/fileexchange/69378-kernel-principal-component-analysis-kpca) 14 | 15 | 16 | 17 | 18 | 19 | 20 |
21 | 22 |
23 | 24 | ## Main features 25 | 26 | - Easy-used API for training and testing KPCA model 27 | - Support for dimensionality reduction, data reconstruction, fault detection, and fault diagnosis 28 | - Multiple kinds of kernel functions (linear, gaussian, polynomial, sigmoid, laplacian) 29 | - Visualization of training and test results 30 | - Component number determination based on given explained level or given number 31 | 32 | ## Notices 33 | 34 | - Only fault diagnosis of Gaussian kernel is supported. 35 | - This code is for reference only. 36 | 37 | ## How to use 38 | 39 | ### 01. Kernel funcions 40 | 41 | A class named ***Kernel*** is defined to compute kernel function matrix. 42 | ```MATLAB 43 | %{ 44 | type - 45 | 46 | linear : k(x,y) = x'*y 47 | polynomial : k(x,y) = (γ*x'*y+c)^d 48 | gaussian : k(x,y) = exp(-γ*||x-y||^2) 49 | sigmoid : k(x,y) = tanh(γ*x'*y+c) 50 | laplacian : k(x,y) = exp(-γ*||x-y||) 51 | 52 | 53 | degree - d 54 | offset - c 55 | gamma - γ 56 | %} 57 | kernel = Kernel('type', 'gaussian', 'gamma', value); 58 | kernel = Kernel('type', 'polynomial', 'degree', value); 59 | kernel = Kernel('type', 'linear'); 60 | kernel = Kernel('type', 'sigmoid', 'gamma', value); 61 | kernel = Kernel('type', 'laplacian', 'gamma', value); 62 | ``` 63 | For example, compute the kernel matrix between **X** and **Y** 64 | 65 | ```MATLAB 66 | X = rand(5, 2); 67 | Y = rand(3, 2); 68 | kernel = Kernel('type', 'gaussian', 'gamma', 2); 69 | kernelMatrix = kernel.computeMatrix(X, Y); 70 | >> kernelMatrix 71 | 72 | kernelMatrix = 73 | 74 | 0.5684 0.5607 0.4007 75 | 0.4651 0.8383 0.5091 76 | 0.8392 0.7116 0.9834 77 | 0.4731 0.8816 0.8052 78 | 0.5034 0.9807 0.7274 79 | ``` 80 | 81 | ### 02. Simple KPCA model for dimensionality reduction 82 | 83 | ```MATLAB 84 | clc 85 | clear all 86 | close all 87 | addpath(genpath(pwd)) 88 | 89 | load('.\data\helix.mat', 'data') 90 | kernel = Kernel('type', 'gaussian', 'gamma', 2); 91 | parameter = struct('numComponents', 2, ... 92 | 'kernelFunc', kernel); 93 | % build a KPCA object 94 | kpca = KernelPCA(parameter); 95 | % train KPCA model 96 | kpca.train(data); 97 | 98 | % mapping data 99 | mappingData = kpca.score; 100 | 101 | % Visualization 102 | kplot = KernelPCAVisualization(); 103 | % visulize the mapping data 104 | kplot.score(kpca) 105 | ``` 106 | 107 | The training results (dimensionality reduction): 108 | ```MATLAB 109 | *** KPCA model training finished *** 110 | running time = 0.2798 seconds 111 | kernel function = gaussian 112 | number of samples = 1000 113 | number of features = 3 114 | number of components = 2 115 | number of T2 alarm = 135 116 | number of SPE alarm = 0 117 | accuracy of T2 = 86.5000% 118 | accuracy of SPE = 100.0000% 119 | ``` 120 | 121 |

122 | 123 |

124 | 125 | Another application using banana-shaped data: 126 |

127 | 128 |

129 | 130 | 131 | ### 03. Simple KPCA model for reconstruction 132 | ```MATLAB 133 | clc 134 | clear all 135 | close all 136 | addpath(genpath(pwd)) 137 | 138 | load('.\data\circle.mat', 'data') 139 | kernel = Kernel('type', 'gaussian', 'gamma', 0.2); 140 | parameter = struct('numComponents', 2, ... 141 | 'kernelFunc', kernel); 142 | % build a KPCA object 143 | kpca = KernelPCA(parameter); 144 | % train KPCA model 145 | kpca.train(data); 146 | 147 | % reconstructed data 148 | reconstructedData = kpca.newData; 149 | 150 | % Visualization 151 | kplot = KernelPCAVisualization(); 152 | kplot.reconstruction(kpca) 153 | ``` 154 | 155 |

156 | 157 |

158 | 159 | 160 | ### 04. Component number determination 161 | 162 | The Component number can be determined based on given explained level or given number. 163 | 164 | ***Case 1*** 165 | 166 | The number of components is determined by the given explained level. The given explained level should be 0 < explained level < 1. 167 | For example, when explained level is set to 0.75, the parameter should 168 | be set as: 169 | ```MATLAB 170 | parameter = struct('numComponents', 0.75, ... 171 | 'kernelFunc', kernel); 172 | ``` 173 | 174 | The code is 175 | 176 | ```MATLAB 177 | clc 178 | clear all 179 | close all 180 | addpath(genpath(pwd)) 181 | 182 | load('.\data\TE.mat', 'trainData') 183 | kernel = Kernel('type', 'gaussian', 'gamma', 1/128^2); 184 | 185 | parameter = struct('numComponents', 0.75, ... 186 | 'kernelFunc', kernel); 187 | % build a KPCA object 188 | kpca = KernelPCA(parameter); 189 | % train KPCA model 190 | kpca.train(trainData); 191 | 192 | % Visualization 193 | kplot = KernelPCAVisualization(); 194 | kplot.cumContribution(kpca) 195 | ``` 196 |

197 | 198 |

199 | 200 | As shown in the image, when the number of components is 21, the cumulative contribution rate is 75.2656%,which exceeds the given explained level (0.75). 201 | 202 | ***Case 2*** 203 | 204 | The number of components is determined by the given number. For example, when the given number is set to 24, the parameter should 205 | be set as: 206 | ```MATLAB 207 | parameter = struct('numComponents', 24, ... 208 | 'kernelFunc', kernel); 209 | ``` 210 | 211 | The code is 212 | 213 | ```MATLAB 214 | clc 215 | clear all 216 | close all 217 | addpath(genpath(pwd)) 218 | 219 | load('.\data\TE.mat', 'trainData') 220 | kernel = Kernel('type', 'gaussian', 'gamma', 1/128^2); 221 | 222 | parameter = struct('numComponents', 24, ... 223 | 'kernelFunc', kernel); 224 | % build a KPCA object 225 | kpca = KernelPCA(parameter); 226 | % train KPCA model 227 | kpca.train(trainData); 228 | 229 | % Visualization 230 | kplot = KernelPCAVisualization(); 231 | kplot.cumContribution(kpca) 232 | ``` 233 |

234 | 235 |

236 | 237 | As shown in the image, when the number of components is 24, the cumulative contribution rate is 80.2539%. 238 | 239 | ### 05. Fault detection 240 | 241 | Demonstration of fault detection using KPCA (TE process data) 242 | 243 | ```MATLAB 244 | clc 245 | clear all 246 | close all 247 | addpath(genpath(pwd)) 248 | 249 | load('.\data\TE.mat', 'trainData', 'testData') 250 | kernel = Kernel('type', 'gaussian', 'gamma', 1/128^2); 251 | parameter = struct('numComponents', 0.65, ... 252 | 'kernelFunc', kernel); 253 | 254 | % build a KPCA object 255 | kpca = KernelPCA(parameter); 256 | % train KPCA model 257 | kpca.train(trainData); 258 | % test KPCA model 259 | results = kpca.test(testData); 260 | 261 | % Visualization 262 | kplot = KernelPCAVisualization(); 263 | kplot.cumContribution(kpca) 264 | kplot.trainResults(kpca) 265 | kplot.testResults(kpca, results) 266 | ``` 267 | 268 | The training results are 269 | ```MATLAB 270 | *** KPCA model training finished *** 271 | running time = 0.0986 seconds 272 | kernel function = gaussian 273 | number of samples = 500 274 | number of features = 52 275 | number of components = 16 276 | number of T2 alarm = 16 277 | number of SPE alarm = 17 278 | accuracy of T2 = 96.8000% 279 | accuracy of SPE = 96.6000% 280 | ``` 281 | 282 |

283 | 284 |

285 | 286 | The test results are 287 | ```MATLAB 288 | *** KPCA model test finished *** 289 | running time = 0.0312 seconds 290 | number of test data = 960 291 | number of T2 alarm = 799 292 | number of SPE alarm = 851 293 | ``` 294 | 295 |

296 | 297 |

298 | 299 | ### 06. Fault diagnosis 300 | 301 | **Notice** 302 | 303 | - If you want to calculate CPS of a certain time, you should set starting time equal to ending time. For example, 'diagnosis', [500, 500] 304 | - If you want to calculate the average CPS of a period of time, starting time and ending time should be set respectively. 'diagnosis', [300, 500] 305 | - The fault diagnosis module is only supported for gaussian kernel function and it may still take a long time when the number of the training data is large. 306 | 307 | ```MATLAB 308 | clc 309 | clear all 310 | close all 311 | addpath(genpath(pwd)) 312 | 313 | load('.\data\TE.mat', 'trainData', 'testData') 314 | kernel = Kernel('type', 'gaussian', 'gamma', 1/128^2); 315 | 316 | parameter = struct('numComponents', 0.65, ... 317 | 'kernelFunc', kernel,... 318 | 'diagnosis', [300, 500]); 319 | 320 | % build a KPCA object 321 | kpca = KernelPCA(parameter); 322 | % train KPCA model 323 | kpca.train(trainData); 324 | % test KPCA model 325 | results = kpca.test(testData); 326 | 327 | % Visualization 328 | kplot = KernelPCAVisualization(); 329 | kplot.cumContribution(kpca) 330 | kplot.trainResults(kpca) 331 | kplot.testResults(kpca, results) 332 | kplot.diagnosis(results) 333 | ``` 334 | Diagnosis results: 335 | ```MATLAB 336 | *** Fault diagnosis *** 337 | Fault diagnosis start... 338 | Fault diagnosis finished. 339 | running time = 18.2738 seconds 340 | start point = 300 341 | ending point = 500 342 | fault variables (T2) = 44 1 4 343 | fault variables (SPE) = 1 44 18 344 | ``` 345 | 346 |

347 | 348 |

349 | 350 | -------------------------------------------------------------------------------- /data/TE.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iqiukp/KPCA-MATLAB/16dd1567d7109f55a7c83d2fe3dcb558cf1a8fbf/data/TE.mat -------------------------------------------------------------------------------- /data/banana.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iqiukp/KPCA-MATLAB/16dd1567d7109f55a7c83d2fe3dcb558cf1a8fbf/data/banana.mat -------------------------------------------------------------------------------- /data/circle.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iqiukp/KPCA-MATLAB/16dd1567d7109f55a7c83d2fe3dcb558cf1a8fbf/data/circle.mat -------------------------------------------------------------------------------- /data/diagnosis.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iqiukp/KPCA-MATLAB/16dd1567d7109f55a7c83d2fe3dcb558cf1a8fbf/data/diagnosis.mat -------------------------------------------------------------------------------- /data/helix.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iqiukp/KPCA-MATLAB/16dd1567d7109f55a7c83d2fe3dcb558cf1a8fbf/data/helix.mat -------------------------------------------------------------------------------- /demo_DR.m: -------------------------------------------------------------------------------- 1 | %{ 2 | Demonstration of dimensionality reduction using KPCA. 3 | %} 4 | clc 5 | clear all 6 | close all 7 | addpath(genpath(pwd)) 8 | 9 | load('.\data\helix.mat', 'data') 10 | kernel = Kernel('type', 'gaussian', 'gamma', 2); 11 | parameter = struct('numComponents', 2, ... 12 | 'kernelFunc', kernel); 13 | % build a KPCA object 14 | kpca = KernelPCA(parameter); 15 | % train KPCA model 16 | kpca.train(data); 17 | 18 | % mapping data 19 | mappingData = kpca.score; 20 | 21 | % Visualization 22 | kplot = KernelPCAVisualization(); 23 | % visulize the mapping data 24 | kplot.score(kpca) 25 | 26 | -------------------------------------------------------------------------------- /demo_DR_Contirbution.m: -------------------------------------------------------------------------------- 1 | %{ 2 | Demonstration of dimensionality reduction using KPCA. 3 | %} 4 | clc 5 | clear all 6 | close all 7 | addpath(genpath(pwd)) 8 | 9 | load('.\data\TE.mat', 'trainData') 10 | kernel = Kernel('type', 'gaussian', 'gamma', 1/128^2); 11 | 12 | %% case 1 13 | %{ 14 | The number of components is determined by the given explained level. 15 | The given explained level should be 0 < explained level < 1. 16 | For example, when explained level is set to 0.75, the parameter should 17 | be set as: 18 | 19 | parameter = struct('numComponents', 0.75, ... 20 | 'kernelFunc', kernel); 21 | %} 22 | parameter = struct('numComponents', 0.75, ... 23 | 'kernelFunc', kernel); 24 | % build a KPCA object 25 | kpca = KernelPCA(parameter); 26 | % train KPCA model 27 | kpca.train(trainData); 28 | 29 | % Visualization 30 | kplot = KernelPCAVisualization(); 31 | kplot.cumContribution(kpca) 32 | 33 | %% case 2 34 | %{ 35 | The number of components is determined by the given number. 36 | For example, when the given number is set to 24, the parameter should 37 | be set as: 38 | 39 | parameter = struct('numComponents', 24, ... 40 | 'kernelFunc', kernel); 41 | %} 42 | parameter = struct('numComponents', 24, ... 43 | 'kernelFunc', kernel); 44 | % build a KPCA object 45 | kpca = KernelPCA(parameter); 46 | % train KPCA model 47 | kpca.train(trainData); 48 | 49 | % Visualization 50 | kplot = KernelPCAVisualization(); 51 | kplot.cumContribution(kpca) 52 | 53 | -------------------------------------------------------------------------------- /demo_DR_Reconstruction.m: -------------------------------------------------------------------------------- 1 | %{ 2 | Demonstration of reconstruction using KPCA. 3 | %} 4 | clc 5 | clear all 6 | close all 7 | addpath(genpath(pwd)) 8 | 9 | load('.\data\circle.mat', 'data') 10 | kernel = Kernel('type', 'gaussian', 'gamma', 0.2); 11 | parameter = struct('numComponents', 2, ... 12 | 'kernelFunc', kernel); 13 | % build a KPCA object 14 | kpca = KernelPCA(parameter); 15 | % train KPCA model 16 | kpca.train(data); 17 | 18 | % reconstructed data 19 | reconstructedData = kpca.newData; 20 | 21 | % Visualization 22 | kplot = KernelPCAVisualization(); 23 | kplot.reconstruction(kpca) 24 | -------------------------------------------------------------------------------- /demo_FD.m: -------------------------------------------------------------------------------- 1 | %{ 2 | Demonstration of fault detection using KPCA. 3 | %} 4 | clc 5 | clear all 6 | close all 7 | addpath(genpath(pwd)) 8 | 9 | load('.\data\TE.mat', 'trainData', 'testData') 10 | kernel = Kernel('type', 'gaussian', 'gamma', 1/128^2); 11 | parameter = struct('numComponents', 0.65, ... 12 | 'kernelFunc', kernel); 13 | 14 | % build a KPCA object 15 | kpca = KernelPCA(parameter); 16 | % train KPCA model 17 | kpca.train(trainData); 18 | % test KPCA model 19 | results = kpca.test(testData); 20 | 21 | % Visualization 22 | kplot = KernelPCAVisualization(); 23 | kplot.cumContribution(kpca) 24 | kplot.trainResults(kpca) 25 | kplot.testResults(kpca, results) 26 | -------------------------------------------------------------------------------- /demo_FD_Diagnosis.m: -------------------------------------------------------------------------------- 1 | %{ 2 | Demonstration of fault detection and fault diagnosis using KPCA. 3 | %} 4 | clc 5 | clear all 6 | close all 7 | addpath(genpath(pwd)) 8 | 9 | load('.\data\TE.mat', 'trainData', 'testData') 10 | kernel = Kernel('type', 'gaussian', 'gamma', 1/128^2); 11 | 12 | parameter = struct('numComponents', 0.65, ... 13 | 'kernelFunc', kernel,... 14 | 'diagnosis', [300, 500]); 15 | 16 | % build a KPCA object 17 | kpca = KernelPCA(parameter); 18 | % train KPCA model 19 | kpca.train(trainData); 20 | % test KPCA model 21 | results = kpca.test(testData); 22 | 23 | % Visualization 24 | kplot = KernelPCAVisualization(); 25 | kplot.cumContribution(kpca) 26 | kplot.trainResults(kpca) 27 | kplot.testResults(kpca, results) 28 | kplot.diagnosis(results) -------------------------------------------------------------------------------- /demo_kernel_function.m: -------------------------------------------------------------------------------- 1 | %{ 2 | Demonstration of computing the kernel function matrix. 3 | %} 4 | 5 | clc 6 | clear all 7 | close all 8 | addpath(genpath(pwd)) 9 | 10 | % data 11 | X = rand(33, 2); 12 | Y = rand(23, 2); 13 | 14 | % kernel setting 15 | kernel1 = Kernel('type', 'gaussian', 'gamma', 0.01); 16 | kernel2 = Kernel('type', 'polynomial', 'degree', 3); 17 | kernel3 = Kernel('type', 'linear'); 18 | kernel4 = Kernel('type', 'sigmoid', 'gamma', 0.01); 19 | kernel5 = Kernel('type', 'laplacian', 'gamma', 0.1); 20 | 21 | % compute the kernel function matrix 22 | matrix{1} = kernel1.computeMatrix(X, Y); 23 | matrix{2} = kernel2.computeMatrix(X, Y); 24 | matrix{3} = kernel3.computeMatrix(X, Y); 25 | matrix{4} = kernel4.computeMatrix(X, Y); 26 | matrix{5} = kernel5.computeMatrix(X, Y); --------------------------------------------------------------------------------