机器学习PLA算法.docx
《机器学习PLA算法.docx》由会员分享,可在线阅读,更多相关《机器学习PLA算法.docx(24页珍藏版)》请在冰豆网上搜索。
机器学习PLA算法
PLAandPOCKET
问题描述--------算法思想设计描述------伪代码-----复杂度分析---------编程-----上机调试--------实验分析------结论,本文是采用这样的顺序描述算法的。
本文所写算法对应于一个NP-Hard问题,主要采用近似求解算法和贪心算法的思想。
这对应于机器学习中BinaryClassification,PLA,PocketAlgorithm
问题描述:
银行发信用卡问题。
现有一群人,数量为N,(N很大),假设他们在一个银行中的登记记录数据我们已经得到。
对于每个人记录的数据有
(对应第i个人的信息,相应的
我们可以认为是这个人的一些个人数据的量化值,比如年龄、学历、收入、工作年限等等,他们会对应于一组数值如0.945440.428420.798330.16244-1对应于
)。
如果y是-1,则对应于银行没有给他发信用卡。
如果是y=1,则是发给了它信用卡。
现在由这样的一推数据如何得到一个函数,有这些训练集得到这个目标函数。
并用这个目标函数作用于对于一群待发信用卡的人作出判断,一边给银行提供发卡的依据。
具体数据见附录Q18Train.m为训练数据集,Q18TestData.m为待判断数据集,这里我们可以叫他测试数据集。
对于银行,他之前会设置一个发信用卡的门限值threshold.
算法描述和伪代码表述:
之前我们都是用PLA(perceptionlearningalgorithm):
它是针对于线性可分的训练集的。
也就是这样的所有的数据,比如说是二维数据点,可以用一条直线将他们分成两派,一片是可发卡的数据,直线另一侧则是不可发卡数据。
将用户数据加权求和与门限值相比较,作差为正则发卡,为负则不发卡。
这里假设一个Hypothesisdatasets,每计算一次都是一个H,如果有错则修正,一直到所有的数据都没有错误,这样的H就是我们的未知的目标函数f。
对于h,
这里h可以化简一下,
PLA的算法描述是:
wt是类似于那条直线的法向量,(
)是一个人的数据记录
fort=0,1,2,3....
findamistakeofwtcalled(
)
trytocorrectthemistakeby
对于线性可分数据集PLA算法是收敛的证明:
,t是代表第t次得到的结果或者第t次所用的数值。
(1)
这里是单增的,如果从向量角度看,两个向量内积越大,如果排除其模值得快速增大,可以看做是其角度在不断的调整,逐渐变得同向。
(2)就是证明其模值变化有限。
(2)
这里可以认为每次增加的步长有限,同时也说明
两个向量的内积越来越大,不是因为其模值快速变化所致。
因此可以看出最终得到的Wt是收敛的(对于线性可分数据集)。
而且可以算出t的取值:
而且:
则
这是线性可分数据集的PLA终止时的T的次数表达式。
PLA算法对于线性可分的数据源是可以最后能得到目标函数的。
但是对于线性不可分的数据集,它不会自动的停止。
对于非线性不可分的数据集,如果对其分类,它将是一个NP-Hard问题。
这里的Pocket算法,则是一种近似算法,他是用贪心算法,每次将PLA修正的wt与pocket记录的pwt比较,对于所有数据集犯错最少的那个作为新的pwt,这样PLA一直进行,得到修正的值wt与pwt比较,如果wt的犯错少,则将pwt更新为wt。
如果进行的Pocket算法运行时间足够长,因此我们就可以找到一个算错尽可能少的pwt。
并以此来进行对于测试数据集的分类。
Pocket算法如果对于线性可分数据集,它会自动停止,并且得到一个wt,线性可分数据集,然后用于测试。
本文主要是采用pocket算法():
//%funpocket2.m
initializepocketweightspwt
fort=0,1,2,....
//%finda(random)mistakeofwtcalled(xn(t),yn(t))
while!
flag
d<-(Maxnum-1)*rand()+1;
//%X[d]representativethedrowdatas
x[d][1]=1,x[d][2..n]=X[d][1..n-1];
y=X[d][n],
ifsign(Wt'*x[d])~=y
flag<-true;
//%trytocorrectthemistakeby
//%ifWt+1makesfewermistakesthanreplacepwtwithWt+1
iffunWtError(pwt,dataset)>funWtError(Wt+1,dataset)
pwt=Wt+1;
untilenoughiterationst=
stop.
returnpwt(asWpocket)
%对应于wn的训练集的错误概率计算
%funWtError.m
funWtError(wt1,dataset)
datasetmatrixnrows,mcols
xn[1]=1;
whilecount<=n
xn[2..m]=dataset[count][1..m-1];
yn=dataset[count][m];
ifsign(wn1'*xn)~=yn
errFlag<-=errFlag+1;
count<-=count+1;
reutrnerrFlag/n;
关于pocket算法的几点说明:
(1)对应于上述算法,在funpocket2.m中
initializepocketweightspwt
fort=0,1,2,....
//%finda(random)mistakeofwtcalled(xn(t),yn(t))
查找一个随机的带有错误数据的Wt,这样随机找是很慢的可以改进一下,Wt,对应于这个法向量,先判断出相应有错误的数据集,然后再再从这里面进行随机,这样的查找更快些。
对应于程序中的实现是采用了这种方式。
而不是每次都随机选一行的数据,判断是不是有错,有错在更新,如果一直随机都是没错的那么就相当的耗费时间。
(2)pocket算对于线性不可分数据集是不会终止的,也就是说,他是一个NP问题。
如果数据集大体上是线性可分数据集,只有一部分点不可分,我们只需要运行足够长的时间,或者pwt进行一定数量的替换,用这种T次更新取代完全更新到正确的t次数的近似和每次遇到好的Wt+1都才用贪心的算法替代pwt,这样也能得到一个比较好的分线结果。
复杂度分析
对于近似算法解NP问题,这里的时间复杂度:
对于
,其时间复杂度为
,
finda(random)mistakeofwtcalled(xn(t),yn(t))时间复杂度为
对应于wn的训练集的错误概率计算
总的时间复杂度:
,
,
为一个向量与另一个向量的乘积所用时间。
,
又是n的函数(一个多项式),
。
此时如果采用给出的伪代码中的随机选一个来判断数据对于Wt是否有误,这样就像是非确定算法,采用猜测的形式将所有的可能性随机的选一个,结果是YES/NO,NO时继续随机选取,猜算可以在多项式时间内完成;验算其实就计算的有限时间了
。
有限时,就是采用近似的算法,虽然并不一定能够得到一个全局的满足的Wt,但是对于绝大多数的点分类还是可以的,这就是我们想要的。
因此,近似的贪心算法思想的pocket算法其时间复杂度是多项式的函数,可以在时间多项式内完成。
代码编程(matlab实现)
%////////////////////////////////////////////////////////////////////////////////////////////////////
%FunRandArray.m
function[arr]=FunRandArray(Maxnum,repeatFlag)
%Array[maxnum],ifnotinput,therepeatflag=1
%repeatFlag=0%generatethethenaviecyclydataset
%repeatFlaf==1%,generatetherand,arrmayhavethesamedata
%repeatFlaf==2%generatethetheranddatasetvisit,
rand('state',sum(100.*clock)*rand
(1));
arr=(Maxnum-1).*rand(1,Maxnum)+1;
arr1=ceil(arr(:
:
));
flag=0;
arr=arr1;
%naturesequence
ifrepeatFlag==0
fori=1:
Maxnum
arr(i)=i;
end
elseifrepeatFlag==1
elseifrepeatFlag==2
%tochangeintothedifferentdata
AllData=zeros(1,Maxnum);
fori=1:
Maxnum
ALLData(i)=i;
end
%///////////////////////////////////////////////////
%clearthesamedatainthearr
fori=1:
Maxnum
flag=0;
forj=1:
Maxnum
ifarr(i)==ALLData(j)
flag=1;
ALLData(j)=-1;
break;
end
end
ifflag==0
arr(i)=0;
end
end
%/////////////////////////////////////////////
%addthenoexistdatabutin1-400tothearr
fori=1:
Maxnum
ifarr(i)==0
forj=1:
Maxnum
ifALLData(j)~=-1
arr(i)=ALLData(j);
ALLData(j)=-1;
break;
end
end
end
end
end
end
end
%///////////////////////////////////////////////////////////////////////////////////////////////////
%funWtError.m
function[errDataSetLine,errPossablitiy]=funWtError(Wn1,DataSet)
[nm]=size(DataSet);
errFlag1=0;
count=1;
xn=ones(1,m);
errDataSetLineTemp=zeros(1,n);
whilecount<=n
xn(1,2:
m)=DataSet(count,1:
m-1);
yn1=xn*Wn1';
ifyn1==0%==not==
yn1=-1;
end
ifsign(yn1)~=DataSet(count,m)%sign()function
errFlag1=errFlag1+1;
errDataSetLineTemp(1,errFlag1)=count;
end
count=count+1;
end
errDataSetLine=zeros(1,errFlag1);
errDataSetLine(1,:
)=errDataSetLineTemp(1,1:
errFlag1);
errPossablitiy=errFlag1/n;
%//////////////////////////////////////////////////////////////////////////////////////////////////////
%funWwtBest
function[pockWn,flag,errPossablitiy]=funWwtBest(Wn1,Wn2,DataSet)
[nm]=size(DataSet);
errFlag1=0;
errFlag2=0;
flag=0;%0Wn1,1Wn2
count=1;
xn=ones(1,m);
whilecount<=n
xn(1,2:
m)=DataSet(count,1:
m-1);
yn1=xn*Wn1';
yn2=xn*Wn2';
ifyn1==0%==not==
yn1=-1;
end
ifyn2==0
yn2=-1;
end
%thisiserrorbecausethesignfunctionnotuse.
%ifyn1~=DataSet(count,m)
ifsign(yn1)~=DataSet(count,m)
errFlag1=errFlag1+1;
end
%ifyn2~=DataSet(count,m)
ifsign(yn2)~=DataSet(count,m)
errFlag2=errFlag2+1;
end
count=count+1;
end
errPossablitiy=errFlag1/n;
pockWn=Wn1;
iferrFlag1>errFlag2
pockWn=Wn2;
flag=1;
errPossablitiy=errFlag2/n;
end
%/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
%funPocket.m
function[pockWn,Wn,count,updateTTs,errposs]=funPocket(FData,FunRandArray,funWwtBest,updateTimes,WnrndFlag,DatasetFlag,nn)
%parametersannotaion
%totheinputparametersrequest
ifnargin==0|nargin==1|nargin==2
error('parametersnumberlacks');
end
ifnargin==3
updateTimes=200;
WnrndFlag=0;
DatasetFlag=0;
n=1;
end
ifnargin>7
error('inputparameterstoolarger');
end
%initial
dataset1=FData;
[nm]=size(dataset1);
Wn=zeros(1,m);
Wn(1,1)=0;
ifWnrndFlag==1
rand('state',sum(100*clock)*rand
(1));
Wn(2,m)=rand(1,m-1);
end
%trainingsetvisitingsequence
%ResultRand=zeros(1,n);
%ResultRand=FunRandArray(n,DatasetFlag);
xn=ones(1,m);
count=0;%countnumbers
noequalCount=0;
%pocketWn
pockWn=zeros(1,m);
updateTTs=0;
errposs=0;%attheendthepockWn'serrorpossiablity
filename1=strcat('aa_',num2str(updateTimes*rand
(1)));
filename1=strcat(filename1,'.txt')
ffile1=fopen(filename1,'w');
whileupdateTTs%fromtheerrorDataSet(someWn)randselectaXi
%errDataSetLineisarr[1....errFlag],
%arr[1]=thefirstnumberofXinotsatisfyingyn=xn*Wn'
%thenumbercorresponingtheDataSet'slinelabel
[errDataSetLine,errPossTemp]=funWtError(Wn,dataset1);
[nerr,merr]=size(errDataSetLine);
rand('state',sum(100*clock)*rand
(1));
num=ceil((merr-1)*rand
(1)+1);
xn(2:
m)=dataset1(errDataSetLine(1,num),1:
m-1);
ytemp=xn*Wn';
ifytemp==0
ytemp=-1;
end
signtemp=sign(ytemp);
%signtemp,dataset1(ResultRand(num),m)
%num,xn,xn*Wn',signtemp,dataset1(num,m)
%ifsigntemp~=dataset1(ResultRand(num),m)
%num
ifsigntemp~=dataset1(errDataSetLine(1,num),m)
%Wn(1,1:
m)=Wn(1,1:
m)+nn.*xn(1,1:
m)*dataset1(ResultRand(num),m);
Wn(1,1:
m)=Wn(1,1:
m)+nn*dataset1(errDataSetLine(1,num),m).*xn(1,1:
m);
%a='before',Wn,pockWn
[tempWn,flag,errposs]=funWwtBest(Wn,pockWn,dataset1);
%a='after',Wn,tempWn
ifflag==0
updateTTs=updateTTs+1;
pockWn=tempWn;
fprintf(ffile1,'%s\t\t','updateTTs');
fprintf(ffile1,'%d\t\t\t\r\n',updateTTs);
fprintf(ffile1,'%s\t\t','pocketWn');
fprintf(ffile1,'%f\t\t\t\r\n',pockWn);
updateTTs
%else
%Wn=pockWn;
end
%pockWn
%count=1;
end
end
fclose(ffile1);
%pockWn
%/////////////////////////////////////////////////////////////////////////////////////////////////////////
%pocketTrainTest.m
function[errAverage]=pocketTrainTest(LoopNum,FDataTrain,FDTest,FunRandArray,funWwtBest,funWtError,updateTimes,WnrndFlag,DatasetFlag,nn)
FData=load(FDataTrain);%%
[nm]=size(FData);
FDataTest=load(FDTest);
avgerr=0;
errPossArr=zeros(1,LoopNum);
%pockWn=zeros(LoopNum,m);
pockWnTemp=zeros(1,m);
Wn=zeros(1,m);
fori=1:
1:
LoopNum
[pockWnTemp,Wn,count,updatenum,errposs]=funPocket(FData,FunRandArray,funWwtBest,updateTimes,WnrndFlag,DatasetFlag,nn);
[errDataSetLine,errPossTemp]=funWtError(pockWnTemp,FDataTest);
%errPossTemp
avgerr=(avgerr*(i-1)+errPossTemp)/i
%errPossTemp
errPossArr(1,i)=errPossTemp;
end
errAverage=mean(errPossArr(1,:
));
%///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
%pocketTrainTest.m[errAverage]=pocketTrainTest(LoopNum,FDataTrain,FDTest,FunRandArray,funWwtBest,funWtError,updateTimes,WnrndFlag,DatasetFlag,nn)
FData=load(FDataTrain);%%
[nm]=size(FData);
FDataTest=load(FDTest);
avgerr=0;
errPossArr=zeros(1,LoopNum);
pockWnTemp=zeros(1,m);
Wn=zeros(1,m);
filename=strcat('aa',num2str(updateTimes));
filename=strcat(filename,'.txt')
ffile=fopen(filename,'w');
%filename
fprintf(ffile,'%s\t\t','i');
fprintf(ffile,'%s\t\t','pockWnTemp');
fprintf(ffile,'%s\t\t\t\r\n','avgerr');
fori=1:
1:
LoopNum
i
[pockWnTemp,Wn,count,updatenum,errposs]=funPocket(FData,FunRandArray,funWwtBest,