Stata数据处理:模糊匹配-reclink2-matchit-strgroup

发布时间:2022-09-12 阅读 196

Stata连享会   主页 || 视频 || 推文 || 知乎 || Bilibili 站

温馨提示: 定期 清理浏览器缓存,可以获得最佳浏览体验。

New! lianxh 命令发布了:
随时搜索推文、Stata 资源。安装:
. ssc install lianxh
详情参见帮助文件 (有惊喜):
. help lianxh
连享会新命令:cnssc, ihelp, rdbalance, gitee, installpkg

课程详情 https://gitee.com/lianxh/Course

课程主页 https://gitee.com/lianxh/Course

⛳ Stata 系列推文:

PDF下载 - 推文合集

作者:冯超楠 (北京航空航天大学大学)
邮箱fengcn@buaa.edu.cn


目录


1. 模糊匹配简介

通常你可以使用或构造唯一的 ID 变量来合并两个或多个数据集,比如同一家企业在不同年份的企业代码是一致的,则可以通过企业代码合并不同年份的海关数据。但是对于海关数据和工业企业数据的合并,两个数据库中的企业代码设置是完全独立的,因此无法找到唯一标识符合并工企和海关数据。

通常情况下,我们尝试匹配企业名称或其他字符串变量 (例如联系人、电话、邮编等)。但是,企业名称的记录不规范 (例如 “XXX 有限公司” 会被记录为 “XXX 股份有限公司” 或 “XXXX 公司”)、企业名称中存在错别字或空格等问题都会导致两个数据集中的同一家企业无法匹配,大大降低了匹配的完整度。

通过合并前的数据清理,例如剔除企业名称中的空格、将企业名称中所有字母统一以大写或小写的形式存储可以提高匹配过程中的完整度。另外,当数据量较少的时候,手动匹配能够完全解决上述问题。但在绝大多数研究中,我们面临的数据量较大,且用于匹配的字符串变量无法彻底清理,此时模糊匹配 (fuzzy merging/fuzzy matching) 可以作为一种解决方案。

模糊匹配是指在比较中找到近似匹配或最为相似的字符串的技术 (区别于完全匹配/精确匹配),使用这种算法类型的命令通常会给出匹配的概率。模糊匹配,顾名思义,其合并数据的匹配准确度会低于精确匹配。

因此,我们给出的应用建议是:匹配数据时,首选精确匹配,若不同数据集无法构造唯一匹配符时,可考虑模糊匹配。

本文是在模糊匹配相关推文「Stata:模糊匹配之 matchit」和「Stata:模糊匹配-matchit-reclink」的基础上增加了 Stata 命令 strgroup 用法以及 strgroupreclink2matchit 的注意事项和应用实例,以帮助大家更好地理解和应用模糊匹配的相关命令。

1.1 匹配步骤

模糊匹配包括三个步骤:

  • Step 1:字符串清理。通过统一处理空格、字母大小写、特殊字符等进行匹配前变量清理。
  • Step 2:概率匹配。使用模糊匹配函数估计两个数据集中样本匹配的概率。
  • Step 3:匹配检查。首先基于研究需要和数据情况设置可视为样本匹配成功的概率临界值 p,之后我们需要肉眼观察匹配概率低于 p 的部分 (手动匹配),保留手动匹配成功的样本。

1.2 Stata 命令

下面介绍 3 个用以实现模糊匹配的 Stata 外部命令:reclink2matchitstrgroup。其安装命令如下:

net install dm0082.pkg, replace  // reclink2
ssc install matchit,    replace
ssc install strgroup,   replace

接下来我将使用 masterfile 指代当前文件 (待匹配文件),使用 usingfile 指代将与 masterfile 匹配的文件。

2. reclink2

2.1 命令简介

reclink2 使用 record linkage 方法来匹配不存在完美匹配变量的两个数据集——本质上是模糊合并。

