以每桶最小比例进行hpbin

问题描述 投票:0回答:2

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

我的问题是当我有大范围的极端偏斜数据时。几乎所有的数据点都在一个桶中,而有几个观察点分散在极端。

我想知道是否有办法强制PROC HPBIN考虑每个箱子中的值的比例并确保至少有例如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;

我希望看到一种方法,将hpbin或其他方法组合在一起,这些箱子是空的,每桶的比例至少为5%。但是,我不打算在这种情况下使用百分位数(这是我的pdf上的另一个情节),因为我看到希望看到传播。

sas nested-loops binning sas-studio
2个回答
1
投票

你尝试过使用WINSOR方法(winsorised binning)吗?来自documentation

Winsorized binning类似于桶分箱,除了切掉两个尾部以获得平滑的分箱结果。该技术通常用于在数据准备阶段删除异常值。

您可以指定WINSORRATE来影响它如何调整这些尾部。


1
投票

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

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

由于bin(问题箱)中的比例过高而需要动态重新组合bin的值,因此需要hpbin仅在问题箱中使用这些值。可以编写一个宏来循环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);
© www.soinside.com 2019 - 2024. All rights reserved.