首页 > 解决方案 > SAS 尝试在小样本数据集上使用哈希表进行模糊匹配时内存不足

问题描述

我有一个大约 5,000,000 行的姓名、电话号码和地址列表。我正在尝试在每个地址创建一个唯一客户列表,并为每个唯一客户分配一个密钥。客户名称的格式不一致,因此 John Smith 可能显示为 Smith、John 或 John Smith Jr. 等。

我要遵循的逻辑是这样的:

如果一个地址的两条记录具有相同的电话号码,则它是同一个客户,无论他们是否具有不同的名称,并分配相同的 customer_key。

如果一个地址的两条记录没有相同的电话号码(或没有电话号码),但他们的名字的模糊匹配超过了某个阈值,则它们是同一个客户,并被分配相同的 customer_key。

请注意,在两个不同地址匹配的相同客户名称 + 电话号码不应分配相同的客户密钥。

以下是包含示例输入和所需输出的示例表:

https://docs.google.com/spreadsheets/d/1RsABSFy5a5dLE8mC-ZQF_lNg4I0kLQy7dEFhbfovq40/edit?usp=sharing

我使用此示例数据集的代码尝试如下:


data customer_keys(keep=customer_name customer_key customer_phone clean_address);
   length customer_name $50 Comp_Name $20 customer_key 8 clean_address comp_address $5 customer_phone comp_phone $11.;

   if _N_ = 1 then do;
      declare hash h(multidata:'Y');
      h.defineKey('Comp_Name','comp_address');
      h.defineData('Comp_Name', 'customer_key','comp_address', 'comp_phone');
      h.defineDone();
      declare hiter hi('h');

      declare hash hh(multidata:'Y');
      hh.defineKey('customer_key');
      hh.defineData('customer_key', 'Comp_Name','comp_address','comp_phone');
      hh.defineDone(); 

      _customer_key=0; 
   end;

   set testdat;

   rc=h.find(key:customer_name, key:clean_address);

   if rc ne 0 then do;
      rc=hi.first();
      do while (rc=0);
         if not missing(customer_phone) and clean_address=comp_address and customer_phone=comp_phone
            then do;
                  h.add(key:customer_name,key:clean_address, data:customer_name, data:customer_key, data:clean_address, data:customer_phone);
                  hh.add();
            end;
         else if not missing(customer_name) and clean_address=comp_address and jaroT(customer_name,Comp_name) ge 0.8
            then do;
            rc=hh.find();

            do while (r ne 0);

               dist2=jaroT(customer_name,Comp_name);
               hh.has_next(result:r);

               if r=0 & dist2 ge 0.8 then do;
                  h.add(key:customer_name,key:clean_address, data:customer_name, data:customer_key, data:clean_address, data:customer_phone);
                  hh.add();
                  output;return;
               end;

               else if r ne 0 & dist2 ge 0.8
                then rc=hh.find_next();

               else if dist2 < 0.8
            then leave;

            end;

         end;

         rc=hi.next();

      end;

      _customer_key+1;
      customer_key=_customer_key;
      h.add(key:customer_name,key:clean_address, data:customer_name, data:customer_key, data:clean_address, data:customer_phone);
      hh.add(key:customer_key, data:customer_key, data:customer_name, data:clean_address, data:customer_phone);
   end;

   output;
run;

运行此代码会产生错误:

ERROR: Hash object added 23068656 items when memory failure occurred.
FATAL: Insufficient memory to execute DATA step program. Aborted during the EXECUTION phase.
ERROR: The SAS System stopped processing this step because of insufficient memory.

我注意到,如果我完全删除处理电话号码的附加逻辑,我就没有这个内存问题。但是,当我尝试在完整数据集上运行它时,我仍然会假设我的方法会因为内存不足而失败。

标签: indexingsashashtablelarge-datafuzzy-comparison

解决方案


在您的 Windows 搜索功能中搜索“sas.exe-memsize 16G”以提取新版本的 sas 程序,该程序将具有 16G 的内存存储。您也可以更改 G 之前的数字。还要确保您有足够的磁盘空间。干杯。


推荐阅读