SAS-选择最佳数量

SAS-选择最佳数量,sas,Sas,我正试图解决SAS中的一个问题,在SAS中,我在一系列组中拥有大量客户,我选择的数量需要在不同类别中尽可能均匀。这将更容易用一个小表格来解释,这是我试图解决的一个更大问题的简化 这是表格: Customer Category | Revenue band | Churn Band | # Customers A 1 1 4895 A 1

我正试图解决SAS中的一个问题,在SAS中,我在一系列组中拥有大量客户,我选择的数量需要在不同类别中尽可能均匀。这将更容易用一个小表格来解释,这是我试图解决的一个更大问题的简化

这是表格:

Customer Category | Revenue band | Churn Band | # Customers

        A                 1             1              4895
        A                 1             2               383
        A                 1             3               222
        A                 2             1                28
        A                 2             2              2828
        A                 2             3               232
        B                 1             1              4454
        B                 1             2               545
        B                 1             3               454
        B                 2             1              4534
        B                 2             2               434
        B                 2             3               454
假设我需要从类别A中选择3000名客户,从类别B中选择3000名客户。从第二个类别中,在每个A和B中,我需要从1和2中选择相等的金额。如果可能,我需要在每个1、2和3个子类别中选择一个比例金额。这个问题有一个优雅的解决方案吗?我对SAS比较陌生,到目前为止,我已经研究了OPTMODEL,但这些示例要么太简单,要么太高级,对我来说还没有多大用处


编辑:我考虑过使用“调查选择”。我可以使用此选项在收入级别1、2和3中选择相同的大小。但是,如果我在各个客户流失带中缺少客户,surveyselect可能无法选择数量较低的最大可用客户数,我将重新手动选择客户。

问题陈述中仍有一些含糊不清的地方,但我希望下面的PROC OPTMODEL代码对您来说是一个良好的开端。我试图添加许多不同功能的示例,以便您可以玩弄该模型,并希望更接近您实际需要的功能

在您可以优化的许多事情中,我将最大限度地减少违反您“如果可能”目标的情况,例如:

min MaxMismatch = MaxChurnMismatch;
我能够将您的约束建模为线性程序,这意味着它应该可以很好地扩展。您可能有其他未提及的限制,但这可能超出了本网站的范围

根据您发布的数据,您可以从
print
语句的输出中看到,最佳惩罚对应于从
A,1,1
中选择1500名客户,其中理想值为1736。这比忽略几个群体的客户要昂贵:

[1] ChooseByCat 
 A     3000 
 B     3000 

[1] [2] [3] Choose IdealProportion 
 A    1  1   1500      1736.670 
 A    1  2      0       135.882 
 A    1  3      0        78.762 
 A    2  1     28         9.934 
 A    2  2   1240      1003.330 
 A    2  3    232        82.310 
 B    1  1   1500      1580.210 
 B    1  2      0       193.358 
 B    1  3      0       161.072 
 B    2  1   1500      1608.593 
 B    2  2      0       153.976 
 B    2  3      0       161.072 

Proportion MaxChurnMisMatch 
  0.35478       236.67 
这可能不是一个理想的解决方案,但是弄清楚如何准确地建模您的需求对于这个站点来说并没有多大用处。如果相关的话,你可以离线联系我

我在下面的代码中添加了问题陈述中的引号作为注释

玩得开心!

数据统计;
输入cat$rev搅动器n;
数据线;
A 1114895
A 12383
A 12322
A 21 28
A 22 2828
A 2 3 232
b114454
B12545
B 13 454
B 2 1 4534
B 2 434
B 2 3 454
;
proc optmodel printlevel=0;
设置CATxREVxCHURN init{}inter{};
set CAT=setof{in CATxREVxCHURN}c;
num n{CATxREVxCHURN};
将数据custCounts读入CATxREVxCHURN=[cat rev CHARNER]n;
放置n[*]=;
var Choose{in CATxREVxCHURN}>=0=0,比例>=0=sign*(选择[c,r,ch]-比例*n[c,r,ch]);
最小最大不匹配=最大不匹配;
解决;
打印选择图标;
impvar IdealProportion{in CATxREVxCHURN}=比例*n[c,r,ch];
打印选择理想比例;
打印比例不匹配;
退出

如果您希望每组人数相等,您需要查看最小的组中有多少人,然后从其他组中选择这些人。或者你所说的“选择一个相等的数字”是指其他的东西。你的专栏标题是什么?标题是-客户类型、收入级别(1:1000,2:2000)和客户流失级别(1:0-500,2:500-1000,3:1000+)。在这个问题中,我可能缺少足够的客户,我需要选择all(例如,A,2,1仅为28)。我需要从其他类别中选择更多,以满足A求和到3000和B求和到3000的约束。因为缺少A,2,1,我会从A,1,1中选择更多,这是4895。有趣。如果你能写下一个目标函数——它基本上会惩罚人口分布不均的解决方案——也许你可以通过PROC GA使用遗传算法。也许调查选择大小?请通过编辑而不是评论将列标题添加到问题中。您只列出了3列,显示了4列。
data custCounts;
    input cat $ rev churn n;
datalines;
        A                 1             1              4895
        A                 1             2               383
        A                 1             3               222
        A                 2             1                28
        A                 2             2              2828
        A                 2             3               232
        B                 1             1              4454
        B                 1             2               545
        B                 1             3               454
        B                 2             1              4534
        B                 2             2               434
        B                 2             3               454
;

proc optmodel printlevel = 0;
    set CATxREVxCHURN init {} inter {<'A',1,1>};
    set CAT = setof{<c,r,ch> in CATxREVxCHURN} c; 

    num n{CATxREVxCHURN};
    read data custCounts into CATxREVxCHURN=[cat rev churn] n;
    put n[*]=;

    var Choose{<c,r,ch> in CATxREVxCHURN} >= 0 <= n[c,r,ch]
      , MaxChurnMisMatch >= 0, Proportion >= 0 <= 1
    ;

    /* From OP:
       Suppose I need to select 3000 customers from category A, 
       and 3000 customers from category B. */
    num goal = 3000;
    /* See "implicit slice" for the parenthesis notation, i.e. (c) below. */
    impvar ChooseByCat{c in CAT} = 
        sum{<(c),r,ch> in CATxREVxCHURN} Choose[c,r,ch];
    con MatchCatGoal{c in CAT}:
        ChooseByCat[c] = goal;

    /* From OP:
       From the second category, within each A and B, 
       I need to select an equal amount from 1 and 2 */
    con MatchRevenueGroupsWithinCat{c in CAT}:
        sum{<(c),(1),ch> in CATxREVxCHURN} Choose[c,1,ch]
      = sum{<(c),(2),ch> in CATxREVxCHURN} Choose[c,2,ch]
    ;

    /* From OP: 
       If possible, I need to select a proportional amount 
       across each 1, 2, and 3 subcategories. */
    con MatchBandProportion{<c,r,ch> in CATxREVxCHURN, sign in / 1 -1 /}:
        MaxChurnMismatch >= sign * ( Choose[c,r,ch] - Proportion * n[c,r,ch] );

    min MaxMismatch = MaxChurnMismatch;

    solve;

    print ChooseByCat;
    impvar IdealProportion{<c,r,ch> in CATxREVxCHURN} = Proportion * n[c,r,ch];
    print Choose IdealProportion;
    print Proportion MaxChurnMismatch;

quit;