#nltk.download()
mycorpus = nltk.corpus.reuters

"""
Explanation: Master Telefónica Big Data & Analytics
Prueba de Evaluación del  Tema 4:
Topic Modelling.
Date: 2016/04/10
Para realizar esta prueba es necesario tener actualizada la máquina virtual con la versión más reciente de MLlib.
Para la actualización, debe seguir los pasos que se indican a continuación:
Pasos para actualizar MLlib:


Entrar en la vm como root:
vagrant ssh
sudo bash 
Ir a /usr/local/bin


Descargar la última versión de spark desde la vm mediante 
wget http://www-eu.apache.org/dist/spark/spark-1.6.1/spark-1.6.1-bin-hadoop2.6.tgz


Desempaquetar: 
tar xvf spark-1.6.1-bin-hadoop2.6.tgz (y borrar el tgz)


Lo siguiente es un parche, pero suficiente para que funcione:
Guardar copia de spark-1.3: mv spark-1.3.1-bin-hadoop2.6/ spark-1.3.1-bin-hadoop2.6_old
Crear enlace a spark-1.6: ln -s spark-1.6.1-bin-hadoop2.6/ spark-1.3.1-bin-hadoop2.6


Librerías
Puede utilizar este espacio para importar todas las librerías que necesite para realizar el examen.
0. Adquisición de un corpus.
Descargue el contenido del corpus reuters de nltk.
import nltk
nltk.download()

Selecciona el identificador reuters.
End of explanation
"""


n_docs = 500000

filenames = mycorpus.fileids()
fn_train = [f for f in filenames if f[0:5]=='train']

corpus_text = [mycorpus.raw(f) for f in fn_train]

# Reduced dataset:
n_docs = min(n_docs, len(corpus_text))
corpus_text = [corpus_text[n] for n in range(n_docs)]

print 'Loaded {0} files'.format(len(corpus_text))

"""
Explanation: Para evitar problemas de sobrecarga de memoria, o de tiempo de procesado, puede reducir el tamaño el corpus, modificando el valor de la variable n_docs a continuación.
End of explanation
"""


corpusRDD = sc.parallelize(corpus_text, 4)
print "\nRDD created with {0} elements".format(corpusRDD.count())

"""
Explanation: A continuación cargaremos los datos en un RDD
End of explanation
"""


# Compute RDD replacing tokens by token_ids
corpus_sparseRDD = corpus_wcRDD2.map(lambda x: [(invD[t[0]], t[1]) for t in x])

# Convert list of tuplas into Vectors.sparse object.
corpus_sparseRDD = corpus_sparseRDD.map(lambda x: Vectors.sparse(n_tokens, x))
corpus4lda = corpus_sparseRDD.zipWithIndex().map(lambda x: [x[1], x[0]]).cache()

"""
Explanation: 1. Ejercicios
Ejercicio 1: (0.6 ptos) Preprocesamiento de datos.
Prepare los datos para aplicar un algoritmo de modelado de tópicos en pyspark. Para ello, aplique los pasos siguientes:

Tokenización: convierta cada texto a utf-8, y transforme la cadena en una lista de tokens.
Homogeneización: pase todas las palabras a minúsculas y elimine todos los tokens no alfanuméricos.
Limpieza: Elimine todas las stopwords utilizando el fichero de stopwords disponible en NLTK para el idioma inglés.

Guarde el resultado en la variable corpus_tokensRDD
Ejercicio 2:  (0.6 ptos) Stemming
Aplique un procedimiento de stemming al corpus, utilizando el SnowballStemmer de NLTK. Guarde el resultado en corpus_stemRDD.
Ejercicio 3:  (0.6 ptos) Vectorización
En este punto cada documento del corpus es una lista de tokens. 
Calcule un nuevo RDD que contenga, para cada documento, una lista de tuplas. La clave (key) de cada lista será un token y su valor el número de repeticiones del mismo en el documento. 
Imprima una muestra de 20 tuplas uno de los documentos del corpus.
Ejercicio 4:  (0.8 ptos) Cálculo del diccionario de tokens
Construya, a partir de corpus_wcRDD, un nuevo diccionario con todos los tokens del corpus. El resultado será un diccionario python de nombre wcDict, cuyas entradas serán los tokens y sus valores el número de repeticiones del token en todo el corpus.
wcDict = {token1: valor1, token2, valor2, ...}
Imprima el número de repeticiones del token interpret
Ejercicio 5:  (0.6 ptos) Número de tokens.
Determine el número total de tokens en el diccionario. Imprima el resultado.
Ejercicio 6:  (0.8 ptos) Términos demasiado frecuentes:
Determine los 5 tokens más frecuentes del corpus. Imprima el resultado.
Ejercicio 7:  (0.8 ptos) Número de documentos del token más frecuente.
Determine en qué porcentaje de documentos aparece el token más frecuente.
Ejercicio 8:  (1 ptos) Filtrado de términos.
Elimine del corpus los dós términos más frecuentes. Guarde el resultado en un nuevo RDD denominado corpus_wcRDD2, con la misma estructura que corpus_wcRDD (es decir, cada documento una lista de tuplas).
Ejercicio 9:  (0.8 ptos) Lista de tokens y diccionario inverso.
Determine la lista de topicos de todo el corpus, y construya un dictionario inverso, invD, cuyas entradas sean cada uno de los tokens, y sus salidas los números consecutivos de 0 al número total de tokens, es decir
invD = {token0: 0, token1: 1, token2: 2, ...}

Ejercicio 10:  (0.6 ptos) Algoritmo LDA.
Para aplicar el algoritmo LDA, es necesario reemplazar las tuplas (token, valor) de wcRDD por tuplas del tipo (token_id, value), sustituyendo cada token por un identificador entero.
El código siguiente se encarga de completar este proceso:
End of explanation
"""


