我有一个拥有以下属性的6万客户的SAS数据集:
1)客户编号
2)X坐标
3)Y坐标
4)实体店访问
我需要计算每个客户与表中所有其他客户的平均加权距离,其中每个距离按比较客户的访问次数加权。例如,客户A和A之间的距离。客户B为10.然后,我们将根据客户B的访问次数(2)对该距离进行加权,该次数等于5.此过程将对表中的所有其他客户重复,然后我们将对每个60k的加权距离进行平均客户。
我认为执行此操作的蛮力方式是笛卡尔连接(即创建一个60k x 60k = 36亿记录表),但这可能会耗尽内存或崩溃SAS。我还想过将其分解为更易于管理的笛卡尔连接(即10 x 60K = 600k x 6000次迭代,但这可能非常耗时 - 可能是我唯一的选择)。我猜你们/ gals知道一个更好的方法来做到这一点!
我感谢您的所有建议。
谢谢你的帮助!
答案 0 :(得分:2)
坏消息,没有办法加快这个计算(我知道)。
好消息是如果您使用笛卡尔积,SAS不会崩溃或内存不足。其他好消息是在数据步骤中执行此操作比在PROC SQL中执行此操作更快。
data test;
do cn=1 to 64000;
x = ceil(Ranuni(13)*100);
y = ceil(ranuni(13)*100);
visits = max(1,round(rannor(12)*3 + 8,1));
output;
end;
run;
sasfile test load;
data ave_dist(keep=cn ave_dist);
set test end=last;
dist=0;
td= 0;
total_visits=0;
do i=1 to n;
set test(rename=(cn=cn_2 x=x_2 y=y_2) drop=visits) point=i nobs=n;
if cn ^= cn_2 then do;
xx = (x-x_2);
yy = (y-y_2);
total_visits = total_visits + visits;
dist = sqrt(xx*xx + yy*yy);
if dist^= 0 then
dist = 1/dist;
else
dist = 100; /*Adjust to something that makes sense to your data*/
td = visits*dist + td;
end;
end;
ave_dist = td / total_visits;
output;
run;
sasfile test close;
我倒转了距离计算。你希望小距离获得更高的分数。我认为这是一个真正的访问加权平均值。
在我的笔记本电脑上运行大约需要13分钟。
答案 1 :(得分:1)
如果您的客户群将<100k,那么PROC DISTANCE
可能会有所帮助。使用@DomPazz创建的数据集,您可以运行以下代码并检查结果。在这种情况下,我只是尝试了以16secs运行的前10K客户。不要让那个愚弄你的虚假安全感。当你加倍的时候。客户所花费的时间是4倍。
(实际时间:10K - 16秒,20K - 47秒,40K - 3分钟......)
此过程生成NxN
方阵(其中N是输入数据集中的客户编号)。您可以尝试并尝试并查看SAS在什么时候遇到RAM
内存问题(确保有足够的硬盘空间,至少大约为1.10 * NxN * 8字节)。
矩阵中的每个单元代表i
客户(在行中)与第j个客户(在列中)的距离。一旦达到距离,就可以将相应的距离乘以客户的访问量并取平均值。
proc distance data = test(obs = 100)
OUT=test_distances(compress = binary)
METHOD= EUCLID shape = SQUARE
UNDEF=1000000
VARDEF=wdf;
var INTERVAL(x y)
;
copy cn visits;
run;
data avg_dist;
set train_distances;
array dist{*} dist:;
prod=0;
do i = 1 to dim(dist);
prod = visits*dist{i}+prod;
end;
avg_dist=prod/dim(dist);
dims=dim(dist);
drop i dist:
;
run;
proc sql;
drop table test_distances;
quit;
您要解决的问题类型通常称为k-nearest neighbour
问题。在这个领域已经进行了数十年的研究,并且通常使用特殊的数据结构(例如Kd-trees
)来解决这些问题。大多数情况下,人们有兴趣回答诸如who are the top-10 (or K) closest customers to this customer I'm interested in?
之类的问题。另一个非常有效解决这类问题的程序是PROC PMBR
,它同时支持kd-tree
和SAS的专有结构Rd-tree
{1}} - 查阅 - 您只能在4.3天内找到SAS Eminer的pdf文档
当您需要计算N * N项目之间的距离时,您会遇到麻烦。 通过阅读评论中的项目描述,您需要的不是计算每个客户与其他客户之间的距离,而是计算每个客户与每个商店之间的距离。
这将大大提高您的查询性能,因为问题的维度大大降低。
假设你有N个顾客和S商店,那么你只需要计算N * S点之间的距离。 (一个简单的数据步骤将完成工作,因为不需要笛卡尔积或专门的数据结构)
从那里你可以看到,对于S中的每家商店来说,在该商店购买的客户中有多少比例居住在1KM,2KM,3KM ....
然后你可以得出答案,如80%住在1公里内,15%住在2公里以内等......