在 R 中使用 Jaro-Winkler 模糊匹配进行文本挖掘
Text Mining using Jaro-Winkler fuzzy matching in R
我试图在 R 中进行一些距离匹配,并且正在努力获得可用的输出。
我有一个数据框 terms
,其中包含 5 个文本字符串,以及每个字符串的类别。我有第二个数据框 notes
,其中包含 10 个拼写错误的单词以及一个 NoteID。
我希望能够使用距离算法将我的 5 个 terms
中的每一个与我的 10 个 notes
中的每一个进行比较,以尝试抓住简单的拼写错误。我试过:
near_match<- subset(notes, jarowinkler(notes$word, terms$word) >0.9)
NoteID Note
5 e5 thought
10 e5 tough
和
jarowinkler(notes$word, terms$word)
[1] 0.8000000 0.7777778 0.8266667 0.8833333 0.9714286 0.8000000 0.8000000 0.8266667 0.8833333 0.9500000
第一个实例几乎是我所需要的,它只是缺少 terms
中导致匹配的单词。第二个 returns 10 分,但我不确定算法是否依次检查了 5 个 terms
中的每一个与 10 个 notes
中的每一个,并返回了最接近的匹配项(最高分)与否。
如果使用 jarowinkler()
可以实现我想要的效果,或者是否有更好的选择,我该如何更改以上内容以实现我想要的输出?
我对 R 比较陌生,所以非常感谢任何帮助我进一步理解算法如何生成分数以及实现我想要的输出的方法。
下面的示例数据帧
谢谢
> notes
NoteID word
1 a1 hit
2 b2 hot
3 c3 shirt
4 d4 than
5 e5 thought
6 a1 hat
7 b2 get
8 c3 shirt
9 d4 than
10 e5 tough
> terms
Category word
1 a hot
2 b got
3 a shot
4 d that
5 c though
你的data.frames:
notes<-data.frame(NoteID=c("a1","b2","c3","d4","e5","a1","b2","c3","d4","e5"),
word=c("hit","hot","shirt","than","thought","hat","get","shirt","that","tough"))
terms<-data.frame(Category=c("a","b","c","d","e"),
word=c("hot","got","shot","that","though"))
使用 stringdistmatrix
(包 stringdist
)和方法 "jw" (jarowinkler)
library(stringdist)
dist<-stringdistmatrix(notes$word,terms$word,method = "jw")
row.names(dist)<-as.character(notes$word)
colnames(dist)<-as.character(terms$word)
现在你有所有的距离:
dist
hot got shot that though
hit 0.2222222 0.4444444 0.27777778 0.27777778 0.50000000
hot 0.0000000 0.2222222 0.08333333 0.27777778 0.33333333
shirt 0.4888889 1.0000000 0.21666667 0.36666667 0.54444444
than 0.4722222 1.0000000 0.50000000 0.16666667 0.38888889
thought 0.3571429 0.5158730 0.40476190 0.40476190 0.04761905
hat 0.2222222 0.4444444 0.27777778 0.08333333 0.50000000
get 0.4444444 0.2222222 0.47222222 0.47222222 0.50000000
shirt 0.4888889 1.0000000 0.21666667 0.36666667 0.54444444
that 0.2777778 0.4722222 0.33333333 0.00000000 0.38888889
tough 0.4888889 0.4888889 0.51666667 0.51666667 0.05555556
找到更接近音符的词
output<-cbind(notes,word_close=terms[as.numeric(apply(dist, 1, which.min)),"word"],dist_min=apply(dist, 1, min))
output
NoteID word word_close dist_min
1 a1 hit hot 0.22222222
2 b2 hot hot 0.00000000
3 c3 shirt shot 0.21666667
4 d4 than that 0.16666667
5 e5 thought though 0.04761905
6 a1 hat that 0.08333333
7 b2 get got 0.22222222
8 c3 shirt shot 0.21666667
9 d4 that that 0.00000000
10 e5 tough though 0.05555556
如果你想要刚好在word_close一定距离阈值(在本例中为0.1)下的单词,你可以这样做:
output[output$dist_min>=0.1,c("word_close","dist_min")]<-NA
output
NoteID word word_close dist_min
1 a1 hit <NA> NA
2 b2 hot hot 0.00000000
3 c3 shirt <NA> NA
4 d4 than <NA> NA
5 e5 thought though 0.04761905
6 a1 hat that 0.08333333
7 b2 get <NA> NA
8 c3 shirt <NA> NA
9 d4 that that 0.00000000
10 e5 tough though 0.05555556
我试图在 R 中进行一些距离匹配,并且正在努力获得可用的输出。
我有一个数据框 terms
,其中包含 5 个文本字符串,以及每个字符串的类别。我有第二个数据框 notes
,其中包含 10 个拼写错误的单词以及一个 NoteID。
我希望能够使用距离算法将我的 5 个 terms
中的每一个与我的 10 个 notes
中的每一个进行比较,以尝试抓住简单的拼写错误。我试过:
near_match<- subset(notes, jarowinkler(notes$word, terms$word) >0.9)
NoteID Note
5 e5 thought
10 e5 tough
和
jarowinkler(notes$word, terms$word)
[1] 0.8000000 0.7777778 0.8266667 0.8833333 0.9714286 0.8000000 0.8000000 0.8266667 0.8833333 0.9500000
第一个实例几乎是我所需要的,它只是缺少 terms
中导致匹配的单词。第二个 returns 10 分,但我不确定算法是否依次检查了 5 个 terms
中的每一个与 10 个 notes
中的每一个,并返回了最接近的匹配项(最高分)与否。
如果使用 jarowinkler()
可以实现我想要的效果,或者是否有更好的选择,我该如何更改以上内容以实现我想要的输出?
我对 R 比较陌生,所以非常感谢任何帮助我进一步理解算法如何生成分数以及实现我想要的输出的方法。
下面的示例数据帧
谢谢
> notes
NoteID word
1 a1 hit
2 b2 hot
3 c3 shirt
4 d4 than
5 e5 thought
6 a1 hat
7 b2 get
8 c3 shirt
9 d4 than
10 e5 tough
> terms
Category word
1 a hot
2 b got
3 a shot
4 d that
5 c though
你的data.frames:
notes<-data.frame(NoteID=c("a1","b2","c3","d4","e5","a1","b2","c3","d4","e5"),
word=c("hit","hot","shirt","than","thought","hat","get","shirt","that","tough"))
terms<-data.frame(Category=c("a","b","c","d","e"),
word=c("hot","got","shot","that","though"))
使用 stringdistmatrix
(包 stringdist
)和方法 "jw" (jarowinkler)
library(stringdist)
dist<-stringdistmatrix(notes$word,terms$word,method = "jw")
row.names(dist)<-as.character(notes$word)
colnames(dist)<-as.character(terms$word)
现在你有所有的距离:
dist
hot got shot that though
hit 0.2222222 0.4444444 0.27777778 0.27777778 0.50000000
hot 0.0000000 0.2222222 0.08333333 0.27777778 0.33333333
shirt 0.4888889 1.0000000 0.21666667 0.36666667 0.54444444
than 0.4722222 1.0000000 0.50000000 0.16666667 0.38888889
thought 0.3571429 0.5158730 0.40476190 0.40476190 0.04761905
hat 0.2222222 0.4444444 0.27777778 0.08333333 0.50000000
get 0.4444444 0.2222222 0.47222222 0.47222222 0.50000000
shirt 0.4888889 1.0000000 0.21666667 0.36666667 0.54444444
that 0.2777778 0.4722222 0.33333333 0.00000000 0.38888889
tough 0.4888889 0.4888889 0.51666667 0.51666667 0.05555556
找到更接近音符的词
output<-cbind(notes,word_close=terms[as.numeric(apply(dist, 1, which.min)),"word"],dist_min=apply(dist, 1, min))
output
NoteID word word_close dist_min
1 a1 hit hot 0.22222222
2 b2 hot hot 0.00000000
3 c3 shirt shot 0.21666667
4 d4 than that 0.16666667
5 e5 thought though 0.04761905
6 a1 hat that 0.08333333
7 b2 get got 0.22222222
8 c3 shirt shot 0.21666667
9 d4 that that 0.00000000
10 e5 tough though 0.05555556
如果你想要刚好在word_close一定距离阈值(在本例中为0.1)下的单词,你可以这样做:
output[output$dist_min>=0.1,c("word_close","dist_min")]<-NA
output
NoteID word word_close dist_min
1 a1 hit <NA> NA
2 b2 hot hot 0.00000000
3 c3 shirt <NA> NA
4 d4 than <NA> NA
5 e5 thought though 0.04761905
6 a1 hat that 0.08333333
7 b2 get <NA> NA
8 c3 shirt <NA> NA
9 d4 that that 0.00000000
10 e5 tough though 0.05555556