Yo estoy haciendo un montón de análisis con el TM paquete. Uno de mis mayores problemas están relacionados con derivados y derivados-como las transformaciones.

Digamos que tengo varias de la contabilidad de términos relacionados (soy consciente de los problemas de ortografía).

Después de frenar tenemos:

accounts   -> account  
account    -> account  
accounting -> account  
acounting  -> acount  
acount     -> acount  
acounts    -> acount  
accounnt   -> accounnt  

Resultado: 3 Términos (cuenta, cuenta, cuenta) donde me hubiera gustado 1 (cuenta) ya que todos estos se relacionan con el mismo término.

1) Para corregir la ortografía es una posibilidad, pero nunca he intentado que en R. Es que incluso posible?

2) La otra opción es hacer una lista de referencias, es decir, de la cuenta = (cuentas, cuentas, contabilidad, acounting, acount, acounts, accounnt) y, a continuación, reemplazar todas las ocurrencias con el término maestro. ¿Cómo puedo hacer esto en R?

Una vez más, cualquier ayuda/sugerencia sería muy apreciada.

InformationsquelleAutor RUser | 2014-06-27

3 Comentarios

  1. 13

    Podemos configurar una lista de sinónimos y reemplazar esos valores. Por ejemplo

    synonyms <- list(
        list(word="account", syns=c("acount", "accounnt"))
    )

    Este dice que quiere sustituir a «cuenta» y «accounnt» con «cuenta» (estoy asumiendo que estamos haciendo esto después de lematización). Ahora vamos a crear datos de prueba.

    raw<-c("accounts", "account", "accounting", "acounting", 
         "acount", "acounts", "accounnt")

    Y ahora vamos a definir una función de transformación que va a sustituir las palabras en nuestra lista con el principal sinónimo.

    library(tm)
    replaceSynonyms <- content_transformer(function(x, syn=NULL) { 
        Reduce(function(a,b) {
            gsub(paste0("\b(", paste(b$syns, collapse="|"),")\b"), b$word, a)}, syn, x)   
    })

    Aquí se utiliza el content_transformer función para definir una transformación personalizada. Y, básicamente, acabamos de hacer un gsub para reemplazar cada una de las palabras. A continuación, podemos utilizar esto en un corpus

    tm <- Corpus(VectorSource(raw))
    tm <- tm_map(tm, stemDocument)
    tm <- tm_map(tm, replaceSynonyms, synonyms)
    inspect(tm)

    y podemos ver todos estos valores son transformados en «cuenta» como se desee. Agregar otros sinónimos, sólo tiene que añadir listas adicionales a la principal synonyms lista. Cada sub-lista debe tener los nombres de «palabra» y «solicitudes de syn».

    • Genial, esto debería funcionar para mí, pero tengo que compilar las listas manualmente – que está bien. Mucho más control que antes. Gracias!
    • Prueba esta en mis datos en vivo – Funciona como un encanto! La parte difícil es, en primer lugar identificar la palabra variantes y, a continuación, hacer de alguna manera el edificio de la lista de la parte más fácil/automatizado.
  2. 8

    Señor Flick ha respondido a la pregunta #2. Me estoy acercando a través de responder a la pregunta #1.

    Aquí es un enfoque de los usos de un binario de búsqueda de una palabra conocida base de datos (DICTIONARY de qdapDictionaries). Una búsqueda binaria es lento, seguro, pero si podemos hacer algunas suposiciones acerca de la sustitución (como una serie de diferencias en número de caracteres). Así que aquí es la idea básica:

    1. Gire el Corpus en una única bolsa de palabras utilizando qdap‘s bag_o_words
    2. Buscar esas palabras en un diccionario (qdapDictionariesDICTIONARY conjunto de datos) para encontrar las palabras que no se reconoce el uso de match
      • Estos misses desde el paso # 2 será lo que nos de búsqueda
    3. Determinar el número de caracteres de las palabras en el diccionario para eliminar bruto diferencia más adelante el uso de nchar
    4. Ejecutar cada elemento de misses a través de un bucle (sapply) y hacer lo siguiente:

      una. madre de cada elemento de misses utilizando tm::stemDocument

      b. determinar el número de caracteres y eliminar aquellos de diccionario que no están dentro de ese rango el uso de nchar

      c. uso agrep con un max.distance para eliminar palabras del diccionario

      d. el uso de una búsqueda binaria (que invertir ingenieros agrep) para determinar la palabra de diccionario que es la más cercana a la perdida elemento [nota: esta no es una función exportada desde qdap llamado qdap:::Ldist]
    5. El resultado es un vector que podemos utilizar para gsubbing
    6. Uso tm_map con una costumbre tm con sabor a gsub función para reemplazar palabras
    7. Hacer la lematización con tm_map y stemDocument

    Aquí está el código. He hecho una falsa Corpus el uso de las palabras que usted proporciona y algunas palabras al azar para demostrar cómo hacerlo desde el inicio hasta el final. Usted puede jugar con range y max.distance que se suministra a sapply. El perdedor de usted con estas la más lenta la búsqueda será pero tightiening estas demasiado hará que sea más probable cometer un error. Esto realmente no es una respuesta para la corrección ortográfica en un sentido general, sino que trabaja aquí porque fueron derivados de todos modos. Hay un Aspell paquete, pero nunca lo he usado antes.

    terms <- c("accounts", "account", "accounting", "acounting", "acount", "acounts", "accounnt")
    
    library(tm); library(qdap)
    
    fake_text <- unlist(lapply(terms, function(x) {
        paste(sample(c(x, sample(DICTIONARY[[1]], sample(1:5, 1)))), collapse=" ")
    }))
    
    fake_text
    
    myCorp <- Corpus(VectorSource(fake_text))
    terms2 <- unique(bag_o_words(as.data.frame(myCorp)[[2]]))
    misses <- terms2[is.na(match(terms2, DICTIONARY[[1]]))]
    
    chars <- nchar(DICTIONARY[[1]])
    
    replacements <- sapply(misses, function(x, range = 3, max.distance = .2) {
        x <- stemDocument(x)
        wchar <- nchar(x)
        dict <- DICTIONARY[[1]][chars >= (wchar - range) & chars <= (wchar + range)]
        dict <- dict[agrep(x, dict, max.distance=max.distance)]
        names(which.min(sapply(dict, qdap:::Ldist, x)))
    })
    
    replacer <- content_transformer(function(x) { 
        mgsub(names(replacements), replacements, x, ignore.case = FALSE, fixed = FALSE)
    })
    
    myCorp <- tm_map(myCorp, replacer)
    inspect(myCorp <- tm_map(myCorp, stemDocument))
    • Gracias Tyler, por ahora creo que es más fácil para mí hacer uso de MrFlick la solución, ya que tengo mucho más control sobre él, PERO me han puesto en un par de ideas y paquetes para explorar, gracias por tu solución!
  3. 7

    Esta pregunta me inspiró a intentar escribir un corrector ortográfico para el qdap paquete. Hay una versión interactiva que puede ser útil aquí. Está disponible en qdap >= version 2.1.1. Eso significa que usted necesitará el dev versión en el momento.. aquí están los pasos para instalar:

    library(devtools)
    install_github("qdapDictionaries", "trinker")
    install_github("qdap", "trinker")
    library(tm); library(qdap)

    ## Recrear un Corpus como la que usted describe.

    terms <- c("accounts", "account", "accounting", "acounting", "acount", "acounts", "accounnt")
    
    fake_text <- unlist(lapply(terms, function(x) {
        paste(sample(c(x, sample(DICTIONARY[[1]], sample(1:5, 1)))), collapse=" ")
    }))
    
    fake_text
    
    inspect(myCorp <- Corpus(VectorSource(fake_text)))

    ## Interactivo corrector ortográfico (check_spelling_interactive)

    m <- check_spelling_interactive(as.data.frame(myCorp)[[2]])
    preprocessed(m)
    inspect(myCorp <- tm_map(myCorp, correct(m)))

    La correct función simplemente agarra un cierre a la función de la salida de check_spelling_interactive y le permite aplicar a continuación la «corrección» a cualquier nueva cadena de texto(s).

Dejar respuesta

Please enter your comment!
Please enter your name here