Analisando dados rtweet com Kerasformula


Visão geral

O kerasformula o pacote oferece uma interface de alto nível para a interface R para Keras. Sua interface principal é o kms função, uma interface no estilo de regressão para keras_model_sequential que usa fórmulas e matrizes esparsas.

O pacote Kerasformula está disponível em Cran e pode ser instalado com:

# set up the kerasformula bundle
set up.packages("kerasformula")    
# or devtools::install_github("rdrr1990/kerasformula")

library(kerasformula)

# set up the core keras library (if you have not already finished so)
# see ?install_keras() for choices e.g. install_keras(tensorflow = "gpu")
install_keras()

A função kms ()

Muitos tutoriais clássicos de aprendizado de máquina assumem que os dados vêm de uma forma relativamente homogênea (por exemplo, pixels para reconhecimento de dígitos ou contagem ou classificação de palavras) que podem tornar a codificação um pouco complicada quando os dados estão contidos em um quadro de dados heterogêneos. kms() Aproveite a flexibilidade das fórmulas R para suavizar esse processo.

kms Construa redes neurais densas e, depois de ajustá -las, retorna um único objeto com previsões, medidas de ajuste e detalhes sobre a chamada de função. kms aceita vários parâmetros, incluindo as funções de perda e ativação encontradas em keras. kms também aceita compilado keras_model_sequential objetos que permitem ainda mais personalização. Esta pequena demonstração mostra como kms pode ajudar é a construção de modelos e seleção de hiperparâmetro (por exemplo, tamanho do lote), começando com dados brutos coletados usando library(rtweet).

Vejamos o #RSTATS Tweets (excluindo retweets) por um período de seis dias encerrado em 24 de janeiro de 2018 às 10:40. Isso nos dá um bom número razoável de observações para trabalhar em termos de tempo de execução (e o objetivo deste documento é mostrar sintaxe, não construir modelos particularmente preditivos).

rstats <- search_tweets("#rstats", n = 10000, include_rts = FALSE)
dim(rstats)
  (1) 2840   42

Suponha que nosso objetivo seja prever como os tweets populares serão baseados na frequência com que o tweet foi retweetado e favorito (que se correlaciona fortemente).

cor(rstats$favorite_count, rstats$retweet_count, methodology="spearman")
    (1) 0.7051952

Como poucas pistas se tornam virais, os dados são bastante distorcidos em direção a zero.

Analisando dados rtweet com Kerasformula

Tirando o máximo das fórmulas

Suponhamos que estamos interessados em colocar tweets em categorias com base na popularidade, mas não temos certeza de quão finamente grave queremos fazer distinções. Alguns dos dados, como rstats$mentions_screen_name Vem em uma lista de comprimentos variados, então vamos escrever uma função auxiliar para contar entradas não-NA.

Vamos começar com uma densa rede neural, o padrão de kms. Podemos usar as funções B base para ajudar a limpar os dados – neste caso, minimize para discretizar o resultado, grepl procurar palavras -chave e weekdays e format Para capturar diferentes aspectos da época em que o tweet foi publicado.

breaks <- c(-1, 0, 1, 10, 100, 1000, 10000)
recognition <- kms(minimize(retweet_count + favorite_count, breaks) ~ screen_name + 
                  supply + n(hashtags) + n(mentions_screen_name) + 
                  n(urls_url) + nchar(textual content) +
                  grepl('picture', media_type) +
                  weekdays(created_at) + 
                  format(created_at, '%H'), rstats)
plot(recognition$historical past) 
  + ggtitle(paste("#rstat recognition:", 
            paste0(spherical(100*recognition$evaluations$acc, 1), "%"),
            "out-of-sample accuracy")) 
  + theme_minimal()

recognition$confusion

recognition$confusion

                    (-1,0) (0,1) (1,10) (10,100) (100,1e+03) (1e+03,1e+04)
      (-1,0)            37    12     28        2           0             0
      (0,1)             14    19     72        1           0             0
      (1,10)             6    11    187       30           0             0
      (10,100)           1     3     54       68           0             0
      (100,1e+03)        0     0      4       10           0             0
      (1e+03,1e+04)      0     0      0        1           0             0

O modelo classifica apenas cerca de 55% dos dados fora da amostra corretamente e que a precisão preditiva não melhora após as dez primeiras épocas. A matriz de confusão sugere que o modelo se sai melhor com tweets que são retweetados algumas vezes, mas superestam o nível 1-10. O historical past O enredo também sugere que a precisão fora da amostra não é muito estável. Podemos alterar facilmente os pontos de interrupção e o número de épocas.

breaks <- c(-1, 0, 1, 25, 50, 75, 100, 500, 1000, 10000)
recognition <- kms(minimize(retweet_count + favorite_count, breaks) ~  
                  n(hashtags) + n(mentions_screen_name) + n(urls_url) +
                  nchar(textual content) +
                  screen_name + supply +
                  grepl('picture', media_type) +
                  weekdays(created_at) + 
                  format(created_at, '%H'), rstats, Nepochs = 10)

plot(recognition$historical past) 
  + ggtitle(paste("#rstat recognition (new breakpoints):",
            paste0(spherical(100*recognition$evaluations$acc, 1), "%"),
            "out-of-sample accuracy")) 
  + theme_minimal()

Isso ajudou alguns (cerca de 5% de precisão preditiva adicional). Suponha que queremos adicionar um pouco mais de dados. Vamos primeiro armazenar a fórmula de entrada.

pop_input <- "minimize(retweet_count + favorite_count, breaks) ~  
                          n(hashtags) + n(mentions_screen_name) + n(urls_url) +
                          nchar(textual content) +
                          screen_name + supply +
                          grepl('picture', media_type) +
                          weekdays(created_at) + 
                          format(created_at, '%H')"

