El t√©rmino “Deeplearning” fue acu√Īado en 2006, y se refiere a algoritmos de aprendizaje autom√°tico que tienen m√ļltiples capas no lineales y pueden aprender jerarqu√≠as de caracter√≠sticas y es realmente √ļtil a la hora de usar t√©cnicas de NLP (Natural language processing).

El aprendizaje autom√°tico m√°s moderno se basa en la ingenier√≠a de caracter√≠sticas o alg√ļn nivel de conocimiento para obtener buenos resultados. En los sistemas de aprendizaje profundo, este no es el caso, sino que los algoritmos pueden aprender autom√°ticamente las jerarqu√≠as de caracter√≠sticas, que representan objetos en niveles crecientes de abstracci√≥n.


Materiales de estudio de redes neuronales y NLP

Aprendizaje profundo para el procesamiento de se√Īales e informaci√≥n“, por Li Deng y Dong Yu (de Microsoft)

Tutorial de aprendizaje profundo” (Presentaci√≥n de 2013 por Yann LeCun y Marc’Aurelio Ranzato)

 

¬ŅD√≥nde encaja Word2Vec?

Resultado de imagen de word2vec

Word2Vec funciona de manera similar a los enfoques profundos, como las redes neuronales recurrentes o las redes neuronales profundas, pero implementa ciertos algoritmos, como el softmax jer√°rquico, que lo hace computacionalmente m√°s eficiente.

para obtener más información sobre Word2Vec, así como este documento: Estimación eficiente de representaciones de palabras en el espacio vectorial.

En este tutorial, usamos un enfoque híbrido para la capacitación, que consiste en una pieza no supervisada (Word2Vec) seguida de un aprendizaje supervisado (el Bosque aleatorio).

Si quieres descubrir alg√ļn truco para viajar m√°s barato te dejo aqui unos descuentos:

Bibliotecas y Paquetes

Las listas a continuación no deben considerarse exhaustivas.

En Python:

Theano ofrece funciones de muy bajo nivel, tuercas y tornillos para la construcción de sistemas de aprendizaje profundo. También puede encontrar algunos buenos tutoriales en su sitio.
Caffe es un marco de aprendizaje profundo del Centro de Visión y Aprendizaje de Berkeley.
Pylearn2 envuelve a Theano y parece un poco m√°s f√°cil de usar.
OverFeat se usó para ganar la competencia Kaggle Cats and Dogs.

Mas tutoriales

El blog de O’Reilly tiene unos titoriales de lo m√°s interesante:

Resultado de imagen de nlp movies kaggle

PNL (Procesamiento de lenguaje natural) es un conjunto de t√©cnicas para abordar problemas de texto. Esta p√°gina le ayudar√° a comenzar a cargar y limpiar las rese√Īas de pel√≠culas de IMDB de unacompetici√≥n creada en Kaggle, y luego a aplicar un modelo simple de Bolsa de palabras para obtener predicciones sorprendentemente precisas de si una revisi√≥n es hacia arriba o hacia abajo.

Antes de empezar

Este tutorial está en Python. Si no has usado Python anteriormente, te sugerimos que vayas a los Tutoriales de Python de Titanic Competition para que te mojes los pies (consulta la introducción de Random Forest cuando estés allí).

Si ya se siente cómodo con Python y con las técnicas básicas de NLP, puede continuar.

Esta parte del tutorial no depende de la plataforma. A lo largo de este tutorial,usaremos varios módulos de Python para el procesamiento de texto, aprendizaje profundo, bosques aleatorios y otras aplicaciones.

Hay muchos buenos tutoriales y, de hecho, libros completos escritos sobre NLP y procesamiento de texto en Python. Este tutorial no pretende ser exhaustivo, solo para ayudarte a comenzar con este tipo de desafios.

Leyendo los datos

Los archivos necesarios se pueden descargar desde la p√°gina de Datos. El primer archivo que necesitar√° es unTrainData sin etiqueta, que contiene 25,000 rese√Īas de pel√≠culas IMDB, cada una con una etiqueta de sentimiento positivo o negativo.

