构造性覆盖算法简单实现(MATLAB)
一、算法原理
1.n维的数据可以表示维n维空间中的点,而在n维空间中划分n维球面,将同一类样本点划分在同一个球面内部。(需保证每个样本点与原点距离相等,即都在以原点为圆心,某个值r为半径的n维球面上)
2.随机抽取一个未被标记的样本点为球心,找出最大的n维球体,使得球面内全部样本点与球心分类相同。将球心和球体范围内的样本点标记。其中求半径的方法有:
①最大半径法:以中心到最近的异类样本点的距离为半径。
②最小半径法:以中心到最近的异类样本点以内的范围内最远的同类样本点的距离为半径。
③折中半径法:以上述两种的平均值做为半径。
3.重复2中的步骤 ,直到所有的点都被标记。
4.训练完成后就可以通过判断待分类的样本点落在哪个球体内来进行分类。由于训练样本的有限性,在实际分类过程中样本点可能会落在所有球体范围外;或者可能落在两个球体的重叠部分。区域划分过程使用最大半径法往往重叠范围较大;使用最小半径法重叠范围往往较小;折中半径法介于两者之间。这些情况有以下解决方法:
①距中心最近原则:将样本点划分到最近的中心点所在的分类中。
②距边界最近原则:将样本点划分到最近边界所在圆形领域的分类中。
③万有引力原则:将圆形领域的样本数量除以样本到圆形领域的中心的欧式距离,划分到较大的那个中。
补充:
①升维处理:将n-1维数据升到n维,以保证所有样本点在n维超空间中与原点欧式距离相等,这样才能使用本算法。
②数据归一化:将样本数据变换使得分布于0-1之间
二、算法实现
运行环境:MATLAB 2017B。
1.CCA函数
(数据的预处理写的乱七八糟,还把label分开了,很麻烦,代码写了一年了我自己都不太明白了改不动了,下面放上github链接,里面的有我处理过的数据的文件夹,放在主文件同目录下就直接能跑出文中结果。)
https://github.com/XuPeng23/MachineLearning/tree/master/%E6%9E%84%E9%80%A0%E6%80%A7%E8%A6%86%E7%9B%96%E7%AE%97%E6%B3%95
Input2:归一化、升维处理后的数据(不包含Label)
Label:分类信息
function [ ] = CCA(Input2,Label)
%Input:Matrix of the data attributes
%Label:classfication label of the data
%构造性覆盖算法
%ratio : training
%1-ratio : validation
ratio = 0.7;
[m,n] = size(Input2);
%Data line1 : Label
%Data line2 : attributes
Data = [Label,Input2];
[ndata,d] = size(Data);
nTr = int16(ndata*ratio);
nVar = int16(ndata*(1-ratio));
R = randperm(ndata);
Tr = zeros(nTr,d);
Var = zeros(int16(nVar),d);
%devide data into TrainData and VarData
for i = 1:nTr
Tr(i,:) = Data(R(i),:);
end
for i = nTr+1:ndata
Var(i-nTr,:) = Data(R(i),:);
end
%Flag line1 : if samples is classified
%Flag line2 : witch class
FlagTr = zeros(nTr,2);
FlagVar = zeros(nVar,2);
%Hidden 1-n : attributes
%Hidden n+1 : radius
%Hidden n+2 : classNumber
Hidden = zeros(1,n+2);
nHidden = 0;
% ***************** Start Training ******************************
disp('Start Training ...');
% find a random sample as the center
while sum(FlagTr(:,1))~=nTr
x = rand(1,1)*(nTr-1) + 1;
if FlagTr(x,1)==1
continue;
end
if FlagTr(x,1)==0
nHidden = nHidden + 1;
for i = 1:n
Hidden(nHidden,i) = Tr(x,i+1);
end
Hidden(nHidden,n+1) = 0;
Hidden(nHidden,n+2) = Tr(x,1);
FlagTr(x,1) = 1;
FlagTr(x,2) = nHidden;
dis = 0;
for i = 1:nTr
if Tr(i,1)~=Hidden(nHidden,n+2)
if dis < sum(Hidden(nHidden,1:n).*Tr(i,2:n+1))
dis = sum(Hidden(nHidden,1:n).*Tr(i,2:n+1));
end
end
end
Hidden(nHidden,n+1) = dis;
%fprintf('the radius of cricle %d is %f ,center is %d\n',nHidden,dis,x);
for i = 1:nTr
if FlagTr(i,1)==0 && Tr(i,1)==Hidden(nHidden,n+2)
if dis < sum(Hidden(nHidden,1:n).*Tr(i,2:n+1))
FlagTr(i,1) = 1;
FlagTr(i,2) = nHidden;
end
end
end
end
end
disp(Hidden);
% ***************** Start Validating ******************************
disp('Start Validating ...');
for x = 1:nVar
for y = 1:nHidden
if sum(Hidden(y,1:n).*Var(x,2:n+1)) > Hidden(y,n+1)
FlagVar(x,1) = 1;
FlagVar(x,2) = Hidden(y,n+2);
break;
end
end
if FlagVar(x,1) == 0
max = 0;
FlagVar(x,1) = 8;
for y = 1:nHidden
if sum(Hidden(y,1:n).*Var(x,2:n+1)) > max
max = sum(Hidden(y,1:n).*Var(x,2:n+1));
FlagVar(x,2) = Hidden(y,n+2);
end
end
end
end
nTrue = 0;
for x = 1:nVar
if FlagVar(x,2)==Var(x,1);
nTrue = nTrue + 1;
end
end
% disp('XXX predictedValue realValue');
% disp([FlagVar,Var(:,1)]);
numC = 0;
for i = 1:nVar
if FlagVar(i,1)==1
numC = numC + 1;
end
end
fprintf('nHidden = %d个\n',nHidden);
fprintf('%d,%d\n',nTrue,nVar);
fprintf('AccuracyRate = %.1f %s\n',nTrue*100/nVar,'%');
fprintf('%d,%d\n',numC,nVar);
fprintf('num_sample_inCricles = %.1f %s\n',numC*100/nVar,'%');
end
2.主程序
clc;
close all;
load('diagnosis\In.mat');
load('diagnosis\Label.mat');
Input = normalization(In); %归一化处理
Input2 = dimensionRaise(Input); %升维处理
% CCA(Input2,Label);
VCCA(Input2,Label);
3.归一化处理函数
function [Input] = normalization(In)
% 将数据归一化处理
disp('开始数据归一化');
[m,n] = size(In);
Input = zeros(m,n);
[max_In,index] = max(In);
[min_In,index2] = min(In);
for i = [1:n]
for j = [1:m]
Input(j,i) = (In(j,i)-min_In(i))/(max_In(i)-min_In(i));
end
end
disp('数据归一化完成');
end
4.升维处理函数
function [Input2] = dimensionRaise(In)
%属性数据升维处理
disp('开始数据升维处理');
[m,n] = size(In);
Input2 = [In,zeros(m,1)];
Dis = zeros(m,1);
for i = [1:m]
for j = [1:n]
Dis(i) = Dis(i) + Input2(i,j)^2;
end
end
indexMax = find(Dis == max(Dis));
for i = 1:m
Input2(i,n+1) = sqrt(max(Dis) - Dis(i));
end
disp('数据升维处理完成');
end
三、基于投票的改进型CCA算法
一次训练多个模型,进行分类的时候通过多个模型来分类,根据分类结果投票选择最终分类结果。相比于基础CCA算法在分类准确性方面有小幅度提升。
四、运行结果
1.运行示例
运行结果有点乱,说明一下:
①这个nHidden就是训练出的模型的隐层即划分的超空间中的球体的个数
②上面的行中前n-2列是球体的球心位置,倒数第二列是球体半径,最后一列是该划分的分类标签
③最下面是验证集的样本总数和分类正确的样本数
2.实验结果
参考资料:
[1] Zhang L , Zhang B . A geometrical representation of McCulloch-Pitts neural model and its applications[J]. IEEE Transactions on Neural Networks, 1999, 10(4):925-929.
[2] 张燕平, 2], 邹慧锦,等. CCA三支决策模型的边界域样本处理[J]. 计算机科学与探索, 2014(05):85-92.