Aqui usamos paste0 Para adicionar à fórmula, loop sobre os IDs de usuário adicionando algo como:

grepl("12233344455556", mentions_user_id)
mentions <- unlist(rstats$mentions_user_id)
mentions <- distinctive(mentions(which(desk(mentions) > 5))) # take away rare
mentions <- mentions(!is.na(mentions)) # drop NA

for(i in mentions)
  pop_input <- paste0(pop_input, " + ", "grepl(", i, ", mentions_user_id)")

recognition <- kms(pop_input, rstats)

Isso ajudou um toque, mas a precisão preditiva ainda é bastante instável em épocas …

Camadas de personalização com KMS ()

Poderíamos adicionar mais dados, talvez adicionar palavras individuais do texto ou alguma outra estatística de resumo (imply(textual content %in% LETTERS) para ver se todos os caps explica popularidade). Mas vamos alterar a rede neural.

O enter.system é usado para criar uma matriz de modelo esparsa. Por exemplo, rstats$supply (Tipo de aplicativo do Twitter ou Twitter-Shopper) e rstats$screen_name são vetores de personagens que serão divididos. Quantas colunas ele tem?

    (1) 1277

Digamos que queríamos remodelar as camadas para fazer a transição mais gradualmente da forma de entrada para a saída.

recognition <- kms(pop_input, rstats,
                  layers = record(
                    models = c(1024, 512, 256, 128, NA),
                    activation = c("relu", "relu", "relu", "relu", "softmax"), 
                    dropout = c(0.5, 0.45, 0.4, 0.35, NA)
                  ))

kms constrói a keras_sequential_model()que é uma pilha de camadas lineares. A forma de entrada é determinada pela dimensionalidade da matriz do modelo (recognition$P) Mas depois disso os usuários são gratuitos para determinar o número de camadas e assim por diante. O kms argumento layers espera uma lista, cuja primeira entrada é um vetor models com o que ligar keras::layer_dense(). O primeiro elemento o número de models Na primeira camada, o segundo elemento da segunda camada e assim por diante (NA Como o elemento remaining se conecta para detectar automaticamente o número remaining de unidades com base no número observado de resultados). activation também é passado para layer_dense() e pode levar valores como softmaxAssim, reluAssim, elue linear. (kms Também possui um parâmetro separado para controlar o otimizador; por padrão kms(... optimizer="rms_prop").) O dropout Isso segue cada taxa de camada densa impede o excesso de ajuste (mas é claro que não é aplicável à camada remaining).

Escolhendo um tamanho de lote

Por padrão, kms Usa lotes de 32. Suponha que estivéssemos felizes com o nosso modelo, mas não tivemos nenhuma intuição específica sobre qual deveria ser o tamanho.

Nbatch <- c(16, 32, 64)
Nruns <- 4
accuracy <- matrix(nrow = Nruns, ncol = size(Nbatch))
colnames(accuracy) <- paste0("Nbatch_", Nbatch)

est <- record()
for(i in 1:Nruns){
  for(j in 1:size(Nbatch)){
   est((i)) <- kms(pop_input, rstats, Nepochs = 2, batch_size = Nbatch(j))
   accuracy(i,j) <- est((i))(("evaluations"))(("acc"))
  }
}
  
colMeans(accuracy)
    Nbatch_16 Nbatch_32 Nbatch_64 
    0.5088407 0.3820850 0.5556952 

Por uma questão de reduzir o tempo de execução, o número de épocas foi definido arbitrariamente curto, mas, a partir desses resultados, 64 é o melhor tamanho em lote.

Fazendo previsões para novos dados

Até agora, estamos usando as configurações padrão para kms que primeiro divide os dados em 80% de treinamento e 20% de testes. Do treinamento de 80%, uma certa parte é reservada para validação e é isso que produz os gráficos de perda e precisão da época. Os 20% são usados apenas no remaining para avaliar a precisão preditiva. Mas suponha que você queira fazer previsões em um novo conjunto de dados…

recognition <- kms(pop_input, rstats(1:1000,))
predictions <- predict(recognition, rstats(1001:2000,))
predictions$accuracy
    (1) 0.579

Como a fórmula cria uma variável dummy para cada nome de tela e menção, qualquer conjunto de tweets é quase garantido para ter colunas diferentes. predict.kms_fit é um S3 methodology Isso pega os novos dados e constrói uma matriz modelo (esparsa) que preserva a estrutura unique da matriz de treinamento. predict Em seguida, retorna as previsões junto com uma matriz de confusão e pontuação de precisão.

Se o seu newData tiver os mesmos níveis observados de y e colunas de x_train (a matriz do modelo), você também pode usar keras::predict_classes sobre object$mannequin.

Usando um modelo de Keras compilado

Esta seção mostra como inserir um modelo compilado da maneira típica de library(keras)que é útil para modelos mais avançados. Aqui está um exemplo para lstm análogo ao IMBD com exemplo de Keras.

okay <- keras_model_sequential()
okay %>%
  layer_embedding(input_dim = recognition$P, output_dim = recognition$P) %>% 
  layer_lstm(models = 512, dropout = 0.4, recurrent_dropout = 0.2) %>% 
  layer_dense(models = 256, activation = "relu") %>%
  layer_dropout(0.3) %>%
  layer_dense(models = 8, # variety of ranges noticed on y (final result)  
              activation = 'sigmoid')

okay %>% compile(
  loss = 'categorical_crossentropy',
  optimizer = 'rmsprop',
  metrics = c('accuracy')
)

popularity_lstm <- kms(pop_input, rstats, okay)

Deixe -me uma linha através do projeto Repo Github. Agradecimentos especiais a @dfalbel e @jjallaire Para sugestões úteis !!

Deixe um comentário

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *