Mostrando entradas con la etiqueta Data Minig. Mostrar todas las entradas
Mostrando entradas con la etiqueta Data Minig. Mostrar todas las entradas

30 dic 2020

Curso de Análisis estadístico en R

La siguiente entrada contiene un curso de Métodos Estadístico de Investigación en R, usando los fundamentos del tidyverso para la manipulación y comunicación de datos. 

Parte I. Análisis exploratorio en R
Clase 1.0. pdf. video. Introducción a R
Clase 1.1. pdf. video. Estructura de datos (tomado del curso de Derek Corcoran)

Clase 2.1. pdf. video. Análisis exploratorio: posición central y dispersión


Clase 2.2. pdf. video. Análisis exploratorio: posición (quintiles), distribuciones y asociación


Clase 2.3. pdf. video. 
Análisis exploratorio: datos perdidos y valores atípicos
Clase 2.4. pdf. video. Tablas en R


Parte II. Manipulación y comunicación de datos en R
Clase 3.1. pdf. video. Manipulando datos usando dplyr I (select, filter, mutate)


Clase 3.2. pdf. video. Manipulando datos usando dplyr I (summarize, by_group, accros, if, at)
Clase 3.3. pdf. video. Ejercicios usando dplyr


Clase 4.1.
pdf. video. Comunicación de datos con ggplot2 y rmakdowm
Clase 4.2. pdf. video. Ejercicios con ggplot2


Clase 5.1.
 pdf. video. Gestión de datos relacionales en R (join, reshape, long, wide)


Parte III. Inferencia estadística y nociones de ciencia de datos en R
Clase 6.1. pdf. video. Repaso de inferencia estadística
Clase 6.2. pdf. video. Análisis de independencia estadística en R
Clase 6.3. pdf. video. Ejercicios aplicados a independencia y datos relacionales 


Clase 7.1. pdf. video. Métodos de clasificación en R (Statistical Learning)
Clase 8.1. pdf. video. Modelos de regresión y aprendizaje supervisado


Parte IV. Análisis de series temporales
Clase 9.1.   pdf. video. Exploración y agregación
Clase 10.1. pdf. video. Estacionariedad y modelos ARIMA
Clase 10.2. pdf. video. Ejericicios
Clase 11.1. pdf. video. Pronóstico
Clase 12.1. pdf. video. Modelos de volatilidad (GARCH)
Clase 12.2. pdf. video. Markov GARCH

29 mar 2019

Tidyverse y minería de datos en R: estimar regresiones por grupos

La siguiente entrada utiliza la potente librería tidyverse, de R, para estimar regresiones por grupo. Para el siguiente ejemplo se utiliza la base  bwght del libro de wooldridge.

library(tidyverse); library(purrr)
library(wooldridge)
attach(bwght)

En primer lugar, indicamos la base de datos con la que deseamos trabajar (bwght %>%); posteriormente, le indicamos para cuales grupos específicos requerimos estimar nuestra regresiones (split(.$white) %>%). En este caso, se desea repetir la estimación para cada grupo, según color de la piel; finalmente, especificamos la regresión que deseamos estimar (map(~ lm(lbwght ~ cigprice+faminc, data = .)) %>%) ayudados por la funciones map y lm; y llamamos la tradicional salida de la regresión de R (map(summary)). Note, que la regresión propuesta se estima para cada una de las categorías indicadas en la variable White.

bwght %>%
  split(.$white) %>%
  map(~ lm(lbwght ~ cigprice+faminc, data = .)) %>%
  map(summary)

$`0`

Call:
lm(formula = lbwght ~ cigprice + faminc, data = .)

Residuals:
     Min       1Q   Median       3Q      Max
-1.57471 -0.11323  0.02753  0.15088  0.48549

Coefficients:
             Estimate Std. Error t value Pr(>|t|)   
(Intercept) 4.522e+00  1.706e-01  26.503   <2e-16 ***
cigprice    1.483e-03  1.327e-03   1.117    0.265   
faminc      2.742e-05  8.369e-04   0.033    0.974   
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 0.2212 on 296 degrees of freedom
Multiple R-squared:  0.004233, Adjusted R-squared:  -0.002495
F-statistic: 0.6292 on 2 and 296 DF,  p-value: 0.5337


$`1`

Call:
lm(formula = lbwght ~ cigprice + faminc, data = .)

Residuals:
     Min       1Q   Median       3Q      Max
-1.21048 -0.08434  0.01967  0.11253  0.81989

Coefficients:
             Estimate Std. Error t value Pr(>|t|)   
(Intercept) 4.7104582  0.0692942  67.978  < 2e-16 ***
cigprice    0.0002696  0.0005266   0.512  0.60876   
faminc      0.0008468  0.0002940   2.880  0.00406 **
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 0.1789 on 1086 degrees of freedom
Multiple R-squared:  0.00803,  Adjusted R-squared:  0.006204
F-statistic: 4.396 on 2 and 1086 DF,  p-value: 0.01255

En el segundo ejemplo, únicamente se agrega la función map_dbl, para llamar un estadístico específico de los calculados por R de forma automática. En este ejemplo se llama el R cuadrado (map_dbl("r.squared")).  

# Ejemplo: obtiene el R2 para cada grupo
bwght %>%
  split(.$white) %>%
  map(~ lm(lbwght ~ cigprice+faminc, data = .)) %>%
  map(summary) %>%
  map_dbl("r.squared")

En caso de desear ver cómo saber cuáles estadísticos podemos llamar:

models1<-lm(lbwght ~ cigprice+faminc)
summary(models1)
ames(summary(models1))

> names( summary(models1))
 [1] "call"          "terms"         "residuals"     "coefficients"  "aliased"       "sigma"        

 [7] "df"            "r.squared"     "adj.r.squared" "fstatistic"    "cov.unscaled" 

1 mar 2019

Minería de texto: limpiar, estandarizar y “tokenizar” datos de texto en R

# install.packages("tm")
# install.packages("NLP")
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])

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"

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

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]])
## [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]])
## [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]])
## [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]])
## [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)

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]])
## [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

## <<DocumentTermMatrix (documents: 3, terms: 11)>>
## 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
                         )
                       )
findFreqTerms(sms_dtm2)
##  [1] "amo"     "conozco" "formado" "hecho"   "hombr"   "humano"  "los"   
##  [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

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

Ahora, realizamos una nube de puntos con la frecuencia de cada variable:

# install.packages("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. 


Estimación del modelo HP mediante máxima verosimilitud

El filtro de Hodrick–Prescott (HP) se utiliza ampliamente para descomponer una serie macroeconómica en un componente cíclico y transitorio. ...