我有一百万条记录,其中包含一个名为product的字段,由使用自由文本的用户填写。有时字段为空白,有时它包含batteries
或laptop
之类的内容,有时它包含bateries
或lptp
之类的内容,这些内容与随意的内容相同,但是电脑是非常不同的。
我不知道不同类型产品的变化,因为它们每天都在变化(我们每天可以获得大约一百万条记录)。我希望能够清理数据,并且我正在找人指出正确的方向研究论文博客任何可以帮助我对所有这些事情进行分类的事情
我看过层次聚类Text clustering with Levenshtein distances
我也有想法以某种方式获得亚马逊分类学并试图让产品映射到这个(我还在调查这是否可行)。 Google有similar
我使用R来制作原型,我想表明它可以完成
谢谢大家的时间
答案 0 :(得分:1)
我不确定您是否需要群集方法。
你需要的是字符串之间的距离度量(例如Levenshtein)。你很可能也需要某种词典。但这与我在下面建议的方法有相同的缺点。如果你有一些正确的单词与拼写错误的单词有相同的距离,例如你的词典包含" car"," cart"," card"你会有拼错的单词" carx"你无法决定哪一个是正确的。你需要上下文信息(汽车比卡更贵)。
我将使用单词的频率。我想如果你想表明你的问题通常是可以解决的,那就足够了。我的想法很少发生拼写错误的单词。一个很少出现的正确单词可能会导致我的方法出现问题,但只有在存在距离较小的其他正确单词时才会出现问题。
我将使用adist
包中的stringdist
函数。
require (stringdist)
我的例子是
words <- c("monitor", "laptop", "mouse", "mouse", "keybsard", "monitor",
"mous", "keyboard", "keyboard", "monitor", "keybxard", "monitor",
"motse", "monitod", "laptop", "keyboard", "laptop", "mousq",
"laptop", "mobitor", "keybolrd", "monitor", "mouse", "laptop",
"monitor", "moute", "mouwe", "mwuse", "tonitor", "ltptop", "keybovrd",
"monitor", "laptop", "moase", "keyboard", "keyboard", "keywoard",
"laptnp", "laptop", "laptop")
让我们看看频率:
freq_table <- as.data.frame(table(words), stringsAsFactors = F)
看起来像这样:
words Freq
1 keyboard 5
2 keybolrd 1
3 keybovrd 1
4 keybsard 1
5 keybxard 1
6 keywoard 1
7 laptnp 1
8 laptop 8
9 ltptop 1
10 moase 1
11 mobitor 1
12 monitod 1
13 monitor 7
14 motse 1
15 mous 1
16 mouse 3
17 mousq 1
18 moute 1
19 mouwe 1
20 mwuse 1
21 tonitor 1
现在我分开了好的&#39;并且&#39;坏&#39;单词:
s <- split(freq_table, freq_table$Freq < 3)
good <- s[['FALSE']]
good <- good[order(-good$Freq),]$words
bad <- s[['TRUE']]$words
我所做的是将出现3次或更多次的条目中的频率表和出现次数少于3次的条目分开。我稍后会解释为什么我要排好好的。现在我们有了好处:
[1] "laptop" "monitor" "keyboard" "mouse"
和坏:
[1] "keybolrd" "keybovrd" "keybsard" "keybxard" "keywoard" "laptnp" "ltptop" "moase"
[9] "mobitor" "monitod" "motse" "mous" "mousq" "moute" "mouwe" "mwuse"
[17] "tonitor"
现在我计算好词和坏词之间的距离矩阵:
dis <- adist(bad,good)
并查看&#39;邻居中是否有好话。坏话。
hits <- sapply(1:NROW(dis), function (i) which(dis[i,] < 3)[1])
我总是第一次打。由于我们之前对好词进行了排序,因此首次点击将是点击中最常用的词。通过这种方式,我想避免使用拼错的单词,但通常以相同的方式,将其用作正确的单词。这不会一直有效,它是一种启发式。
现在我生成某种查找表df
:
bad_corr <- bad
ind <- which(!is.na(hits))
bad_corr[ind] <- good[hits[ind]]
df <- data.frame(bad, bad_corr, stringsAsFactors = F)
看起来像:
bad bad_corr
1 keybolrd keyboard
2 keybovrd keyboard
3 keybsard keyboard
4 keybxard keyboard
5 keywoard keyboard
6 laptnp laptop
7 ltptop laptop
8 moase mouse
9 mobitor monitor
10 monitod monitor
11 motse mouse
12 mous mouse
13 mousq mouse
14 moute mouse
15 mouwe mouse
16 mwuse mouse
17 tonitor monitor
这是我用来替换拼写错误的单词。总结一下,整个功能是 这样:
correct <- function (words, minfreq = 3, sensitivity = 3) {
freq_table <- as.data.frame(table(words), stringsAsFactors = F)
s <- split(freq_table, freq_table$Freq < minfreq)
good <- s[['FALSE']]
good <- good[order(-good$Freq),]$words
bad <- s[['TRUE']]$words
dis <- adist(bad,good)
hits <- sapply(1:NROW(dis), function (i) which(dis[i,] < sensitivity)[1])
bad_corr <- bad
ind <- which(!is.na(hits))
bad_corr[ind] <- good[hits[ind]]
df <- data.frame(bad, bad_corr, stringsAsFactors = F)
ind <- match(words, df$bad)
words[which(!is.na(ind))] <- df$bad_corr[ind[!is.na(ind)]]
words
}
sensitivity
说,如何远离&#39;允许拼写错误的单词。 minfreq
表示发生的时间少于minfreq
次的每个单词都被视为可能拼写错误(但只有在字符串距离小于sensitivity
的情况下更频繁的单词时才会被替换)。但是这个功能并不完美。如果你没有拼错单词,例如它会导致错误。因此,如果您想使用它,您应该进一步优化它。
所有这一切的结果:
words correct.words.
1 monitor monitor
2 laptop laptop
3 mouse mouse
4 mouse mouse
5 keybsard keyboard
6 monitor monitor
7 mous mouse
8 keyboard keyboard
9 keyboard keyboard
10 monitor monitor
11 keybxard keyboard
12 monitor monitor
13 motse mouse
.. ...... ........
最后,如果您有分类法,则省略频率部分并将分类法的单词存储在good
中。
祝你好运!