A continuación, lea el archivo delimitado por tabulaciones en Python. Para hacer esto, podemos usar el paquete pandas, introducido en el tutorial de Titanic, que proporcionala función read_csvpara leer y escribir archivos de datos fácilmente. Si no ha usado pandas anteriormente, es posible que deba instalarlo.

In [1]:
# Import the pandas package, then use the "read_csv" function to read‚Ä©# the labeled training data‚Ä©import pandas as pd       ‚Ä©train = pd.read_csv("labeledTrainData.tsv", header=0, \‚Ä©                    delimiter="\t", quoting=3)

Aqu√≠,¬†“header = 0”¬†indica que la primera l√≠nea del archivo contiene nombres de columna, “delimitador = \ t” indica que los campos est√°n separados por tabulaciones, y que comentar = 3 le dice a Python que ignore las comillas dobles, de lo contrario puede encontrar errores tratando de leer el archivo.

Podemos asegurarnos de que leemos 25,000 filas y 3 columnas de la siguiente manera:

In [2]:
print train.shape‚Ä©‚Ä©print train.columns.values‚Ä©#array([id, sentiment, review], dtype=object)
(25000, 3)‚Ä©['id' 'sentiment' 'review']
In [3]:
print train["review"][0]



Hay etiquetas HTML como “< br />”, abreviaturas, puntuaci√≥n, todos los problemas comunes al procesar texto en l√≠nea. T√≥mese un tiempo para revisar otras revisiones en el conjunto de capacitaci√≥n mientras est√° en ello. La siguiente secci√≥n tratar√° sobre c√≥mo ordenar el texto para el aprendizaje autom√°tico.

Limpieza de datos y preprocesamiento de textos.

Eliminando el marcado HTML: El paquete BeautifulSoup Primero, eliminaremos las etiquetas HTML. Para ello, utilizaremos la librería Beautiful Soup. Si no la tienes instalada, haz:

$ sudo pip install BeautifulSoup4

desde la línea de comandos (NO desde Python). Luego, desde Python, cargue el paquete y utilícelo para extraer el texto de una revisión:

In [4]:
# Import BeautifulSoup into your workspace‚Ä©from bs4 import BeautifulSoup             ‚Ä©‚Ä©# Initialize the BeautifulSoup object on a single movie review     ‚Ä©example1 = BeautifulSoup(train["review"][0])  ‚Ä©‚Ä©# Print the raw review and then the output of get_text(), for ‚Ä©# comparison‚Ä©print train["review"][0]‚Ä©print example1.get_text()

Llamar a get_text () te da el texto de la revisión, sin etiquetas ni marcas. Si navega por la documentación de BeautifulSoup, verá que es una biblioteca muy poderosa, más poderosa que la que necesitamos para este conjunto de datos.

Sin embargo, no se considera una práctica confiable eliminar marcas con expresiones regulares, por lo que incluso para una aplicación tan simple como esta, generalmente es mejor usar un paquete como BeautifulSoup.

Manejo de puntuaci√≥n, n√ļmeros y palabras de parada: NLTK y expresiones regulares

Resultado de imagen de NLTK

