粗糙集 属性约简
注:这是我学粗糙集时老师给的作业
题目: SARS 诊断
干
咳
U
呼
吸
困
难
血
液
检
测
高
烧
38
度
X
射
线
浓
痰
血
细
胞
多
寒
战
肌
肉
酸
痛
乏
力
胸
膜
痛
头
痛
非
典
1 1 1 1 1 0 0 0 0 1 1 0 1 1
2 0 0 0 0 0 0 0 0 0 0 0 0 0
3 1 0 1 0 0 0 0 0 0 1 0 0 0
4 0 0 0 1 1 1 1 0 1 0 1 1 0
5 1 0 0 1 1 1 1 1 0 1 1 0 0
6 0 1 0 1 1 1 1 1 1 0 0 1 0
7 1 0 0 0 1 1 1 0 0 1 1 1 0
8 1 1 1 1 0 0 0 0 1 1 0 1 1
9 1 0 1 1 1 0 0 0 1 1 0 1 1
10 1 1 1 1 0 0 0 0 1 1 0 1 1
11 1 0 1 1 1 0 0 0 1 1 0 1 1
12 1 0 1 1 1 0 0 0 1 1 0 1 1
属性约简的顺序如下:求正域、生成未经处理的区分矩阵、对区分矩阵进行化简、求核、对
已经处理过的区分矩阵进行属性约简。约简后的决策表有 26 行,所有 12 个属性都是正域中
的属性,核为空
程序:
% main.m
tic;
a=[ 1,1,1,1,0,0,0,0,1,1,0,1;
0,0,0,0,0,0,0,0,0,0,0,0;
1,0,1,0,0,0,0,0,0,1,0,0;
0,0,0,1,1,1,1,0,1,0,1,1;
1,0,0,1,1,1,1,1,0,1,1,0;
0,1,0,1,1,1,1,1,1,0,0,1;
1,0,0,0,1,1,1,0,0,1,1,1;
1,1,1,1,0,0,0,0,1,1,0,1;
1,0,1,1,1,0,0,0,1,1,0,1;
1,1,1,1,0,0,0,0,1,1,0,1;
1,0,1,1,1,0,0,0,1,1,0,1;
1,0,1,1,1,0,0,0,1,1,0,1 ];
d=[1;0;0;0;0;0;0;1;1;1;1;1];
pos=posCD(a,d);
dismat=dismatrix(a,d,pos);
dism=disbe(dismat);
core=cor(dism);
[red,row]=redu(dism);
time=toc
% dismatrix.m
% 生成未经处理的区分矩阵 dismat
function dismat=dismatrix(a,d,pos)
[m,n]=size(a);
p=1;
index1=0;index2=0;index=0;
dis=-1*ones(m*(m-1)/2,n);
for i=1:m
for j=i+1:m
if (isxbelongtopos(i,pos)&~isxbelongtopos(j,pos))...
|(~isxbelongtopos(i,pos)&isxbelongtopos(j,pos))...
|(isxbelongtopos(i,pos)&isxbelongtopos(j,pos)&~isxybelongtoindD(i,j,d))
index2=1;
end
if index2==0
continue;
end
for k=1:n
if a(i,k)~=a(j,k)
dis(p,k)=1;
index1=1;
else dis(p,k)=0;
end
end
if index1==1
p=p+1;index=1;
end
index1=0;
index2=0;
end
end
if p<=m*(m-1)/2
if index==0
dismat=[];
return;
end
if dis(p,1)==-1
p=p-1;
end
else p=m*(m-1)/2;
end
dismat=dis(1:p,:);
% redu.m
% 对已经处理过的区分矩阵进行知识约简
function [red,row]=redu(dism)
[m,n]=size(dism);
red=[];
row=0;
if m<=0
return;
end
for i=1:n
if dism(1,i)~=0
row=row+1;
end
end
red(1:row,:)=zeros(row,n);
j=1;
for i=1:row
while dism(1,j)==0
j=j+1;
end
red(i,j)=1;
j=j+1;
end
temp=[];tempdis=[];
rowd=0;rowd1=0;
for i=2:m
j=1;
while j<=row
temp=uni(dism(i,:),red(j,:));
[s,n]=size(temp);
rowd1=rowd+s;
tempdis(rowd+1:rowd1,:)=temp;
rowd=rowd1;
j=j+1;
temp=[];
end
red=[];
red=disbe(tempdis);
tempdis=[];
[row,n]=size(red);
rowd=0;rowd1=0;
end
% disbe.m
% 对区分矩阵或者约简矩阵进行化简即去掉包含关系
function dism=disbe(dis)
[m,n]=size(dis);
p=m;
for i=1:m
if dis(i,1)~=-1
for j=1:m
if i~=j & dis(j,1)~=-1
if dis(i,:)<=dis(j,:)
dis(j,1)=-1;
p=p-1;
elseif dis(i,:)>=dis(j,:)
dis(i,:)=dis(j,:);
dis(j,1)=-1;
p=p-1;
end
end
end
end
end
dism=ones(p,n);
j=1;
for i=1:p
while j<=m & dis(j,1)==-1
j=j+1;
end
dism(i,:)=dis(j,:);
j=j+1;
end
% posCD.m
% a 为条件属性矩阵,d 为决策属性向量
% pos 为正域,保存条件属性矩阵的索引值
function pos=posCD(a,d)
[m,n]=size(a);
p=m;
index=0;
for i=1:m
if a(i,1)~=-1
for j=i+1:m
if a(j,1)~=-1 &(a(i,:)==a(j,:)&d(i)~=d(j))
a(j,1)=-1;p=p-1;index=1;
end
end
if index==1
a(i,1)=-1;p=p-1;index=0;
end
end
end
pos=zeros(p,1);
i=1;
for r=1:p
while a(i,1)==-1&i<=m
i=i+1;
end
pos(r)=i;
r=r+1;
i=i+1;
end
% cor.m
% 对已经处理过的区分矩阵求核
function core=cor(dism)
[m,n]=size(dism);
core1=zeros(1,n);
number=0;
for i=1:m
num=0;p=0;
for j=1:n
if dism(i,j)~=0
num=num+1;
p=j;
end
end
if num==1
core1(p)=1;
number=number+1;
end
end
if number==0
core=0;
else
core=zeros(1,number);
j=1;
for i=1:number
while core1(j)==0
j=j+1;
end
core(i)=core1(j);
j=j+1;
end
end
% uni.m
%对区分矩阵的第 i 行和 red(j,:)运算,即将 a 中
%所有的 1 分别插入到 red(j,:)中,待去掉包含关系
function tempred=uni(disa,red)
[m,n]=size(red);
num=0;
for i=1:n
if disa(i)~=0
num=num+1;
end
end
tempred=ones(m*num,n);
temp=[];
j=1;
for i=1:num
while disa(j)==0
j=j+1;
end
temp=red;
temp(:,j)=ones(m,1);
tempred((i-1)*m+1:i*m,:)=temp;
j=j+1;
end
% isxbelongtopos.m
% 判断 x 是否在正域 pos 中
% x 为索引值
% 返回值 p,如果 x 在 pos 中 p=1 否则 p=0
function p=isxbelongtopos(x,pos)
[m,n]=size(pos);
p=0;
if x<=0
p=-1;
return;
end
for i=1:m
if x==pos(i)
p=1;
break;
end
end
% isxybelongtoindD.m
% 判断 x,y 是否在 indD 中
% x,y 为索引值
% 返回值 p,如果 x,y 在 indD 中 p=1 否则 p=0
function p=isxybelongtoindD(x,y,d)
if x<=0 | x>size(d) | y<=0 | y>size(d)
p=-1;
return;
end
if d(x)==d(y)
p=1;
else p=0;
end
约简后的决策表