У меня есть набор данных из 27 файлов, каждый из которых содержит коды операций. Я хочу использовать стемминг, чтобы сопоставить все версии похожих кодов операций с одним и тем же кодом операции. Например: push, pusha, pushb и т. д. будут отображаться как push; addf addi для добавления, multi multf для mult и т. д.). Как я могу это сделать? Я пытался использовать PorterStemmer с расширениями NLTK, но он не работает с моим набором данных. Я думаю, что это работает только с нормальными человеческими языковыми словами. (типа играл, играл --> играть), а не на этих опкодах вроде (пуша, pushb --> нажать).
НЛП: анализ набора данных кодов операций
Ответы (1)
Я не думаю, что стемминг - это то, что вы хотите здесь сделать. Стеммеры специфичны для языка и основаны на общих флективных морфологических моделях этого языка. Например, в английском языке у глаголов есть формы инфинитива (например, «to walk»), которые изменяются для времени, вида и лица/числа: I walk vs. She walks (walk+s), I walk vs. ходил (гулял + ходил), а также ходил + ходил и т. д. Стеммеры систематизируют эти стохастические распределения в «правила», которые затем применяются к «слову», чтобы превратиться в его основу. Другими словами, для ваших кодов операций не существует готового стеммера.
У вас есть два возможных решения: (1) создать словарь или (2) написать собственный стеммер. Если у вас не слишком много вариантов для сопоставления, вероятно, быстрее всего будет просто создать собственный словарь, в котором вы используете все варианты слов в качестве ключей, а значением является лемма/основа/каноническая форма.
addi -> add
addf -> add
multi -> mult
multf -> mult
Если ваших потенциальных сопоставлений слишком много, чтобы выполнять их вручную, вы можете написать собственный стеммер регулярных выражений для сопоставления и преобразования. Вот как это можно сделать в R. Следующая функция берет входное слово и пытается сопоставить его с шаблоном, представляющим все варианты основы для всех n
основ в вашей коллекции. Он возвращает 1 x n
data.frame, где 1 указывает на наличие или 0 указывает на отсутствие совпадения вариантов.
#' Return word's stem data.frame with each column indicating presence (1) or
#' absence (0) of stem in that word.
map_to_stem_df <- function(word) {
## named list of patterns to match
stem_regex <- c(add = "^add[if]$",
mult = "^mult[if]$")
## iterate across the stem names
res <- lapply(names(stem_regex), function(stem) {
pat <- stem_regex[stem]
## if pattern matches word, then 1 else 0
if (grepl(pattern = pat, x = word)) {
pat_match <- 1
} else {
pat_match <- 0
}
## create 1x1 data.frame for stem
df <- data.frame(pat_match)
names(df) <- stem
return(df)
})
## bind all cols into single row data.frame 1 x length(stem_regex) & return
data.frame(res)
}
map_to_stem_df("addi")
# add mult
# 1 0
map_to_stem_df("additional")
# add mult
# 0 0