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 dataimport pandas as pdtrain = 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 workspacefrom 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 # comparisonprint 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-replaceletters_only = re.sub("[^a-zA-Z]",           # The pattern to search for" ",                   # The pattern to replace it withexample1.get_text() )  # The text to searchprint 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 casewords = 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 nltknltk.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 listprint 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 HTMLreview_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 wordswords = letters_only.lower().split()## 4. In Python, searching a set is much faster than searching#   a list, so convert the stop words to a setstops = set(stopwords.words("english"))# # 5. Remove stop wordsmeaningful_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 sizenum_reviews = train["review"].size

# Initialize an empty list to hold the clean reviewsclean_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 reviewsclean_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 messageif( (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 # arraytrain_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 vocabularyvocab = 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 worddist = np.sum(train_data_features, axis=0)

# For each, print the vocabulary word and the number of times it # appears in the training setfor 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 treesforest = 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 runforest = 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 datatest = pd.read_csv("testData.tsv", header=0, delimiter="\t", \
                   quoting=3 )

# Verify that there are 25,000 rows and 2 columnsprint test.shape

# Create an empty list and append the clean reviews one by onenum_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 arraytest_data_features = vectorizer.transform(clean_test_reviews)test_data_features = test_data_features.toarray()

# Use the random forest to make sentiment label predictionsresult = forest.predict(test_data_features)

# Copy the results to a pandas dataframe with an "id" column and# a "sentiment" columnoutput = pd.DataFrame( data={"id":test["id"], "sentiment":result} )

# Use pandas to write the comma-separated output fileoutput.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.

 

 

A %d blogueros les gusta esto: