# install.packages("NLP")
library(NLP)
library(tm)
library(NLP)
library(tm)
El manejo de datos tipo
cadenas, son complejos y requiere mucha reflexión y esfuerzo. Uno tiene que
considerar cómo quitar números y puntuación; encargarse de palabras poco
interesantes como: y, pero, y o; y cómo separar las oraciones en palabras
individuales (tokenization).
Afortunadamente, esta
funcionalidad ha sido proporcionada por los miembros de la comunidad R en un
paquete de minería de texto titulado tm. En el siguiente ejemplo se colocan los
datos de forma tal que data observación corresponden a un elemento de lista.
Para ver el texto del
mensaje real, la función as.character () debe aplicarse a los mensajes
deseados. Para ver un mensaje, use la función as.character () en un solo
elemento de lista, que señala que se requiere la notación de doble corchete:
texto
<- c("Todos somos
responsables de nuestros hechos. 17?",
"Los recursos humanos suelen ser formados por un hombre",
"Conozco al hombre y amo a sus perro")
sms_corpus <- VCorpus(VectorSource(texto))
inspect(sms_corpus[1:2])
"Los recursos humanos suelen ser formados por un hombre",
"Conozco al hombre y amo a sus perro")
sms_corpus <- VCorpus(VectorSource(texto))
inspect(sms_corpus[1:2])
as.character(sms_corpus[[1]])
## [1] "Todos somos responsables de nuestros hechos. 17?"
lapply(sms_corpus[1:2], as.character)
## $`1`
## [1] "Todos somos responsables de nuestros hechos. 17?"
##
## $`2`
## [1] "Los recursos humanos suelen ser formados por un hombre"
## [1] "Todos somos responsables de nuestros hechos. 17?"
##
## $`2`
## [1] "Los recursos humanos suelen ser formados por un hombre"
Debido a que tm
corpus es esencialmente una lista compleja, podemos usar las operaciones de
lista para seleccionar documentos en el corpus. Para recibir un resumen de
mensajes específicos, podemos usar la función inspect() con operadores de
listas. Por ejemplo, el siguiente comando verá un resumen de los mensajes SMS
primero y segundo:
inspect(sms_corpus)
##
<<VCorpus>>
## Metadata: corpus specific: 0, document level (indexed): 0
## Content: documents: 3
##
## [[1]]
## <<PlainTextDocument>>
## Metadata: 7
## Content: chars: 48
##
## [[2]]
## <<PlainTextDocument>>
## Metadata: 7
## Content: chars: 54
##
## [[3]]
## <<PlainTextDocument>>
## Metadata: 7
## Content: chars: 35
## Metadata: corpus specific: 0, document level (indexed): 0
## Content: documents: 3
##
## [[1]]
## <<PlainTextDocument>>
## Metadata: 7
## Content: chars: 48
##
## [[2]]
## <<PlainTextDocument>>
## Metadata: 7
## Content: chars: 54
##
## [[3]]
## <<PlainTextDocument>>
## Metadata: 7
## Content: chars: 35
Para realizar
nuestro análisis, necesitamos dividir estos mensajes en palabras individuales.
Pero primero, tenemos que limpiar el texto, para estandarizar las palabras,
eliminando la puntuación y otros caracteres que saturan el resultado. Por
ejemplo, nos gustaría que las cadenas Hello, HELLO y hello se cuenten como
instancias de la misma palabra. La función tm_map () proporciona un método para
aplicar una transformación (también conocida como mapeo) a un cuerpo de tm.
Usaremos esta función para limpiar nuestro corpus mediante una serie de
transformaciones y guardar el resultado en un nuevo objeto llamado corpusclean.
sms_corpus_clean
<- tm_map(sms_corpus, content_transformer(tolower))
as.character(sms_corpus[[1]])
as.character(sms_corpus[[1]])
## [1] "Todos somos responsables de nuestros hechos. 17?"
as.character(sms_corpus_clean[[1]])
## [1] "todos somos responsables de nuestros hechos. 17?"
Continuemos nuestra
limpieza eliminando números de los mensajes SMS. Aunque algunos números pueden
proporcionar información útil, la mayoría probablemente sea única para los
remitentes individuales y, por lo tanto, no proporcionará patrones útiles en
todos los mensajes. Con esto en mente, eliminaremos todos los números del
corpus de la siguiente manera:
sms_corpus_clean
<- tm_map(sms_corpus_clean, removeNumbers)
as.character(sms_corpus[[1]])
as.character(sms_corpus[[1]])
## [1] "Todos somos responsables de nuestros hechos. 17?"
as.character(sms_corpus_clean[[1]])
## [1] "todos somos responsables de nuestros hechos. ?"
Nuestra siguiente
tarea es eliminar las palabras de relleno como, y, pero, y / o de nuestros
mensajes SMS. Estos términos se conocen como palabras de detención y
generalmente se eliminan antes de la minería de texto. Esto se debe al hecho de
que, aunque aparecen con mucha frecuencia, no proporcionan mucha información
útil para el aprendizaje automático.
#stopwords("english")
sms_corpus_clean <- tm_map(sms_corpus_clean,removeWords, stopwords("spanish"))
as.character(sms_corpus[[1]])
sms_corpus_clean <- tm_map(sms_corpus_clean,removeWords, stopwords("spanish"))
as.character(sms_corpus[[1]])
## [1] "Todos somos responsables de nuestros hechos. 17?"
as.character(sms_corpus_clean[[1]])
## [1] " responsables hechos. ?"
Continuando con
nuestro proceso de limpieza, también podemos eliminar cualquier puntuación de
los mensajes de texto usando la transformación incorporada removePunctuation
():
sms_corpus_clean
<- tm_map(sms_corpus_clean, removePunctuation)
as.character(sms_corpus[[1]])
as.character(sms_corpus[[1]])
## [1] "Todos somos responsables de nuestros hechos. 17?"
as.character(sms_corpus_clean[[1]])
## [1] " responsables hechos "
A continuación de
utiliza el concepto wordStem, este, lo que hace es colocar los diferencies
variantes de una palabra, como para considerarla partes de una misma palabras.
#
install.packages("SnowballC")
library(SnowballC)
library(SnowballC)
wordStem(c("aprender", "aprendiendo", "aprendió"),
"spanish")
## [1]
"aprend" "aprend" "aprend"
#sms_corpus_clean
<- tm_map(sms_corpus_clean, stemDocument, "spanish")
El último paso en
nuestro proceso de limpieza de texto es eliminar espacios en blanco
adicionales, utilizando stripWhitespace ():
sms_corpus_clean
<- tm_map(sms_corpus_clean, stripWhitespace)
as.character(sms_corpus[[1]])
as.character(sms_corpus[[1]])
## [1] "Todos somos responsables de nuestros hechos. 17?"
as.character(sms_corpus_clean[[1]])
## [1] " responsables hechos "
Ahora que los datos
se procesan a nuestro gusto, el paso final es dividir los mensajes en
componentes individuales a través de un proceso llamado tokenización. Un token
es un elemento único de una cadena de texto; en este caso, los tokens son
palabras. El paquete tm proporciona funcionalidad para tokenizar el cuerpo del
mensaje SMS. La función DocumentTermMatrix () tomará un corpus y creará una
estructura de datos llamada Document Term Matrix (DTM) en la que las filas
indican documentos (mensajes SMS) y las columnas indican términos (palabras).
sms_dtm <- DocumentTermMatrix(sms_corpus_clean)
sms_dtm
sms_dtm
##
<<DocumentTermMatrix (documents: 3, terms: 11)>>
## Non-/sparse entries: 12/21
## Sparsity : 64%
## Maximal term length: 12
## Weighting : term frequency (tf)
## Non-/sparse entries: 12/21
## Sparsity : 64%
## Maximal term length: 12
## Weighting : term frequency (tf)
Una alternativa al proceso anterior:
sms_dtm2 <- DocumentTermMatrix(sms_corpus,
control = list(
tolower = TRUE,
removeNumbers = TRUE,
stopwords = TRUE,
removePunctuation = TRUE,
stemming = TRUE
)
)
control = list(
tolower = TRUE,
removeNumbers = TRUE,
stopwords = TRUE,
removePunctuation = TRUE,
stemming = TRUE
)
)
findFreqTerms(sms_dtm2)
## [1] "amo" "conozco" "formado"
"hecho"
"hombr"
"humano"
"los"
## [8] "nuestro" "perro" "por" "recurso" "respons" "ser" "somo"
## [15] "suelen" "sus" "todo"
## [8] "nuestro" "perro" "por" "recurso" "respons" "ser" "somo"
## [15] "suelen" "sus" "todo"
Finalmente, la "tokenización" de los datos se puede obtener utilizando el comando inspect:
inspect(sms_dtm2)
## <<DocumentTermMatrix (documents: 3, terms: 17)>>
## Non-/sparse entries: 18/33
## Sparsity : 65%
## Maximal term length: 7
## Weighting : term frequency (tf)
## Sample :
## Terms
## Docs amo conozco formado hecho hombr humano los nuestro perro por
## 1 0 0 0 1 0 0 0 1 0 0
## 2 0 0 1 0 1 1 1 0 0 1
## 3 1 1 0 0 1 0 0 0 1 0
## Non-/sparse entries: 18/33
## Sparsity : 65%
## Maximal term length: 7
## Weighting : term frequency (tf)
## Sample :
## Terms
## Docs amo conozco formado hecho hombr humano los nuestro perro por
## 1 0 0 0 1 0 0 0 1 0 0
## 2 0 0 1 0 1 1 1 0 0 1
## 3 1 1 0 0 1 0 0 0 1 0
Y finalmente, convertir los datos en un data.frame:
datos<-data.frame(inspect(sms_dtm2))
datos
## amo conozco formado hecho hombr
humano los nuestro perro por
## 1 0 0 0 1 0 0 0 1 0 0
## 2 0 0 1 0 1 1 1 0 0 1
## 3 1 1 0 0 1 0 0 0 1 0
## 1 0 0 0 1 0 0 0 1 0 0
## 2 0 0 1 0 1 1 1 0 0 1
## 3 1 1 0 0 1 0 0 0 1 0
Ahora, realizamos una nube de puntos con la frecuencia de cada variable:
#
install.packages("wordcloud")
library(wordcloud)
library(wordcloud)
wordcloud(sms_corpus_clean, min.freq = 1, random.order = FALSE)
Referencia:
Lantz, Brent (2013). Machine Learning with R. Packt Publishing Ltd. ISBN 978-1-78216-214-8.