使用 R 将拼写错误的产品清理为分类法

Using R to clean mis-spelt products to a taxonomy

我有一百万条记录,其中包含一个名为产品的字段,该字段由使用自由文本的用户填写。有时该字段是空白的,有时它包含诸如 batterieslaptop 之类的内容,有时它包含诸如 baterieslptp 之类的内容一台电脑是非常不同的。

我不知道不同类型的产品每天都在变化(同样,我们每天可以获得大约一百万条记录)。我希望能够清理数据,我正在寻找能为我指明正确方向的人研究论文博客任何真正可以帮助我对所有这些东西进行分类的东西

我见过层次聚类Text clustering with Levenshtein distances

我还想以某种方式获取 Amazon 的分类法并尝试让产品映射到此(我仍在调查这是否可能)。 Google 有东西 similar

我正在使用 R 制作原型,我只是想证明它可以完成

谢谢大家的宝贵时间

我不确定您是否需要聚类方法。

您需要的是字符串之间的一些距离度量(例如 Levenshtein)。您很可能还需要某种词典。但这与我在下面建议的方法有相同的缺点。如果你有一些正确的单词与拼错的单词有相同的距离,例如您的词典包含 "car"、"cart"、"card",并且您会拼错单词 "carx",您无法决定哪个是正确的。您将需要上下文信息(例如,汽车比卡片贵)。

我会使用单词的频率。我想如果你想证明你的问题通常是可以解决的,这就足够了。我的想法是很少出现拼写错误的单词。一个很少出现的正确词可能会导致我的方法出现问题,但前提是存在与它距离很小的其他正确词。

我将使用 stringdist 包中的 adist 函数。

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

现在我把'good'和'bad'字分开:

s <- split(freq_table, freq_table$Freq < 3)
good <- s[['FALSE']]
good <- good[order(-good$Freq),]$words
bad <- s[['TRUE']]$words

我所做的是将出现 3 次或更多次的条目和出现少于 3 次的条目的频率 table 分开。我稍后会解释为什么我把好的排序。现在我们有好处:

[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)

看看坏词'neighbourhood'里面有没有好词。

hits <- sapply(1:NROW(dis), function (i) which(dis[i,] < 3)[1])

我总是先下手为强。由于我们之前对好词进行了排序,因此第一个命中的词将是所有命中词中出现频率最高的词。通过这种方式,我想避免拼错的单词被用作正确的单词,但通常以相同的方式使用。这并不总是有效,它是一种启发式方法。

现在我生成某种查询 table 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 说,如何 'far away' 允许拼写错误的单词。 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

祝你好运!