2015-09-13 3 views
7

Ich habe einen Vektor wie der eine unten und möchte bestimmen, welche Elemente in der Liste sind menschliche Namen und welche nicht sind. Ich habe das humaniformat-Paket gefunden, das Namen formatiert, aber leider nicht feststellt, ob eine Zeichenkette tatsächlich ein Name ist. Ich habe auch ein paar Pakete für Entity-Extraktion gefunden, aber sie scheinen tatsächlichen Text für Wort-zu-Tag-Kennzeichnung zu benötigen, anstatt einen einzelnen Namen.Von der Liste der Zeichenfolgen, identifizieren, die menschliche Namen sind und die nicht sind

Beispiel

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 
+5

Mein Freund Electric Ostrich wäre schrecklich verärgert zu sehen, dass sein Name nicht wirklich ein Name ist. Sie müssen also wissen, was genau einen Namen bestimmt, richtig? Aber heutzutage nennen die Menschen ihren Kindern fast alles (in Amerika sowieso). Nehmen wir zum Beispiel Kanye Wests Kind. Sein Name ist Nordwest. Zugegeben, Kanye ist ein Idiot, das ist immer noch wahr. Wie würde das den Namenstest bestehen? –

+0

Haha, fair genug. Ich vermute, ich würde Kanyes Namen falsch verstehen. Das ist in Ordnung, ein Fehler ist akzeptabel. Ich hoffe nur, es besser zu machen, als nur auf die Länge, die Anzahl der Leerzeichen und die Groß- und Kleinschreibung angewiesen zu sein. –

+1

Das Stanford Entity Recognition "Modul" ist für R verfügbar. Https://rpubs.com/lmullen/nlp-chapter hat ein NLP Intro. Diese http://nlp.stanford.edu/software/CRF-NER.shtml ist die offizielle Quelle für die Java-Bibliothek und es kann möglich sein, eine Lösung daraus zu erstellen. – hrbrmstr

Antwort

11

Dies ist ein Ansatz. Das US Census Bureau tabelliert eine Liste von Nachnamen, die> 100 Mal in ihrer Datenbank vorkommen (mit Häufigkeit): alle 152.000 von ihnen. Wenn Sie die vollständige Liste verwenden, haben alle Ihre Strings einen Namen. Zum Beispiel sind "Klasse", "er" und "die" Namen in bestimmten Sprachen (nicht sicher, welche Sprachen though). Ebenso gibt es viele Listen von Vornamen (siehe this post).

Der folgende Code erfasst alle Nachnamen aus der Volkszählung 2000, und eine Liste der Vornamen aus dem zitierten Beitrag, dann Teilmengen zu den häufigsten 10.000 auf jeder Liste, kombiniert und bereinigt die Listen und verwendet das als ein Wörterbuch im Paket tm, um festzustellen, welche Strings Namen enthalten. Sie können die "Empfindlichkeit" steuern, indem Sie die Variable freq ändern (Freq = 10.000 scheint das gewünschte Ergebnis zu erzeugen).

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