我需要在VAR1_STRUCTURED中实现值,而无需手动输入所有可能的VAR1值,因为我有50000个观察值,意味着50000个可能的情况。
-z
并且......下有更多的价值观。
答案 0 :(得分:9)
您的问题确实不精确。请关注@RiggsFolly建议并阅读有关如何提出好问题的参考资料。
另外,正如@DuduMarkovitz所建议的那样,您应该首先简化问题并清理数据。一些资源可以帮助您入门:
一旦您对结果感到满意,您就可以继续为每个Var1
条目识别一个组(这将有助于您在类似条目上执行进一步分析/操作)这可以在许多不同的方式,但正如@GordonLinoff所提到的,可能是Levenshtein距离。
注意:对于50K条目,结果不会100%准确,因为它不会总是对相应组中的字词进行分类,但这应该相当大减少手工操作。
在R中,您可以使用adist()
计算字符向量之间的近似字符串距离。该 距离是一个广义的Levenshtein(编辑)距离,给出了 插入,删除和删除的最小可能加权数 将一个字符串转换为另一个字符串所需的替换。
使用您的示例数据:
d <- adist(df$Var1)
# add rownames (this will prove useful later on)
rownames(d) <- df$Var1
> d
# [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
#125 Hollywood St. 0 1 1 16 15 16 15 15 15 15
#125 Hllywood St. 1 0 2 15 14 15 15 14 14 14
#125 Hollywood St 1 2 0 15 15 15 14 14 15 15
#Target Store 16 15 15 0 2 1 2 10 10 9
#Trget Stre 15 14 15 2 0 3 4 9 10 8
#Target. Store 16 15 15 1 3 0 3 11 11 10
#T argetStore 15 15 14 2 4 3 0 10 11 9
#Walmart 15 14 14 10 9 11 10 0 5 2
#Walmart Inc. 15 14 15 10 10 11 11 5 0 6
#Wal marte 15 14 15 9 8 10 9 2 6 0
对于这个小样本,您可以看到3个不同的组(低Levensthein距离值的集群)并且可以轻松地手动分配它们,但对于较大的集合,您可能需要一个聚类算法。
我已经在我previous answer之一的评论中向您指出了如何使用hclust()
和Ward的最小方差法进行此操作,但我想在这里您最好使用其他技术(关于该主题的我最喜欢的资源之一,用于快速概述R中一些最广泛使用的方法是detailed answer)
以下是使用关联传播聚类的示例:
library(apcluster)
d_ap <- apcluster(negDistMat(r = 1), d)
您将在APResult对象d_ap
中找到与每个群集关联的元素以及最佳群集数量,在这种情况下:3。
> d_ap@clusters
#[[1]]
#125 Hollywood St. 125 Hllywood St. 125 Hollywood St
# 1 2 3
#
#[[2]]
# Target Store Trget Stre Target. Store T argetStore
# 4 5 6 7
#
#[[3]]
# Walmart Walmart Inc. Wal marte
# 8 9 10
您还可以看到可视化表示:
> heatmap(d_ap, margins = c(10, 10))
然后,您可以对每个组执行进一步的操作。作为示例,我在这里使用hunspell
在en_US字典中查找Var1
中的每个单独的单词以查找拼写错误,并尝试在每个group
内查找id
没有拼写错误(potential_id
)
library(dplyr)
library(tidyr)
library(hunspell)
tibble(Var1 = sapply(d_ap@clusters, names)) %>%
unnest(.id = "group") %>%
group_by(group) %>%
mutate(id = row_number()) %>%
separate_rows(Var1) %>%
mutate(check = hunspell_check(Var1)) %>%
group_by(id, add = TRUE) %>%
summarise(checked_vars = toString(Var1),
result_per_word = toString(check),
potential_id = all(check))
给出了:
#Source: local data frame [10 x 5]
#Groups: group [?]
#
# group id checked_vars result_per_word potential_id
# <int> <int> <chr> <chr> <lgl>
#1 1 1 125, Hollywood, St. TRUE, TRUE, TRUE TRUE
#2 1 2 125, Hllywood, St. TRUE, FALSE, TRUE FALSE
#3 1 3 125, Hollywood, St TRUE, TRUE, TRUE TRUE
#4 2 1 Target, Store TRUE, TRUE TRUE
#5 2 2 Trget, Stre FALSE, FALSE FALSE
#6 2 3 Target., Store TRUE, TRUE TRUE
#7 2 4 T, argetStore TRUE, FALSE FALSE
#8 3 1 Walmart FALSE FALSE
#9 3 2 Walmart, Inc. FALSE, TRUE FALSE
#10 3 3 Wal, marte FALSE, FALSE FALSE
注意:由于我们尚未执行任何文字处理,因此结果并不十分明确,但您明白了这一点。
数据
df <- tibble::tribble(
~Var1,
"125 Hollywood St.",
"125 Hllywood St.",
"125 Hollywood St",
"Target Store",
"Trget Stre",
"Target. Store",
"T argetStore",
"Walmart",
"Walmart Inc.",
"Wal marte"
)
答案 1 :(得分:0)
拥有50K值并不意味着您必须手动查看50K值。 首先对值进行聚合,这最有可能减少问题的规模。 第二步,规范化值。你可以删除标志,例如空格和句点,例如常用词ST。和公司等 标准化没有数字的地址。