0

我正在使用 Proc HPBIN 将我的数据拆分为等间距的桶,即每个桶在变量的总范围中具有相等的比例。

我的问题是当我的数据非常偏斜且范围很大时。几乎我所有的数据点都放在一个桶中,而在极端情况下散布着一些观察结果。

我想知道是否有一种方法可以强制 PROC HPBIN 考虑每个 bin 中值的比例,并确保一个 bin 中至少有 5% 的观察值并将其他值分组?

DATA var1;
    DO VAR1 = 1 TO 100;
        OUTPUT;
    END;
    DO VAR1 = 500 TO 505;
        OUTPUT;
    END;
    DO VAR1 = 7000 TO 7015;
        OUTPUT;
    END;
    DO VAR1 = 1000000 TO 1000010;
        OUTPUT;
    END;
RUN;

/*Use proc hpbin to generate bins of equal width*/
ODS EXCLUDE ALL;
ODS OUTPUT
    Mapping = bin_width_results;
PROC HPBIN
    DATA=var1
    numbin = 15
    bucket;
    input VAR1 / numbin = 15;
RUN;
ODS EXCLUDE NONE;

我希望看到 proc hpbin 或其他方法将空的 bin 组合在一起并允许每个桶至少占 5% 的比例的方式。但是,在这种情况下,我不打算使用百分位数(这是我的 pdf 中的另一个图),因为我希望看到传播。

4

2 回答 2

1

您是否尝试过使用该WINSOR方法(winsorised binning)?从文档中:

Winsorized binning 与 bucket binning 类似,只是两个尾部都被切断以获得平滑的 binning 结果。这种技术通常用于在数据准备阶段去除异常值。

您可以指定WINSORRATE以影响其调整这些尾部的方式。

于 2019-04-15T15:59:58.480 回答
1

Quantile选项和20垃圾箱应该给你每个垃圾箱约 5%

PROC HPBIN DATA=var1 quantile;
    input VAR1 / numbin = 20;
RUN;

当一个 bin 的值由于 bin(问题 bin)中的比例过高而需要动态重新划分时,您hpbin只需要问题 bin 中的那些值。可以编写一个宏来循环HPBIN处理过程,放大问题区域。

例如:

DATA have;
    DO VAR1 = 1 TO 100;
        OUTPUT;
    END;
    DO VAR1 = 500 TO 505;
        OUTPUT;
    END;
    DO VAR1 = 7000 TO 7015;
        OUTPUT;
    END;
    DO VAR1 = 1000000 TO 1000010;
        OUTPUT;
    END;
RUN;

%macro bin_zoomer (data=, var=, nbins=, rezoom=0.25, zoomlimit=8, out=);

  %local data_view step nextstep outbins zoomers;

  proc sql;
    create view data_zoom1 as
    select 1 as step, &var from &data;
  quit;

  %let step = 1;
  %let data_view = data_zoom&step;
  %let outbins = bins_step&step;

%bin:
  %if &step > &zoomlimit %then %goto done;

  ODS EXCLUDE ALL;
  ODS OUTPUT Mapping = &outbins;
  PROC HPBIN DATA=&data_view bucket ;
    id step;
    input &var / numbin = &nbins;
  RUN;
  ODS EXCLUDE NONE;

  proc sql noprint;
    select count(*) into :zoomers trimmed
    from &outbins
    where proportion >= &rezoom
  ;

  %put NOTE: &=zoomers;

  %if &zoomers = 0 %then %goto done;

  %let step = %eval(&step+1);

  proc sql;
    create view data_zoom&step as
    select &step as step, *
    from &data_view data
    join &outbins   bins
    on data.&var between bins.LB and bins.UB
       and bins.proportion >= &rezoom
    ;
  quit;

  %let outbins = bins_step&step;
  %let data_view = data_zoom&step;

  %goto bin;

%done:

  %put NOTE: done @ &=step;

  * stack the bins that are non-problem or of final zoom;
  * the LB to UB domains from step2+ will discretely cover the bounds
  * of the original step1 bins;
  data &out;
    set 
      bins_step1-bins_step&step
      indsname = source
    ;
    if proportion < &rezoom or source = "bins_step&step";
    step = source;
  run;

%mend;

options mprint;

%bin_zoomer(data=have, var=var1, nbins=15, out=bins);
于 2019-04-15T13:32:50.780 回答