NOTAS:
Para mismo ejemplo en PYTHON, ver nota publicada AQUI
El excel con las imágenes se puede descargar AQUI
Para este ejemplo se utilizó la libreria tm_0.6-2
El proceso general sigue estos pasos:
1. Cargar Datos
Para este ejemplo, los datos se cargan de un archivo csv en Dropbox, el cual tiene dos columnas: el texto y la clase a predecir. Conceptualmente queda así:
2. Crear Corpus
El corpus es un conjunto de documentos, que pueden ser artículos periodísticos, noticias, currículos, tweets, chat, o cualquier colección de textos que se vaya a utilizar para predecir/clasificar. En este ejemplo se usan tweets, y la columna "texto" del csv será el corpus.
Una forma de crear el corpus en R es usando la libreria tm de la siguiente forma:
- Crear un objeto VectorSource que será el origen de datos que luego se utiliza para crear un corpus volatil o vcorpus
- Crear un objeto VCorpus que es un corpus que se guarda en memoria, con lo cual es volatil. En este objeto se considera cada observación (tweet para este ejemplo) como un documento. El origen de datos para crear un vcorpus siempre será un VectorSource.
Para detalle sobre estos objetos, ver Referencia No.2
Conceptualmente seria así:
3. Limpiar Corpus
Luego que se tiene el VCorpus, se procede "limpiar" el corpus de la siguiente forma:
- Se sustituyen los signos de puntuación por espacios (replacePunctuation)
- Se eliminan los numeros (removeNumbers)
- Se elimina el doble espacio (stripWhitespace)
- Se convierte en minúscula todas las palabras (tolower)
- Se sustituyen algunas palabras abreviadas (stri_replace_all_fixed)
- Se transforma en documento plano (PlainTextDocument). Esto para cuando se usan funciones que no retornan un TextDocuments. Para detalle ver Ref. Nro 3
- Se eliman los sufijos de las palabras usando el algoritmo PorterStemmer (stemDocument). Para detalle ver referencia Nro. 4
- Se eliminan palabras sin significados, como pronombres, preposiciones, etc. usando el stopwords o lista de palabras que trae la libreria tm (removeWords). Para detalle ver referencia Nro. 4
Conceptualmente sería asi:
4. Crear DocumentTermMatrix
Con la libreria tm se pueden crear dos objetos para analizar el documento:
- TermDocumentMatrix (TDM) donde las filas son los términos o palabras (token) y las columnas los documentos o tweet. Este objeto se usa para analizar frecuencia y asociación de palabras, es decir para "entender" el corpus.
- DocumentTermMatrix (DTM) donde las filas son los documentos o tweets y las columnas son los terminos o palabras (token). Para este ejemplo se usa la DTM para crear una matriz de datos que luego se usa para modelar el clasificador. En la creacion del DTM se eliman las palabras que solo tienen una ocurrencia, asi como las que tienen pocas letras. Para detalle ver pagina 37 de referencia nro 5. Para gráficos con TDM ver referencia Nro. 6
Conceptualmente los objetos quedan así:
5. Se crea una matriz
Se usa la DTM para crear la matriz a usar en el clasificador. Queda así:
6. Train Test
Se divide la matriz en dos set de datos: Train y Test, como tambien el vector de la clase para cada set
7. Modelo
Se usa SVM para crear el clasificador a partir del set de Train, quedando así:
8. Predicción
Se predice la clase en el set de Test. Luego se crea una matriz de confusion para evaluar el ajuste del modelo, quedando así:
R script:
# LIBRERIAS Y FUNCIONES libs<-c('tm','SnowballC','tm','e1071','randomForest','stringi') lapply(libs,require, character.only= TRUE) clean_corpus <- function(xcorpus){ # Se agregan palabras al stopword stopwords_new= c('amaz','amzn', 'amzns','amazon','amazonc', 'amazons' ,tm::stopwords('english')) # Para reemplar algunas palabras: xword <- c('goog', 'googleled', 'googlele', 'aapl', 'aples', 'apples', 'amz', 'amzz', 'amazonn','nflx') xtran <- c('google','google', 'google', 'apple', 'apple', 'apple', 'amazon', 'amazon','amazon','netflix') replacePunctuation <- content_transformer(function(x) {return (gsub("[[:punct:]]"," ", x))}) xcorpus = tm_map(xcorpus, replacePunctuation) xcorpus = tm_map(xcorpus, content_transformer(tm::removeNumbers)) xcorpus = tm_map(xcorpus,tm::stripWhitespace) xcorpus = tm_map(xcorpus,content_transformer(base::tolower)) xcorpus = tm_map(xcorpus, function(x) stringi::stri_replace_all_fixed(x, xword, xtran, vectorize_all = FALSE)) xcorpus = tm_map(xcorpus, PlainTextDocument) xcorpus = tm_map(xcorpus, stemDocument, language = "porter") xcorpus = tm_map(xcorpus,tm::removeWords,stopwords_new) return(xcorpus) } # 1. DATOS df <- read.csv("https://www.dropbox.com/s/qal9dawx67c66wj/amz3.csv?dl=1", sep=",") # 2. CREAR CORPUS vsource <- tm::VectorSource(df$texto) corpus <- tm::VCorpus(vsource) # 3. LIMPIAR CORPUS corpus <- clean_corpus(corpus) # 4. CREAR DocumentTermMatrix dtm <- DocumentTermMatrix(corpus, control = list( weight = weightTfIdf, bounds = list(global = c(2,Inf)), wordLengths=c(4,Inf) )) # 5. MATRIX mtx = as.matrix(dtm) # 6. TRAIN TEST n_train <- sample(nrow(mtx),nrow(mtx)*.7) xtrain <- mtx[n_train,] ytrain <- as.factor(df[n_train,"clase"]) xtest <- mtx[-n_train,] ytest <- as.factor(df[-n_train,"clase"]) # 7. MODELO modelo <- svm(x=xtrain, y=ytrain, kernel = 'linear', scale = FALSE) # 8. PREDICCION prediccion <- predict(modelo,xtest) (mc <- table(ytest,prediccion)) sum(diag(mc))/sum(mc) # OTROS findFreqTerms(dtm, dim(dtm)[1] * 0.05) # palabras repetidas en 5% de tweet findFreqTerms(dtm, lowfreq = 0, highfreq = 4 ) # palabras repetidas en 4 menos tweet
Referencia
1. http://web.letras.up.pt/bhsmaia/EDV/apresentacoes/Bradzil_Classif_withTM.pdf
2. http://stats.stackexchange.com/questions/164372/what-is-vectorsource-and-vcorpus-in-tm-text-mining-package-in-r
3. http://stackoverflow.com/questions/24191728/documenttermmatrix-error-on-corpus-argument
4. http://python-apuntes.blogspot.com.ar/2016/10/sentiment-analysis.html
5. https://cran.r-project.org/web/packages/tm/tm.pdf
6. http://stackoverflow.com/questions/23766124/colors-and-a-plotting-term-document-matrix
Saludos Enmanuel
ResponderEliminar¿Cómo agregarías un código para crear en este ejemplo un wordcloud?