Під час NLP та текстової аналітики з документа слів можна витягти кілька різновидів функцій, які використовуються для прогнозування моделювання. До них належать наступні.
nграм
Візьміть випадковий зразок слів із слів.txt . На кожне слово зразка дістаньте всі можливі біграми букв. Наприклад, сила слова складається з цих двограмів: { st , tr , re , en , ng , gt , th }. Згрупуйте за двограмами та обчисліть частоту кожного біграму у вашому корпусі. Тепер зробіть те ж саме для триграмів, ... аж до n-грамів. На даний момент у вас є приблизне уявлення про частотний розподіл того, як римські букви поєднуються для створення англійських слів.
ngram + межі слів
Щоб зробити належний аналіз, вам, мабуть, слід створити теги для позначення n-грамів на початку та в кінці слова ( собака -> { ^ d , do , og , g ^ }) - це дозволить вам зафіксувати фонологічні / ортографічні обмеження, які в іншому випадку можуть бути пропущені (наприклад, послідовність ng ніколи не може виникнути на початку рідного англійського слова, тому послідовність ^ ng неприпустима - одна з причин, чому в'єтнамські імена, як Nguyễn , важко вимовити для англійців) .
Назвіть цю колекцію грам word_set . Якщо ви перевернете сортування за частотою, ваші найчастіші грами будуть у верхній частині списку - вони відображають найпоширеніші послідовності в англійських словах. Нижче я показую деякий (некрасивий) код за допомогою пакета {ngram} для вилучення літер ngrams зі слів, а потім обчислюю грам частоти:
#' 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
Ваша програма просто візьме вхідну послідовність символів як вхідну, розбить її на грами, як було обговорено раніше, і порівняйте зі списком найкращих грам. Очевидно, що вам доведеться зменшити свої n n вибору, щоб відповідати вимогам програмного розміру .
приголосні & голосні
Іншою можливою особливістю чи підходом було б перегляд послідовностей голосних приголосних. Переважно перетворіть усі слова в приголосні рядки голосних (наприклад, млинець -> CVCCVCV ) і дотримуйтесь тієї ж стратегії, яку обговорювали раніше. Ця програма, ймовірно, може бути набагато меншою, але вона буде страждати від точності, оскільки вона абстрагує телефони в одиницях високого порядку.
nchar
Ще однією корисною особливістю буде довжина рядка, оскільки можливість легальних англійських слів зменшується зі збільшенням кількості символів.
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"))
Аналіз помилок
Тип помилок, що створюються цим типом машини, мають бути дурницькими словами - словами, схожими на те, що вони повинні бути англійськими словами, але їх немає (наприклад, ghjrtg було б правильно відхилено (справжній мінус), але barkle буде неправильно класифіковано як англійське слово (хибно позитивний)).
Цікаво, що zyzzyvas було б неправильно відхилено (хибнонегативний), оскільки zyzzyvas - це справжнє англійське слово (принаймні, згідно слів.txt ), але його грамові послідовності є надзвичайно рідкісними і, таким чином, не можуть сприяти великій дискримінаційній силі.