使用 R 将拼写错误的产品清理为分类法
Using R to clean mis-spelt products to a taxonomy
我有一百万条记录,其中包含一个名为产品的字段,该字段由使用自由文本的用户填写。有时该字段是空白的,有时它包含诸如 batteries
或 laptop
之类的内容,有时它包含诸如 bateries
或 lptp
之类的内容一台电脑是非常不同的。
我不知道不同类型的产品每天都在变化(同样,我们每天可以获得大约一百万条记录)。我希望能够清理数据,我正在寻找能为我指明正确方向的人研究论文博客任何真正可以帮助我对所有这些东西进行分类的东西
我见过层次聚类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
。
祝你好运!
我有一百万条记录,其中包含一个名为产品的字段,该字段由使用自由文本的用户填写。有时该字段是空白的,有时它包含诸如 batteries
或 laptop
之类的内容,有时它包含诸如 bateries
或 lptp
之类的内容一台电脑是非常不同的。
我不知道不同类型的产品每天都在变化(同样,我们每天可以获得大约一百万条记录)。我希望能够清理数据,我正在寻找能为我指明正确方向的人研究论文博客任何真正可以帮助我对所有这些东西进行分类的东西
我见过层次聚类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
。
祝你好运!