分组相似的单词

时间:2016-02-29 03:04:36

标签: r elasticsearch nlp

CompanyName <- c('Kraft', 'Kraft Foods', 'Kfraft', 'nestle', 'nestle usa', 'GM', 'general motors', 'the dow chemical company', 'Dow')

我想得到:

CompanyName2
Kraft
Kraft
Kraft
nestle
nestle
general motors
general motors
Dow
Dow

但是对于:

绝对没问题
CompanyName2
1
1
1
2
2
3
3

我看到了获取两个单词之间距离的算法,所以如果我只有一个奇怪的名字,我会将它与所有其他名称进行比较并选择距离最短的名称。但我有数以千计的名字,并希望将它们分组。

我对弹性搜索一无所知,但是elastic包中的其中一个函数或其他函数可以帮助我吗?

对不起,这里没有编程。我知道。但这远远超出了我的正常专业领域。

1 个答案:

答案 0 :(得分:2)

解决方案:使用字符串距离

你走在正确的轨道上。这里有一些R代码可以帮助您入门:

install.packages("stringdist") # install this package
library("stringdist") 
CompanyName <- c('Kraft', 'Kraft Foods', 'Kfraft', 'nestle', 'nestle usa', 'GM', 'general motors', 'the dow chemical company', 'Dow')
CompanyName = tolower(CompanyName) # otherwise case matters too much
# Calculate a string distance matrix; LCS is just one option
?"stringdist-metrics" # see others
sdm = stringdistmatrix(CompanyName, CompanyName, useNames=T, method="lcs") 

我们来看看。这些是字符串之间的计算距离,使用最长公共子序列度量(尝试其他,例如余弦,Levenshtein)。它们本质上都衡量了字符串共有多少个字符。他们的优缺点超出了Q&amp; A的范围。你可能会研究一些能给两个包含完全相同子串的字符串(如dow)

提供更高相似性值的东西
sdm[1:5,1:5]
            kraft kraft foods kfraft nestle nestle usa
kraft           0           6      1      9         13
kraft foods     6           0      7     15         15
kfraft          1           7      0     10         14
nestle          9          15     10      0          4
nestle usa     13          15     14      4          0

一些可视化

# Hierarchical clustering
sdm_dist = as.dist(sdm) # convert to a dist object (you essentially already have distances calculated)
plot(hclust(sdm_dist))

如果您想明确分组到k组,请使用k-medoids。

library("cluster")
clusplot(pam(sdm_dist, 5), color=TRUE, shade=F, labels=2, lines=0)

enter image description here