Grubbs検定 (Grubbs-Smirnov検定) を行なう方法
[OS]ALL
[リリース] ALL
[キーワード] Grubbs-Smirnov, outlier, Bonferroni
[質問]外れ値を検定するGrubbs検定(Grubbs-Smirnov検定)を実行する方法はありますか?
[回答]Grubbs検定を実行できるプロシジャはありません。ただし、検定統計量はMEANSプロシジャおよびDATAステップで簡単に求めることができます。 また、「National Institute of Standards and Technology」サイトの「Engineering Statistics Handbook」のページなどに記載されている Bonferroni調整に基づく近似式を使うと、比較的容易にGrubbs-Smirnov検定を実現することができます。下記の URLに、Grubbs-Smirnov検定の計算式(近似検定)が記載されております。 http://www.itl.nist.gov/div898/handbook/index.html (「Grubbs Test」のページをご参照ください。リンクを許可していただいたNational Institute of Standards and Technology, Statistical Engineering Divisionに感謝いたします)。 Grubbs検定の棄却限界値や p 値をBonferroni調整によって計算するためのサンプルマクロ(%grubbs)を下記に記載します。
******************************************************************************; * サンプルマクロ *; * *; * 作成日:2000-06-07 *; * *; * *; ******************************************************************************; * *; * このサンプルは、あくまで「サンプル」として提供されているものであり、正式 *; * なサポート対象のものではありません。 *; * *; * このサンプルマクロは、Grubbs検定( Grubbs-Sminorv検定) のp値と指定した *; * 有意水準に対しての棄却域を計算します。計算式は、下記のNational Institute *; * of Standards and Technologyなどに記載されているものを用いています。 *; * *; * http://www.itl.nist.gov/div898/handbook/index.html *; * *; * *; * 検定方法として *; * 両側検定 :最大値 もしくは最小値が外れ値であるかどうかの検定 *; * 上側検定 :最大値が外れ値であるかどうかの検定 *; * 下側検定 :最小値が外れ値であるかどうかの検定 *; * を選択することができます。 *; * *; ******************************************************************************; * *パラメータの指定 *; * %macro grubbs(data= データセット名を指定します。, *; * var= 検定をおこなう変数を指定します。, *; * alpha=有意水準を指定します。, *; * test= 両側検定→two *; * 上側検定→max *; * 下側検定→min と指定します。); *; * *; * *データセット名が DATA1 変数がX 有意水準を0.05 で両側検定を *; * 行う場合は、 *; * *; * %macro grubbs(data=data1,var=x,alpha=0.05,test=two); *; * *; * というように指定します。 *; * *; * *__OUT__という名前の結果を含むデータセットを、WORKライブラリに出力します *; ******************************************************************************; ***************** Begin of Sample Macro PGM **********************************; %macro grubbs(data=,var=,alpha=,test=); ****** Submit PROC MEANS *************************; proc means data=&data noprint; var &var; output out=__out__ mean=mean std=std max=max min=min n=n; run; ****** Calculate p-value and critical value ******; data __out__; set __out__; test="&test"; alpha=α ******* Two-tail **********************************; %if &test=two %then %do; g=max(max-mean,mean-min)/std; t=tinv(1-alpha/(2*n),n-2); c=((n-1)/sqrt(n))*sqrt(t**2/(n-2+t**2)); gg=(g**2*n-(n-1)**2); if gg =. then goto END; else if gg < 0 then st=sqrt(-1*(g**2*n*(n-2)/gg)); else if gg = 0 then st=sqrt(g**2*n*(n-2)/gg); if st=. then goto END; p=n*(2*(1-probt(st,n-2))); %end; ******* For Max ************************************; %if &test=max %then %do; g=(max-mean)/std; t=tinv(1-alpha/n,n-2); c=((n-1)/sqrt(n))*sqrt(t**2/(n-2+t**2)); gg=(g**2*n-(n-1)**2); if gg =. then goto END; else if gg < 0 then st=sqrt(-(g**2*n*(n-2)/gg)); else if gg = 0 then st=sqrt(g**2*n*(n-2)/gg); if st=. then goto END; p=n*(1-probt(st,n-2)); %end; ******* For Min ***********************************; %if &test=min %then %do; g=(mean-min)/std; t=tinv(alpha/n,n-2); c=((n-1)/sqrt(n))*sqrt(t**2/(n-2+t**2)); gg=(g**2*n-(n-1)**2); if gg =. then goto END; else if gg < 0 then st=sqrt(-(g**2*n*(n-2)/gg)); else if gg = 0 then st=sqrt(g**2*n*(n-2)/gg); if st=. then goto END; p=n*(1-probt(st,n-2)); %end; if p > 1 then p=1; END: if p=. then put 'ERROR: The value become missing because of some reasons.'; run; title 'Grubbs test'; proc print data=__out__; var test alpha max mean min std g c p; format p pvalue.; run; title; %mend; ***************** End of Sample Macro PGM *********************************; ■ 実行例 **サンプルデータの作成***; data data1; input x@@; cards; 10 11 12 14 15 17 19 20 70 ; run; ****マクロの指定 *******************; * 有意水準は、0.05で両側検定を指定; %grubbs(data=data1,var=x, alpha=0.05,test=two) ■ 実行結果の一部 Grubbs test OBS test alpha max mean min std g c p 1 two 0.05 70 20.8889 10 18.7380 2.62094 2.21500 <.0001 出力される変数は以下のようになります。
なお、p値だけを求めたいのであれば、回帰分析を行なうREGプロシジャのRSTUDENT(1オブザベーションを除いて計算するスチューデント化残差)を用いたプログラミングの方が簡単です。
%let data=data1; /*** データセット名 ***/ %let var=x; /*** 変数名 ***********/ proc reg data=&data noprint; model &var=; output out=__out2__ rstudent=r; run; proc means data=__out2__ noprint; var r; output out=__out3__ max=max min=min n=n; run; data __out3__; set __out3__; amin=abs(min); max_p=min((1-probt(max,n-2))*n,1); /*** One-tail (for max) *****/ min_p=min((1-probt(amin,n-2))*n,1); /*** One-tail (for min) *****/ two_p=min((1-probt(max(max,amin),n-2))*2*n,1); /*** two-tail ****/ run; proc print data=__out3__; run; ■ 実行結果の一部 OBS max_p min_p two_p 1 .000009619 1 .000019237 |