Durante a PNL e a análise de texto, várias variedades de recursos podem ser extraídas de um documento de palavras para usar na modelagem preditiva. Isso inclui o seguinte.
ngrams
Pegue uma amostra aleatória de palavras em words.txt . Para cada palavra da amostra, extraia todos os gramas possíveis de letras. Por exemplo, a palavra força consiste nos seguintes gramas: { st , tr , re , en , ng , gt , th }. Agrupe por grama e calcule a frequência de cada grama no seu corpus. Agora faça o mesmo com três gramas, ... até n gramas. Neste ponto, você tem uma idéia aproximada da distribuição de frequência de como as letras romanas se combinam para criar palavras em inglês.
ngram + limites de palavras
Para fazer uma análise adequada, você provavelmente deve criar tags para indicar n-gramas no início e no final de uma palavra ( cão -> { ^ d , fazer , og , g ^ }) - isso permitiria capturar fonologia / ortografia restrições que de outra forma poderiam ser perdidas (por exemplo, a sequência ng nunca pode ocorrer no início de uma palavra nativa em inglês, portanto, a sequência ^ ng não é permitida - uma das razões pelas quais nomes vietnamitas como Nguyễn são difíceis de pronunciar para falantes de inglês) .
Chame essa coleção de gramas de word_set . Se você inverter a classificação por frequência, seus gramas mais frequentes estarão no topo da lista - refletirão as seqüências mais comuns entre as palavras em inglês. Abaixo, mostro algum código (feio) usando o pacote {ngram} para extrair a letra ngrams das palavras e depois computar as frequências de grama:
#' Return orthographic n-grams for word
#' @param w character vector of length 1
#' @param n integer type of n-gram
#' @return character vector
#'
getGrams <- function(w, n = 2) {
require(ngram)
(w <- gsub("(^[A-Za-z])", "^\\1", w))
(w <- gsub("([A-Za-z]$)", "\\1^", w))
# for ngram processing must add spaces between letters
(ww <- gsub("([A-Za-z^'])", "\\1 \\2", w))
w <- gsub("[ ]$", "", ww)
ng <- ngram(w, n = n)
grams <- get.ngrams(ng)
out_grams <- sapply(grams, function(gram){return(gsub(" ", "", gram))}) #remove spaces
return(out_grams)
}
words <- list("dog", "log", "bog", "frog")
res <- sapply(words, FUN = getGrams)
grams <- unlist(as.vector(res))
table(grams)
## ^b ^d ^f ^l bo do fr g^ lo og ro
## 1 1 1 1 1 1 1 4 1 4 1
Seu programa terá apenas uma sequência de caracteres de entrada como entrada, dividida em gramas conforme discutido anteriormente e comparada com a lista dos principais gramas. Obviamente, você terá que reduzir suas principais escolhas para atender ao requisito de tamanho do programa .
consoantes e vogais
Outra característica ou abordagem possível seria examinar sequências de vogais consoantes. Converta basicamente todas as palavras em seqüências de caracteres de vogal consoante (por exemplo, panqueca -> CVCCVCV ) e siga a mesma estratégia discutida anteriormente. Esse programa provavelmente poderia ser muito menor, mas sofreria de precisão porque abstrai os telefones em unidades de alta ordem.
nchar
Outro recurso útil será o comprimento da string, pois a possibilidade de palavras legítimas em inglês diminui à medida que o número de caracteres aumenta.
library(dplyr)
library(ggplot2)
file_name <- "words.txt"
df <- read.csv(file_name, header = FALSE, stringsAsFactors = FALSE)
names(df) <- c("word")
df$nchar <- sapply(df$word, nchar)
grouped <- dplyr::group_by(df, nchar)
res <- dplyr::summarize(grouped, count = n())
qplot(res$nchar, res$count, geom="path",
xlab = "Number of characters",
ylab = "Frequency",
main = "Distribution of English word lengths in words.txt",
col=I("red"))
Erro de análise
O tipo de erro produzido por esse tipo de máquina deve ser sem sentido - palavras que parecem ser palavras em inglês, mas que não são (por exemplo, ghjrtg seriam corretamente rejeitadas (verdadeiro negativo), mas barkle seria incorretamente classificado como uma palavra em inglês (falso positivo)).
Curiosamente, zyzzyvas seria incorretamente rejeitado (falso negativo), porque zyzzyvas é uma palavra real em inglês (pelo menos de acordo com words.txt ), mas suas seqüências de grama são extremamente raras e, portanto, provavelmente não contribuem com muito poder discriminatório.