【问题标题】:From of list of strings, identify which are human names and which are not从字符串列表中,识别哪些是人名,哪些不是
【发布时间】:2015-12-09 07:07:06
【问题描述】:

我有一个像下面这样的向量,想确定列表中的哪些元素是人名,哪些不是。我找到了 humaniformat 包,它格式化名称,但不幸的是不能确定字符串是否实际上是名称。我还发现了一些用于实体提取的包,但它们似乎需要用于词性标记的实际文本,而不是单个名称。

示例

pkd.names.quotes <- c("Mr. Rick Deckard", # Name
                      "Do Androids Dream of Electric Sheep", # Not a name
                      "Roy Batty", # Name 
                      "How much is an electric ostrich?", # Not a name
                      "My schedule for today lists a six-hour self-accusatory depression.", # Not a name
                      "Upon him the contempt of three planets descended.", # Not a name
                      "J.F. Sebastian", # Name
                      "Harry Bryant", # Name
                      "goat class", # Not a name
                      "Holden, Dave", # Name
                      "Leon Kowalski", # Name
                      "Dr. Eldon Tyrell") # Name

【问题讨论】:

  • 我的朋友电鸵鸟看到他的名字不是真正的名字会非常沮丧。所以你需要知道究竟是什么决定了一个名字,对吗?但是现在人们几乎可以给他们的孩子起任何名字(无论如何在美国)。以 Kanye West 的孩子为例。他叫西北。诚然,Kanye 是个白痴,这仍然是事实。那如何通过名称测试?
  • 哈哈,很公平。我想我会弄错 Kanye 孩子的名字。不过没关系,有些错误是可以接受的。我只是希望比简单地依赖字符串长度、空格数和大小写做得更好。
  • 斯坦福命名实体识别“模块”可供 R 使用。rpubs.com/lmullen/nlp-chapter 有 NLP 介绍。这个nlp.stanford.edu/software/CRF-NER.shtml 是 java lib 的官方来源,也许可以从中制定解决方案。

标签: r text nlp classification


【解决方案1】:

这是一种方法。美国人口普查局将在其数据库中出现超过 100 次的姓氏列表(有频率):全部 152,000 个。如果使用完整列表,则所有字符串都有名称。例如,“class”、“him”和“the”是某些语言中的名称(虽然不确定是哪种语言)。同样,有许多名字列表(参见this post)。

下面的代码从 2000 年人口普查中获取所有姓氏,并从引用的帖子中获取名字列表,然后将每个列表中最常见的 10,000 个作为子集,合并和清理列表,并将其用作字典tm 包来识别哪些字符串包含名称。您可以通过更改freq 变量来控制“灵敏度”(freq=10,000 似乎会生成您想要的结果)。

url <- "http://www2.census.gov/topics/genealogy/2000surnames/names.zip"
tf <- tempfile()
download.file(url,tf, mode="wb")                     # download archive of surname data
files    <- unzip(tf, exdir=tempdir())               # unzips and returns a vector of file names
surnames <- read.csv(files[grepl("\\.csv$",files)])  # 152,000 surnames occurring >100 times
url <- "http://deron.meranda.us/data/census-derived-all-first.txt"
firstnames <- read.table(url(url), header=FALSE)
freq <- 10000
dict  <- unique(c(tolower(surnames$name[1:freq]), tolower(firstnames$V1[1:freq])))
library(tm)
corp <- Corpus(VectorSource(pkd.names.quotes))
tdm  <- TermDocumentMatrix(corp, control=list(tolower=TRUE, dictionary=dict))
m    <- as.matrix(tdm)
m    <- m[rowSums(m)>0,]
m
#            Docs
# Terms       1 2 3 4 5 6 7 8 9 10 11 12
#   bryant    0 0 0 0 0 0 0 1 0  0  0  0
#   dave      0 0 0 0 0 0 0 0 0  1  0  0
#   deckard   1 0 0 0 0 0 0 0 0  0  0  0
#   eldon     0 0 0 0 0 0 0 0 0  0  0  1
#   harry     0 0 0 0 0 0 0 1 0  0  0  0
#   kowalski  0 0 0 0 0 0 0 0 0  0  1  0
#   leon      0 0 0 0 0 0 0 0 0  0  1  0
#   rick      1 0 0 0 0 0 0 0 0  0  0  0
#   roy       0 0 1 0 0 0 0 0 0  0  0  0
#   sebastian 0 0 0 0 0 0 1 0 0  0  0  0
#   tyrell    0 0 0 0 0 0 0 0 0  0  0  1
which(colSums(m)>0)
#  1  3  7  8 10 11 12 

【讨论】:

    猜你喜欢
    • 2019-08-27
    • 1970-01-01
    • 1970-01-01
    • 2021-04-17
    • 1970-01-01
    • 2013-05-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多