楼主: yukai08008
1032 0

[学习分享] Apriori_V2_IML程序(调整)_Andy的原创帖24 [推广有奖]

  • 2关注
  • 17粉丝

讲师

2%

还不是VIP/贵宾

-

威望
0
论坛币
2176 个
通用积分
3.0600
学术水平
10 点
热心指数
7 点
信用等级
7 点
经验
5915 点
帖子
120
精华
0
在线时间
556 小时
注册时间
2012-11-28
最后登录
2022-4-11

+2 论坛币
k人 参与回答

经管之家送您一份

应届毕业生专属福利!

求职就业群
赵安豆老师微信:zhaoandou666

经管之家联合CDA

送您一个全额奖学金名额~ !

感谢您参与论坛问题回答

经管之家送您两个论坛币!

+2 论坛币

把之前的一个频数检验的错误改过来,然后把程序做了一些精简,再把一些过程用module封装。
*******************************************************
*主控宏;
%macro ap2(ins,dim,sup);
/*1数据集载入矩阵,默认矩阵为m1*/
%im1(&ins,&dim)
/*2执行第一次,并生成一些关键矩阵*/
%im2
/*3执行第二次,生成二项集,并且给出iter_jud来控制循环*/
%im3;
%do iter=3 %to &dim;
%if %eval(&iter-&iter_jud) > 1 %then %goto jumpout;
%im4;
%end;
%jumpout:;
%mend;

im1:
%macro im1(ins,vdim);
data m1;
retain c1-c&vdim.;
set &ins;
run;
proc iml ;
use m1;
read all var _num_ into m1;
close m1;
store m1;
quit;
%mend;

im2:
%macro im2;
proc iml;
load m1;
sup_c=symget('sup');
supr=num(sup_c);
mdim=ncol(m1);
/*支持频数*/
sup=max(int((nrow(m1)*supr)),1);
/*全向量 c1*/
vec=j(1,mdim,1);
/*空向量*/
vnull=j(1,mdim,0);
/*开始计算*/
cal1=m1 & vec;
cal2=cal1[+,];
/*行向量*/
cal3=cal2 > sup;
/*将f1从cal3从拆解成矩阵*/
/*使用单位向量*/
e=i(mdim);
res=e#cal3;
side=res[,+];
res=res[loc(side),];
/*为f1矩阵生成‘侧边栏’*/
side=res[,+];
store  sup  vnull res side;
quit;
%mend;


im3:
%macro im3;
proc iml;
load m1 sup vnull res side;
/*模块定义:定义nodup为删除空行的模块*/
start nodup(a);
/*获取侧边栏*/
side_tem=a[,+];
/*选择非空行*/
a=a[loc(side_tem),];
finish;
/*指定检查的矩阵和轮数,在m1中查询并把结果附加到res*/
start fcheck(iter,a,m1,res,sup);
do i=1 to nrow(a);
t1=m1 & a[i,];
/*选取侧边栏对应的记录*/
side_tem=t1[,+];
loc_tem=loc(side_tem=iter);
t1_tem=t1[loc_tem,];
t1_sum=t1_tem[+,];
tmax=t1_sum[<>];
if tmax > sup then res=res//a[i,];
end;
finish;

/*获取项集=1的位置*/
loc=loc(side=1);
/*取出后组成一行数维数即为个数*/
nloc=ncol(loc);       

/*嵌套循环生成候选二项集,先存在候选集里*/
cand=vnull;
do i=1 to nloc-1;
   do j=i+1 to nloc;
/*二项集只要按顺序相加即可生成*/
   vtem=res[i,]+res[j,];
   cand=cand//vtem;
   end;
end;
/*去掉cand的空行*/
run nodup(cand);
/*在第二轮进行频数支持检查*/
run fcheck(2,cand,m1,res,sup);

side=res[,+];
iter_jud=side[<>];
call symput('iter_jud',char(iter_jud));
store module=(nodup fcheck) res side;
quit;
%mend;

im4:
%macro im4;
proc iml;
load module=(nodup fcheck) m1 sup vnull res side;
iter_c=symget('iter');
iter=num(iter_c);
iter_1=iter-1;
/*取k-1项集,即 iter-1*/
loc=loc(side=iter_1);
nloc=ncol(loc);

/*1 growth*/
/*嵌套循环形成全组合*/
cand=vnull;
cand1=vnull;
do i=1 to nloc-1;
   do j=i+1 to nloc;
/*左边部分*/
lf=res[loc[i],];
loclf=loc(lf);
lflast=loclf[<>];
lftem=lf;
lftem[lflast]=0;
/*右边部分*/
rt=res[loc[j],];
locrt=loc(rt);
rtlast=locrt[<>];
rttem=rt;
rttem[rtlast]=0;
/*判断部分*/
if lftem = rttem then do;
mer=lf+rt;
mer=mer > 0;
cand=cand//mer;
end;
end;
end;


/*这里应该生成完整的cand,必须要把cand首项移除,否则空值无法继续*/
run nodup(cand);

/*2 剪枝*/
/*获取iter-1项集*/
/*获取iter-1项集下标,利用侧边栏*/
loccm=loc(side=iter_1);
cm=res[loccm,];
/*对cand中每一项循环*/
do i=1 to nrow(cand);
check=cand[i,];
ck=0;
/*获取检查向量的1下标*/
loc_tem=loc(check);
/*每项循环k次进行检查*/
do j=1 to iter;
tem=check;
tem[loc_tem[j]]=0;
tem_a=cm & tem;
tem_b=tem_a[,+];
tem_c=tem_b[<>];
/*如果检查数正确那么计数加1*/
if tem_c = iter_1 then ck=ck+1;
else goto mm;
/*如果k项检查都通过,那么把这项附加到cand1中*/
if ck=iter then cand1=cand1//check;
end;
mm:;
end;

/*把cand1的首项空也去掉*/
run nodup(cand1);

/*3再次扫描进行频繁项检查*/
run fcheck(iter,cand1,m1,res,sup);

side=res[,+];
iter_jud=side[<>];
call symput('iter_jud',char(iter_jud));
store res side;
quit;
%mend;

二维码

扫码加我 拉你入群

请注明:姓名-公司-职位

以便审核进群资格,未注明则拒绝

关键词:Apriori Priori PRIOR Andy Apr 图片 程序

您需要登录后才可以回帖 登录 | 我要注册

本版微信群
加好友,备注cda
拉您进交流群

京ICP备16021002-2号 京B2-20170662号 京公网安备 11010802022788号 论坛法律顾问:王进律师 知识产权保护声明   免责及隐私声明

GMT+8, 2024-6-10 12:15