看板 NCTU-STAT94G 關於我們 聯絡資訊
內建的好像有點問題,改寫如下 (目前我寫的是沒看到問題,有興趣可以試試看) 後面有testing data pin=0.06 pout=0.05 keep=[] intercept=true 會選入 x4 x1 x2 -x4 。 即,最後剩下 x1 x2 在STATS.inmodel中 row 代表第幾步,column代表第幾個變數,0:沒有選到 1:選到 % 沒有內設的參數,所以,每一個arguments都要填滿。 % % STATS=stepwf(X,Y,pin,pout,keep,intercpt) % % Algorithm % 1. k=1,加入最小RSS的變數 (至少有一個變數比 null model好) % 2. k=k+1 % 3. 在(p-k+1)個變數中,找有最小的RSS的變數 % 4. 若其RSS的p-value<pin 加入。 % 否則,goto 8 % 5. 只要檢查前面k-1個選入的變數 (注意keep住的變數不可在其中) % 找刪除後有最小partial F 的變數 % % 6. 若刪除該變數後,其p-value>pout 則刪除該變數 % 7. 回到 2 % 8. STOP % % Arguments % X:predictors % Y:response % pin:entering probability % pout: removing probability % keep: keep some predictors ALWAYS in model ('column numbers' or []) % intercept: add intercept term or not (true or false) % % Return Values : % STATS.inmodel=inmodel; % STATS.SSE; % STATS.dfE; % STATS.SSR; % STATS.dfR; % STATS.sst; % STATS.pf (partial F statistic) % function STATS=stepwf(X,Y,pin,pout,keep,intercept) [nrow ncol]=size(X); % first step k=1; sse=10^10; SSE=zeros(ncol,1); dfE=zeros(ncol,1); SSR=zeros(ncol,1); dfR=zeros(ncol,1); pf=zeros(ncol,1); index=setdiff(1:ncol,keep); %candidate variables idx0=zeros(ncol,1); if ~isempty(keep) idx0(keep,1)=1; end for i=index idx1=sort([find(idx0==1);i]); if(intercept) x=[ones(nrow,1),X(:,idx1)]; else x=X(:,idx1); end beta=inv(x'*x)*x'*Y; yhat=x*beta; e=Y-yhat; r=yhat-mean(Y); ssr1=r'*r; sse1=e'*e; dfr=k; dfe=nrow-k-intercept; PF=ssr1/sse1/dfr*dfe; pval=1-fcdf(PF,dfr,dfe); % pval小表示和null model 有差異所以要選非null model if sse1<sse sse=sse1; idx=idx1; end end inmodel=zeros(1,ncol); inmodel(idx)=1; SSE(1)=sse; dfR(1)=k+(~isempty(keep))*length(keep); dfE(1)=nrow-intercept-dfR(1); SSR(1)=ssr1; pf(1)=PF; sse0=sse; t=Y-mean(Y); sst=t'*t; % setpwise %先加一個再看看可不可以丟一個 pval0=0; index=setdiff(1:ncol,keep); while pval0<pin [k ncol]=size(inmodel); k=k+1; sse0=SSE(k-1); sse=10^10; in0=sign(sum(inmodel,1)); for i=find(in0==0) in=in0; in(i)=1; if(intercept) x=[ones(nrow,1),X(:,in==1)]; else x=X(:,in==1); end beta=inv(x'*x)*x'*Y; yhat=x*beta; e=Y-yhat; %residual sse1=e'*e; r=yhat-mean(Y); %regression ssr1=r'*r; if sse1<sse flag=i; sse=sse1; ssr=ssr1; end end dfr=sum(in); dfe=nrow-dfr-intercept; PF=(sse0-sse)/sse*dfe; pval=1-fcdf(PF,1,dfe); pval0=pval; %若沒有增加變數,表示上一步就是最終結果,若有增加變數就要看前面有沒有可以 丟。 if pval<pin inmodel=[inmodel;zeros(1,ncol)]; inmodel(k,flag)=1; if ~isempty(keep) inmodel(k,keep)=1; end SSE(k)=sse;dfE(k)=dfe;SSR(k)=ssr;dfR(k)=dfr;pf(k)=PF; sse0=sse; sse=0; % % remove variable clear flag; out0=sign(sum(inmodel,1)); size(out0) PF=10^10; dfr=sum(out0)-1; dfe=nrow-dfr-intercept; indd=find(sign(sum(inmodel(1:(k-1),:),1))==1);% %把keep的位置移掉 if ~isempty(keep) indd(indd==keep)=[]; end for i=indd i out=zeros(1,ncol); out(i)=1 out=out0-out if(intercept) x=[ones(nrow,1),X(:,out==1)]; %intercept=true else x=X(:,out==1); %intercept=false end beta=inv(x'*x)*x'*Y; yhat=x*beta; e=Y-yhat; sse1=e'*e; r=yhat-mean(Y); ssr1=r'*r; PF1=(sse1-sse0)/sse0*(dfe-1); if PF1<PF %挑一個最不顯著改善殘值的變數,看是否可刪除該變數 flag=i; sse=sse1; ssr=ssr1; PF=PF1; end end % disp('dfe');dfe; pval=1-fcdf(PF,1,dfe-1); %pval小表示二個model有差異,故不可刪除該變數 if pval>pout [a b]=find(inmodel==1); inmodel=[inmodel;zeros(1,ncol)]; k=k+1; disp('k=');k inmodel(k,flag)=-1; SSE(k)=sse;dfE(k)=dfe;SSR(k)=ssr;dfR(k)=dfr;pf(k)=PF; end else k=k-1; break; end end inmod=sign(cumsum(STATS.inmodel,1)); STATS.inmodel=inmod; STATS.SSE=SSE(1:k); STATS.dfE=dfE(1:k); STATS.SSR=SSR(1:k); STATS.dfR=dfR(1:k); STATS.pf=pf(1:k); STATS.sst=sst; -- ※ 發信站: 批踢踢實業坊(ptt.cc) ◆ From: 140.114.204.50 ※ 編輯: shyfang 來自: 140.114.204.50 (02/25 21:49) ※ 編輯: shyfang 來自: 140.114.36.148 (03/04 11:03) ※ 編輯: shyfang 來自: 140.114.36.148 (04/12 13:52)