全部版块 我的主页
论坛 数据科学与人工智能 数据分析与数据科学 SAS专版
1136 9
2013-10-19
最近在做一个关于sampling的项目,有一个问题很有趣,想跟大家讨论一下。
这个data有37747个关于付款的数据,现在已经按照大小排序好,最少付款额是1块,最高是61125.21,现在想从这37747个数据里面选出600个sample在付款额上代表整个数据。一种想法是因为这些钱数都比较分散,并不是平均分布的,所以用SRS的方法不太合理。所以想到既然是要对钱数做sample,那就索性做10个strata,每一个strata里面包含10%的total payment,这样的话,落在0-10%的数据最多,然后10%-20%里面其次,这样下去,90%-100%里面数据最少,然后按照一定比例,在每个strata里面抽取一定量的sample,最后合成600个。

我现在的想法是既然要取600个sample,那我可以直接做600个strata,这样的话,每个strata里面随机取一个数据去表征这一个strata,然后把这600个sample合并起来。但是实际操作中发现,因为数据是付款大小排列,最高的金额61125.21可能已经占到整个付款额的1%左右,那样第600个或者第599个strata里面只会有一个数据,那样选的话,最大的几个值一定会选中,这样就会使整个sample的有些skew to the right.
proc sql;
create table sum as
select sum(payment) as total from sorted
;
quit;

data sort1;
if _n_=1 then set sum;
set sorted;
cum+payment;
strata=ceil((cum/total)*600);
run;

有时候用这种方法都不一定能够得到600个strata,可能差了1-2个,所以我的想法就是把最后几个里面只有一个数据的strata合并成一个新的strata,然后倒着推上去,重新把剩下的数据按照付款额再分599个strata,把最后几个里面只有一个数据的strata合并成一个新的strata,然后以此从下往上类推上去,直到里面所有的strata里面都至少含有两个数据以上,然后再用SRS的方法每个strata里面取出一个数据来。


我自己试了一下,可能是我自己写程序的时候逻辑还不是很清楚,所以折腾了好半天也不行,不知道版上有没有哪位兄弟可以一起与我讨论一下,甚至提出一些更好的方法来呢?


附件列表

sorted.rar

大小:52.13 KB

 马上下载

数据文件

本附件包括:

  • sorted.sas7bdat

二维码

扫码加我 拉你入群

请注明:姓名-公司-职位

以便审核进群资格,未注明则拒绝

全部回复
2013-10-20 12:48:12
"一种想法是因为这些钱数都比较分散,并不是平均分布的,所以用SRS的方法不太合理",

我觉得你想法挺有趣的,为何simple random sampling取样不合理?因为原来数据不是平均分布?

以下面数据为例子,x属于一个exponential distribution, 非常skew的分布。随机取样后,新的样本(1000个)和老样本(10000个)有什么区别? 没有区别嘛

data sim;
     do i=1 to 10000;
            x=rand("exponential");
                output;
         end;
         run;

proc univariate data=sim;
     var x;
         histogram x;
         run;

title1 'Customer Satisfaction Survey';
title2 'Simple Random Sampling';
proc surveyselect data=sim method=srs n=1000
                  out=SampleSRS;
run;

proc univariate data=sampleSRS;
     var x;
         histogram x;
         run;

二维码

扫码加我 拉你入群

请注明:姓名-公司-职位

以便审核进群资格,未注明则拒绝

2013-10-20 13:32:18
duoweisa 发表于 2013-10-20 12:48
"一种想法是因为这些钱数都比较分散,并不是平均分布的,所以用SRS的方法不太合理",

我觉得你想法挺有趣 ...
谢谢您的建议
我稍微改了一下程序,其实,你是10000个population里面取1000个,可能差别不大,但是如果是1000000个里面取就有有一点差别了。


data sim;
     do i=1 to 1000000;
            x=rand("exponential");
                output;
         end;
         run;

proc univariate data=sim;
     var x;
         histogram x;
         run;

title1 'Customer Satisfaction Survey';
title2 'Simple Random Sampling';
proc surveyselect data=sim method=srs n=1000
                  out=SampleSRS;
run;

proc univariate data=sampleSRS;
     var x;
         histogram x;
         run;

data sim2;
set sim;
group='population';
data SampleSRS2;
set SampleSRS;
group='sample';
run;

DATA GRAPH;
SET sim2 SampleSRS2;
RUN;

proc sql;
create table test as
select max(x) as maxx from GRAPH
;
quit;

data _null_;
set test;
call symputx('maxx', put (maxx,8.0));
call symputx('maxx2',put (maxx*0.1,8.0));
run;

title '1000 sample out of 1000000 population';
   proc univariate data=GRAPH noprint;
      CLASS group;
      histogram x;
        inset mean std='Std Dev' median/ pos = ne format = 6.3 ;
   run;
二维码

扫码加我 拉你入群

请注明:姓名-公司-职位

以便审核进群资格,未注明则拒绝

2013-10-20 23:24:32
tangliang0905 发表于 2013-10-20 13:32
谢谢您的建议
我稍微改了一下程序,其实,你是10000个population里面取1000个,可能差别不大,但是如果是 ...
取样小,肯定和总体有差别了,因为这是random sampling,为何你觉得很奇怪? 或者你想要的结果是从近4万个样本里随机取600样本,然后你想要这600个样本和原来的样本有一样的mean,std,min,max? 这是随机取样?

你随机取样的目的是什么?
二维码

扫码加我 拉你入群

请注明:姓名-公司-职位

以便审核进群资格,未注明则拒绝

2013-10-21 01:40:43
是啊,理论上想要从600个sample里面得到和4w个population差不多的分布,当然这个差不多的分布我目前来说也只能通过mean,std,CV这些去比较,比如说mean,std和CV在和原样本90%的区间内。所以当然这个随机取样也不是仅仅取一次就好了,会取很多次,直到取到落入那个区间内的sample才会停止。

现在只是在想直接分600个strata去取样本呢,还是分成10个strata去取样本。
二维码

扫码加我 拉你入群

请注明:姓名-公司-职位

以便审核进群资格,未注明则拒绝

2013-10-21 10:09:06
分层抽样吧
二维码

扫码加我 拉你入群

请注明:姓名-公司-职位

以便审核进群资格,未注明则拒绝

点击查看更多内容…
相关推荐
栏目导航
热门文章
推荐文章

说点什么

分享

扫码加好友,拉您进群
各岗位、行业、专业交流群