reclink2 varlist using filename, idmaster(varname) idusing(varname) gen(newvarname) 
  [wmatch(match_weight_list) wnomatch(nonmatch_weight_list) orblock(varlist) 
  required(varlist) exactstr(varlist) exclude(filename) _merge(newvarname)
  uvarlist(varlist) uprefix(text) minscore(#) minbigram(#) manytoone npairs(#)]
  • idmaster(varname):指定唯一识别 masterfile 样本值的变量。如果唯一标识符不存在,可以简单地创建为 gen idmaster = _n
  • idusing(varname):指定唯一识别 usingfile 样本值的变量名称,与 idmaster(varname) 类似。
  • gen(newvarname):指定由 reclink2 创建的存储样本匹配分数 (分数范围:0-1) 的新变量名称。
  • wmatch(numlist):指定参与数据匹配的每个变量的匹配权重。每个变量都需要匹配权重,若未指定,所有变量匹配权重默认为 1。权重 (必须  1) 通常是 1 到 20 之间的整数。权重反映了变量准确匹配后数据样本能够准确匹配的相对可能性。例如,工企和海关数据匹配时,我们会赋予企业名称一个较大的权重,例如 10,而邮编 (多个企业使用一个邮编) 的权重可能只有 2。
  • wnomatch(numlist):指定参与数据匹配的每个变量的不匹配权重。类似于 wmatch(numlist),但反映了变量无法匹配后数据样本无法匹配的相对可能性。权重越小表明数据样本准确匹配情况下,变量之间的不匹配可能性越大。例如电话号码的 wmatch 较大,wnomatch 较小 (电话号码随时间变化或同一个人/实体拥有多个电话号码)。
  • orblock(varlist | none):用于通过提供一种从 usingfile 中选择样本子集进行数据匹配的方法来加速匹配。该过程仅保留 usingfile 中与 orblock 中至少一个变量匹配的样本。如果 orblock 指定了 4 个及以上变量,则默认指定了全部变量,等同于设置 orblock(none)。有时可以在 masterfileusingfile 中创建新变量例如名字和姓氏的首字母、从地址中提取的街道号码和电话区号同时结合 orblock 选项来提高匹配速度。
  • required(varlist):允许用户指定一个或多个变量,这些变量必须完全匹配才能将样本视为匹配。
  • exclude(filename):允许用户指定包含之前匹配样本的文件名称,从而在当前的数据匹配中剔除之前匹配成功的样本。通过对不同数据样本使用不同匹配方法 (例如通过 orblock 指定不同变量),使得匹配过程更加灵活。
  • _merge(varname):指定标记数据样本来源的变量名称。默认为 _merge(_merge)
  • exactstr(varlist):允许用户指定一个或多个用于准确比较的字符串变量,比较结果为 0 或 1 (二元变量)。
  • uvarlist(varlist):允许 usingfile 具有与要匹配 masterfile 变量不同的匹配变量名称。使用该选项时,两个数据集中变量数据和对应变量顺序必须相同。
  • uprefix(string):允许更改匹配后样本中重命名 usingfile 中匹配变量的前缀 (默认前缀为 U)。例如,如果匹配变量是 nameaddress,则生成的匹配数据集将包含来源于 usingfile 的变量 UnameUaddress
  • minscore(#):指定两个严格不能匹配的最小匹配得分值 (0-1),默认为 0.6。usingfile 中只有最高匹配分数并且匹配分数  minscore 的样本才会合并到 masterfile 中。
  • manytoone:指定 reclink2usingfile 中的样本与 masterfile 中的多条样本相匹配 (多对一链接过程)。reclink 首先集中找到并删除两个数据完全匹配的样本对。因此,与 masterfile 中的样本完全匹配的 usingfile 中的样本随后无法链接到 masterfile 中的其他样本。
  • npairs(#):指定程序保留 usingfile 中与 masterfile 样本匹配成功前 # 个样本 (高于最低分数阈值)。relink 仅保留匹配分数最高的样本。

2.2 应用举例

这里我们以 2004 年海关数据 fuzzy_merge_custom_b356.dta 和工业企业子样本 fuzzy_merge_firm_b356.dta 的合并为例,展示 reclink2 的用法。

npairs 选项使用:

. lxhget fuzzy_merge_custom_b356.dta, replace 
. lxhget fuzzy_merge_firm_b356.dta, replace 

. * 基础用法
. use fuzzy_merge_custom_b356, clear 
. reclink2 name contact prov zip tel_7 using fuzzy_merge_firm_b356, ///
>     idmaster(id1) idusing(id2) gen(myscore)

0 perfect matches found
Going through 4308 observation to assess fuzzy matches, each .=5% complete
....................
Added: id2= identifier from fuzzy_merge_firm_b356   myscore = matching score
Observations:  Master N = 4308    fuzzy_merge_firm_b356 N= 10365 
  Unique Master Cases: matched = 2923 (exact = 0), unmatched = 1385
  
. * npairs 选项
. use fuzzy_merge_custom_b356, clear
. reclink2 name contact prov zip tel_7 using fuzzy_merge_firm_b356, ///
>     idmaster(id1) idusing(id2) gen(myscore) npairs(2)

0 perfect matches found
Going through 4308 observation to assess fuzzy matches, each .=5% complete
....................
Added: id2= identifier from fuzzy_merge_firm_b356   myscore = matching score
Observations:  Master N = 4308    fuzzy_merge_firm_b356 N= 10365 
  Unique Master Cases: matched = 2923 (exact = 0), unmatched = 1385

manytoone 选项使用:

. * 基础用法
. use fuzzy_merge_custom_b356, clear
. keep id1 contact
. reclink2 contact using fuzzy_merge_firm_b356, idmaster(id1) idusing(id2) gen(myscore)

558 perfect matches found
Going through 3750 observation to assess fuzzy matches, each .=5% complete
....................
Added: id2= identifier from fuzzy_merge_firm_b356   myscore = matching score
Observations:  Master N = 4308    fuzzy_merge_firm_b356 N= 10365 
  Unique Master Cases: matched = 3702 (exact = 558), unmatched = 606

. * manytoone 选项
. use fuzzy_merge_custom_b356, clear
. keep id1 contact
. reclink2 contact using fuzzy_merge_firm_b356, idmaster(id1) idusing(id2) gen(myscore) manytoone

558 perfect matches found
Going through 3750 observation to assess fuzzy matches, each .=5% complete
....................
Added: id2= identifier from fuzzy_merge_firm_b356   myscore = matching score
Observations:  Master N = 4308    fuzzy_merge_firm_b356 N= 10365 
  Unique Master Cases: matched = 3717 (exact = 558), unmatched = 591

需要注意的是:

  • 可以指定一个或多个重新评估相似性的变量,而不是单个 ID,同时 reclink 还支持字符串匹配。
  • idusing() 中的指定变量不应该出现在 masterfile 中。
  • 除了要匹配的变量外,这两个数据集不应共享任何变量名称。
  • idusing()idmaster() 中的指定变量名称不能相同。
  • 相比 reclinkreclink2 命令添加了多对一匹配。

3. matchit

3.1 命令简介

matchit 根据相似的文本模式匹配两列或两个数据集。

* 同一个数据集中两列变量的匹配
  matchit varname1 varname2 [, options]
* 两个数据集的匹配
  matchit idmaster txtmaster using filename.dta , idusing(varname) txtusing(varname) [options]

其中,通用选项如下:

  • similmethod(simfcn):字符串匹配方法。默认为二元组。其他内置 simfcn 有:ngram、ngram_circ、firstgram、token、cotoken、scotoken、soundex、soundex_nara、soundex_fk、soundex_ext、token_soundex 和 nysiis_fk。
  • score(scrfcn):指定相似度得分。默认为 Jaccard。其他内置选项有:simple 和 minsimple。
  • weights(wgtfcn):权重变换。默认为 noweights。其他内置选项有:simple,log 和 root。
  • generate(varname):指定相似度得分变量的名称。默认为 similscore。

两个数据集匹配必需命令选项如下:

  • idmaster:当前文件 (masterfile) 中的数值型变量。无需唯一识别 masterfile 中样本。
  • txtmaster:当前文件 (masterfile) 中的字符串,将与 txtusing 匹配。
  • using(filename):要与 masterfile 匹配的 Stata 文件的名称 (usingfile) 。
  • idusing(varname)usingfile 中的数值型变量。无需唯一识别 usingfile 中样本。
  • txtusing(varname)usingfile 中的字符串,将与 txtmaster 匹配。

通用高级命令选项如下:

  • wgtfile(filename):允许从其他 Stata 文件加载权重,而不是基于 masterfileusingfile 计算权重。默认不加载权重。
  • time:在执行期间输出时间戳。
  • flag(step):控制 matchit 报告回输出屏幕的频率。只有通过尝试不同的 simfcn 来优化索引才真正有用。 默认值为 step = 20 (百分比)。

仅对两个数据集匹配适用的高级命令选项如下:

  • threshold(num):最终结果中保留的最低相似性分数。 默认值为 num = .5。
  • override:忽略未保存的数据警告。
  • diagnose:报告有关索引的初步分析。用于通过清理原始数据和尝试不同的 simfcn 来优化索引。
  • stopwordsauto:自动生成停用词列表。它提高了索引速度,但忽略了潜在的匹配可能性。
  • swthreshold(grams-per-observation):仅对 stopwordsauto 有效,默认值为 grams-per-observation = .2。

matchit 通过执行许多不同的基于字符串的匹配技术来提供两个不同文本字符串之间的相似度分数。它返回一个包含相似度分数的新数值变量 (similscore),范围从 0 到 1。基于所选的字符串匹配技术,similscore 为 1 表示完全相似,不太相似时 similscore 值会降低。similscore 是一种相对度量,它能 (并且经常) 随着所选择的技术而改变。

这两个变量可以来自同一个数据集,也可以来自两个不同的数据集。后者允许当前在内存中的数据集 (masterfile) 与 usingfile 通过每个数据集字符串变量之间的相似性进行模糊匹配。在这种情况下,matchit 返回一个包含五个变量的新数据集:两个来自 masterfile (idmastertxtmaster),两个来自 usingfile (idusingtxtusing) 和相似度得分 (similscore)。

matchit 较为适用的两个情况:

  • 当相同的字符串数据在两个列/数据集中具有不同形式,例如其中一个数据集包含名和姓两个变量,而另一个数据集只有一个全名字段。matchit 允许通过简单地组合第一个数据集的两个字段来连接两个数据集,而无需关心名字和姓氏的顺序或是否缺少中间名。
  • 当其中一个数据集相当大并且由不同来源提供时,相同的字符串数据在两个列/数据集格式不统一。例如一个包含不同个体以自由文本形式输入的地址的大型数据集。

需要注意的是 matchit 区分大小写以及其他所有符号。虽然 matchit 使用前不需要数据清理,但一定程度的数据清理通常能提高相似度分数,从而提高匹配质量。但是,过多的数据清理可能会导致数据信息缺失,降低匹配质量。

3.2 应用举例

匹配两个数据集:

. lxhget fuzzy_merge_custom_b356.dta, replace 
. lxhget fuzzy_merge_firm_b356.dta, replace 
. use fuzzy_merge_custom_b356, clear
. matchit id1 name using fuzzy_merge_firm_b356.dta, idu(id2) txtu(name)
Matching current dataset with fuzzy_merge_firm_b356.dta
Similarity function: bigram
Loading USING file: fuzzy_merge_firm_b356.dta
Indexing USING file.
0%
20%
40%
60%
80%
Done!
Computing results
        Percent completed ...   (search space saved by index so far)
        20%               ...   (9%)
        40%               ...   (6%)
        60%               ...   (6%)
        80%               ...   (5%)
        Done!
Total search space saved by index: 5%

通过 sim() 选项设置不同的匹配方式:

 use fuzzy_merge_custom_b356, clear
. matchit id1 name using fuzzy_merge_firm_b356.dta, idu(id2) txtu(name) sim(token)

Matching current dataset with fuzzy_merge_firm_b356.dta
Similarity function: token
Loading USING file: fuzzy_merge_firm_b356.dta
Indexing USING file.
0%
20%
40%
60%
80%
Done!
Computing results
        Percent completed ...   (search space saved by index so far)
        20%               ...   (100%)
        40%               ...   (100%)
        60%               ...   (100%)
        80%               ...   (100%)
        Done!
Total search space saved by index: 100%
. use fuzzy_merge_custom_b356, clear
. matchit id1 name using fuzzy_merge_firm_b356.dta, idu(id2) txtu(name) sim(ngram,3)

Matching current dataset with fuzzy_merge_firm_b356.dta
Similarity function: ngram
Loading USING file: fuzzy_merge_firm_b356.dta
Indexing USING file.
0%
20%
40%
60%
80%
Done!
Computing results
        Percent completed ...   (search space saved by index so far)
        20%               ...   (26%)
        40%               ...   (20%)
        60%               ...   (20%)
        80%               ...   (19%)
        Done!
Total search space saved by index: 18%

通过 s() 选项设置不同的相似度计算方式:

 use fuzzy_merge_custom_b356, clear
. matchit id1 name using fuzzy_merge_firm_b356.dta, idu(id2) txtu(name) s(simple)

Matching current dataset with fuzzy_merge_firm_b356.dta
Similarity function: bigram
Loading USING file: fuzzy_merge_firm_b356.dta
Indexing USING file.
0%
20%
40%
60%
80%
Done!
Computing results
        Percent completed ...   (search space saved by index so far)
        20%               ...   (9%)
        40%               ...   (6%)
        60%               ...   (6%)
        80%               ...   (5%)
        Done!
Total search space saved by index: 5%
use fuzzy_merge_custom_b356, clear
. matchit id1 name using fuzzy_merge_firm_b356.dta, idu(id2) txtu(name) s(minsimple)

Matching current dataset with fuzzy_merge_firm_b356.dta
Similarity function: bigram
Loading USING file: fuzzy_merge_firm_b356.dta
Indexing USING file.
0%
20%
40%
60%
80%
Done!
Computing results
        Percent completed ...   (search space saved by index so far)
        20%               ...   (9%)
        40%               ...   (6%)
        60%               ...   (6%)
        80%               ...   (5%)
        Done!
Total search space saved by index: 5%

通过 w() 选项设置不同权重:

. use fuzzy_merge_custom_b356, clear
. matchit id1 name using fuzzy_merge_firm_b356.dta, idu(id2) txtu(name) w(log)

Matching current dataset with fuzzy_merge_firm_b356.dta
Applying weights function: log
Similarity function: bigram
Loading USING file: fuzzy_merge_firm_b356.dta
Indexing USING file.
0%
20%
40%
60%
80%
Done!
Computing results
        Percent completed ...   (search space saved by index so far)
        20%               ...   (9%)
        40%               ...   (6%)
        60%               ...   (6%)
        80%               ...   (5%)
        Done!
Total search space saved by index: 5%

问题报告:

. use fuzzy_merge_custom_b356, clear
. matchit id1 name using fuzzy_merge_firm_b356.dta, idu(id2) txtu(name) di

Matching current dataset with fuzzy_merge_firm_b356.dta
Similarity function: bigram
Performing preliminary diagnosis
--------------------------------
Analyzing Master file
List of most frequent grams in Master file:
       grams   freq   grams_per_obs  
  1.       �   4843          1.1242  
  2.      ��   4769          1.1070  
  3.       �   4544          1.0548  
  4.       �   4256          0.9879  
  5.      ��   4094          0.9503  
  6.      ��   4085          0.9482  
  7.       �   3862          0.8965  
  8.      ��   3423          0.7946  
  9.      ��   3402          0.7897  
 1.       ��   3387          0.7862  
 2.       ��   3320          0.7707  
 3.        �   2441          0.5666  
 4.        �   2336          0.5422  
 5.        �   2317          0.5378  
 6.       ��   1905          0.4422  
 7.       ��   1865          0.4329  
 8.       ��   1846          0.4285  
 9.       ��   1804          0.4188  
 10.      ��   1804          0.4188  
 11.       �   1803          0.4185  

Analyzing Using file
List of most frequent grams in Using file:

       grams   freq   grams_per_obs  
  1.      ��   9597          0.9259  
  2.       �   8266          0.7975  
  3.       �   8191          0.7903  
  4.       �   7951          0.7671  
  5.       �   7343          0.7084  
  6.      ��   6967          0.6722  
  7.      ��   6937          0.6693  
  8.       �   6321          0.6098  
  9.      ��   6291          0.6069  
 1.        �   6290          0.6068  
 2.        �   6256          0.6036  
 3.       ��   6247          0.6027  
 4.       ��   6187          0.5969  
 5.       ��   5844          0.5638  
 6.       ��   5771          0.5568  
 7.       ��   5587          0.5390  
 8.       ��   5451          0.5259  
 9.       ��   5101          0.4921  
 10.       �   4973          0.4798  
 11.      ��   4926          0.4753  
 
Overall diagnosis
Pairs being compared: Master(4308) x Using(10365) = 44652420
Estimated maximum reduction by indexation (%):0
(note: this is an indication, final results may differ)
List of grams with greater negative impact to indexation:
(note: values are estimated, final results may differ)

       grams   crosspairs   max_common_space   grams_per_obs  
  1.      ��     45768092             100.00          0.9791  
  2.       �     38506692              86.24          0.8719  
  3.       �     37219904              83.35          0.8679  
  4.       �     35180096              78.79          0.8534  
  5.      ��     28522898              63.88          0.7538  
  6.      ��     28337644              63.46          0.7512  
  7.       �     24291980              54.40          0.6919  
  8.      ��     21534092              48.23          0.6620  
  9.      ��     21252294              47.59          0.6576  
 1.       ��     20955368              46.93          0.6525  
 2.       ��     19402080              43.45          0.6245  
 3.        �     17013732              38.10          0.6584  
 4.        �     15429561              34.55          0.5972  
 5.        �     14614016              32.73          0.5856  
 6.       ��     10993755              24.62          0.5231  
 7.       ��     10419755              23.34          0.5079  
 8.       ��     10062546              22.54          0.4973  
 9.       ��      9202204              20.61          0.4706  
 10.       �      8966319              20.08          0.4618  
 11.      ��      8886504              19.90          0.4587  
 
Loading USING file: fuzzy_merge_firm_b356.dta
Indexing USING file.
0%
20%
40%
60%
80%
Done!
Computing results
        Percent completed ...   (search space saved by index so far)
        20%               ...   (9%)
        40%               ...   (6%)
        60%               ...   (6%)
        80%               ...   (5%)
        Done!
Total search space saved by index: 5%

应用自动停用词列表:

. use fuzzy_merge_custom_b356, clear
. matchit id1 name using fuzzy_merge_firm_b356.dta, idu(id2) txtu(name) di stopw

Matching current dataset with fuzzy_merge_firm_b356.dta
Similarity function: bigram
Performing preliminary diagnosis
--------------------------------
Analyzing Master file
List of most frequent grams in Master file:

       grams   freq   grams_per_obs  
  1.       �   4843          1.1242  
  2.      ��   4769          1.1070  
  3.       �   4544          1.0548  
  4.       �   4256          0.9879  
  5.      ��   4094          0.9503  
  6.      ��   4085          0.9482  
  7.       �   3862          0.8965  
  8.      ��   3423          0.7946  
  9.      ��   3402          0.7897  
 1.       ��   3387          0.7862  
 2.       ��   3320          0.7707  
 3.        �   2441          0.5666  
 4.        �   2336          0.5422  
 5.        �   2317          0.5378  
 6.       ��   1905          0.4422  
 7.       ��   1865          0.4329  
 8.       ��   1846          0.4285  
 9.       ��   1804          0.4188  
 10.      ��   1804          0.4188  
 11.       �   1803          0.4185  
 
Analyzing Using file
List of most frequent grams in Using file:

       grams   freq   grams_per_obs  
  1.      ��   9597          0.9259  
  2.       �   8266          0.7975  
  3.       �   8191          0.7903  
  4.       �   7951          0.7671  
  5.       �   7343          0.7084  
  6.      ��   6967          0.6722  
  7.      ��   6937          0.6693  
  8.       �   6321          0.6098  
  9.      ��   6291          0.6069  
 1.        �   6290          0.6068  
 2.        �   6256          0.6036  
 3.       ��   6247          0.6027  
 4.       ��   6187          0.5969  
 5.       ��   5844          0.5638  
 6.       ��   5771          0.5568  
 7.       ��   5587          0.5390  
 8.       ��   5451          0.5259  
 9.       ��   5101          0.4921  
 10.       �   4973          0.4798  
 11.      ��   4926          0.4753  
 
Overall diagnosis
Pairs being compared: Master(4308) x Using(10365) = 44652420
Estimated maximum reduction by indexation (%):0
List of grams with greater negative impact to indexation:

       grams   crosspairs   max_common_space   grams_per_obs  
  1.      ��     45768092             100.00          0.9791  
  2.       �     38506692              86.24          0.8719  
  3.       �     37219904              83.35          0.8679  
  4.       �     35180096              78.79          0.8534  
  5.      ��     28522898              63.88          0.7538  
  6.      ��     28337644              63.46          0.7512  
  7.       �     24291980              54.40          0.6919  
  8.      ��     21534092              48.23          0.6620  
  9.      ��     21252294              47.59          0.6576  
 1.       ��     20955368              46.93          0.6525  
 2.       ��     19402080              43.45          0.6245  
 3.        �     17013732              38.10          0.6584  
 4.        �     15429561              34.55          0.5972  
 5.        �     14614016              32.73          0.5856  
 6.       ��     10993755              24.62          0.5231  
 7.       ��     10419755              23.34          0.5079  
 8.       ��     10062546              22.54          0.4973  
 9.       ��      9202204              20.61          0.4706  
 10.       �      8966319              20.08          0.4618  
 11.      ��      8886504              19.90          0.4587  
 
Loading USING file: fuzzy_merge_firm_b356.dta
Generating stopwords automatically, threshold set at:.2
Done!
Indexing USING file.
0%
20%
40%
60%
80%
Done!
Computing results
        Percent completed ...   (search space saved by index so far)
        20%               ...   (60%)
        40%               ...   (60%)
        60%               ...   (60%)
        80%               ...   (61%)
        Done!
Total search space saved by index: 62%

需要注意的是:

  • matchit 只能通过匹配单个变量生成变量的相似度分数。实际操作中,我们可以匹配多个变量,并对多个相似度分数简单平均或加权平均处理得到基于多个变量匹配的相似度分数。
  • matchit 有多种匹配算法,通过不同匹配算法可以得到不同的匹配结果。
  • matchit 的结果可以通过 joinby 合并或合并到 usingfilemasterfile

4. strgroup

4.1 命令简介

strgroup varname [if] [in] , generate(newvarname) threshold(#) [first normalize([shorter|longer|none]) noclean force]

strgroup 使用以下算法执行字符串模糊匹配:

  • 计算 varname 中所有成对字符串组合之间的 Levenshtein edit distance (help levenshtein)。
  • 通过指定 normalize([shorter|longer|none]) 将 Levenshtein edit distance 归一化处理。默认为将 Levenshtein edit distance 除以较短字符串的长度。
  • 若某一成对字符串归一化后的 Levenshtein edit distanc 小于或等于用户指定的临界点,则该字符串对匹配成功。
  • 如果字符串 A 匹配到字符串 B,字符串 B 匹配到字符串 C,则将 A 匹配到 C
  • 为每组匹配结果分配一个唯一编号并存储在 newvarname 中。

例如,"widgets" 和 "widgetts" 之间的 Levenshtein edit distance 为 1。这两个的长度字符串分别为 7 和 8。假设归一化后的 Levenshtein edit distance=1/7  匹配临界点,则这两个字符串匹配成功。有关 Levenshtein edit distance 的说明,请参阅 help levenshtein

strgroup 选项如下:

  • generate(newvarname):指定用于存储结果的新变量的名称。
  • threshold(#):设置匹配是否成功的临界值。
  • firstfirst 指示 strgroup 仅匹配第一个字符相同的字符串。这通常会将 strgroup 运行所需的时间减少几个数量级,但有可能使得原本应该匹配上的字符无法匹配成功。例如,"widgets" 和 "qidgets" 在指定 first 之后将无法匹配成功,因为它们的首字母不相同。
  • normalize([shorter|longer|none]):用于定义 Levenshtein edit distance 的归一化公式。选择 shorter 会将 Levenshtein edit distance 除以较短字符串的长度,这也是默认情况下的设置。选择 longer 会将 Levenshtein edit distance 除以较长字符串的长度。选择 none 则表明无需标准化。
  • noclean:指示 strgroup 在比较字符串对时不要删除字符串前后空格。空格的删除可以减少运行时间。
  • force:即使在比较超过 10,000 个样本值时也会强制strgroup运行。如果数据集太大,可能会导致内存问题。

4.2 应用举例

. sysuse auto, clear
. tempfile t
. keep make price
. replace make = make + "a" in 5
. replace make = "gibberish" in 10
. save "`t'", replace 

. sysuse auto, clear
. keep make
. merge make using "`t'", sort
. list if _merge != 3

     +---------------------------------+
     | make             price   _merge |
     |---------------------------------|
  1. | Buick Electra        .        1 |
 1.  | Buick Skylark        .        1 |
 2.  | Buick Electraa   7,827        2 |
 3.  | gibberish        4,082        2 |
     +---------------------------------+

. strgroup make if _merge != 3, gen(group) threshold(0.25)
. list if _merge != 3

     +-----------------------------------------+
     | make             price   _merge   group |
     |-----------------------------------------|
  8. | Buick Electra        .        1       1 |
 13. | Buick Skylark        .        1       2 |
 75. | Buick Electraa   7,827        2       1 |
 76. | gibberish        4,082        2       3 |
     +-----------------------------------------+

需要注意的是:

  • strgroup 在单个数据集下操作。
  • 此命令计算字符串之间的差异并与用户指定的临界值比较从而创建匹配项。
  • strgroup 不匹配缺失的字符串。
  • strgroup 区分大小写。
  • 如上所述,strgroup 计算 varname 中所有成对字符串组合之间的 Levenshtein edit distance。令 N 为要比较的样本值。那么 strgroup 所需的内存量和计算次数与 (N)(N-1)/2 成正比,这个表达式随着 N 的平方而增加。因此,需要将大型数据集划分为子集,以便于计算。第一个选项通过根据字符串的第一个字符对字符串进行子集化来自动执行此操作。或者,用户可以使用 ifinby 选项对数据子集运行 strgroup

5. 相关推文

Note:产生如下推文列表的 Stata 命令为:
lianxh 匹配 相似度, m
安装最新版 lianxh 命令:
ssc install lianxh, replace

相关课程

免费公开课

最新课程-直播课

专题 嘉宾 直播/回看视频
最新专题 文本分析、机器学习、效率专题、生存分析等
研究设计 连玉君 我的特斯拉-实证研究设计-幻灯片-
面板模型 连玉君 动态面板模型-幻灯片-
面板模型 连玉君 直击面板数据模型 [免费公开课,2小时]
  • Note: 部分课程的资料,PPT 等可以前往 连享会-直播课 主页查看,下载。

课程主页

课程主页

关于我们

  • Stata连享会 由中山大学连玉君老师团队创办,定期分享实证分析经验。
  • 连享会-主页知乎专栏,700+ 推文,实证分析不再抓狂。直播间 有很多视频课程,可以随时观看。
  • 公众号关键词搜索/回复 功能已经上线。大家可以在公众号左下角点击键盘图标,输入简要关键词,以便快速呈现历史推文,获取工具软件和数据下载。常见关键词:课程, 直播, 视频, 客服, 模型设定, 研究设计, stata, plus, 绘图, 编程, 面板, 论文重现, 可视化, RDD, DID, PSM, 合成控制法

连享会小程序:扫一扫,看推文,看视频……

扫码加入连享会微信群,提问交流更方便

✏ 连享会-常见问题解答:
https://gitee.com/lianxh/Course/wikis

New! lianxhsongbl 命令发布了:
随时搜索连享会推文、Stata 资源,安装命令如下:
. ssc install lianxh
使用详情参见帮助文件 (有惊喜):
. help lianxh