【发布时间】:2019-01-17 22:25:40
【问题描述】:
我有一个多维度的模糊字符串匹配问题:
假设我有一个 pandas 数据框,其中包含变量“公司名称”、“股票代码”和“国家/地区”。简化的子集可能如下所示:
pd.DataFrame(columns = ["Company name", "Ticker", "Country"],
data = [["Vestas Wind Systems", "VWS.CO", "Denmark"],
["Vestas", "VWS", "Denmark"],
["Vestas Wind", "VWS", np.nan],
["Amazon.com Inc", np.nan, "United States of America"],
["AMAZONIA", "BAZA3 BZ", "Brazil"],
["AMAZON.COM", "AMZN US", "United States"]])
整个数据框将包含数十万行。
我想要的是识别数据框中的公司,它们是相同的。 在这种情况下,这意味着确定第 0、1、2 行都是公司“Vestas Wind Systems”的不同表达方式,第 3、5 行都代表“Amazon.com Inc”,第 4 行代表“Amazonia”。
为了增加正确匹配的机会,我假设最好利用所有三列的信息。
但是,所有三列都需要通过模糊逻辑进行比较:公司、股票代码和国家/地区都可能以不同的方式书写。例如。 “Vestas Wind Systems”与“Vestas”或“United States of America”与“United States”。
另一个复杂性是 Ticker 和 Country 列都可能包含 NaN 值(公司名称永远不会为空)。
问题 1:解决此问题的理想方法是什么?
我目前的计划:
我想通过利用三列中的信息来匹配公司。列中的实体越相似,匹配的概率就越高。此外,每列应该有不同的权重:仅仅因为两家公司位于美国,并不意味着它们是同一家公司。因此,例如,Country 列的权重应该较低。
我目前尝试在每一列上使用模糊算法来识别相似的字符串表示。这将产生这样的结果,其中分数代表字符串相似度:
pd.DataFrame(columns = ["Company name 1", "Company name 2", "Score"],
data = [["vestas wind systems", "vestas wind", 0.9],
["vestas wind", "vestas", 0.85],
["amazon.com inc", "amazon.com", 0.84],
["amazon.com", "amazonia", 0.79],
["vestas wind systems", "vestas", 0.75],
["amazon.com inc", "amazonia", 0.70],
["vestas", "amazonia", 0.4],
["...", "...", "..."]])
pd.DataFrame(columns = ["Ticker 1", "Ticker 2", "Score"],
data = [["vws.co", "vws", 0.8],
["baza3 bz", "amzn us", 0.6],
["vws", "amzn us", 0.4],
["vws.co", "amzn us", 0.35],
["baza3 bz", "vws.co", 0.3],
["baza3 bz", "vws", 0.28]])
pd.DataFrame(columns = ["Country 1", "Country 2", "Score"],
data = [["united states", "united states of america", 0.8],
["brazil", "denmark", 0.3],
["brazil", "united states", 0.28],
["brazil", "united states of america", 0.26],
["denmark", "united states", 0.25],
["denmark", "united states of america", 0.23]])
注意:我意识到我应该在模糊匹配之前通过正则表达式进行一些简单的字符串清理,但为了简单起见,我们假设我已经这样做了。同样,我已将上述结果中的所有字符串都转换为小写。
所以现在我在不同的列中有相似度分数。然后,我想使用这些相似性来确定初始数据框中的哪些行代表相同的公司。正如我之前提到的,我想对列相似性应用不同的权重:假设我想使用以下权重:
weights = {"Company name" : 0.45, "Ticker" : 0.45, "Country" : 0.1}
也就是说,当比较数据框中的任意两行时,它们的相似度得分为
similarity_score = 0.45 * Company Name similarity score + 0.45 * Ticker Name similarity score + 0.1 * Country similarity score
例如第0行和第1行的相似度得分为:
similarity_score_0_1 = 0.45 * 0.75 + 0.45 * 0.8 + 0.1 * 1.0 = 0.7975
当某些行的代码和/或国家/地区为空值时,这当然会成为一个问题。
最后 - 当我在数据框中有几十万行时,计算所有行之间的相似度分数变得非常耗时。
问题 2:如何以最有效的方式完成此任务?
【问题讨论】:
-
只有两个cmets::你可以搜索的主题叫做实体识别。一般来说,没有最佳解决方案,因此无法准确回答两个,因为您必须考虑多种权衡
-
使用欧式距离进行匹配怎么样?可以匹配 n 个变量。
-
谢谢@Quickbeam2k1,我不知道该主题有实际名称。我会尝试搜索它。
-
谢谢,@Waleed。我会调查的!
标签: python string pandas matching