Trong quá trình phân tích văn bản và NLP, một số tính năng có thể được trích xuất từ một tài liệu các từ để sử dụng cho mô hình dự đoán. Chúng bao gồm những điều sau đây.
ngrams
Lấy một mẫu từ ngẫu nhiên từ words.txt . Đối với mỗi từ trong mẫu, trích xuất mọi bi-gram có thể có của các chữ cái. Ví dụ: cường độ từ bao gồm các bi-gram: { st , tr , re , en , ng , gt , th }. Nhóm theo bi-gram và tính tần số của mỗi bi-gram trong kho văn bản của bạn. Bây giờ làm điều tương tự cho tri-gram, ... tất cả các cách lên đến n-gram. Tại thời điểm này, bạn có một ý tưởng sơ bộ về phân phối tần số về cách các chữ cái La Mã kết hợp để tạo ra các từ tiếng Anh.
ngram + ranh giới từ
Để thực hiện phân tích chính xác, có lẽ bạn nên tạo các thẻ để chỉ ra n-gram ở đầu và cuối của một từ, ( dog -> { ^ d , do , og , g ^ }) - điều này sẽ cho phép bạn nắm bắt ngữ âm / chính tả các ràng buộc có thể bị bỏ qua (ví dụ: chuỗi ng không bao giờ có thể xảy ra ở đầu từ tiếng Anh bản địa, do đó, chuỗi ^ ng không được phép - một trong những lý do tại sao tên tiếng Việt như Nguyễn khó phát âm cho người nói tiếng Anh) .
Gọi bộ sưu tập gram này là word_set . Nếu bạn đảo ngược sắp xếp theo tần suất, gram thường xuyên nhất của bạn sẽ ở đầu danh sách - những thứ này sẽ phản ánh các chuỗi phổ biến nhất trong các từ tiếng Anh. Dưới đây tôi hiển thị một số mã (xấu) bằng cách sử dụng gói {ngram} để trích xuất các chữ cái ngram từ các từ sau đó tính toán tần số gram:
#' 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
Chương trình của bạn sẽ chỉ lấy một chuỗi các ký tự đến làm đầu vào, chia nó thành gram như đã thảo luận trước đó và so sánh với danh sách các gram hàng đầu. Rõ ràng bạn sẽ phải giảm số lượt chọn hàng đầu của mình để phù hợp với yêu cầu kích thước chương trình .
phụ âm và nguyên âm
Một tính năng hoặc cách tiếp cận khác có thể là xem xét các chuỗi nguyên âm phụ âm. Về cơ bản chuyển đổi tất cả các từ trong chuỗi nguyên âm phụ âm (ví dụ: pancake -> CVCCVCV ) và làm theo cùng một chiến lược đã thảo luận trước đây. Chương trình này có thể nhỏ hơn nhiều nhưng nó sẽ bị ảnh hưởng bởi độ chính xác vì nó trừu tượng hóa điện thoại thành các đơn vị cao cấp.
than chì
Một tính năng hữu ích khác sẽ là độ dài chuỗi, vì khả năng các từ tiếng Anh hợp pháp giảm khi số lượng ký tự tăng lên.
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"))
Phân tích lỗi
Loại lỗi do loại máy này tạo ra phải là những từ vô nghĩa - những từ trông giống như chúng phải là từ tiếng Anh nhưng không (ví dụ, ghjrtg sẽ bị từ chối chính xác (phủ định đúng) nhưng barkle sẽ phân loại không chính xác thành một từ tiếng Anh (dương tính giả)).
Thật thú vị, zyzzyvas sẽ bị từ chối không chính xác (âm tính giả), bởi vì zyzzyvas là một từ tiếng Anh thực sự (ít nhất là theo words.txt ), nhưng các chuỗi gram của nó cực kỳ hiếm và do đó không có khả năng đóng góp nhiều sức mạnh phân biệt đối xử.