模糊匹配是日常工作中经常遇到的问题。比如我们手上有一份多家上市公司的利润表(每行为一家公司)和一份这些公司的现金流量表(同样一行一家公司),但由于种种原因(比如利润表的公司名称是简称,而现金流量表的公司名称是全称)导致同一家公司在两份表中有不同的名称。只有当这两张表的公司名称一致时,我们才能合并这两份表,同时看到这些公司的总体情况。
处理模糊匹配的方法有很多种:最简单的情况下可用excel的vlookup函数,或者用find结合通配符。稍复杂情况下可用正则表达式。此外,我们也可以借助Power Query里的Merge方法(选择模糊匹配),将两个表合并。
我们在上回提到,当公司简称与公司全称之间的变化规则比较复杂的情况下,单纯依靠excel上vlookup、find等函数或者正则表达式难以处理这样的模糊匹配问题。因此,上回给大家提供了一个模糊匹配的小工具——FuzzMatch。该工具也比Power Query的Merge方法具有更高的准确度。但该工具和Power Query都存在面对稍大数据集时速度慢的问题。当两个表的行数达到“成千上万”级别时,小工具在半小时内还完成不了匹配。
那么,为什么匹配那么耗时?该如何提速?
进行模糊匹配的基本原理是计算文本的相似度。比较典型的模型有两类,一种是计算两个文本的Levenshtein距离,另一种则是计算两个文本的余弦相似度。
Levenshtein距离
简单来说,Levenshtein距离是指将一个文本转换为另一个文本所需的最少编辑(增加、减少或替换)次数。上回小工具的工作原理就是,把表A中每个文本,与表B的文本一一对比计算,选出最优Levenshtein距离所对应的文本。假设表A共有1000个不同的文本,每个都要与表B所有非重复文本(假设也是1000个)进行对比,那么将要进行1000*1000=1000000(即100万)次计算。假设每次计算0.01秒,也需要花费1万秒(约为167分钟,将近3个小时)。
选择不同的编程语言,以及优化算法,可以提升该模型的运算速度。比如在借助一个基于C 编写的库,运算速度提升了几十倍。如下图所示,匹配两个1-2万行的表,耗费了976秒,约16分钟。
但无论怎么优化,还是避免不了数据遍历,耗时依然巨大。
余弦相似度 Cosine Similarity
该算法,将文本分词再转化为向量,计算文本相似度变成了计算两个空间向量之间的夹角,通过余弦相似度来反映。夹角越接近0,余弦值越接近于1,两个文本相似度越高。使用余弦相似度的优势在于,只需要把两个表转化为两个矩阵,求它们的内积即可。换言之,Levenshtein距离的算法需要两表细化到行级进行遍历,而余弦相似度算法只需要将文本转化之后,两表直接再表级处理。因而速度极大提升。对于同样的数据,我们只需要花6秒就能完成,如下图所示:
速度提升了163倍!!!
结语
上述算法已封装成一个小工具。大家在本公众号后台回复“快速匹配”即可获得。使用方法及注意事项与上一个小工具基本一致(除了速度极大提升)。需要百分百准确匹配的,可以跟我交流或者找我定制。