我在不止一种意义上是新来的。在我第一次尝试熟悉任何编程语言时,关于我的第一个脚本的第一篇文章。鉴于此,您可能会发现这个项目过于雄心勃勃,但是,嘿,边做边学一直是要走的路。我正在尽我所能在这里满足stackoverflow-etiquette,但如果我违反了任何规定,请告诉我。
我想编写一段代码,它可以应用某种模糊逻辑来匹配非结构化公司名称表(例如 Google)与结构化公司名称表(例如 Google Inc.)和丹麦公司标识符 ( CVR
)。
我可以通过谷歌搜索找到一些代码,并且我设法操纵它们来处理我的项目。我发现 Jaro-Winkler 算法包含在stringdist
package 特别适用于公司名称。当尝试将 40 个非结构化公司名称与数百个结构化名称进行比较和匹配时,该脚本工作得非常好,但我需要将大约 4000 个非结构化名称与包含 700k 个结构化名称的表进行比较和匹配。正如您可能已经猜到的那样,这需要很长时间。为了给您一个想法,我尝试将 6 个非结构化名称与 700k 匹配,这需要三个小时。快速计算告诉我,如果这是脚本的平均速度,我将需要将近 3 个月的时间来处理 4000 家公司,这有点让人不知所措。我知道它必须进行数十亿次计算,而这不可能在几分钟内完成。但是,如果我可以将其减少到可能只有几天,我会非常高兴,而且我觉得这一定是可能的。
所以,我正在寻找加速这段代码的方法。我已经设法通过最初将精确匹配与match()
函数配对来改进它,这使得大约 500 家公司需要使用模糊匹配算法进行进一步处理。不过,至少可以说这需要很长时间。
我希望我能清楚地解释自己!任何建议将不胜感激。
library(stringdist)
#Reading the two files to be compared and making sure that I'm dealing with characters
companies.unstructured <- read.csv(
"https://www.dropbox.com/s/opbk0s2q14l5c71/unstructured_companies.csv?dl=0",
sep = ";",
stringsAsFactors = FALSE
)
companies.structured <- read.csv(
"https://www.dropbox.com/s/kyi0rvz77frr7sd/structured_companies_w_CVR.csv?dl=0",
sep=";",
stringsAsFactors = FALSE
)
#Using the match function to match up all 100% identical companies to avoid unnecessary workload for the Jaro-Winkler loop
companies.unstructured$CVR = companies.structured$CVR[match(companies.unstructured$Company,
companies.structured$Company)]
companies.exact.match <- companies.unstructured[!is.na(companies.unstructured$CVR), ]
#Creating a subset to work on with the Jaro-Winkler loop.
companies.unstructured.na <- subset(companies.unstructured, is.na(CVR))
#And here's the loop measuring the distance between the company names using the Jaro-Winkler algorithm.
distance.methods<- c('jw')
dist.methods<-list()
for(m in 1:length(distance.methods))
{
dist.name.enh<-matrix(NA, ncol = length(companies.structured$Company),
nrow = length(companies.unstructured.na$Company))
for(i in 1:length(companies.structured$Company)) {
for(j in 1:length(companies.unstructured.na$Company)) {
dist.name.enh[j,i]<-stringdist(tolower(companies.structured[i,]$Company),
tolower(companies.unstructured.na[j,]$Company),
method = distance.methods[m])
}
}
dist.methods[[distance.methods[m]]]<-dist.name.enh
}
#matching up pairs of minimum distance
match.s1.s2.enh<-NULL
for(m in 1:length(dist.methods))
{
dist.matrix<-as.matrix(dist.methods[[distance.methods[m]]])
min.name.enh<-apply(dist.matrix, 1, base::min)
for(i in 1:nrow(dist.matrix))
{
s2.i<-match(min.name.enh[i],dist.matrix[i,])
s1.i<-i
match.s1.s2.enh<-rbind(data.frame(s2.i=s2.i,
s1.i=s1.i,
s1Company=companies.unstructured.na[s1.i,]$Company,
s2Company=companies.structured[s2.i,]$Company,
CVR=companies.structured[s2.i,]$CVR,
adist=min.name.enh[i],
method=distance.methods[m]),
match.s1.s2.enh)
}
}
编辑:这里有一些可以使用的数据示例:structured_companies_w_CVR和unstructured_companies