library(lda)
library(LDAvis)
library(text2vec)
library(parallel)
library(stringi)
library(topicmodels)

hacerLDA <- function(texto, paralelo = F,
                     lda.k = 40, lda.iter = 1000, lda.alpha = 0.5, lda.delta = 0.1,
                     vocab.minCount = 2, vocab.maxFreq = 0.3,
                     token = function(s){stri_split(str=s,regex="\\W+",omit_empty=T)}){
  # Crea el Vocabulario
  vocab = crearVocab(texto, paralelo = paralelo,
                     minCount = vocab.minCount, maxFreq = vocab.maxFreq,
                     token = token)
  
  # Crea la matriz DTM
  dtm = crearDTM(texto, paralelo = paralelo, sparse = F,
                 vocab = vocab, peso = weightTf,
                 token = token)
  
  # Remuevo documentos sin palabras en el vocabulario
  dtm = dtm[rowSums(dtm)>0,]
  doc.length=rowSums(dtm)
  counts = vocab$vocab$terms_counts
  
  # Entreno el modelo Dirichlet-Multinomial
  lda = LDA(dtm, k = lda.k, method = 'Gibbs',
            control = list(iter = lda.iter, alpha = lda.alpha, delta = lda.delta))  
  return(list(lda,doc.length,counts))
}


crearVocab <- function(texto, paralelo = F,
                       minCount = 10, maxFreq = 0.3, ngramaMax = 1L,
                       token = function(s){stri_split(str=s,regex="\\W+",omit_empty=T)}){
  # Tokenización.
  if(paralelo){
    cl = makeCluster(detectCores())
    clusterExport(cl,'stri_split')
    tokens = parSapply(cl, texto, FUN = token, USE.NAMES = F)
    stopCluster(cl)
  }else{
    tokens = sapply(texto, FUN = token, USE.NAMES = F)
  }
  
  # Extracción de Vocabulario.
  v = create_vocabulary(itoken(tokens), ngram = c(ngram_min = 1L, ngram_max = ngramaMax))
  
  # Imputación de palabras excéntricas o muy frecuentes.
  v = prune_vocabulary(v, term_count_min = minCount, doc_proportion_max =  maxFreq)
  
  # Ordenar el vocabulario de acuerdo a frecuencia.
  v$vocab = v$vocab[order(v$vocab$terms_counts, decreasing = T),]
  return(v)
}

crearDTM <- function(texto, paralelo = F, sparse = F,
                     vocab, peso = weightTf,
                     token = function(s){stri_split(str=s,regex="\\W+",omit_empty=T)}){
  # Tokenización.
  if(paralelo){
    cl = makeCluster(detectCores())
    clusterExport(cl,'stri_split')
    tokens = parSapply(cl, texto, FUN = token, USE.NAMES = F)
    stopCluster(cl)
  }else{
    tokens = token(texto)
  }
  
  # Mapeo a matriz DTM.
  it = itoken(tokens)
  vectorizer = vocab_vectorizer(vocab)
  
  # Creación de DTM con text2vec.
  dtm = create_dtm(it, vectorizer,stopwords= stopwords("es"))
  
  # Ponderación con tm, se podría hacer con text2vec.
  dtm = as.DocumentTermMatrix(dtm, weighting = peso)
  
  if(!sparse){
    dtm = as.matrix(dtm)
  }
  return(dtm)
}


punto3 = tolower(rawPuntos$p3)
punto3 = gsub(pattern = "-|/as",replacement = "",punto3)

modelo = hacerLDA(texto = punto3,lda.k = 15)
doc.length = modelo[[2]]
term.freq = modelo[[3]]
modelo= modelo[[1]]
library(dplyr)

# Find required quantities
phi <- posterior(modelo)$terms %>% as.matrix
theta <- posterior(modelo)$topics %>% as.matrix
vocab <- colnames(phi)


# Convert to json
json_lda <- LDAvis::createJSON(phi = phi, theta = theta,
                               vocab = vocab,
                               doc.length = doc.length,
                               term.frequency = term.freq)

serVis(json_lda,open.browser = T)