Al considerar c√≥mo limpiar el texto,¬†debemos pensar en el problema de datos que intentamos resolver. Para muchos problemas, tiene sentido eliminar la puntuaci√≥n. Por otro lado, en este caso, estamos abordando un problema de an√°lisis de sentimientos, y es posible que¬†“!!!” o “:-(” podr√≠a transmitir sentimientos, y deber√≠an tratarse como palabras. En este tutorial, para simplificar, eliminamos la puntuaci√≥n por completo, pero es algo con lo que puedes jugar por tu cuenta.

De manera similar, en este tutorial eliminaremos n√ļmeros,¬†pero hay otras formas de tratarlos que tienen tanto sentido. Por ejemplo, podr√≠amos tratarlos como palabras o reemplazarlos a todos con una cadena de marcador de posici√≥n como “NUM”.

Para eliminar la puntuaci√≥n y los n√ļmeros, usaremos un paquete para tratar las expresiones regulares, llamado re. El paquete viene incorporado con Python; No es necesario instalar nada. Para obtener una descripci√≥n detallada de c√≥mo funcionan las expresiones regulares, consulte la documentaci√≥n del paquete. Ahora, intente lo siguiente:

In [5]:
import re‚Ä©# Use regular expressions to do a find-and-replace‚Ä©letters_only = re.sub("[^a-zA-Z]",           # The pattern to search for‚Ä©                      " ",                   # The pattern to replace it with‚Ä©                      example1.get_text() )  # The text to search‚Ä©print letters_only

Una visi√≥n general completa de las expresiones regulares est√° fuera del alcance de este tutorial, pero por ahora es suficiente saber que¬†[] indica pertenencia a un grupo y ^ significa “no”. En otras palabras, la declaraci√≥n re.sub () anterior dice: “Encuentre cualquier cosa que NO sea una letra min√ļscula (a-z) o una letra may√ļscula (A-Z), y reempl√°cela con un espacio”.

Tambi√©n convertiremos nuestras revisiones a min√ļsculas y las dividiremos en palabras individuales (llamadas “tokenizaci√≥n” en la jerga de la PNL):

In [6]:
lower_case = letters_only.lower()        # Convert to lower case‚Ä©words = lower_case.split()               # Split into words

Finalmente, debemos decidir c√≥mo¬†tratar con las palabras que aparecen con frecuencia y que no tienen mucho significado. Tales palabras se llaman “palabras vac√≠as”

En ingl√©s incluyen palabras como “a”, “y”, “es” y “el”. Convenientemente, hay paquetes de Python que vienen con listas de palabras de parada integradas.¬†Importemos una lista de palabras de parada del Kit de herramientas de lenguaje natural de Python (NLTK). Necesitar√° instalar la biblioteca si a√ļn no la tiene en su computadora.

También deberá instalar los paquetes de datos que vienen con él, de la siguiente manera:

In [7]:
import nltk‚Ä©nltk.download()  # Download text data sets, including stop words

showing info https://raw.githubusercontent.com/nltk/nltk_data/gh-pages/index.xml

In [8]:
from nltk.corpus import stopwords # Import the stop word list‚Ä©print stopwords.words("english")
In [9]:
# Remove stop words from "words"‚Ä©words = [w for w in words if not w in stopwords.words("english")]‚Ä©print words

Esto le permitir√°¬†ver la lista de palabras vac√≠as en ingl√©s. Para eliminar las palabras clave de nuestra rese√Īa de pel√≠culas, haga:

In [10]:
def review_to_words( raw_review ):‚Ä©    # Function to convert a raw review to a string of words‚Ä©    # The input is a single string (a raw movie review), and ‚Ä©    # the output is a single string (a preprocessed movie review)‚Ä©    #‚Ä©    # 1. Remove HTML‚Ä©    review_text = BeautifulSoup(raw_review).get_text() ‚Ä©    #‚Ä©    # 2. Remove non-letters        ‚Ä©    letters_only = re.sub("[^a-zA-Z]", " ", review_text) ‚Ä©    #‚Ä©    # 3. Convert to lower case, split into individual words‚Ä©    words = letters_only.lower().split()                             ‚Ä©    #‚Ä©    # 4. In Python, searching a set is much faster than searching‚Ä©    #   a list, so convert the stop words to a set‚Ä©    stops = set(stopwords.words("english"))                  ‚Ä©    # ‚Ä©    # 5. Remove stop words‚Ä©    meaningful_words = [w for w in words if not w in stops]   ‚Ä©    #‚Ä©    # 6. Join the words back into one string separated by space, ‚Ä©    # and return the result.‚Ä©    return( " ".join( meaningful_words ))




No te preocupes por la “u” antes de cada palabra; solo indica que Python est√° representando internamente cada palabra como una cadena Unicode.Hay muchas otras cosas que podr√≠amos hacer con los datos: por ejemplo, Porter Stemming y Lemmatizing (ambos disponibles en NLTK) nos permitir√≠an tratar “mensajes”, “mensajes” y “mensajes” como la misma palabra, lo que ciertamente podr√≠a s√© √ļtil. Sin embargo, por simplicidad, el tutorial se detendr√° aqu√≠.Poniendolo todo junto Ahora tenemos un c√≥digo para limpiar una revisi√≥n,¬†¬°pero necesitamos limpiar 25,000 evaluaciones de capacitaci√≥n!¬†Para hacer que nuestro c√≥digo sea reutilizable, vamos a crear una funci√≥n que se pueda llamar muchas veces:

In [11]:
clean_review = review_to_words( train["review"][0] )‚Ä©print clean_review

debería darle exactamente el mismo resultado que todos los pasos individuales que hicimos en las secciones de tutoriales anteriores. Ahora pasemos y limpiemos todo el conjunto de entrenamiento a la vez (esto puede tardar unos minutos dependiendo de tu computadora):

In [12]:
# Get the number of reviews based on the dataframe column size‚Ä©num_reviews = train["review"].size‚Ä©‚Ä©# Initialize an empty list to hold the clean reviews‚Ä©clean_train_reviews = []‚Ä©‚Ä©# Loop over each review; create an index i that goes from 0 to the length‚Ä©# of the movie review list ‚Ä©for i in xrange( 0, num_reviews ):‚Ä©    # Call our function for each one, and add the result to the list of‚Ä©    # clean reviews‚Ä©    clean_train_reviews.append( review_to_words( train["review"][i] ) )

A veces puede ser molesto esperar a que se ejecute un trozo de c√≥digo largo. Puede ser √ļtil escribir c√≥digo para que ofrezca actualizaciones de estado. Para que¬†Python imprima una actualizaci√≥n de estado despu√©s de cada 1000 revisiones que procesa, intente agregar una o dos l√≠neas al c√≥digo anterior:

In [13]:
print "Cleaning and parsing the training set movie reviews...\n"‚Ä©clean_train_reviews = []‚Ä©for i in xrange( 0, num_reviews ):‚Ä©    # If the index is evenly divisible by 1000, print a message‚Ä©    if( (i+1)%1000 == 0 ):‚Ä©        print "Review %d of %d\n" % ( i+1, num_reviews )                                                                    ‚Ä©    clean_train_reviews.append( review_to_words( train["review"][i] ))

Creación de características a partir de una bolsa de palabras (utilizando scikit-learn)

Ahora que tenemos nuestras revisiones de capacitaci√≥n en orden, ¬Ņc√≥mo podemos convertirlas en alg√ļn tipo de representaci√≥n num√©rica para el aprendizaje autom√°tico?

Resultado de imagen de bag of words

Un enfoque com√ļn se llama una bolsa de palabras. El modelo¬†Bolsa de palabras¬†aprende un vocabulario de todos los documentos, luego modela cada documento contando el n√ļmero de veces que aparece cada palabra. Por ejemplo, considere las siguientes dos oraciones:

  • Oraci√≥n 1: “El gato se sent√≥ en el sombrero”
  • Oraci√≥n 2: “El perro se comi√≥ al gato y al sombrero”

De estas dos frases, nuestro vocabulario es el siguiente:

  • {el, gato, se sent√≥, en, gorro, perro, comi√≥, y}

Para obtener nuestras bolsas de palabras,¬†contamos el n√ļmero de veces que cada palabra aparece en cada oraci√≥n. En la oraci√≥n 1, “el” aparece dos veces, y “gato”, “sent√≥”, “en” y “sombrero” aparecen una vez, por lo que el vector de caracter√≠sticas de la oraci√≥n 1 es:

{el, gato, se sentó, en, gorro, perro, comió, y}

  • Oraci√≥n 1: {2, 1, 1, 1, 1, 0, 0, 0}

De manera similar, las características de la oración 2 son: {3, 1, 0, 0, 1, 1, 1, 1}

En los datos de IMDB, tenemos una gran cantidad de revisiones, que nos dar√°n un gran vocabulario. Para limitar el tama√Īo de los vectores de caracter√≠sticas, debemos elegir un¬†tama√Īo m√°ximo de vocabulario. A continuaci√≥n, utilizamos las 5000 palabras m√°s frecuentes (recordando que las palabras de detenci√≥n ya se han eliminado).

Usaremos el módulo feature_extraction de scikit-learn para crear características de bolsa de palabras.

Puede que ya tenga instalado scikit-learn; de lo contrario tendr√° que instalarlo.

In [15]:
print "Creating the bag of words...\n"‚Ä©from sklearn.feature_extraction.text import CountVectorizer‚Ä©‚Ä©# Initialize the "CountVectorizer" object, which is scikit-learn's‚Ä©# bag of words tool.  ‚Ä©vectorizer = CountVectorizer(analyzer = "word",   \‚Ä©                             tokenizer = None,    \‚Ä©                             preprocessor = None, \‚Ä©                             stop_words = None,   \‚Ä©                             max_features = 5000) ‚Ä©‚Ä©# fit_transform() does two functions: First, it fits the model‚Ä©# and learns the vocabulary; second, it transforms our training data‚Ä©# into feature vectors. The input to fit_transform should be a list of ‚Ä©# strings.‚Ä©train_data_features = vectorizer.fit_transform(clean_train_reviews)‚Ä©‚Ä©# Numpy arrays are easy to work with, so convert the result to an ‚Ä©# array‚Ä©train_data_features = train_data_features.toarray()

 

In [16]:
print train_data_features.shape

Tiene 25,000 filas y 5,000 funciones (una para cada palabra de vocabulario).

Tenga en cuenta que¬†CountVectorizer¬†viene con sus propias opciones para realizar autom√°ticamente el preprocesamiento, la tokenizaci√≥n y la eliminaci√≥n de la palabra: para cada uno de estos, en lugar de especificar “Ninguno”, podr√≠amos haber utilizado un m√©todo incorporado o haber especificado nuestra propia funci√≥n. Sin embargo, quisimos escribir nuestra propia funci√≥n para la limpieza de datos en este tutorial para mostrarle c√≥mo se hace paso a paso.

Ahora que el modelo de la bolsa de palabras est√° entrenado, veamos el vocabulario:

In [17]:
# Take a look at the words in the vocabulary‚Ä©vocab = vectorizer.get_feature_names()‚Ä©print vocab

Si está interesado, también puede imprimir los conteos de cada palabra en el vocabulario:

In [18]:
import numpy as np‚Ä©‚Ä©# Sum up the counts of each vocabulary word‚Ä©dist = np.sum(train_data_features, axis=0)‚Ä©‚Ä©# For each, print the vocabulary word and the number of times it ‚Ä©# appears in the training set‚Ä©for tag, count in zip(vocab, dist):‚Ä©    print count, tag
  • 187 abandoned
  • 125 abc
  • 108 abilities
  • 454 ability
  • 1259 able
  • 85 abraham
  • 116 absence …

Bosque aleatorio

Resultado de imagen de random forest

En este punto, tenemos características de entrenamiento numéricas de la Bolsa de Palabras y las etiquetas de sentimiento originales para cada vector de características, ¡así que hagamos algo de aprendizaje supervisado! Aquí, usaremos el clasificador de bosque aleatorio que se usa en Kaggle en el tutorial de Titanic.

El algoritmo de bosque aleatorio se incluye en scikit-learn¬†(el bosque aleatorio utiliza muchos clasificadores basados en √°rboles para hacer predicciones, de ah√≠ el “bosque”). A continuaci√≥n, establecemos el n√ļmero de √°rboles en 100 como un valor predeterminado razonable. M√°s √°rboles pueden (o no) rendir mejor, pero sin duda tomar√°n m√°s tiempo para correr. Del mismo modo, cuantas m√°s funciones incluya para cada revisi√≥n, m√°s tiempo llevar√°.

In [19]:
print "Training the random forest..."‚Ä©from sklearn.ensemble import RandomForestClassifier‚Ä©‚Ä©# Initialize a Random Forest classifier with 100 trees‚Ä©forest = RandomForestClassifier(n_estimators = 100) ‚Ä©‚Ä©# Fit the forest to the training set, using the bag of words as ‚Ä©# features and the sentiment labels as the response variable‚Ä©#‚Ä©# This may take a few minutes to run‚Ä©forest = forest.fit( train_data_features, train["sentiment"] )

Creando un Fichero de Envio

Todo lo que queda es ejecutar el Bosque aleatorio entrenado en nuestro conjunto de pruebas y crear un archivo de env√≠o. Si a√ļn no lo ha hecho,¬†descargue testData.tsv¬†desde la p√°gina de Datos. Este archivo contiene otras 25,000 revisiones e identificaciones;¬†nuestra tarea es predecir la etiqueta de sentimiento.

Tenga en cuenta que cuando usamos la Bolsa de Palabras para el conjunto de prueba, solo llamamos “transform”, no “fit_transform” como hicimos para el conjunto de entrenamiento.¬†En el aprendizaje autom√°tico, no debe utilizar el conjunto de pruebas para adaptarse a su modelo, de lo contrario, corre el riesgo de sobreajuste. Por esta raz√≥n, mantenemos el conjunto de pruebas fuera de los l√≠mites hasta que estemos listos para hacer predicciones.

In [21]:
# Read the test data‚Ä©test = pd.read_csv("testData.tsv", header=0, delimiter="\t", \‚Ä©                   quoting=3 )‚Ä©‚Ä©# Verify that there are 25,000 rows and 2 columns‚Ä©print test.shape‚Ä©‚Ä©# Create an empty list and append the clean reviews one by one‚Ä©num_reviews = len(test["review"])‚Ä©clean_test_reviews = [] ‚Ä©‚Ä©print "Cleaning and parsing the test set movie reviews...\n"‚Ä©for i in xrange(0,num_reviews):‚Ä©    if( (i+1) % 1000 == 0 ):‚Ä©        print "Review %d of %d\n" % (i+1, num_reviews)‚Ä©    clean_review = review_to_words( test["review"][i] )‚Ä©    clean_test_reviews.append( clean_review )‚Ä©‚Ä©# Get a bag of words for the test set, and convert to a numpy array‚Ä©test_data_features = vectorizer.transform(clean_test_reviews)‚Ä©test_data_features = test_data_features.toarray()‚Ä©‚Ä©# Use the random forest to make sentiment label predictions‚Ä©result = forest.predict(test_data_features)‚Ä©‚Ä©# Copy the results to a pandas dataframe with an "id" column and‚Ä©# a "sentiment" column‚Ä©output = pd.DataFrame( data={"id":test["id"], "sentiment":result} )‚Ä©‚Ä©# Use pandas to write the comma-separated output file‚Ä©output.to_csv( "Bag_of_Words_model.csv", index=False, quoting=3 )



¡Felicidades, estás listo para hacer tu primer envío!

Prueba cosas diferentes y mira c√≥mo cambian tus resultados. Puede limpiar las revisiones de manera diferente, elegir un n√ļmero diferente de palabras de vocabulario para la representaci√≥n de la Bolsa de Palabras, probar Porter Stemming, un clasificador diferente o cualquier otro tipo de cosas.

 

 


Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

Este sitio usa Akismet para reducir el spam. Aprende cómo se procesan los datos de tus comentarios.

A %d blogueros les gusta esto: