Gensim - Guía rápida

Este capítulo le ayudará a comprender la historia y las características de Gensim junto con sus usos y ventajas.

¿Qué es Gensim?

Gensim = “Generate Similar”es una biblioteca popular de procesamiento de lenguaje natural (NLP) de código abierto que se utiliza para el modelado de temas sin supervisión. Utiliza los mejores modelos académicos y el aprendizaje automático estadístico moderno para realizar varias tareas complejas como:

  • Construcción de vectores de documento o palabra
  • Corpora
  • Realizar identificación de temas
  • Realizar comparación de documentos (recuperar documentos semánticamente similares)
  • Análisis de documentos de texto sin formato para estructura semántica

Además de realizar las tareas complejas anteriores, Gensim, implementado en Python y Cython, está diseñado para manejar grandes colecciones de texto utilizando transmisión de datos, así como algoritmos incrementales en línea. Esto lo diferencia de los paquetes de software de aprendizaje automático que solo tienen como objetivo el procesamiento en memoria.

Historia

En 2008, Gensim comenzó como una colección de varios scripts de Python para las matemáticas digitales checas. Allí, sirvió para generar una breve lista de los artículos más similares a un artículo determinado. Pero en 2009, RARE Technologies Ltd. lanzó su lanzamiento inicial. Luego, más tarde en julio de 2019, obtuvimos su versión estable (3.8.0).

Varias características

A continuación se muestran algunas de las características y capacidades que ofrece Gensim:

Escalabilidad

Gensim puede procesar fácilmente corpus grandes y a escala web mediante el uso de sus algoritmos de capacitación en línea incrementales. Es de naturaleza escalable, ya que no es necesario que todo el corpus de entrada resida completamente en la memoria de acceso aleatorio (RAM) en un momento dado. En otras palabras, todos sus algoritmos son independientes de la memoria con respecto al tamaño del corpus.

Robusto

Gensim es de naturaleza robusta y se ha utilizado en varios sistemas por varias personas y organizaciones durante más de 4 años. Podemos conectar fácilmente nuestro propio corpus de entrada o flujo de datos. También es muy fácil de ampliar con otros algoritmos de espacio vectorial.

Plataforma agnóstico

Como sabemos, Python es un lenguaje muy versátil ya que, al ser Python puro, Gensim se ejecuta en todas las plataformas (como Windows, Mac OS, Linux) que admiten Python y Numpy.

Implementaciones eficientes multinúcleo

Para acelerar el procesamiento y la recuperación en grupos de máquinas, Gensim proporciona implementaciones multinúcleo eficientes de varios algoritmos populares como Latent Semantic Analysis (LSA), Latent Dirichlet Allocation (LDA), Random Projections (RP), Hierarchical Dirichlet Process (HDP).

Código abierto y abundancia de apoyo comunitario

Gensim tiene la licencia GNU LGPL aprobada por OSI que permite su uso tanto para uso personal como comercial de forma gratuita. Cualquier modificación realizada en Gensim es, a su vez, de código abierto y también cuenta con abundante apoyo de la comunidad.

Usos de Gensim

Gensim se ha utilizado y citado en más de mil aplicaciones comerciales y académicas. También es citado por varios trabajos de investigación y tesis de estudiantes. Incluye implementaciones en paralelo transmitidas de lo siguiente:

fastText

fastText, utiliza una red neuronal para la inserción de palabras, es una biblioteca para el aprendizaje de la inserción de palabras y la clasificación de texto. Es creado por el laboratorio de investigación de inteligencia artificial (FAIR) de Facebook. Este modelo, básicamente, nos permite crear un algoritmo supervisado o no supervisado para obtener representaciones vectoriales para palabras.

Word2vec

Word2vec, utilizado para producir incrustaciones de palabras, es un grupo de modelos de redes neuronales superficiales y de dos capas. Los modelos están básicamente entrenados para reconstruir contextos lingüísticos de palabras.

LSA (análisis semántico latente)

Es una técnica en NLP (Natural Language Processing) que nos permite analizar las relaciones entre un conjunto de documentos y los términos que los contienen. Se realiza produciendo un conjunto de conceptos relacionados con los documentos y términos.

LDA (asignación de Dirichlet latente)

Es una técnica en PNL que permite que grupos no observados expliquen conjuntos de observaciones. Estos grupos no observados explican por qué algunas partes de los datos son similares. Esa es la razón, es un modelo estadístico generativo.

tf-idf (término frecuencia-frecuencia inversa del documento)

tf-idf, una estadística numérica en la recuperación de información, refleja la importancia de una palabra para un documento en un corpus. Los motores de búsqueda lo utilizan a menudo para calificar y clasificar la relevancia de un documento dada una consulta de usuario. También se puede utilizar para el filtrado de palabras vacías en el resumen y la clasificación de texto.

Todos ellos se explicarán en detalle en los siguientes apartados.

Ventajas

Gensim es un paquete de PNL que modela temas. Las importantes ventajas de Gensim son las siguientes:

  • Podemos obtener las facilidades de modelado de temas e incrustación de palabras en otros paquetes como ‘scikit-learn’ y ‘R’, pero las facilidades proporcionadas por Gensim para construir modelos de temas e incrustaciones de palabras son incomparables. También proporciona instalaciones más convenientes para el procesamiento de texto.

  • Otra ventaja más significativa de Gensim es que nos permite manejar archivos de texto grandes incluso sin cargar el archivo completo en la memoria.

  • Gensim no requiere costosas anotaciones o etiquetado manual de documentos porque utiliza modelos sin supervisión.

El capítulo aclara los requisitos previos para instalar Gensim, sus dependencias principales e información sobre su versión actual.

Prerrequisitos

Para instalar Gensim, debemos tener Python instalado en nuestras computadoras. Puede ir al enlace www.python.org/downloads/ y seleccionar la última versión para su sistema operativo, es decir, Windows y Linux / Unix. Puede consultar el enlace para obtener un tutorial básico sobre Python. Gensim es compatible con Linux, Windows y Mac OS X.

Dependencias de código

Gensim debe ejecutarse en cualquier plataforma que admita Python 2.7 or 3.5+ y NumPy. De hecho, depende del siguiente software:

Pitón

Gensim se prueba con las versiones 2.7, 3.5, 3.6 y 3.7 de Python.

Numpy

Como sabemos eso, NumPy es un paquete para computación científica con Python. También se puede utilizar como un contenedor multidimensional eficiente de datos genéricos. Gensim depende del paquete NumPy para procesar números. Para obtener un tutorial básico sobre Python, puede consultar el enlace .

smart_open

smart_open, una biblioteca de Python 2 y Python 3, se utiliza para la transmisión eficiente de archivos muy grandes. Admite la transmisión desde / hacia almacenamientos como S3, HDFS, WebHDFS, HTTP, HTTPS, SFTP o sistemas de archivos locales. Gensim depende desmart_open Biblioteca de Python para abrir archivos de forma transparente en almacenamiento remoto, así como archivos comprimidos.

Versión actual

La versión actual de Gensim es 3.8.0 que fue lanzado en julio de 2019.

Instalación mediante terminal

Una de las formas más sencillas de instalar Gensim es ejecutar el siguiente comando en su terminal:

pip install --upgrade gensim

Instalación mediante el entorno Conda

Una forma alternativa de descargar Gensim es usar condamedio ambiente. Ejecute el siguiente comando en suconda terminal -

conda install –c conda-forge gensim

Instalación mediante paquete fuente

Supongamos que, si ha descargado y descomprimido el paquete fuente, debe ejecutar los siguientes comandos:

python setup.py test
python setup.py install

Aquí, aprenderemos sobre los conceptos centrales de Gensim, con un enfoque principal en los documentos y el corpus.

Conceptos básicos de Gensim

A continuación se presentan los conceptos y términos básicos que se necesitan para comprender y utilizar Gensim:

  • Document - Z Se refiere a algún texto.

  • Corpus - Se refiere a una colección de documentos.

  • Vector - La representación matemática de un documento se llama vector.

  • Model - Se refiere a un algoritmo que se utiliza para transformar vectores de una representación a otra.

¿Qué es un documento?

Como se discutió, se refiere a algún texto. Si entramos en algún detalle, es un objeto del tipo de secuencia de texto que se conoce como‘str’ en Python 3. Por ejemplo, en Gensim, un documento puede ser cualquier cosa como:

  • Tuit corto de 140 caracteres
  • Párrafo único, es decir, resumen de artículo o trabajo de investigación
  • Artículo de noticias
  • Book
  • Novel
  • Theses

Secuencia de texto

Un tipo de secuencia de texto se conoce comúnmente como ‘str’ en Python 3. Como sabemos que en Python, los datos textuales se manejan con cadenas o más específicamente ‘str’objetos. Las cadenas son básicamente secuencias inmutables de puntos de código Unicode y se pueden escribir de las siguientes formas:

  • Single quotes - Por ejemplo, ‘Hi! How are you?’. También nos permite incrustar comillas dobles. Por ejemplo,‘Hi! “How” are you?’

  • Double quotes - Por ejemplo, "Hi! How are you?". También nos permite insertar comillas simples. Por ejemplo,"Hi! 'How' are you?"

  • Triple quotes - Puede tener tres comillas simples como, '''Hi! How are you?'''. o tres comillas dobles como,"""Hi! 'How' are you?"""

Todos los espacios en blanco se incluirán en el literal de cadena.

Ejemplo

A continuación se muestra un ejemplo de un documento en Gensim:

Document = “Tutorialspoint.com is the biggest online tutorials library and it’s all free also”

¿Qué es Corpus?

Un corpus puede definirse como el conjunto grande y estructurado de textos legibles por máquina producidos en un entorno comunicativo natural. En Gensim, una colección de objetos de documento se denomina corpus. El plural de corpus escorpora.

Papel del Corpus en Gensim

Un corpus en Gensim cumple las dos funciones siguientes:

Sirve como entrada para entrenar un modelo

El primer e importante papel que juega un corpus en Gensim es el de entrada para entrenar un modelo. Para inicializar los parámetros internos del modelo, durante el entrenamiento, el modelo busca algunos temas comunes y temas del corpus de entrenamiento. Como se discutió anteriormente, Gensim se enfoca en modelos no supervisados, por lo tanto, no requiere ningún tipo de intervención humana.

Sirve como extractor de temas

Una vez que se entrena el modelo, se puede utilizar para extraer temas de los nuevos documentos. Aquí, los nuevos documentos son los que no se utilizan en la fase de formación.

Ejemplo

El corpus puede incluir todos los tweets de una persona en particular, lista de todos los artículos de un periódico o todos los trabajos de investigación sobre un tema en particular, etc.

Recolectando Corpus

A continuación se muestra un ejemplo de pequeño corpus que contiene 5 documentos. Aquí, cada documento es una cadena que consta de una sola oración.

t_corpus = [
   "A survey of user opinion of computer system response time",
   "Relation of user perceived response time to error measurement",
   "The generation of random binary unordered trees",
   "The intersection graph of paths in trees",
   "Graph minors IV Widths of trees and well quasi ordering",
]

Preprocesamiento de recopilación de corpus

Una vez que recopilamos el corpus, se deben seguir algunos pasos de preprocesamiento para mantener el corpus simple. Simplemente podemos eliminar algunas palabras en inglés de uso común como 'the'. También podemos eliminar palabras que aparecen solo una vez en el corpus.

Por ejemplo, la siguiente secuencia de comandos de Python se usa para poner en minúsculas cada documento, dividirlo por espacios en blanco y filtrar las palabras vacías:

Ejemplo

import pprint
t_corpus = [
   "A survey of user opinion of computer system response time", 
   "Relation of user perceived response time to error measurement", 
   "The generation of random binary unordered trees", 
   "The intersection graph of paths in trees", 
   "Graph minors IV Widths of trees and well quasi ordering",
]
stoplist = set('for a of the and to in'.split(' '))
processed_corpus = [[word for word in document.lower().split() if word not in stoplist]
   for document in t_corpus]
	
pprint.pprint(processed_corpus)
]

Salida

[['survey', 'user', 'opinion', 'computer', 'system', 'response', 'time'],
['relation', 'user', 'perceived', 'response', 'time', 'error', 'measurement'],
['generation', 'random', 'binary', 'unordered', 'trees'],
['intersection', 'graph', 'paths', 'trees'],
['graph', 'minors', 'iv', 'widths', 'trees', 'well', 'quasi', 'ordering']]

Preprocesamiento eficaz

Gensim también proporciona una función para un preprocesamiento más eficaz del corpus. En tal tipo de preprocesamiento, podemos convertir un documento en una lista de tokens en minúsculas. También podemos ignorar los tokens que son demasiado cortos o demasiado largos. Tal función esgensim.utils.simple_preprocess(doc, deacc=False, min_len=2, max_len=15).

gensim.utils.simple_preprocess() fucntion

Gensim proporciona esta función para convertir un documento en una lista de tokens en minúsculas y también para ignorar tokens que son demasiado cortos o demasiado largos. Tiene los siguientes parámetros:

doc (str)

Se refiere al documento de entrada en el que se debe aplicar el procesamiento previo.

deacc (bool, opcional)

Este parámetro se utiliza para eliminar las marcas de acento de los tokens. Usadeaccent() para hacer esto.

min_len (int, opcional)

Con la ayuda de este parámetro, podemos establecer la longitud mínima de un token. Se descartarán los tokens más cortos que la longitud definida.

max_len (int, opcional)

Con la ayuda de este parámetro podemos establecer la longitud máxima de un token. Los tokens más largos que la longitud definida serán descartados.

La salida de esta función serían los tokens extraídos del documento de entrada.

Aquí, aprenderemos sobre los conceptos centrales de Gensim, con un enfoque principal en el vector y el modelo.

¿Qué es Vector?

¿Qué pasa si queremos inferir la estructura latente en nuestro corpus? Para esto, necesitamos representar los documentos de tal manera que podamos manipularlos matemáticamente. Un tipo de representación popular es representar cada documento del corpus como un vector de características. Por eso podemos decir que el vector es una representación matemática conveniente de un documento.

Para darle un ejemplo, representemos una sola característica, de nuestro corpus usado anteriormente, como un par de QA:

Q - ¿Cuántas veces la palabra Hello aparecer en el documento?

A - Cero (0).

Q - ¿Cuántos párrafos hay en el documento?

A - Dos (2)

La pregunta generalmente está representada por su ID entero, por lo tanto, la representación de este documento es una serie de pares como (1, 0.0), (2, 2.0). Esta representación vectorial se conoce comodensevector. Por quédense, porque comprende una respuesta explícita a todas las preguntas escritas anteriormente.

La representación puede ser un simple like (0, 2), si conocemos todas las preguntas de antemano. Tal secuencia de las respuestas (por supuesto, si las preguntas se conocen de antemano) es lavector para nuestro documento.

Otro tipo de representación popular es la bag-of-word (BoW)modelo. En este enfoque, cada documento está básicamente representado por un vector que contiene el recuento de frecuencia de cada palabra en el diccionario.

Para darle un ejemplo, suponga que tenemos un diccionario que contiene las palabras ['Hola', 'Cómo', 'eres', 'tú']. Un documento que consta de la cadena "¿Cómo estás cómo?" Se representaría entonces mediante el vector [0, 2, 1, 1]. Aquí, las entradas del vector están en orden de apariciones de "Hola", "Cómo", "eres" y "tú".

Vector versus documento

De la explicación anterior del vector, casi se comprende la distinción entre un documento y un vector. Pero, para que quede más claro,document es texto y vectores una representación matemáticamente conveniente de ese texto. Desafortunadamente, a veces muchas personas usan estos términos indistintamente.

Por ejemplo, supongamos que tenemos algún documento A arbitrario, entonces en lugar de decir “el vector que corresponde al documento A”, solían decir, “el vector A” o “el documento A”. Esto conduce a una gran ambigüedad. Una cosa más importante a tener en cuenta aquí es que dos documentos diferentes pueden tener la misma representación vectorial.

Conversión de corpus en una lista de vectores

Antes de tomar un ejemplo de implementación de conversión de corpus en la lista de vectores, necesitamos asociar cada palabra en el corpus con un ID entero único. Para ello, ampliaremos el ejemplo tomado en el capítulo anterior.

Ejemplo

from gensim import corpora
dictionary = corpora.Dictionary(processed_corpus)
print(dictionary)

Salida

Dictionary(25 unique tokens: ['computer', 'opinion', 'response', 'survey', 'system']...)

Muestra que en nuestro corpus hay 25 tokens diferentes en este gensim.corpora.Dictionary.

Ejemplo de implementación

Podemos usar el diccionario para convertir documentos tokenizados en estos vectores de 5 dietas de la siguiente manera:

pprint.pprint(dictionary.token2id)

Salida

{
   'binary': 11,
   'computer': 0,
   'error': 7,
   'generation': 12,
   'graph': 16,
   'intersection': 17,
   'iv': 19,
   'measurement': 8,
   'minors': 20,
   'opinion': 1,
   'ordering': 21,
   'paths': 18,
   'perceived': 9,
   'quasi': 22,
   'random': 13,
   'relation': 10,
   'response': 2,
   'survey': 3,
   'system': 4,
   'time': 5,
   'trees': 14,
   'unordered': 15,
   'user': 6,
   'well': 23,
   'widths': 24
}

Y de manera similar, podemos crear la representación de bolsa de palabras para un documento de la siguiente manera:

BoW_corpus = [dictionary.doc2bow(text) for text in processed_corpus]
pprint.pprint(BoW_corpus)

Salida

[
   [(0, 1), (1, 1), (2, 1), (3, 1), (4, 1), (5, 1), (6, 1)],
   [(2, 1), (5, 1), (6, 1), (7, 1), (8, 1), (9, 1), (10, 1)],
   [(11, 1), (12, 1), (13, 1), (14, 1), (15, 1)],
   [(14, 1), (16, 1), (17, 1), (18, 1)],
   [(14, 1), (16, 1), (19, 1), (20, 1), (21, 1), (22, 1), (23, 1), (24, 1)]
]

¿Qué es el modelo?

Una vez que hemos vectorizado el corpus, ¿qué sigue? Ahora, podemos transformarlo usando modelos. El modelo puede referirse a un algoritmo utilizado para transformar una representación de documento en otra.

Como hemos discutido, los documentos, en Gensim, se representan como vectores, por lo tanto, podemos, aunque modelar, como una transformación entre dos espacios vectoriales. Siempre hay una fase de entrenamiento donde los modelos aprenden los detalles de tales transformaciones. El modelo lee el corpus de entrenamiento durante la fase de entrenamiento.

Inicializar un modelo

Vamos a inicializar tf-idfmodelo. Este modelo transforma los vectores de la representación BoW (Bolsa de palabras) a otro espacio vectorial donde los recuentos de frecuencia se ponderan de acuerdo con la rareza relativa de cada palabra en el corpus.

Ejemplo de implementación

En el siguiente ejemplo, vamos a inicializar el tf-idfmodelo. Lo entrenaremos en nuestro corpus y luego transformaremos la cadena "gráfico de árboles".

Ejemplo

from gensim import models
tfidf = models.TfidfModel(BoW_corpus)
words = "trees graph".lower().split()
print(tfidf[dictionary.doc2bow(words)])

Salida

[(3, 0.4869354917707381), (4, 0.8734379353188121)]

Ahora, una vez que creamos el modelo, podemos transformar todo el corpus a través de tfidf e indexarlo, y consultar la similitud de nuestro documento de consulta (le estamos dando al documento de consulta 'sistema de árboles') en cada documento del corpus -

Ejemplo

from gensim import similarities
index = similarities.SparseMatrixSimilarity(tfidf[BoW_corpus],num_features=5)
query_document = 'trees system'.split()
query_bow = dictionary.doc2bow(query_document)
simils = index[tfidf[query_bow]]
print(list(enumerate(simils)))

Salida

[(0, 0.0), (1, 0.0), (2, 1.0), (3, 0.4869355), (4, 0.4869355)]

A partir del resultado anterior, el documento 4 y el documento 5 tienen una puntuación de similitud de alrededor del 49%.

Además, también podemos ordenar esta salida para una mayor legibilidad de la siguiente manera:

Ejemplo

for doc_number, score in sorted(enumerate(sims), key=lambda x: x[1], reverse=True):
   print(doc_number, score)

Salida

2 1.0
3 0.4869355
4 0.4869355
0 0.0
1 0.0

En el último capítulo donde discutimos sobre vector y modelo, tuvo una idea sobre el diccionario. Aquí vamos a discutirDictionary objeto con un poco más de detalle.

¿Qué es el Diccionario?

Antes de profundizar en el concepto de diccionario, comprendamos algunos conceptos simples de PNL:

  • Token - Un token significa una 'palabra'.

  • Document - Un documento se refiere a una oración o párrafo.

  • Corpus - Se refiere a una colección de documentos como una bolsa de palabras (BoW).

Para todos los documentos, un corpus siempre contiene la identificación del token de cada palabra junto con su recuento de frecuencia en el documento.

Pasemos al concepto de diccionario en Gensim. Para trabajar con documentos de texto, Gensim también requiere que las palabras, es decir, los tokens, se conviertan en sus identificadores únicos. Para lograrlo, nos brinda la facilidad deDictionary object, que asigna cada palabra a su ID entero único. Para ello, convierte el texto de entrada en la lista de palabras y luego lo pasa alcorpora.Dictionary() objeto.

Necesidad de diccionario

Ahora surge la pregunta de cuál es realmente la necesidad de un objeto de diccionario y dónde se puede usar. En Gensim, el objeto de diccionario se utiliza para crear un corpus de bolsa de palabras (BoW) que se utiliza además como entrada para el modelado de temas y otros modelos también.

Formas de entrada de texto

Hay tres formas diferentes de entrada de texto que podemos proporcionar a Gensim:

  • Como las oraciones almacenadas en el objeto de lista nativo de Python (conocido como str en Python 3)

  • Como un solo archivo de texto (puede ser pequeño o grande)

  • Varios archivos de texto

Creación de un diccionario con Gensim

Como se discutió, en Gensim, el diccionario contiene el mapeo de todas las palabras, también conocidas como tokens, con su ID entero único. Podemos crear un diccionario a partir de una lista de oraciones, de uno o más de un archivo de texto (archivo de texto que contiene varias líneas de texto). Entonces, primero comencemos creando un diccionario usando una lista de oraciones.

De una lista de oraciones

En el siguiente ejemplo crearemos un diccionario a partir de una lista de oraciones. Cuando tenemos una lista de oraciones o puedes decir varias oraciones, debemos convertir cada oración en una lista de palabras y las comprensiones es una de las formas más comunes de hacer esto.

Ejemplo de implementación

Primero, importe los paquetes requeridos y necesarios de la siguiente manera:

import gensim
from gensim import corpora
from pprint import pprint

Luego, haga la lista de comprensión de la lista de oraciones / documento para usarla creando el diccionario -

doc = [
   "CNTK formerly known as Computational Network Toolkit",
   "is a free easy-to-use open-source commercial-grade toolkit",
   "that enable us to train deep learning algorithms to learn like the human brain."
]

Luego, necesitamos dividir las oraciones en palabras. Se llama tokenización.

text_tokens = [[text for text in doc.split()] for doc in doc]

Ahora, con la ayuda del siguiente script, podemos crear el diccionario:

dict_LoS = corpora.Dictionary(text_tokens)

Ahora obtengamos más información, como la cantidad de tokens en el diccionario:

print(dict_LoS)

Salida

Dictionary(27 unique tokens: ['CNTK', 'Computational', 'Network', 'Toolkit', 'as']...)

También podemos ver la palabra a la asignación de enteros únicos de la siguiente manera:

print(dict_LoS.token2id)

Salida

{
   'CNTK': 0, 'Computational': 1, 'Network': 2, 'Toolkit': 3, 'as': 4, 
   'formerly': 5, 'known': 6, 'a': 7, 'commercial-grade': 8, 'easy-to-use': 9,
   'free': 10, 'is': 11, 'open-source': 12, 'toolkit': 13, 'algorithms': 14,
   'brain.': 15, 'deep': 16, 'enable': 17, 'human': 18, 'learn': 19, 'learning': 20,
   'like': 21, 'that': 22, 'the': 23, 'to': 24, 'train': 25, 'us': 26
}

Ejemplo de implementación completo

import gensim
from gensim import corpora
from pprint import pprint
doc = [
   "CNTK formerly known as Computational Network Toolkit",
   "is a free easy-to-use open-source commercial-grade toolkit",
   "that enable us to train deep learning algorithms to learn like the human brain."
]
text_tokens = [[text for text in doc.split()] for doc in doc]
dict_LoS = corpora.Dictionary(text_tokens)
print(dict_LoS.token2id)

Desde un archivo de texto único

En el siguiente ejemplo, crearemos un diccionario a partir de un solo archivo de texto. De manera similar, también podemos crear un diccionario a partir de más de un archivo de texto (es decir, directorio de archivos).

Para ello, hemos guardado el documento, utilizado en el ejemplo anterior, en el archivo de texto denominado doc.txt. Gensim leerá el archivo línea por línea y procesará una línea a la vez utilizandosimple_preprocess. De esta manera, no necesita cargar el archivo completo en la memoria de una vez.

Ejemplo de implementación

Primero, importe los paquetes requeridos y necesarios de la siguiente manera:

import gensim
from gensim import corpora
from pprint import pprint
from gensim.utils import simple_preprocess
from smart_open import smart_open
import os

La siguiente línea de códigos hará que el diccionario gensim use el archivo de texto único llamado doc.txt -

dict_STF = corpora.Dictionary(
   simple_preprocess(line, deacc =True) for line in open(‘doc.txt’, encoding=’utf-8’)
)

Ahora obtengamos más información, como la cantidad de tokens en el diccionario:

print(dict_STF)

Salida

Dictionary(27 unique tokens: ['CNTK', 'Computational', 'Network', 'Toolkit', 'as']...)

También podemos ver la palabra a la asignación de enteros únicos de la siguiente manera:

print(dict_STF.token2id)

Salida

{
   'CNTK': 0, 'Computational': 1, 'Network': 2, 'Toolkit': 3, 'as': 4, 
   'formerly': 5, 'known': 6, 'a': 7, 'commercial-grade': 8, 'easy-to-use': 9, 
   'free': 10, 'is': 11, 'open-source': 12, 'toolkit': 13, 'algorithms': 14, 
   'brain.': 15, 'deep': 16, 'enable': 17, 'human': 18, 'learn': 19, 
   'learning': 20, 'like': 21, 'that': 22, 'the': 23, 'to': 24, 'train': 25, 'us': 26
}

Ejemplo de implementación completo

import gensim
from gensim import corpora
from pprint import pprint
from gensim.utils import simple_preprocess
from smart_open import smart_open
import os
dict_STF = corpora.Dictionary(
   simple_preprocess(line, deacc =True) for line in open(‘doc.txt’, encoding=’utf-8’)
)
dict_STF = corpora.Dictionary(text_tokens)
print(dict_STF.token2id)

Desde varios archivos de texto

Ahora creemos un diccionario a partir de varios archivos, es decir, más de un archivo de texto guardado en el mismo directorio. Para este ejemplo, hemos creado tres archivos de texto diferentes, a saberfirst.txt, second.txt y third.txtque contiene las tres líneas del archivo de texto (doc.txt), que usamos para el ejemplo anterior. Todos estos tres archivos de texto se guardan en un directorio llamadoABC.

Ejemplo de implementación

Para implementar esto, necesitamos definir una clase con un método que pueda iterar a través de los tres archivos de texto (Primero, Segundo y Tercero.txt) en el directorio (ABC) y producir la lista procesada de tokens de palabras.

Definamos la clase llamada Read_files tener un método llamado __iteration__ () como sigue -

class Read_files(object):
   def __init__(self, directoryname):
      elf.directoryname = directoryname
   def __iter__(self):
      for fname in os.listdir(self.directoryname):
         for line in open(os.path.join(self.directoryname, fname), encoding='latin'):
   yield simple_preprocess(line)

A continuación, debemos proporcionar la ruta del directorio de la siguiente manera:

path = "ABC"

#provide the path as per your computer system where you saved the directory.

Los siguientes pasos son similares a los que hicimos en los ejemplos anteriores. La siguiente línea de códigos creará el directorio Gensim utilizando el directorio que tiene tres archivos de texto:

dict_MUL = corpora.Dictionary(Read_files(path))

Salida

Dictionary(27 unique tokens: ['CNTK', 'Computational', 'Network', 'Toolkit', 'as']...)

Ahora también podemos ver la palabra a la asignación de enteros únicos de la siguiente manera:

print(dict_MUL.token2id)

Salida

{
   'CNTK': 0, 'Computational': 1, 'Network': 2, 'Toolkit': 3, 'as': 4, 
   'formerly': 5, 'known': 6, 'a': 7, 'commercial-grade': 8, 'easy-to-use': 9, 
   'free': 10, 'is': 11, 'open-source': 12, 'toolkit': 13, 'algorithms': 14, 
   'brain.': 15, 'deep': 16, 'enable': 17, 'human': 18, 'learn': 19, 
   'learning': 20, 'like': 21, 'that': 22, 'the': 23, 'to': 24, 'train': 25, 'us': 26
}

Guardar y cargar un diccionario Gensim

Gensim apoya a su propio nativo save() método para guardar el diccionario en el disco y load() método para volver a cargar el diccionario desde el disco.

Por ejemplo, podemos guardar el diccionario con la ayuda del siguiente script:

Gensim.corpora.dictionary.save(filename)

#provide the path where you want to save the dictionary.

De manera similar, podemos cargar el diccionario guardado usando el método load (). El siguiente script puede hacer esto:

Gensim.corpora.dictionary.load(filename)

#provide the path where you have saved the dictionary.

Hemos entendido cómo crear un diccionario a partir de una lista de documentos y de archivos de texto (tanto de uno como de más de uno). Ahora, en esta sección, crearemos un corpus de bolsa de palabras (BoW). Para trabajar con Gensim, es uno de los objetos más importantes con los que debemos familiarizarnos. Básicamente, es el corpus que contiene la palabra id y su frecuencia en cada documento.

Creación de un corpus de BoW

Como se discutió, en Gensim, el corpus contiene la palabra id y su frecuencia en cada documento. Podemos crear un corpus BoW a partir de una simple lista de documentos y de archivos de texto. Lo que tenemos que hacer es pasar la lista tokenizada de palabras al objeto llamadoDictionary.doc2bow(). Entonces, primero, comencemos creando un corpus BoW usando una lista simple de documentos.

De una lista simple de oraciones

En el siguiente ejemplo, crearemos un corpus BoW a partir de una lista simple que contiene tres oraciones.

Primero, necesitamos importar todos los paquetes necesarios de la siguiente manera:

import gensim
import pprint
from gensim import corpora
from gensim.utils import simple_preprocess

Ahora proporcione la lista que contiene las oraciones. Tenemos tres frases en nuestra lista:

doc_list = [
   "Hello, how are you?", "How do you do?", 
   "Hey what are you doing? yes you What are you doing?"
]

A continuación, realice la tokenización de las oraciones de la siguiente manera:

doc_tokenized = [simple_preprocess(doc) for doc in doc_list]

Crea un objeto de corpora.Dictionary() como sigue -

dictionary = corpora.Dictionary()

Ahora pase estas oraciones simbólicas a dictionary.doc2bow() objectcomo sigue -

BoW_corpus = [dictionary.doc2bow(doc, allow_update=True) for doc in doc_tokenized]

Por fin podemos imprimir Bag of word corpus -

print(BoW_corpus)

Salida

[
   [(0, 1), (1, 1), (2, 1), (3, 1)], 
   [(2, 1), (3, 1), (4, 2)], [(0, 2), (3, 3), (5, 2), (6, 1), (7, 2), (8, 1)]
]

La salida anterior muestra que la palabra con id = 0 aparece una vez en el primer documento (porque tenemos (0,1) en la salida) y así sucesivamente.

De alguna manera, los humanos no pueden leer la salida anterior. También podemos convertir estos identificadores en palabras, pero para esto necesitamos que nuestro diccionario haga la conversión de la siguiente manera:

id_words = [[(dictionary[id], count) for id, count in line] for line in BoW_corpus]
print(id_words)

Salida

[
   [('are', 1), ('hello', 1), ('how', 1), ('you', 1)], 
   [('how', 1), ('you', 1), ('do', 2)], 
   [('are', 2), ('you', 3), ('doing', 2), ('hey', 1), ('what', 2), ('yes', 1)]
]

Ahora la salida anterior es de alguna manera legible por humanos.

Ejemplo de implementación completo

import gensim
import pprint
from gensim import corpora
from gensim.utils import simple_preprocess
doc_list = [
   "Hello, how are you?", "How do you do?", 
   "Hey what are you doing? yes you What are you doing?"
]
doc_tokenized = [simple_preprocess(doc) for doc in doc_list]
dictionary = corpora.Dictionary()
BoW_corpus = [dictionary.doc2bow(doc, allow_update=True) for doc in doc_tokenized]
print(BoW_corpus)
id_words = [[(dictionary[id], count) for id, count in line] for line in BoW_corpus]
print(id_words)

Desde un archivo de texto

En el siguiente ejemplo, crearemos un corpus BoW a partir de un archivo de texto. Para ello, hemos guardado el documento, utilizado en el ejemplo anterior, en el archivo de texto denominadodoc.txt..

Gensim leerá el archivo línea por línea y procesará una línea a la vez utilizando simple_preprocess. De esta manera, no necesita cargar el archivo completo en la memoria de una vez.

Ejemplo de implementación

Primero, importe los paquetes requeridos y necesarios de la siguiente manera:

import gensim
from gensim import corpora
from pprint import pprint
from gensim.utils import simple_preprocess
from smart_open import smart_open
import os

A continuación, la siguiente línea de códigos hará que se lean los documentos de doc.txt y los tokenice:

doc_tokenized = [
   simple_preprocess(line, deacc =True) for line in open(‘doc.txt’, encoding=’utf-8’)
]
dictionary = corpora.Dictionary()

Ahora tenemos que pasar estas palabras tokenizadas a dictionary.doc2bow() objeto (como se hizo en el ejemplo anterior)

BoW_corpus = [
   dictionary.doc2bow(doc, allow_update=True) for doc in doc_tokenized
]
print(BoW_corpus)

Salida

[
   [(9, 1), (10, 1), (11, 1), (12, 1), (13, 1), (14, 1), (15, 1)], 
   [
      (15, 1), (16, 1), (17, 1), (18, 1), (19, 1), (20, 1), (21, 1), 
      (22, 1), (23, 1), (24, 1)
   ], 
   [
      (23, 2), (25, 1), (26, 1), (27, 1), (28, 1), (29, 1), 
      (30, 1), (31, 1), (32, 1), (33, 1), (34, 1), (35, 1), (36, 1)
   ], 
   [(3, 1), (18, 1), (37, 1), (38, 1), (39, 1), (40, 1), (41, 1), (42, 1), (43, 1)], 
   [
      (18, 1), (27, 1), (31, 2), (32, 1), (38, 1), (41, 1), (43, 1), 
      (44, 1), (45, 1), (46, 1), (47, 1), (48, 1), (49, 1), (50, 1), (51, 1), (52, 1)
   ]
]

los doc.txt archivo tiene el siguiente contenido -

CNTK, anteriormente conocido como Computational Network Toolkit, es un juego de herramientas de calidad comercial, de código abierto y fácil de usar que nos permite entrenar algoritmos de aprendizaje profundo para aprender como el cerebro humano.

Puede encontrar su tutorial gratuito en tutorialspoint.com y también proporciona los mejores tutoriales técnicos sobre tecnologías como el aprendizaje automático de aprendizaje profundo de inteligencia artificial de forma gratuita.

Ejemplo de implementación completo

import gensim
from gensim import corpora
from pprint import pprint
from gensim.utils import simple_preprocess
from smart_open import smart_open
import os
doc_tokenized = [
   simple_preprocess(line, deacc =True) for line in open(‘doc.txt’, encoding=’utf-8’)
]
dictionary = corpora.Dictionary()
BoW_corpus = [dictionary.doc2bow(doc, allow_update=True) for doc in doc_tokenized]
print(BoW_corpus)

Guardar y cargar un Gensim Corpus

Podemos guardar el corpus con la ayuda del siguiente script:

corpora.MmCorpus.serialize(‘/Users/Desktop/BoW_corpus.mm’, bow_corpus)

#provide the path and the name of the corpus. The name of corpus is BoW_corpus and we saved it in Matrix Market format.

De manera similar, podemos cargar el corpus guardado usando el siguiente script:

corpus_load = corpora.MmCorpus(‘/Users/Desktop/BoW_corpus.mm’)
for line in corpus_load:
print(line)

Este capítulo le ayudará a conocer las distintas transformaciones de Gensim. Comencemos por comprender los documentos transformadores.

Transformar documentos

Transformar documentos significa representar el documento de tal manera que el documento se pueda manipular matemáticamente. Además de deducir la estructura latente del corpus, la transformación de documentos también servirá para los siguientes objetivos:

  • Descubre la relación entre palabras.

  • Destaca la estructura oculta en el corpus.

  • Describe los documentos de una manera nueva y más semántica.

  • Hace que la representación de los documentos sea más compacta.

  • Mejora la eficiencia porque la nueva representación consume menos recursos.

  • Mejora la eficacia porque en la nueva representación se ignoran las tendencias de datos marginales.

  • El ruido también se reduce en la representación de nuevos documentos.

Veamos los pasos de implementación para transformar los documentos de una representación de espacio vectorial a otra.

Pasos de implementación

Para transformar documentos, debemos seguir los siguientes pasos:

Paso 1: creación del corpus

El primer paso básico es crear el corpus a partir de los documentos. Ya hemos creado el corpus en ejemplos anteriores. Creemos otro con algunas mejoras (eliminando palabras comunes y las palabras que aparecen solo una vez) -

import gensim
import pprint
from collections import defaultdict
from gensim import corpora

Ahora proporcione los documentos para crear el corpus:

t_corpus = ["CNTK antes conocido como Computational Network Toolkit", "es un juego de herramientas de código abierto de grado comercial y fácil de usar", "que nos permite entrenar algoritmos de aprendizaje profundo para aprender como el cerebro humano.", " Puede encontrar su tutorial gratuito en tutorialspoint.com "," Tutorialspoint.com también proporciona los mejores tutoriales técnicos sobre tecnologías como el aprendizaje automático de aprendizaje profundo de inteligencia artificial de forma gratuita "]

A continuación, necesitamos hacer tokenise y, junto con él, también eliminaremos las palabras comunes:

stoplist = set('for a of the and to in'.split(' '))
processed_corpus = [
   [
      word for word in document.lower().split() if word not in stoplist
   ]
	for document in t_corpus
]

La siguiente secuencia de comandos eliminará las palabras que solo aparecen:

frequency = defaultdict(int)
for text in processed_corpus:
   for token in text:
      frequency[token] += 1
   processed_corpus = [
      [token for token in text if frequency[token] > 1] 
      for text in processed_corpus
   ]
pprint.pprint(processed_corpus)

Salida

[
   ['toolkit'],
   ['free', 'toolkit'],
   ['deep', 'learning', 'like'],
   ['free', 'on', 'tutorialspoint.com'],
   ['tutorialspoint.com', 'on', 'like', 'deep', 'learning', 'learning', 'free']
]

Ahora páselo al corpora.dictionary() objeto para obtener los objetos únicos en nuestro corpus -

dictionary = corpora.Dictionary(processed_corpus)
print(dictionary)

Salida

Dictionary(7 unique tokens: ['toolkit', 'free', 'deep', 'learning', 'like']...)

A continuación, la siguiente línea de códigos creará el modelo Bag of Word para nuestro corpus:

BoW_corpus = [dictionary.doc2bow(text) for text in processed_corpus]
pprint.pprint(BoW_corpus)

Salida

[
   [(0, 1)],
   [(0, 1), (1, 1)],
   [(2, 1), (3, 1), (4, 1)],
   [(1, 1), (5, 1), (6, 1)],
   [(1, 1), (2, 1), (3, 2), (4, 1), (5, 1), (6, 1)]
]

Paso 2: crear una transformación

Las transformaciones son algunos objetos estándar de Python. Podemos inicializar estas transformaciones, es decir, objetos de Python utilizando un corpus entrenado. Aquí vamos a utilizartf-idf modelo para crear una transformación de nuestro corpus entrenado, es decir BoW_corpus.

Primero, necesitamos importar el paquete de modelos desde gensim.

from gensim import models

Ahora, necesitamos inicializar el modelo de la siguiente manera:

tfidf = models.TfidfModel(BoW_corpus)

Paso 3: Transformar vectores

Ahora, en este último paso, los vectores se convertirán de la representación anterior a la nueva representación. Como hemos inicializado el modelo tfidf en el paso anterior, el tfidf ahora se tratará como un objeto de solo lectura. Aquí, al usar este objeto tfidf, convertiremos nuestro vector de representación de bolsa de palabras (representación anterior) a pesos de valor real Tfidf (nueva representación).

doc_BoW = [(1,1),(3,1)]
print(tfidf[doc_BoW]

Salida

[(1, 0.4869354917707381), (3, 0.8734379353188121)]

Aplicamos la transformación en dos valores de corpus, pero también podemos aplicarla a todo el corpus de la siguiente manera:

corpus_tfidf = tfidf[BoW_corpus]
for doc in corpus_tfidf:
   print(doc)

Salida

[(0, 1.0)]
[(0, 0.8734379353188121), (1, 0.4869354917707381)]
[(2, 0.5773502691896257), (3, 0.5773502691896257), (4, 0.5773502691896257)]
[(1, 0.3667400603126873), (5, 0.657838022678017), (6, 0.657838022678017)]
[
   (1, 0.19338287240886842), (2, 0.34687949360312714), (3, 0.6937589872062543), 
   (4, 0.34687949360312714), (5, 0.34687949360312714), (6, 0.34687949360312714)
]

Ejemplo de implementación completo

import gensim
import pprint
from collections import defaultdict
from gensim import corpora
t_corpus = [
   "CNTK formerly known as Computational Network Toolkit", 
   "is a free easy-to-use open-source commercial-grade toolkit", 
   "that enable us to train deep learning algorithms to learn like the human brain.", 
   "You can find its free tutorial on tutorialspoint.com", 
   "Tutorialspoint.com also provide best technical tutorials on 
   technologies like AI deep learning machine learning for free"
]
stoplist = set('for a of the and to in'.split(' '))
processed_corpus = [
   [word for word in document.lower().split() if word not in stoplist]
   for document in t_corpus
]
frequency = defaultdict(int)
for text in processed_corpus:
   for token in text:
      frequency[token] += 1
   processed_corpus = [
      [token for token in text if frequency[token] > 1] 
      for text in processed_corpus
   ]
pprint.pprint(processed_corpus)
dictionary = corpora.Dictionary(processed_corpus)
print(dictionary)
BoW_corpus = [dictionary.doc2bow(text) for text in processed_corpus]
pprint.pprint(BoW_corpus)
   from gensim import models
   tfidf = models.TfidfModel(BoW_corpus)
   doc_BoW = [(1,1),(3,1)]
   print(tfidf[doc_BoW])
   corpus_tfidf = tfidf[BoW_corpus]
   for doc in corpus_tfidf:
print(doc)

Varias transformaciones en Gensim

Usando Gensim, podemos implementar varias transformaciones populares, es decir, algoritmos del modelo de espacio vectorial. Algunos de ellos son los siguientes:

Tf-Idf (término frecuencia-frecuencia inversa del documento)

Durante la inicialización, este algoritmo de modelo tf-idf espera un corpus de entrenamiento con valores enteros (como el modelo Bag-of-Words). Luego, después de eso, en el momento de la transformación, toma una representación vectorial y devuelve otra representación vectorial.

El vector de salida tendrá la misma dimensionalidad, pero se incrementará el valor de las características raras (en el momento del entrenamiento). Básicamente, convierte vectores con valores enteros en vectores con valores reales. A continuación se muestra la sintaxis de la transformación Tf-idf:

Model=models.TfidfModel(corpus, normalize=True)

LSI (indexación semántica latente)

El algoritmo del modelo LSI puede transformar el documento de un modelo vectorial con valores enteros (como el modelo Bag-of-Words) o del espacio ponderado Tf-Idf en un espacio latente. El vector de salida será de menor dimensionalidad. A continuación se muestra la sintaxis de la transformación LSI:

Model=models.LsiModel(tfidf_corpus, id2word=dictionary, num_topics=300)

LDA (asignación de Dirichlet latente)

El algoritmo del modelo LDA es otro algoritmo que transforma el documento del espacio modelo Bag-of-Words en un espacio temático. El vector de salida será de menor dimensionalidad. A continuación se muestra la sintaxis de la transformación LSI:

Model=models.LdaModel(corpus, id2word=dictionary, num_topics=100)

Proyecciones aleatorias (RP)

RP, un enfoque muy eficiente, tiene como objetivo reducir la dimensionalidad del espacio vectorial. Este enfoque es básicamente una aproximación de las distancias Tf-Idf entre los documentos. Hace esto agregando un poco de aleatoriedad.

Model=models.RpModel(tfidf_corpus, num_topics=500)

Proceso de Dirichlet jerárquico (HDP)

HDP es un método bayesiano no paramétrico que es una nueva incorporación a Gensim. Deberíamos tener cuidado al usarlo.

Model=models.HdpModel(corpus, id2word=dictionary

Aquí, aprenderemos a crear una matriz de frecuencia de documento inversa de frecuencia de término (TF-IDF) con la ayuda de Gensim.

¿Qué es TF-IDF?

Es el modelo de Frecuencia de Término-Frecuencia de Documento Inversa que también es un modelo de bolsa de palabras. Es diferente del corpus regular porque reduce el peso de los tokens, es decir, las palabras que aparecen con frecuencia en los documentos. Durante la inicialización, este algoritmo de modelo tf-idf espera un corpus de entrenamiento con valores enteros (como el modelo Bag-of-Words).

Luego, después de eso, en el momento de la transformación, toma una representación vectorial y devuelve otra representación vectorial. El vector de salida tendrá la misma dimensionalidad, pero se incrementará el valor de las características raras (en el momento del entrenamiento). Básicamente, convierte vectores con valores enteros en vectores con valores reales.

¿Cómo se calcula?

El modelo TF-IDF calcula tfidf con la ayuda de dos sencillos pasos:

Paso 1: multiplicar el componente local y global

En este primer paso, el modelo multiplicará un componente local como TF (frecuencia de término) con un componente global como IDF (frecuencia de documento inverso).

Paso 2: normaliza el resultado

Una vez hecho esto con la multiplicación, en el siguiente paso, el modelo TFIDF normalizará el resultado a la unidad de longitud.

Como resultado de estos dos pasos anteriores, las palabras que aparecen con frecuencia en los documentos se reducirán.

¿Cómo obtener pesos TF-IDF?

Aquí, implementaremos un ejemplo para ver cómo podemos obtener pesos TF-IDF. Básicamente, para obtener pesos TF-IDF, primero necesitamos entrenar el corpus y luego aplicar ese corpus dentro del modelo tfidf.

Entrena al Corpus

Como se dijo anteriormente, para obtener el TF-IDF, primero debemos entrenar nuestro corpus. Primero, necesitamos importar todos los paquetes necesarios de la siguiente manera:

import gensim
import pprint
from gensim import corpora
from gensim.utils import simple_preprocess

Ahora proporcione la lista que contiene las oraciones. Tenemos tres frases en nuestra lista:

doc_list = [
   "Hello, how are you?", "How do you do?", 
   "Hey what are you doing? yes you What are you doing?"
]

A continuación, realice la tokenización de las oraciones de la siguiente manera:

doc_tokenized = [simple_preprocess(doc) for doc in doc_list]

Crea un objeto de corpora.Dictionary() como sigue -

dictionary = corpora.Dictionary()

Ahora pase estas oraciones simbólicas a dictionary.doc2bow() objeto de la siguiente manera -

BoW_corpus = [dictionary.doc2bow(doc, allow_update=True) for doc in doc_tokenized]

A continuación, obtendremos los identificadores de palabras y sus frecuencias en nuestros documentos.

for doc in BoW_corpus:
   print([[dictionary[id], freq] for id, freq in doc])

Salida

[['are', 1], ['hello', 1], ['how', 1], ['you', 1]]
[['how', 1], ['you', 1], ['do', 2]]
[['are', 2], ['you', 3], ['doing', 2], ['hey', 1], ['what', 2], ['yes', 1]]

De esta forma hemos entrenado nuestro corpus (corpus Bag-of-Word).

A continuación, debemos aplicar este corpus entrenado dentro del modelo tfidf models.TfidfModel().

Primero importe el paquete numpay -

import numpy as np

Ahora aplicando nuestro corpus entrenado (BoW_corpus) dentro de los corchetes de models.TfidfModel()

tfidf = models.TfidfModel(BoW_corpus, smartirs='ntc')

A continuación, obtendremos los identificadores de palabras y sus frecuencias en nuestro corpus modelado tfidf:

for doc in tfidf[BoW_corpus]:
   print([[dictionary[id], np.around(freq,decomal=2)] for id, freq in doc])

Salida

[['are', 0.33], ['hello', 0.89], ['how', 0.33]]
[['how', 0.18], ['do', 0.98]]
[['are', 0.23], ['doing', 0.62], ['hey', 0.31], ['what', 0.62], ['yes', 0.31]]

[['are', 1], ['hello', 1], ['how', 1], ['you', 1]]
[['how', 1], ['you', 1], ['do', 2]]
[['are', 2], ['you', 3], ['doing', 2], ['hey', 1], ['what', 2], ['yes', 1]]

[['are', 0.33], ['hello', 0.89], ['how', 0.33]]
[['how', 0.18], ['do', 0.98]]
[['are', 0.23], ['doing', 0.62], ['hey', 0.31], ['what', 0.62], ['yes', 0.31]]

De los resultados anteriores, vemos la diferencia en las frecuencias de las palabras en nuestros documentos.

Ejemplo de implementación completo

import gensim
import pprint
from gensim import corpora
from gensim.utils import simple_preprocess
doc_list = [
   "Hello, how are you?", "How do you do?", 
   "Hey what are you doing? yes you What are you doing?"
]
doc_tokenized = [simple_preprocess(doc) for doc in doc_list]
dictionary = corpora.Dictionary()
BoW_corpus = [dictionary.doc2bow(doc, allow_update=True) for doc in doc_tokenized]
for doc in BoW_corpus:
   print([[dictionary[id], freq] for id, freq in doc])
import numpy as np
tfidf = models.TfidfModel(BoW_corpus, smartirs='ntc')
for doc in tfidf[BoW_corpus]:
   print([[dictionary[id], np.around(freq,decomal=2)] for id, freq in doc])

Diferencia de peso de palabras

Como se mencionó anteriormente, las palabras que aparecerán con más frecuencia en el documento obtendrán los pesos más pequeños. Entendamos la diferencia en el peso de las palabras de los dos resultados anteriores. La palabra‘are’ocurre en dos documentos y se han reducido. Del mismo modo, la palabra‘you’ que aparecen en todos los documentos y se eliminan por completo.

Este capítulo trata sobre el modelado de temas con respecto a Gensim.

Para anotar nuestros datos y comprender la estructura de la oración, uno de los mejores métodos es utilizar algoritmos lingüísticos computacionales. Sin duda, con la ayuda de estos algoritmos lingüísticos computacionales podemos comprender algunos detalles más finos sobre nuestros datos, pero,

  • ¿Podemos saber qué tipo de palabras aparecen con más frecuencia que otras en nuestro corpus?

  • ¿Podemos agrupar nuestros datos?

  • ¿Podemos ser temas subyacentes en nuestros datos?

Podríamos lograr todo esto con la ayuda del modelado de temas. Así que profundicemos en el concepto de modelos temáticos.

¿Qué son los modelos de tema?

Un modelo de tema puede definirse como el modelo probabilístico que contiene información sobre los temas de nuestro texto. Pero aquí surgen dos preguntas importantes que son las siguientes:

Primero, what exactly a topic is?

El tema, como su nombre lo indica, son las ideas subyacentes o los temas representados en nuestro texto. Para darle un ejemplo, el corpus que contienenewspaper articles tendría los temas relacionados con finance, weather, politics, sports, various states news y así.

Segundo, what is the importance of topic models in text processing?

Como sabemos, para identificar similitudes en el texto, podemos utilizar técnicas de búsqueda y recuperación de información mediante el uso de palabras. Pero, con la ayuda de modelos de temas, ahora podemos buscar y organizar nuestros archivos de texto usando temas en lugar de palabras.

En este sentido podemos decir que los temas son la distribución probabilística de palabras. Es por eso que, al usar modelos de temas, podemos describir nuestros documentos como distribuciones probabilísticas de temas.

Objetivos de los modelos de tema

Como se discutió anteriormente, el enfoque del modelado de temas es sobre ideas y temas subyacentes. Sus principales objetivos son los siguientes:

  • Los modelos de temas se pueden utilizar para resumir el texto.

  • Se pueden utilizar para organizar los documentos. Por ejemplo, podemos usar el modelado de temas para agrupar artículos de noticias en una sección organizada / interconectada, como organizar todos los artículos de noticias relacionados concricket.

  • Pueden mejorar el resultado de la búsqueda. ¿Cómo? Para una consulta de búsqueda, podemos usar modelos de temas para revelar que el documento tiene una combinación de diferentes palabras clave, pero que tienen la misma idea.

  • El concepto de recomendaciones es muy útil para el marketing. Es utilizado por varios sitios web de compras en línea, sitios web de noticias y muchos más. Los modelos de temas ayudan a hacer recomendaciones sobre qué comprar, qué leer a continuación, etc. Lo hacen buscando materiales que tengan un tema común en la lista.

Algoritmos de modelado de temas en Gensim

Sin lugar a dudas, Gensim es el conjunto de herramientas de modelado de temas más popular. Su disponibilidad gratuita y estar en Python lo hacen más popular. En esta sección, discutiremos algunos de los algoritmos de modelado de temas más populares. Aquí, nos centraremos en "qué" en lugar de "cómo" porque Gensim los abstrae muy bien para nosotros.

Asignación de Dirichlet latente (LDA)

La asignación de Dirichlet latente (LDA) es la técnica más común y popular actualmente en uso para el modelado de temas. Es el que los investigadores de Facebook utilizaron en su artículo de investigación publicado en 2013. Fue propuesto por primera vez por David Blei, Andrew Ng y Michael Jordan en 2003. Propusieron LDA en su artículo que se titulaba simplementeLatent Dirichlet allocation.

Características de LDA

Conozcamos más sobre esta maravillosa técnica a través de sus características -

Probabilistic topic modeling technique

LDA es una técnica de modelado de temas probabilísticos. Como discutimos anteriormente, en el modelado de temas asumimos que en cualquier colección de documentos interrelacionados (pueden ser artículos académicos, artículos de periódicos, publicaciones de Facebook, tweets, correos electrónicos, etc.), hay algunas combinaciones de temas incluidos en cada documento. .

El objetivo principal del modelado probabilístico de temas es descubrir la estructura de tema oculta para la recopilación de documentos interrelacionados. Las siguientes tres cosas se incluyen generalmente en la estructura de un tema:

  • Topics

  • Distribución estadística de temas entre los documentos

  • Palabras en un documento que comprende el tema

Work in an unsupervised way

LDA funciona de forma no supervisada. Es porque, LDA usa probabilidades condicionales para descubrir la estructura del tema oculto. Se asume que los temas están distribuidos de manera desigual a lo largo de la colección de documentos interrelacionados.

Very easy to create it in Gensim

En Gensim, es muy fácil crear un modelo LDA. solo necesitamos especificar el corpus, el mapeo del diccionario y la cantidad de temas que nos gustaría usar en nuestro modelo.

Model=models.LdaModel(corpus, id2word=dictionary, num_topics=100)

May face computationally intractable problem

Calcular la probabilidad de cada posible estructura temática es un desafío computacional al que se enfrenta LDA. Es un desafío porque necesita calcular la probabilidad de cada palabra observada en cada posible estructura temática. Si tenemos una gran cantidad de temas y palabras, LDA puede enfrentar un problema computacionalmente intratable.

Indexación semántica latente (LSI)

Los algoritmos de modelado de temas que se implementaron por primera vez en Gensim con Latent Dirichlet Allocation (LDA) es Latent Semantic Indexing (LSI). También es llamadoLatent Semantic Analysis (LSA).

Fue patentado en 1988 por Scott Deerwester, Susan Dumais, George Furnas, Richard Harshman, Thomas Landaur, Karen Lochbaum y Lynn Streeter. En esta sección vamos a configurar nuestro modelo LSI. Se puede hacer de la misma manera que configura el modelo LDA. necesitamos importar el modelo LSI degensim.models.

Papel de LSI

En realidad, LSI es una técnica de PNL, especialmente en semántica distributiva. Analiza la relación entre un conjunto de documentos y los términos que contienen estos documentos. Si hablamos de su funcionamiento, entonces construye una matriz que contiene recuentos de palabras por documento a partir de una gran parte de texto.

Una vez construido, para reducir el número de filas, el modelo LSI utiliza una técnica matemática llamada descomposición de valor singular (SVD). Además de reducir el número de filas, también conserva la estructura de similitud entre columnas. En la matriz, las filas representan palabras únicas y las columnas representan cada documento. Funciona sobre la base de hipótesis de distribución, es decir, asume que las palabras que tienen un significado cercano aparecerán en el mismo tipo de texto.

Model=models.LsiModel(corpus, id2word=dictionary, num_topics=100)

Proceso de Dirichlet jerárquico (HDP)

Los modelos de temas como LDA y LSI ayudan a resumir y organizar grandes archivos de textos que no es posible analizar a mano. Además de LDA y LSI, otro modelo de tema poderoso en Gensim es HDP (Proceso de Dirichlet jerárquico). Básicamente, es un modelo de membresía mixta para el análisis no supervisado de datos agrupados. A diferencia de LDA (su contraparte finita), HDP infiere el número de temas de los datos.

Model=models.HdpModel(corpus, id2word=dictionary

Este capítulo le ayudará a aprender cómo crear un modelo de tema de asignación de Dirichlet latente (LDA) en Gensim.

Extracción automática de información sobre temas de un gran volumen de textos en una de las aplicaciones principales de PNL (procesamiento del lenguaje natural). Un gran volumen de textos podría ser información de reseñas de hoteles, tweets, publicaciones de Facebook, fuentes de cualquier otro canal de redes sociales, reseñas de películas, noticias, comentarios de usuarios, correos electrónicos, etc.

En esta era digital, saber de qué están hablando las personas / clientes, comprender sus opiniones y sus problemas, puede ser muy valioso para las empresas, las campañas políticas y los administradores. Pero, ¿es posible leer manualmente volúmenes tan grandes de texto y luego extraer la información de los temas?

No, no es. Requiere un algoritmo automático que pueda leer este gran volumen de documentos de texto y extraer automáticamente la información o los temas que se debaten.

Papel de LDA

El enfoque de LDA para el modelado de temas es clasificar el texto de un documento en un tema en particular. Modelado como distribuciones de Dirichlet, LDA construye:

  • Un tema por modelo de documento y
  • Palabras por modelo de tema

Después de proporcionar el algoritmo del modelo de tema LDA, para obtener una buena composición de la distribución tema-palabra clave, reorganiza:

  • Las distribuciones de temas dentro del documento y
  • Distribución de palabras clave dentro de los temas.

Durante el procesamiento, algunas de las suposiciones hechas por LDA son:

  • Cada documento se modela como distribuciones multinominales de temas.
  • Cada tema se modela como distribuciones multinominales de palabras.
  • Deberíamos elegir el corpus de datos correcto porque LDA supone que cada fragmento de texto contiene las palabras relacionadas.
  • LDA también asume que los documentos se producen a partir de una combinación de temas.

Implementación con Gensim

Aquí, vamos a utilizar LDA (asignación de Dirichlet latente) para extraer los temas discutidos naturalmente del conjunto de datos.

Cargando conjunto de datos

El conjunto de datos que vamos a utilizar es el conjunto de datos de ’20 Newsgroups’tener miles de artículos de noticias de varias secciones de un informe de noticias. Está disponible bajoSklearnconjuntos de datos. Podemos descargar fácilmente con la ayuda de la siguiente secuencia de comandos de Python:

from sklearn.datasets import fetch_20newsgroups
newsgroups_train = fetch_20newsgroups(subset='train')

Veamos algunas de las noticias de muestra con la ayuda del siguiente guión:

newsgroups_train.data[:4]
["From: [email protected] (where's my thing)\nSubject: 
WHAT car is this!?\nNntp-Posting-Host: rac3.wam.umd.edu\nOrganization: 
University of Maryland, College Park\nLines: 
15\n\n I was wondering if anyone out there could enlighten me on this car 
I saw\nthe other day. It was a 2-door sports car, looked to be from the 
late 60s/\nearly 70s. It was called a Bricklin. The doors were really small. 
In addition,\nthe front bumper was separate from the rest of the body. 
This is \nall I know. If anyone can tellme a model name, 
engine specs, years\nof production, where this car is made, history, or 
whatever info you\nhave on this funky looking car, please e-mail.\n\nThanks,
\n- IL\n ---- brought to you by your neighborhood Lerxst ----\n\n\n\n\n",

"From: [email protected] (Guy Kuo)\nSubject: SI Clock Poll - Final 
Call\nSummary: Final call for SI clock reports\nKeywords: 
SI,acceleration,clock,upgrade\nArticle-I.D.: shelley.1qvfo9INNc3s\nOrganization: 
University of Washington\nLines: 11\nNNTP-Posting-Host: carson.u.washington.edu\n\nA 
fair number of brave souls who upgraded their SI clock oscillator have\nshared their 
experiences for this poll. Please send a brief message detailing\nyour experiences with 
the procedure. Top speed attained, CPU rated speed,\nadd on cards and adapters, heat 
sinks, hour of usage per day, floppy disk\nfunctionality with 800 and 1.4 m floppies 
are especially requested.\n\nI will be summarizing in the next two days, so please add 
to the network\nknowledge base if you have done the clock upgrade and haven't answered 
this\npoll. Thanks.\n\nGuy Kuo <;[email protected]>\n",

'From: [email protected] (Thomas E Willis)\nSubject: 
PB questions...\nOrganization: Purdue University Engineering 
Computer Network\nDistribution: usa\nLines: 36\n\nwell folks, 
my mac plus finally gave up the ghost this weekend after\nstarting 
life as a 512k way back in 1985. sooo, i\'m in the market for 
a\nnew machine a bit sooner than i intended to be...\n\ni\'m looking 
into picking up a powerbook 160 or maybe 180 and have a bunch\nof 
questions that (hopefully) somebody can answer:\n\n* does anybody 
know any dirt on when the next round of powerbook\nintroductions 
are expected? i\'d heard the 185c was supposed to make an\nappearence 
"this summer" but haven\'t heard anymore on it - and since i\ndon\'t 
have access to macleak, i was wondering if anybody out there had\nmore 
info...\n\n* has anybody heard rumors about price drops to the powerbook 
line like the\nones the duo\'s just went through recently?\n\n* what\'s 
the impression of the display on the 180? i could probably swing\na 180 
if i got the 80Mb disk rather than the 120, but i don\'t really have\na 
feel for how much "better" the display is (yea, it looks great in the\nstore, 
but is that all "wow" or is it really that good?). could i solicit\nsome 
opinions of people who use the 160 and 180 day-to-day on if its
worth\ntaking the disk size and money hit to get the active display? 
(i realize\nthis is a real subjective question, but i\'ve only played around 
with the\nmachines in a computer store breifly and figured the opinions 
of somebody\nwho actually uses the machine daily might prove helpful).\n\n* 
how well does hellcats perform? ;)\n\nthanks a bunch in advance for any info - 
if you could email, i\'ll post a\nsummary (news reading time is at a premium 
with finals just around the\ncorner... :
( )\n--\nTom Willis \\ [email protected] \\ Purdue Electrical 
Engineering\n---------------------------------------------------------------------------\
n"Convictions are more dangerous enemies of truth than lies." - F. W.\nNietzsche\n',

'From: [email protected] (Joe Green)\nSubject: Re: Weitek P9000 ?\nOrganization: 
Harris Computer Systems Division\nLines: 14\nDistribution: world\nNNTP-Posting-Host: 
amber.ssd.csd.harris.com\nX-Newsreader: TIN [version 1.1 PL9]\n\nRobert 
J.C. Kyanko ([email protected]) wrote:\n >[email protected] writes in article 
<[email protected] >:\n> > Anyone know about the 
Weitek P9000 graphics chip?\n > As far as the low-level stuff goes, it looks 
pretty nice. It\'s got this\n> quadrilateral fill command that requires just 
the four points.\n\nDo you have Weitek\'s address/phone number? I\'d like to get 
some information\nabout this chip.\n\n--\nJoe Green\t\t\t\tHarris 
Corporation\[email protected]\t\t\tComputer Systems Division\n"The only 
thing that really scares me is a person with no sense of humor.
"\n\t\t\t\t\t\t-- Jonathan Winters\n']

Requisito previo

Necesitamos palabras vacías de NLTK y el modelo en inglés de Scapy. Ambos se pueden descargar de la siguiente manera:

import nltk;
nltk.download('stopwords')
nlp = spacy.load('en_core_web_md', disable=['parser', 'ner'])

Importación de paquetes necesarios

Para construir el modelo LDA, necesitamos importar el siguiente paquete necesario:

import re
import numpy as np
import pandas as pd
from pprint import pprint
import gensim
import gensim.corpora as corpora
from gensim.utils import simple_preprocess
from gensim.models import CoherenceModel
import spacy
import pyLDAvis
import pyLDAvis.gensim
import matplotlib.pyplot as plt

Preparación de palabras vacías

Ahora, necesitamos importar las palabras vacías y usarlas:

from nltk.corpus import stopwords
stop_words = stopwords.words('english')
stop_words.extend(['from', 'subject', 're', 'edu', 'use'])

Limpiar el texto

Ahora, con la ayuda de Gensim's simple_preprocess()necesitamos tokenizar cada oración en una lista de palabras. También debemos eliminar las puntuaciones y los caracteres innecesarios. Para hacer esto, crearemos una función llamadasent_to_words() -

def sent_to_words(sentences):
   for sentence in sentences:
      yield(gensim.utils.simple_preprocess(str(sentence), deacc=True))
data_words = list(sent_to_words(data))

Creación de modelos Bigram y Trigram

Como sabemos, los bigramas son dos palabras que aparecen juntas con frecuencia en el documento y los trigramas son tres palabras que aparecen juntas con frecuencia en el documento. Con la ayuda de Gensim'sPhrases modelo, podemos hacer esto -

bigram = gensim.models.Phrases(data_words, min_count=5, threshold=100)
trigram = gensim.models.Phrases(bigram[data_words], threshold=100)
bigram_mod = gensim.models.phrases.Phraser(bigram)
trigram_mod = gensim.models.phrases.Phraser(trigram)

Filtrar palabras vacías

A continuación, debemos filtrar las palabras vacías. Junto con eso, también crearemos funciones para hacer bigramas, trigramas y para lematización -

def remove_stopwords(texts):
   return [[word for word in simple_preprocess(str(doc))
if word not in stop_words] for doc in texts]
def make_bigrams(texts):
   return [bigram_mod[doc] for doc in texts]
def make_trigrams(texts):
   return [trigram_mod[bigram_mod[doc]] for doc in texts]
def lemmatization(texts, allowed_postags=['NOUN', 'ADJ', 'VERB', 'ADV']):
   texts_out = []
   for sent in texts:
     doc = nlp(" ".join(sent))
     texts_out.append([token.lemma_ for token in doc if token.pos_ in allowed_postags])
   return texts_out

Creación de diccionario y corpus para el modelo de tema

Ahora necesitamos construir el diccionario y el corpus. También lo hicimos en los ejemplos anteriores:

id2word = corpora.Dictionary(data_lemmatized)
texts = data_lemmatized
corpus = [id2word.doc2bow(text) for text in texts]

Modelo de tema de construcción de LDA

Ya implementamos todo lo que se requiere para entrenar el modelo LDA. Ahora es el momento de construir el modelo de temas de LDA. Para nuestro ejemplo de implementación, se puede hacer con la ayuda de la siguiente línea de códigos:

lda_model = gensim.models.ldamodel.LdaModel(
   corpus=corpus, id2word=id2word, num_topics=20, random_state=100, 
   update_every=1, chunksize=100, passes=10, alpha='auto', per_word_topics=True
)

Ejemplo de implementación

Veamos el ejemplo de implementación completo para construir el modelo de temas de LDA:

import re
import numpy as np
import pandas as pd
from pprint import pprint
import gensim
import gensim.corpora as corpora
from gensim.utils import simple_preprocess
from gensim.models import CoherenceModel
import spacy
import pyLDAvis
import pyLDAvis.gensim
import matplotlib.pyplot as plt
from nltk.corpus import stopwords
stop_words = stopwords.words('english')
stop_words.extend(['from', 'subject', 're', 'edu', 'use'])
from sklearn.datasets import fetch_20newsgroups
newsgroups_train = fetch_20newsgroups(subset='train')
data = newsgroups_train.data
data = [re.sub('\S*@\S*\s?', '', sent) for sent in data]
data = [re.sub('\s+', ' ', sent) for sent in data]
data = [re.sub("\'", "", sent) for sent in data]
print(data_words[:4]) #it will print the data after prepared for stopwords
bigram = gensim.models.Phrases(data_words, min_count=5, threshold=100)
trigram = gensim.models.Phrases(bigram[data_words], threshold=100)
bigram_mod = gensim.models.phrases.Phraser(bigram)
trigram_mod = gensim.models.phrases.Phraser(trigram)
def remove_stopwords(texts):
   return [[word for word in simple_preprocess(str(doc)) 
   if word not in stop_words] for doc in texts]
def make_bigrams(texts):
   return [bigram_mod[doc] for doc in texts]
def make_trigrams(texts):
   [trigram_mod[bigram_mod[doc]] for doc in texts]
def lemmatization(texts, allowed_postags=['NOUN', 'ADJ', 'VERB', 'ADV']):
   texts_out = []
   for sent in texts:
      doc = nlp(" ".join(sent))
      texts_out.append([token.lemma_ for token in doc if token.pos_ in allowed_postags])
   return texts_out
data_words_nostops = remove_stopwords(data_words)
data_words_bigrams = make_bigrams(data_words_nostops)
nlp = spacy.load('en_core_web_md', disable=['parser', 'ner'])
data_lemmatized = lemmatization(data_words_bigrams, allowed_postags=[
   'NOUN', 'ADJ', 'VERB', 'ADV'
])
print(data_lemmatized[:4]) #it will print the lemmatized data.
id2word = corpora.Dictionary(data_lemmatized)
texts = data_lemmatized
corpus = [id2word.doc2bow(text) for text in texts]
print(corpus[:4]) #it will print the corpus we created above.
[[(id2word[id], freq) for id, freq in cp] for cp in corpus[:4]] 
#it will print the words with their frequencies.
lda_model = gensim.models.ldamodel.LdaModel(
   corpus=corpus, id2word=id2word, num_topics=20, random_state=100, 
   update_every=1, chunksize=100, passes=10, alpha='auto', per_word_topics=True
)

Ahora podemos usar el modelo LDA creado anteriormente para obtener los temas y calcular la perplejidad del modelo.

En este capítulo, entenderemos cómo utilizar el modelo de tema de asignación de Dirichlet latente (LDA).

Visualización de temas en el modelo LDA

El modelo LDA (lda_model) que hemos creado anteriormente se puede utilizar para ver los temas de los documentos. Se puede hacer con la ayuda del siguiente script:

pprint(lda_model.print_topics())
doc_lda = lda_model[corpus]

Salida

[
   (0, 
   '0.036*"go" + 0.027*"get" + 0.021*"time" + 0.017*"back" + 0.015*"good" + '
   '0.014*"much" + 0.014*"be" + 0.013*"car" + 0.013*"well" + 0.013*"year"'),
   (1,
   '0.078*"screen" + 0.067*"video" + 0.052*"character" + 0.046*"normal" + '
   '0.045*"mouse" + 0.034*"manager" + 0.034*"disease" + 0.031*"processor" + '
   '0.028*"excuse" + 0.028*"choice"'),
   (2,
   '0.776*"ax" + 0.079*"_" + 0.011*"boy" + 0.008*"ticket" + 0.006*"red" + '
   '0.004*"conservative" + 0.004*"cult" + 0.004*"amazing" + 0.003*"runner" + '
   '0.003*"roughly"'),
   (3,
   '0.086*"season" + 0.078*"fan" + 0.072*"reality" + 0.065*"trade" + '
   '0.045*"concept" + 0.040*"pen" + 0.028*"blow" + 0.025*"improve" + '
   '0.025*"cap" + 0.021*"penguin"'),
   (4,
   '0.027*"group" + 0.023*"issue" + 0.016*"case" + 0.016*"cause" + '
   '0.014*"state" + 0.012*"whole" + 0.012*"support" + 0.011*"government" + '
   '0.010*"year" + 0.010*"rate"'),
   (5,
   '0.133*"evidence" + 0.047*"believe" + 0.044*"religion" + 0.042*"belief" + '
   '0.041*"sense" + 0.041*"discussion" + 0.034*"atheist" + 0.030*"conclusion" +
   '
   '0.029*"explain" + 0.029*"claim"'),
   (6,
   '0.083*"space" + 0.059*"science" + 0.031*"launch" + 0.030*"earth" + '
   '0.026*"route" + 0.024*"orbit" + 0.024*"scientific" + 0.021*"mission" + '
   '0.018*"plane" + 0.017*"satellite"'),
   (7,
   '0.065*"file" + 0.064*"program" + 0.048*"card" + 0.041*"window" + '
   '0.038*"driver" + 0.037*"software" + 0.034*"run" + 0.029*"machine" + '
   '0.029*"entry" + 0.028*"version"'),
   (8,
   '0.078*"publish" + 0.059*"mount" + 0.050*"turkish" + 0.043*"armenian" + '
   '0.027*"western" + 0.026*"russian" + 0.025*"locate" + 0.024*"proceed" + '
   '0.024*"electrical" + 0.022*"terrorism"'),
   (9,
   '0.023*"people" + 0.023*"child" + 0.021*"kill" + 0.020*"man" + 0.019*"death" '
   '+ 0.015*"die" + 0.015*"live" + 0.014*"attack" + 0.013*"age" + '
   '0.011*"church"'),
   (10,
   '0.092*"cpu" + 0.085*"black" + 0.071*"controller" + 0.039*"white" + '
   '0.028*"water" + 0.027*"cold" + 0.025*"solid" + 0.024*"cool" + 0.024*"heat" '
   '+ 0.023*"nuclear"'),
   (11,
   '0.071*"monitor" + 0.044*"box" + 0.042*"option" + 0.041*"generate" + '
   '0.038*"vote" + 0.032*"battery" + 0.029*"wave" + 0.026*"tradition" + '
   '0.026*"fairly" + 0.025*"task"'),
   (12,
   '0.048*"send" + 0.045*"mail" + 0.036*"list" + 0.033*"include" + '
   '0.032*"price" + 0.031*"address" + 0.027*"email" + 0.026*"receive" + '
   '0.024*"book" + 0.024*"sell"'),
   (13,
   '0.515*"drive" + 0.052*"laboratory" + 0.042*"blind" + 0.020*"investment" + '
   '0.011*"creature" + 0.010*"loop" + 0.005*"dialog" + 0.000*"slave" + '
   '0.000*"jumper" + 0.000*"sector"'),
   (14,
   '0.153*"patient" + 0.066*"treatment" + 0.062*"printer" + 0.059*"doctor" + '

   '0.036*"medical" + 0.031*"energy" + 0.029*"study" + 0.029*"probe" + '
   '0.024*"mph" + 0.020*"physician"'),
   (15,
   '0.068*"law" + 0.055*"gun" + 0.039*"government" + 0.036*"right" + '
   '0.029*"state" + 0.026*"drug" + 0.022*"crime" + 0.019*"person" + '
   '0.019*"citizen" + 0.019*"weapon"'),
   (16,
   '0.107*"team" + 0.102*"game" + 0.078*"play" + 0.055*"win" + 0.052*"player" + '
   '0.051*"year" + 0.030*"score" + 0.025*"goal" + 0.023*"wing" + 0.023*"run"'),
   (17,
   '0.031*"say" + 0.026*"think" + 0.022*"people" + 0.020*"make" + 0.017*"see" + '
   '0.016*"know" + 0.013*"come" + 0.013*"even" + 0.013*"thing" + 0.013*"give"'),
   (18,
   '0.039*"system" + 0.034*"use" + 0.023*"key" + 0.016*"bit" + 0.016*"also" + '
   '0.015*"information" + 0.014*"source" + 0.013*"chip" + 0.013*"available" + '
   '0.010*"provide"'),
   (19,
   '0.085*"line" + 0.073*"write" + 0.053*"article" + 0.046*"organization" + '
   '0.034*"host" + 0.023*"be" + 0.023*"know" + 0.017*"thank" + 0.016*"want" + '
   '0.014*"help"')
]

Perplejidad del modelo de computación

El modelo LDA (lda_model) que hemos creado anteriormente se puede utilizar para calcular la perplejidad del modelo, es decir, qué tan bueno es el modelo. Cuanto menor sea la puntuación, mejor será el modelo. Se puede hacer con la ayuda del siguiente script:

print('\nPerplexity: ', lda_model.log_perplexity(corpus))

Salida

Perplexity: -12.338664984332151

Puntuación de coherencia informática

El modelo LDA (lda_model)que hemos creado anteriormente se puede utilizar para calcular la puntuación de coherencia del modelo, es decir, el promedio / mediana de las puntuaciones de similitud de palabras por pares de las palabras del tema. Se puede hacer con la ayuda del siguiente script:

coherence_model_lda = CoherenceModel(
   model=lda_model, texts=data_lemmatized, dictionary=id2word, coherence='c_v'
)
coherence_lda = coherence_model_lda.get_coherence()
print('\nCoherence Score: ', coherence_lda)

Salida

Coherence Score: 0.510264381411751

Visualización de temas-palabras clave

El modelo LDA (lda_model)que hemos creado anteriormente se puede utilizar para examinar los temas producidos y las palabras clave asociadas. Se puede visualizar usandopyLDAvispaquete de la siguiente manera:

pyLDAvis.enable_notebook()
vis = pyLDAvis.gensim.prepare(lda_model, corpus, id2word)
vis

Salida

De la salida anterior, las burbujas en el lado izquierdo representan un tema y cuanto más grande es la burbuja, más frecuente es ese tema. El modelo de tema será bueno si el modelo de tema tiene burbujas grandes que no se superponen repartidas por todo el gráfico.

Este capítulo explicará qué es un modelo de mazo de asignación de Dirichlet latente (LDA) y cómo crearlo en Gensim.

En la sección anterior hemos implementado el modelo LDA y obtenemos los temas de los documentos del conjunto de datos de 20Newsgroup. Esa era la versión incorporada de Gensim del algoritmo LDA. También hay una versión Mallet de Gensim, que proporciona una mejor calidad de los temas. Aquí, vamos a aplicar LDA de Mallet en el ejemplo anterior que ya hemos implementado.

¿Qué es el modelo LDA Mallet?

Mallet, un conjunto de herramientas de código abierto, fue escrito por Andrew McCullum. Básicamente es un paquete basado en Java que se utiliza para NLP, clasificación de documentos, agrupación en clústeres, modelado de temas y muchas otras aplicaciones de aprendizaje automático para texto. Nos proporciona el kit de herramientas de modelado de temas de Mallet que contiene implementaciones eficientes y basadas en muestras de LDA, así como LDA jerárquico.

Mallet2.0 es la versión actual de MALLET, el kit de herramientas de modelado de temas de Java. Antes de comenzar a usarlo con Gensim para LDA, debemos descargar el paquete mallet-2.0.8.zip en nuestro sistema y descomprimirlo. Una vez instalado y descomprimido, establezca la variable de entorno% MALLET_HOME% para que apunte al directorio MALLET ya sea manualmente o por el código que le proporcionaremos, mientras implementamos el LDA con Mallet a continuación.

Envoltorio Gensim

Python proporciona un contenedor Gensim para la asignación de Dirichlet latente (LDA). La sintaxis de ese contenedor esgensim.models.wrappers.LdaMallet. Este módulo, muestreo de Gibbs contraído de MALLET, permite la estimación del modelo LDA a partir de un corpus de capacitación y la inferencia de la distribución de temas en documentos nuevos y no vistos también.

Ejemplo de implementación

Usaremos LDA Mallet en un modelo LDA construido previamente y verificaremos la diferencia en el rendimiento calculando la puntuación de coherencia.

Proporcionar ruta al archivo Mallet

Antes de aplicar el modelo Mallet LDA en nuestro corpus construido en el ejemplo anterior, debemos actualizar las variables de entorno y proporcionar también la ruta del archivo Mallet. Se puede hacer con la ayuda del siguiente código:

import os
from gensim.models.wrappers import LdaMallet
os.environ.update({'MALLET_HOME':r'C:/mallet-2.0.8/'}) 
#You should update this path as per the path of Mallet directory on your system.
mallet_path = r'C:/mallet-2.0.8/bin/mallet' 
#You should update this path as per the path of Mallet directory on your system.

Una vez que proporcionamos la ruta al archivo Mallet, ahora podemos usarlo en el corpus. Se puede hacer con la ayuda deldamallet.show_topics() funciona de la siguiente manera:

ldamallet = gensim.models.wrappers.LdaMallet(
   mallet_path, corpus=corpus, num_topics=20, id2word=id2word
)
pprint(ldamallet.show_topics(formatted=False))

Salida

[
   (4,
   [('gun', 0.024546225966016102),
   ('law', 0.02181426826996709),
   ('state', 0.017633545129043606),
   ('people', 0.017612848479831116),
   ('case', 0.011341763768445888),
   ('crime', 0.010596684396796159),
   ('weapon', 0.00985160502514643),
   ('person', 0.008671896020034356),
   ('firearm', 0.00838214293105946),
   ('police', 0.008257963035784506)]),
   (9,
   [('make', 0.02147966482730431),
   ('people', 0.021377478029838543),
   ('work', 0.018557122419783363),
   ('money', 0.016676885346413244),
   ('year', 0.015982015123646026),
   ('job', 0.012221540976905783),
   ('pay', 0.010239117106069897),
   ('time', 0.008910688739014919),
   ('school', 0.0079092581238504),
   ('support', 0.007357449417535254)]),
   (14,
   [('power', 0.018428398507941996),
   ('line', 0.013784244460364121),
   ('high', 0.01183271164249895),
   ('work', 0.011560979224821522),
   ('ground', 0.010770484918850819),
   ('current', 0.010745781971789235),
   ('wire', 0.008399002000938712),
   ('low', 0.008053160742076529),
   ('water', 0.006966231071366814),
   ('run', 0.006892122230182061)]),
   (0,
   [('people', 0.025218349201353372),
   ('kill', 0.01500904870564167),
   ('child', 0.013612400660948935),
   ('armenian', 0.010307655991816822),
   ('woman', 0.010287984892595798),
   ('start', 0.01003226060272248),
   ('day', 0.00967818081674404),
   ('happen', 0.009383114328428673),
   ('leave', 0.009383114328428673),
   ('fire', 0.009009363443229208)]),
   (1,
   [('file', 0.030686386604212003),
   ('program', 0.02227713642901929),
   ('window', 0.01945561169918489),
   ('set', 0.015914874783314277),
   ('line', 0.013831003577619592),
   ('display', 0.013794120901412606),
   ('application', 0.012576992586582082),
   ('entry', 0.009275993066056873),
   ('change', 0.00872275292295209),
   ('color', 0.008612104894331132)]),
   (12,
   [('line', 0.07153810971508515),
   ('buy', 0.02975597944523662),
   ('organization', 0.026877236406682988),
   ('host', 0.025451316957679788),
   ('price', 0.025182275552207485),
   ('sell', 0.02461728860071565),
   ('mail', 0.02192687454599263),
   ('good', 0.018967419085797303),
   ('sale', 0.017998870026097017),
   ('send', 0.013694207538540181)]),
   (11,
   [('thing', 0.04901329901329901),
   ('good', 0.0376018876018876),
   ('make', 0.03393393393393394),
   ('time', 0.03326898326898327),
   ('bad', 0.02664092664092664),
   ('happen', 0.017696267696267698),
   ('hear', 0.015615615615615615),
   ('problem', 0.015465465465465466),
   ('back', 0.015143715143715144),
   ('lot', 0.01495066495066495)]),
   (18,
   [('space', 0.020626317374284855),
   ('launch', 0.00965716006366413),
   ('system', 0.008560244332602057),
   ('project', 0.008173097603991913),
   ('time', 0.008108573149223556),
   ('cost', 0.007764442723792318),
   ('year', 0.0076784101174345075),
   ('earth', 0.007484836753129436),
   ('base', 0.0067535595990880545),
   ('large', 0.006689035144319697)]),
   (5,
   [('government', 0.01918437232469453),
   ('people', 0.01461203206475212),
   ('state', 0.011207097828624796),
   ('country', 0.010214802708381975),
   ('israeli', 0.010039691804809714),
   ('war', 0.009436532025838587),
   ('force', 0.00858043427504086),
   ('attack', 0.008424780138532182),
   ('land', 0.0076659662230523775),
   ('world', 0.0075103120865437)]),
   (2,
   [('car', 0.041091194044470564),
   ('bike', 0.015598981291017729),
   ('ride', 0.011019688510138114),
   ('drive', 0.010627877363110981),
   ('engine', 0.009403467528651191),
   ('speed', 0.008081104907434616),
   ('turn', 0.007738270153785875),
   ('back', 0.007738270153785875),
   ('front', 0.007468899990204721),
   ('big', 0.007370947203447938)])
]

Evaluación del desempeño

Ahora también podemos evaluar su desempeño calculando la puntuación de coherencia de la siguiente manera:

ldamallet = gensim.models.wrappers.LdaMallet(
   mallet_path, corpus=corpus, num_topics=20, id2word=id2word
)
pprint(ldamallet.show_topics(formatted=False))

Salida

Coherence Score: 0.5842762900901401

Este capítulo analiza los documentos y el modelo LDA en Gensim.

Encontrar el número óptimo de temas para LDA

Podemos encontrar el número óptimo de temas para LDA creando muchos modelos LDA con varios valores de temas. Entre esos LDA podemos elegir uno que tenga el valor de coherencia más alto.

Siguiente función nombrada coherence_values_computation()entrenará múltiples modelos LDA. También proporcionará los modelos, así como su correspondiente puntuación de coherencia.

def coherence_values_computation(dictionary, corpus, texts, limit, start=2, step=3):
   coherence_values = []
   model_list = []
   for num_topics in range(start, limit, step):
      model = gensim.models.wrappers.LdaMallet(
         mallet_path, corpus=corpus, num_topics=num_topics, id2word=id2word
      )
      model_list.append(model)
   coherencemodel = CoherenceModel(
      model=model, texts=texts, dictionary=dictionary, coherence='c_v'
   )
   coherence_values.append(coherencemodel.get_coherence())
return model_list, coherence_values

Ahora, con la ayuda del siguiente código, podemos obtener la cantidad óptima de temas que podemos mostrar con la ayuda de un gráfico también:

model_list, coherence_values = coherence_values_computation (
   dictionary=id2word, corpus=corpus, texts=data_lemmatized, 
   start=1, limit=50, step=8
)
limit=50; start=1; step=8;
x = range(start, limit, step)
plt.plot(x, coherence_values)
plt.xlabel("Num Topics")
plt.ylabel("Coherence score")
plt.legend(("coherence_values"), loc='best')
plt.show()

Salida

A continuación, también podemos imprimir los valores de coherencia para varios temas de la siguiente manera:

for m, cv in zip(x, coherence_values):
   print("Num Topics =", m, " is having Coherence Value of", round(cv, 4))

Salida

Num Topics = 1 is having Coherence Value of 0.4866
Num Topics = 9 is having Coherence Value of 0.5083
Num Topics = 17 is having Coherence Value of 0.5584
Num Topics = 25 is having Coherence Value of 0.5793
Num Topics = 33 is having Coherence Value of 0.587
Num Topics = 41 is having Coherence Value of 0.5842
Num Topics = 49 is having Coherence Value of 0.5735

Ahora, surge la pregunta ¿qué modelo deberíamos elegir ahora? Una de las buenas prácticas es elegir el modelo, que está dando mayor valor de coherencia antes de favorecer. Por eso, elegiremos el modelo con 25 temas que está en el número 4 en la lista anterior.

optimal_model = model_list[3]
model_topics = optimal_model.show_topics(formatted=False)
pprint(optimal_model.print_topics(num_words=10))

[
   (0,
   '0.018*"power" + 0.011*"high" + 0.010*"ground" + 0.009*"current" + '
   '0.008*"low" + 0.008*"wire" + 0.007*"water" + 0.007*"work" + 0.007*"design" '
   '+ 0.007*"light"'),
   (1,
   '0.036*"game" + 0.029*"team" + 0.029*"year" + 0.028*"play" + 0.020*"player" '
   '+ 0.019*"win" + 0.018*"good" + 0.013*"season" + 0.012*"run" + 0.011*"hit"'),
   (2,
   '0.020*"image" + 0.019*"information" + 0.017*"include" + 0.017*"mail" + '
   '0.016*"send" + 0.015*"list" + 0.013*"post" + 0.012*"address" + '
   '0.012*"internet" + 0.012*"system"'),
   (3,
   '0.986*"ax" + 0.002*"_" + 0.001*"tm" + 0.000*"part" + 0.000*"biz" + '
   '0.000*"mb" + 0.000*"mbs" + 0.000*"pne" + 0.000*"end" + 0.000*"di"'),
   (4,
   '0.020*"make" + 0.014*"work" + 0.013*"money" + 0.013*"year" + 0.012*"people" '
   '+ 0.011*"job" + 0.010*"group" + 0.009*"government" + 0.008*"support" + '
   '0.008*"question"'),
   (5,
   '0.011*"study" + 0.011*"drug" + 0.009*"science" + 0.008*"food" + '
   '0.008*"problem" + 0.008*"result" + 0.008*"effect" + 0.007*"doctor" + '
   '0.007*"research" + 0.007*"patient"'),
   (6,
   '0.024*"gun" + 0.024*"law" + 0.019*"state" + 0.015*"case" + 0.013*"people" + '
   '0.010*"crime" + 0.010*"weapon" + 0.010*"person" + 0.008*"firearm" + '
   '0.008*"police"'),
   (7,
   '0.012*"word" + 0.011*"question" + 0.011*"exist" + 0.011*"true" + '
   '0.010*"religion" + 0.010*"claim" + 0.008*"argument" + 0.008*"truth" + '
   '0.008*"life" + 0.008*"faith"'),
   (8,
   '0.077*"time" + 0.029*"day" + 0.029*"call" + 0.025*"back" + 0.021*"work" + '
   '0.019*"long" + 0.015*"end" + 0.015*"give" + 0.014*"year" + 0.014*"week"'),
   (9,
   '0.048*"thing" + 0.041*"make" + 0.038*"good" + 0.037*"people" + '
   '0.028*"write" + 0.019*"bad" + 0.019*"point" + 0.018*"read" + 0.018*"post" + '
   '0.016*"idea"'),
   (10,
   '0.022*"book" + 0.020*"_" + 0.013*"man" + 0.012*"people" + 0.011*"write" + '
   '0.011*"find" + 0.010*"history" + 0.010*"armenian" + 0.009*"turkish" + '
   '0.009*"number"'),
   (11,
   '0.064*"line" + 0.030*"buy" + 0.028*"organization" + 0.025*"price" + '
   '0.025*"sell" + 0.023*"good" + 0.021*"host" + 0.018*"sale" + 0.017*"mail" + '
   '0.016*"cost"'),
   (12,
   '0.041*"car" + 0.015*"bike" + 0.011*"ride" + 0.010*"engine" + 0.009*"drive" '
   '+ 0.008*"side" + 0.008*"article" + 0.007*"turn" + 0.007*"front" + '
   '0.007*"speed"'),
   (13,
   '0.018*"people" + 0.011*"attack" + 0.011*"state" + 0.011*"israeli" + '
   '0.010*"war" + 0.010*"country" + 0.010*"government" + 0.009*"live" + '
   '0.009*"give" + 0.009*"land"'),
   (14,
   '0.037*"file" + 0.026*"line" + 0.021*"read" + 0.019*"follow" + '
   '0.018*"number" + 0.015*"program" + 0.014*"write" + 0.012*"entry" + '
   '0.012*"give" + 0.011*"check"'),
   (15,
   '0.196*"write" + 0.172*"line" + 0.165*"article" + 0.117*"organization" + '
   '0.086*"host" + 0.030*"reply" + 0.010*"university" + 0.008*"hear" + '
   '0.007*"post" + 0.007*"news"'),
   (16,
   '0.021*"people" + 0.014*"happen" + 0.014*"child" + 0.012*"kill" + '
   '0.011*"start" + 0.011*"live" + 0.010*"fire" + 0.010*"leave" + 0.009*"hear" '
   '+ 0.009*"home"'),
   (17,
   '0.038*"key" + 0.018*"system" + 0.015*"space" + 0.015*"technology" + '
   '0.014*"encryption" + 0.010*"chip" + 0.010*"bit" + 0.009*"launch" + '
   '0.009*"public" + 0.009*"government"'),
   (18,
   '0.035*"drive" + 0.031*"system" + 0.027*"problem" + 0.027*"card" + '
   '0.020*"driver" + 0.017*"bit" + 0.017*"work" + 0.016*"disk" + '
   '0.014*"monitor" + 0.014*"machine"'),
   (19,
   '0.031*"window" + 0.020*"run" + 0.018*"color" + 0.018*"program" + '
   '0.017*"application" + 0.016*"display" + 0.015*"set" + 0.015*"version" + '
   '0.012*"screen" + 0.012*"problem"')
]

Encontrar temas dominantes en oraciones

Encontrar temas dominantes en oraciones es una de las aplicaciones prácticas más útiles del modelado de temas. Determina de qué tema trata un documento determinado. Aquí, encontraremos el número de tema que tiene la mayor contribución porcentual en ese documento en particular. Para agregar la información en una tabla, crearemos una función llamadadominant_topics() -

def dominant_topics(ldamodel=lda_model, corpus=corpus, texts=data):
   sent_topics_df = pd.DataFrame()

A continuación, obtendremos los temas principales en cada documento:

for i, row in enumerate(ldamodel[corpus]):
   row = sorted(row, key=lambda x: (x[1]), reverse=True)

A continuación, obtendremos el tema dominante, la contribución porcentual y las palabras clave para cada documento:

for j, (topic_num, prop_topic) in enumerate(row):
   if j == 0: # => dominant topic
      wp = ldamodel.show_topic(topic_num)
      topic_keywords = ", ".join([word for word, prop in wp])
sent_topics_df = sent_topics_df.append(
   pd.Series([int(topic_num), round(prop_topic,4), topic_keywords]), ignore_index=True
)
   else:
      break
sent_topics_df.columns = ['Dominant_Topic', 'Perc_Contribution', 'Topic_Keywords']

Con la ayuda del siguiente código, agregaremos el texto original al final de la salida:

contents = pd.Series(texts)
   sent_topics_df = pd.concat([sent_topics_df, contents], axis=1)
   return(sent_topics_df)
df_topic_sents_keywords = dominant_topics(
   ldamodel=optimal_model, corpus=corpus, texts=data
)

Ahora, formatee los temas en las oraciones de la siguiente manera:

df_dominant_topic = df_topic_sents_keywords.reset_index()
df_dominant_topic.columns = [
   'Document_No', 'Dominant_Topic', 'Topic_Perc_Contrib', 'Keywords', 'Text'
]

Finalmente, podemos mostrar los temas dominantes de la siguiente manera:

df_dominant_topic.head(15)

Encontrar el documento más representativo

Para comprender más sobre el tema, también podemos encontrar los documentos, un tema determinado ha contribuido más. Podemos inferir ese tema leyendo ese (los) documento (s) en particular.

sent_topics_sorteddf_mallet = pd.DataFrame()
sent_topics_outdf_grpd = df_topic_sents_keywords.groupby('Dominant_Topic')
for i, grp in sent_topics_outdf_grpd:
   sent_topics_sorteddf_mallet = pd.concat([sent_topics_sorteddf_mallet,
grp.sort_values(['Perc_Contribution'], ascending=[0]).head(1)], axis=0)
sent_topics_sorteddf_mallet.reset_index(drop=True, inplace=True)
sent_topics_sorteddf_mallet.columns = [
   'Topic_Number', "Contribution_Perc", "Keywords", "Text"
]
sent_topics_sorteddf_mallet.head()

Salida

Volumen y distribución de temas

A veces también queremos juzgar qué tan ampliamente se discute el tema en los documentos. Para ello, necesitamos comprender el volumen y la distribución de temas en los documentos.

Primero calcule la cantidad de documentos para cada tema de la siguiente manera:

topic_counts = df_topic_sents_keywords['Dominant_Topic'].value_counts()

A continuación, calcule el porcentaje de documentos para cada tema de la siguiente manera:

topic_contribution = round(topic_counts/topic_counts.sum(), 4)

Ahora busque el número de tema y las palabras clave de la siguiente manera:

topic_num_keywords = df_topic_sents_keywords[['Dominant_Topic', 'Topic_Keywords']]

Ahora, concatenar luego Columna de la siguiente manera:

df_dominant_topics = pd.concat(
   [topic_num_keywords, topic_counts, topic_contribution], axis=1
)

A continuación, cambiaremos los nombres de las columnas de la siguiente manera:

df_dominant_topics.columns = [
   'Dominant-Topic', 'Topic-Keywords', 'Num_Documents', 'Perc_Documents'
]
df_dominant_topics

Salida

Este capítulo trata sobre la creación de modelos de temas de Indexación semántica latente (LSI) y Proceso de Dirichlet jerárquico (HDP) con respecto a Gensim.

Los algoritmos de modelado de temas que se implementaron por primera vez en Gensim con Latent Dirichlet Allocation (LDA) es Latent Semantic Indexing (LSI). También es llamadoLatent Semantic Analysis (LSA). Fue patentado en 1988 por Scott Deerwester, Susan Dumais, George Furnas, Richard Harshman, Thomas Landaur, Karen Lochbaum y Lynn Streeter.

En esta sección vamos a configurar nuestro modelo LSI. Se puede hacer de la misma manera que configura el modelo LDA. Necesitamos importar el modelo LSI degensim.models.

Papel de LSI

En realidad, LSI es una técnica de PNL, especialmente en semántica distributiva. Analiza la relación entre un conjunto de documentos y los términos que contienen estos documentos. Si hablamos de su funcionamiento, entonces construye una matriz que contiene recuentos de palabras por documento a partir de una gran parte de texto.

Una vez construido, para reducir el número de filas, el modelo LSI utiliza una técnica matemática llamada descomposición de valor singular (SVD). Además de reducir el número de filas, también conserva la estructura de similitud entre columnas.

En la matriz, las filas representan palabras únicas y las columnas representan cada documento. Funciona con base en hipótesis distributivas, es decir, asume que las palabras que tienen un significado cercano aparecerán en el mismo tipo de texto.

Implementación con Gensim

Aquí, vamos a utilizar LSI (Latent Semantic Indexing) para extraer los temas discutidos naturalmente del conjunto de datos.

Cargando conjunto de datos

El conjunto de datos que vamos a utilizar es el conjunto de datos de ’20 Newsgroups’tener miles de artículos de noticias de varias secciones de un informe de noticias. Está disponible bajoSklearnconjuntos de datos. Podemos descargar fácilmente con la ayuda de la siguiente secuencia de comandos de Python:

from sklearn.datasets import fetch_20newsgroups
newsgroups_train = fetch_20newsgroups(subset='train')

Veamos algunas de las noticias de muestra con la ayuda del siguiente guión:

newsgroups_train.data[:4]
["From: [email protected] (where's my thing)\nSubject: 
WHAT car is this!?\nNntp-Posting-Host: rac3.wam.umd.edu\nOrganization: 
University of Maryland, College Park\nLines: 15\n\n 
I was wondering if anyone out there could enlighten me on this car 
I saw\nthe other day. It was a 2-door sports car,
looked to be from the late 60s/\nearly 70s. It was called a Bricklin. 
The doors were really small. In addition,\nthe front bumper was separate from 
the rest of the body. This is \nall I know. If anyone can tellme a model name, 
engine specs, years\nof production, where this car is made, history, or 
whatever info you\nhave on this funky looking car, 
please e-mail.\n\nThanks,\n- IL\n ---- brought to you by your neighborhood 
Lerxst ----\n\n\n\n\n",

"From: [email protected]hington.edu (Guy Kuo)\nSubject: 
SI Clock Poll - Final Call\nSummary: Final call for SI clock reports\nKeywords: 
SI,acceleration,clock,upgrade\nArticle-I.D.: shelley.1qvfo9INNc3s\nOrganization: 
University of Washington\nLines: 11\nNNTP-Posting-Host: carson.u.washington.edu\n\nA 
fair number of brave souls who upgraded their SI clock oscillator have\nshared their 
experiences for this poll. Please send a brief message detailing\nyour experiences with 
the procedure. Top speed attained, CPU rated speed,\nadd on cards and adapters, heat 
sinks, hour of usage per day, floppy disk\nfunctionality with 800 and 1.4 m floppies 
are especially requested.\n\nI will be summarizing in the next two days, so please add 
to the network\nknowledge base if you have done the clock upgrade and haven't answered 
this\npoll. Thanks.\n\nGuy Kuo <[email protected]>\n",

'From: [email protected] (Thomas E Willis)\nSubject: 
PB questions...\nOrganization: Purdue University Engineering Computer 
Network\nDistribution: usa\nLines: 36\n\nwell folks, my mac plus finally gave up the 
ghost this weekend after\nstarting life as a 512k way back in 1985. sooo, i\'m in the 
market for a\nnew machine a bit sooner than i intended to be...\n\ni\'m looking into 
picking up a powerbook 160 or maybe 180 and have a bunch\nof questions that (hopefully) 
somebody can answer:\n\n* does anybody know any dirt on when the next round of 
powerbook\nintroductions are expected? i\'d heard the 185c was supposed to make 
an\nappearence "this summer" but haven\'t heard anymore on it - and since i\ndon\'t 
have access to macleak, i was wondering if anybody out there had\nmore info...\n\n* has 
anybody heard rumors about price drops to the powerbook line like the\nones the duo\'s 
just went through recently?\n\n* what\'s the impression of the display on the 180? i 
could probably swing\na 180 if i got the 80Mb disk rather than the 120, but i don\'t 
really have\na feel for how much "better" the display is (yea, it looks great in 
the\nstore, but is that all "wow" or is it really that good?). could i solicit\nsome 
opinions of people who use the 160 and 180 day-to-day on if its worth\ntaking the disk 
size and money hit to get the active display? (i realize\nthis is a real subjective 
question, but i\'ve only played around with the\nmachines in a computer store breifly 
and figured the opinions of somebody\nwho actually uses the machine daily might prove 
helpful).\n\n* how well does hellcats perform? ;)\n\nthanks a bunch in advance for any 
info - if you could email, i\'ll post a\nsummary (news reading time is at a premium 
with finals just around the\ncorner... :( )\n--\nTom Willis \\ [email protected] 
\\ Purdue Electrical 
Engineering\n---------------------------------------------------------------------------\
n"Convictions are more dangerous enemies of truth than lies." - F. W.\nNietzsche\n',

'From: [email protected] (Joe Green)\nSubject: Re: Weitek P9000 ?\nOrganization: Harris 
Computer Systems Division\nLines: 14\nDistribution: world\nNNTP-Posting-Host: 
amber.ssd.csd.harris.com\nX-Newsreader: TIN [version 1.1 PL9]\n\nRobert J.C. Kyanko 
([email protected]) wrote:\n > [email protected] writes in article <
[email protected]>:\n> > Anyone know about the Weitek P9000 
graphics chip?\n > As far as the low-level stuff goes, it looks pretty nice. It\'s 
got this\n > quadrilateral fill command that requires just the four
points.\n\nDo you have Weitek\'s address/phone number? I\'d like to get some 
information\nabout this chip.\n\n--\nJoe Green\t\t\t\tHarris 
Corporation\[email protected]\t\t\tComputer Systems Division\n"The only thing that 
really scares me is a person with no sense of humor."\n\t\t\t\t\t\t-- Jonathan 
Winters\n']

Requisito previo

Necesitamos palabras vacías de NLTK y el modelo en inglés de Scapy. Ambos se pueden descargar de la siguiente manera:

import nltk;
nltk.download('stopwords')
nlp = spacy.load('en_core_web_md', disable=['parser', 'ner'])

Importación de paquetes necesarios

Para construir el modelo LSI necesitamos importar el siguiente paquete necesario:

import re
import numpy as np
import pandas as pd
from pprint import pprint
import gensim
import gensim.corpora as corpora
from gensim.utils import simple_preprocess
from gensim.models import CoherenceModel
import spacy
import matplotlib.pyplot as plt

Preparación de palabras vacías

Ahora necesitamos importar las palabras vacías y usarlas:

from nltk.corpus import stopwords
stop_words = stopwords.words('english')
stop_words.extend(['from', 'subject', 're', 'edu', 'use'])

Limpiar el texto

Ahora, con la ayuda de Gensim's simple_preprocess()necesitamos tokenizar cada oración en una lista de palabras. También debemos eliminar las puntuaciones y los caracteres innecesarios. Para hacer esto, crearemos una función llamadasent_to_words() -

def sent_to_words(sentences):
   for sentence in sentences:
      yield(gensim.utils.simple_preprocess(str(sentence), deacc=True))
data_words = list(sent_to_words(data))

Creación de modelos Bigram y Trigram

Como sabemos, los bigramas son dos palabras que aparecen juntas con frecuencia en el documento y los trigramas son tres palabras que aparecen juntas con frecuencia en el documento. Con la ayuda del modelo Phrases de Gensim, podemos hacer esto:

bigram = gensim.models.Phrases(data_words, min_count=5, threshold=100)
trigram = gensim.models.Phrases(bigram[data_words], threshold=100)
bigram_mod = gensim.models.phrases.Phraser(bigram)
trigram_mod = gensim.models.phrases.Phraser(trigram)

Filtrar palabras vacías

A continuación, debemos filtrar las palabras vacías. Junto con eso, también crearemos funciones para hacer bigramas, trigramas y para lematización -

def remove_stopwords(texts):
   return [[word for word in simple_preprocess(str(doc)) 
   if word not in stop_words] for doc in texts]
def make_bigrams(texts):
   return [bigram_mod[doc] for doc in texts]
def make_trigrams(texts):
   return [trigram_mod[bigram_mod[doc]] for doc in texts]
def lemmatization(texts, allowed_postags=['NOUN', 'ADJ', 'VERB', 'ADV']):
   texts_out = []
   for sent in texts:
      doc = nlp(" ".join(sent))
      texts_out.append([token.lemma_ for token in doc if token.pos_ in allowed_postags])
   return texts_out

Creación de diccionario y corpus para el modelo de tema

Ahora necesitamos construir el diccionario y el corpus. También lo hicimos en los ejemplos anteriores:

id2word = corpora.Dictionary(data_lemmatized)
texts = data_lemmatized
corpus = [id2word.doc2bow(text) for text in texts]

Creación del modelo de tema de LSI

Ya implementamos todo lo que se requiere para entrenar el modelo LSI. Ahora es el momento de construir el modelo de temas de LSI. Para nuestro ejemplo de implementación, se puede hacer con la ayuda de la siguiente línea de códigos:

lsi_model = gensim.models.lsimodel.LsiModel(
   corpus=corpus, id2word=id2word, num_topics=20,chunksize=100
)

Ejemplo de implementación

Veamos el ejemplo de implementación completo para construir el modelo de temas de LDA:

import re
import numpy as np
import pandas as pd
from pprint import pprint
import gensim
import gensim.corpora as corpora
from gensim.utils import simple_preprocess
from gensim.models import CoherenceModel
import spacy
import matplotlib.pyplot as plt
from nltk.corpus import stopwords
stop_words = stopwords.words('english')
stop_words.extend(['from', 'subject', 're', 'edu', 'use'])
from sklearn.datasets import fetch_20newsgroups
newsgroups_train = fetch_20newsgroups(subset='train')
data = newsgroups_train.data
data = [re.sub('\S*@\S*\s?', '', sent) for sent in data]
data = [re.sub('\s+', ' ', sent) for sent in data]
data = [re.sub("\'", "", sent) for sent in data]
print(data_words[:4]) #it will print the data after prepared for stopwords
bigram = gensim.models.Phrases(data_words, min_count=5, threshold=100)
trigram = gensim.models.Phrases(bigram[data_words], threshold=100)
bigram_mod = gensim.models.phrases.Phraser(bigram)
trigram_mod = gensim.models.phrases.Phraser(trigram)
def remove_stopwords(texts):
   return [[word for word in simple_preprocess(str(doc)) 
   if word not in stop_words] for doc in texts]
def make_bigrams(texts):
   return [bigram_mod[doc] for doc in texts]
def make_trigrams(texts):
   return [trigram_mod[bigram_mod[doc]] for doc in texts]
def lemmatization(texts, allowed_postags=['NOUN', 'ADJ', 'VERB', 'ADV']):
   texts_out = []
   for sent in texts:
      doc = nlp(" ".join(sent))
      texts_out.append([token.lemma_ for token in doc if token.pos_ in allowed_postags])
return texts_out
data_words_nostops = remove_stopwords(data_words)
data_words_bigrams = make_bigrams(data_words_nostops)
nlp = spacy.load('en_core_web_md', disable=['parser', 'ner'])
data_lemmatized = lemmatization(
   data_words_bigrams, allowed_postags=['NOUN', 'ADJ', 'VERB', 'ADV']
)
print(data_lemmatized[:4]) #it will print the lemmatized data.
id2word = corpora.Dictionary(data_lemmatized)
texts = data_lemmatized
corpus = [id2word.doc2bow(text) for text in texts]
print(corpus[:4]) #it will print the corpus we created above.
[[(id2word[id], freq) for id, freq in cp] for cp in corpus[:4]] 
#it will print the words with their frequencies.
lsi_model = gensim.models.lsimodel.LsiModel(
   corpus=corpus, id2word=id2word, num_topics=20,chunksize=100
)

Ahora podemos usar el modelo LSI creado anteriormente para obtener los temas.

Visualización de temas en el modelo LSI

El modelo LSI (lsi_model)que hemos creado anteriormente se puede utilizar para ver los temas de los documentos. Se puede hacer con la ayuda del siguiente script:

pprint(lsi_model.print_topics())
doc_lsi = lsi_model[corpus]

Salida

[
   (0,
   '1.000*"ax" + 0.001*"_" + 0.000*"tm" + 0.000*"part" +    0.000*"pne" + '
   '0.000*"biz" + 0.000*"mbs" + 0.000*"end" + 0.000*"fax" + 0.000*"mb"'),
   (1,
   '0.239*"say" + 0.222*"file" + 0.189*"go" + 0.171*"know" + 0.169*"people" + '
   '0.147*"make" + 0.140*"use" + 0.135*"also" + 0.133*"see" + 0.123*"think"')
]

Proceso de Dirichlet jerárquico (HPD)

Los modelos de temas como LDA y LSI ayudan a resumir y organizar grandes archivos de textos que no es posible analizar a mano. Además de LDA y LSI, otro modelo de tema poderoso en Gensim es HDP (Proceso de Dirichlet jerárquico). Básicamente, es un modelo de membresía mixta para el análisis no supervisado de datos agrupados. A diferencia de LDA (su contraparte finita), HDP infiere el número de temas de los datos.

Implementación con Gensim

Para implementar HDP en Gensim, necesitamos entrenar el corpus y el diccionario (como se hizo en los ejemplos anteriores al implementar modelos de temas LDA y LSI) modelo de temas HDP que podemos importar desde gensim.models.HdpModel. Aquí también implementaremos el modelo de temas HDP en datos de 20Newsgroup y los pasos también son los mismos.

Para nuestro corpus y diccionario (creado en los ejemplos anteriores para el modelo LSI y LDA), podemos importar HdpModel de la siguiente manera:

Hdp_model = gensim.models.hdpmodel.HdpModel(corpus=corpus, id2word=id2word)

Visualización de temas en el modelo LSI

El modelo HDP (Hdp_model)se puede utilizar para ver los temas de los documentos. Se puede hacer con la ayuda del siguiente script:

pprint(Hdp_model.print_topics())

Salida

[
   (0,
   '0.009*line + 0.009*write + 0.006*say + 0.006*article + 0.006*know + '
   '0.006*people + 0.005*make + 0.005*go + 0.005*think + 0.005*be'),
   (1,
   '0.016*line + 0.011*write + 0.008*article + 0.008*organization + 0.006*know '
   '+ 0.006*host + 0.006*be + 0.005*get + 0.005*use + 0.005*say'),
   (2,
   '0.810*ax + 0.001*_ + 0.000*tm + 0.000*part + 0.000*mb + 0.000*pne + '
   '0.000*biz + 0.000*end + 0.000*wwiz + 0.000*fax'),
   (3,
   '0.015*line + 0.008*write + 0.007*organization + 0.006*host + 0.006*know + '
   '0.006*article + 0.005*use + 0.005*thank + 0.004*get + 0.004*problem'),
   (4,
   '0.004*line + 0.003*write + 0.002*believe + 0.002*think + 0.002*article + '
   '0.002*belief + 0.002*say + 0.002*see + 0.002*look + 0.002*organization'),
   (5,
   '0.005*line + 0.003*write + 0.003*organization + 0.002*article + 0.002*time '
   '+ 0.002*host + 0.002*get + 0.002*look + 0.002*say + 0.001*number'),
   (6,
   '0.003*line + 0.002*say + 0.002*write + 0.002*go + 0.002*gun + 0.002*get + '
   '0.002*organization + 0.002*bill + 0.002*article + 0.002*state'),
   (7,
   '0.003*line + 0.002*write + 0.002*article + 0.002*organization + 0.001*none '
   '+ 0.001*know + 0.001*say + 0.001*people + 0.001*host + 0.001*new'),
   (8,
   '0.004*line + 0.002*write + 0.002*get + 0.002*team + 0.002*organization + '
   '0.002*go + 0.002*think + 0.002*know + 0.002*article + 0.001*well'),
   (9,
   '0.004*line + 0.002*organization + 0.002*write + 0.001*be + 0.001*host + '
   '0.001*article + 0.001*thank + 0.001*use + 0.001*work + 0.001*run'),
   (10,
   '0.002*line + 0.001*game + 0.001*write + 0.001*get + 0.001*know + '
   '0.001*thing + 0.001*think + 0.001*article + 0.001*help + 0.001*turn'),
   (11,
   '0.002*line + 0.001*write + 0.001*game + 0.001*organization + 0.001*say + '
   '0.001*host + 0.001*give + 0.001*run + 0.001*article + 0.001*get'),
   (12,
   '0.002*line + 0.001*write + 0.001*know + 0.001*time + 0.001*article + '
   '0.001*get + 0.001*think + 0.001*organization + 0.001*scope + 0.001*make'),
   (13,
   '0.002*line + 0.002*write + 0.001*article + 0.001*organization + 0.001*make '
   '+ 0.001*know + 0.001*see + 0.001*get + 0.001*host + 0.001*really'),
   (14,
   '0.002*write + 0.002*line + 0.002*know + 0.001*think + 0.001*say + '
   '0.001*article + 0.001*argument + 0.001*even + 0.001*card + 0.001*be'),
   (15,
   '0.001*article + 0.001*line + 0.001*make + 0.001*write + 0.001*know + '
   '0.001*say + 0.001*exist + 0.001*get + 0.001*purpose + 0.001*organization'),
   (16,
   '0.002*line + 0.001*write + 0.001*article + 0.001*insurance + 0.001*go + '
   '0.001*be + 0.001*host + 0.001*say + 0.001*organization + 0.001*part'),
   (17,
   '0.001*line + 0.001*get + 0.001*hit + 0.001*go + 0.001*write + 0.001*say + '
   '0.001*know + 0.001*drug + 0.001*see + 0.001*need'),
   (18,
   '0.002*option + 0.001*line + 0.001*flight + 0.001*power + 0.001*software + '
   '0.001*write + 0.001*add + 0.001*people + 0.001*organization + 0.001*module'),
   (19,
   '0.001*shuttle + 0.001*line + 0.001*roll + 0.001*attitude + 0.001*maneuver + '
   '0.001*mission + 0.001*also + 0.001*orbit + 0.001*produce + 0.001*frequency')
]

El capítulo nos ayudará a comprender el desarrollo de la inserción de palabras en Gensim.

La incrustación de palabras, enfoque para representar palabras y documentos, es una representación de vector denso para texto donde las palabras que tienen el mismo significado tienen una representación similar. A continuación se presentan algunas características de la inserción de palabras:

  • Es una clase de técnica que representa las palabras individuales como vectores de valor real en un espacio vectorial predefinido.

  • Esta técnica a menudo se agrupa en el campo de DL (aprendizaje profundo) porque cada palabra se asigna a un vector y los valores del vector se aprenden de la misma manera que lo hace una NN (redes neuronales).

  • El enfoque clave de la técnica de inserción de palabras es una representación distribuida densa para cada palabra.

Diferentes métodos / algoritmos de incrustación de palabras

Como se discutió anteriormente, los métodos / algoritmos de incorporación de palabras aprenden una representación vectorial de valor real a partir de un corpus de texto. Este proceso de aprendizaje puede usarse con el modelo NN en tareas como clasificación de documentos o es un proceso no supervisado como estadísticas de documentos. Aquí vamos a discutir dos métodos / algoritmos que se pueden usar para aprender una palabra incrustada de texto:

Word2Vec de Google

Word2Vec, desarrollado por Tomas Mikolov, et. Alabama. en Google en 2013, es un método estadístico para aprender eficientemente una incrustación de palabras de un corpus de texto. En realidad, se desarrolló como una respuesta para hacer que el entrenamiento de incrustación de palabras basado en NN sea más eficiente. Se ha convertido en el estándar de facto para la inserción de palabras.

La incrustación de palabras por Word2Vec implica el análisis de los vectores aprendidos, así como la exploración de matemáticas vectoriales en la representación de palabras. A continuación se muestran los dos métodos de aprendizaje diferentes que se pueden utilizar como parte del método Word2Vec:

  • Modelo CBoW (bolsa continua de palabras)
  • Modelo continuo de omisión de gramo

GloVe de Standford

GloVe (Vectores globales para representación de palabras), es una extensión del método Word2Vec. Fue desarrollado por Pennington et al. en Stanford. El algoritmo GloVe es una combinación de ambos:

  • Estadísticas globales de técnicas de factorización matricial como LSA (Análisis semántico latente)
  • Aprendizaje local basado en el contexto en Word2Vec.

Si hablamos de su funcionamiento, en lugar de utilizar una ventana para definir el contexto local, GloVe construye una matriz de co-ocurrencia de palabras explícita utilizando estadísticas en todo el corpus de texto.

Desarrollo de incrustaciones de Word2Vec

Aquí, desarrollaremos la incrustación de Word2Vec usando Gensim. Para trabajar con un modelo Word2Vec, Gensim nos proporcionaWord2Vec clase que se puede importar desde models.word2vec. Para su implementación, word2vec requiere mucho texto, por ejemplo, todo el corpus de revisión de Amazon. Pero aquí, aplicaremos este principio en un texto de memoria pequeña.

Ejemplo de implementación

Primero necesitamos importar la clase Word2Vec de gensim.models de la siguiente manera:

from gensim.models import Word2Vec

A continuación, necesitamos definir los datos de entrenamiento. En lugar de tomar un archivo de texto grande, estamos usando algunas oraciones para implementar este principio.

sentences = [
   ['this', 'is', 'gensim', 'tutorial', 'for', 'free'],
   ['this', 'is', 'the', 'tutorials' 'point', 'website'],
   ['you', 'can', 'read', 'technical','tutorials', 'for','free'],
   ['we', 'are', 'implementing','word2vec'],
   ['learn', 'full', 'gensim', 'tutorial']
]

Una vez que se proporcionan los datos de entrenamiento, necesitamos entrenar el modelo. se puede hacer de la siguiente manera:

model = Word2Vec(sentences, min_count=1)

Podemos resumir el modelo de la siguiente manera -;

print(model)

Podemos resumir el vocabulario de la siguiente manera:

words = list(model.wv.vocab)
print(words)

A continuación, accedamos al vector de una palabra. Lo estamos haciendo por la palabra 'tutorial'.

print(model['tutorial'])

A continuación, debemos guardar el modelo:

model.save('model.bin')

A continuación, necesitamos cargar el modelo:

new_model = Word2Vec.load('model.bin')

Finalmente, imprima el modelo guardado de la siguiente manera:

print(new_model)

Ejemplo de implementación completo

from gensim.models import Word2Vec
sentences = [
   ['this', 'is', 'gensim', 'tutorial', 'for', 'free'],
   ['this', 'is', 'the', 'tutorials' 'point', 'website'],
   ['you', 'can', 'read', 'technical','tutorials', 'for','free'],
   ['we', 'are', 'implementing','word2vec'],
   ['learn', 'full', 'gensim', 'tutorial']
]
model = Word2Vec(sentences, min_count=1)
print(model)
words = list(model.wv.vocab)
print(words)
print(model['tutorial'])
model.save('model.bin')
new_model = Word2Vec.load('model.bin')
print(new_model)

Salida

Word2Vec(vocab=20, size=100, alpha=0.025)
[
   'this', 'is', 'gensim', 'tutorial', 'for', 'free', 'the', 'tutorialspoint', 
   'website', 'you', 'can', 'read', 'technical', 'tutorials', 'we', 'are', 
   'implementing', 'word2vec', 'learn', 'full'
]
[
   -2.5256255e-03 -4.5352755e-03 3.9024993e-03 -4.9509313e-03
   -1.4255195e-03 -4.0217536e-03 4.9407515e-03 -3.5925603e-03
   -1.1933431e-03 -4.6682903e-03 1.5440651e-03 -1.4101702e-03
   3.5070938e-03 1.0914479e-03 2.3334436e-03 2.4452661e-03
   -2.5336299e-04 -3.9676363e-03 -8.5054158e-04 1.6443320e-03
   -4.9968651e-03 1.0974540e-03 -1.1123562e-03 1.5393364e-03
   9.8941079e-04 -1.2656028e-03 -4.4471184e-03 1.8309267e-03
   4.9302122e-03 -1.0032534e-03 4.6892050e-03 2.9563988e-03
   1.8730218e-03 1.5343715e-03 -1.2685956e-03 8.3664013e-04
   4.1721235e-03 1.9445885e-03 2.4097660e-03 3.7517555e-03
   4.9687522e-03 -1.3598346e-03 7.1032363e-04 -3.6595813e-03
   6.0000515e-04 3.0872561e-03 -3.2115565e-03 3.2270295e-03
   -2.6354722e-03 -3.4988276e-04 1.8574356e-04 -3.5757164e-03
   7.5391348e-04 -3.5205986e-03 -1.9795434e-03 -2.8321696e-03
   4.7155009e-03 -4.3349937e-04 -1.5320212e-03 2.7013756e-03
   -3.7055744e-03 -4.1658725e-03 4.8034848e-03 4.8594419e-03
   3.7129463e-03 4.2385766e-03 2.4612297e-03 5.4920948e-04
   -3.8912550e-03 -4.8226118e-03 -2.2763973e-04 4.5571579e-03
   -3.4609400e-03 2.7903817e-03 -3.2709218e-03 -1.1036445e-03
   2.1492650e-03 -3.0384419e-04 1.7709908e-03 1.8429896e-03
   -3.4038599e-03 -2.4872608e-03 2.7693063e-03 -1.6352943e-03
   1.9182395e-03 3.7772327e-03 2.2769428e-03 -4.4629495e-03
   3.3151123e-03 4.6509290e-03 -4.8521687e-03 6.7615538e-04
   3.1034781e-03 2.6369948e-05 4.1454583e-03 -3.6932561e-03
   -1.8769916e-03 -2.1958587e-04 6.3395966e-04 -2.4969708e-03
]
Word2Vec(vocab=20, size=100, alpha=0.025)

Visualización de la incrustación de palabras

También podemos explorar la palabra incrustación con visualización. Se puede hacer usando un método de proyección clásico (como PCA) para reducir los vectores de palabras de alta dimensión a gráficos 2-D. Una vez reducidos, podemos trazarlos en un gráfico.

Trazado de vectores de palabras con PCA

Primero, necesitamos recuperar todos los vectores de un modelo entrenado de la siguiente manera:

Z = model[model.wv.vocab]

A continuación, necesitamos crear un modelo PCA 2-D de vectores de palabras utilizando la clase PCA de la siguiente manera:

pca = PCA(n_components=2)
result = pca.fit_transform(Z)

Ahora, podemos trazar la proyección resultante usando matplotlib de la siguiente manera:

Pyplot.scatter(result[:,0],result[:,1])

También podemos anotar los puntos en el gráfico con las propias palabras. Trace la proyección resultante utilizando matplotlib de la siguiente manera:

words = list(model.wv.vocab)
for i, word in enumerate(words):
   pyplot.annotate(word, xy=(result[i, 0], result[i, 1]))

Ejemplo de implementación completo

from gensim.models import Word2Vec
from sklearn.decomposition import PCA
from matplotlib import pyplot
sentences = [
   ['this', 'is', 'gensim', 'tutorial', 'for', 'free'],
	['this', 'is', 'the', 'tutorials' 'point', 'website'],
	['you', 'can', 'read', 'technical','tutorials', 'for','free'],
	['we', 'are', 'implementing','word2vec'],
	['learn', 'full', 'gensim', 'tutorial']
]
model = Word2Vec(sentences, min_count=1)
X = model[model.wv.vocab]
pca = PCA(n_components=2)
result = pca.fit_transform(X)
pyplot.scatter(result[:, 0], result[:, 1])
words = list(model.wv.vocab)
for i, word in enumerate(words):
   pyplot.annotate(word, xy=(result[i, 0], result[i, 1]))
pyplot.show()

Salida

El modelo Doc2Vec, a diferencia del modelo Word2Vec, se utiliza para crear una representación vectorizada de un grupo de palabras tomadas colectivamente como una sola unidad. No solo da el promedio simple de las palabras en la oración.

Creación de vectores de documentos con Doc2Vec

Aquí para crear vectores de documentos usando Doc2Vec, usaremos el conjunto de datos text8 que se puede descargar desde gensim.downloader.

Descarga del conjunto de datos

Podemos descargar el conjunto de datos text8 usando los siguientes comandos:

import gensim
import gensim.downloader as api
dataset = api.load("text8")
data = [d for d in dataset]

La descarga del conjunto de datos text8 llevará algún tiempo.

Entrene al Doc2Vec

Para entrenar el modelo, necesitamos el documento etiquetado que se puede crear usando models.doc2vec.TaggedDcument() como sigue -

def tagged_document(list_of_list_of_words):
   for i, list_of_words in enumerate(list_of_list_of_words):
      yield gensim.models.doc2vec.TaggedDocument(list_of_words, [i])
data_for_training = list(tagged_document(data))

Podemos imprimir el conjunto de datos entrenado de la siguiente manera:

print(data_for_training [:1])

Salida

[TaggedDocument(words=['anarchism', 'originated', 'as', 'a', 'term', 'of',
'abuse', 'first', 'used', 'against', 'early', 'working', 'class', 'radicals',
'including', 'the', 'diggers', 'of', 'the', 'english', 'revolution', 
'and', 'the', 'sans', 'culottes', 'of', 'the', 'french', 'revolution',
'whilst', 'the', 'term', 'is', 'still', 'used', 'in', 'a', 'pejorative',
'way', 'to', 'describe', 'any', 'act', 'that', 'used', 'violent', 
'means', 'to', 'destroy',
'the', 'organization', 'of', 'society', 'it', 'has', 'also', 'been'
, 'taken', 'up', 'as', 'a', 'positive', 'label', 'by', 'self', 'defined',
'anarchists', 'the', 'word', 'anarchism', 'is', 'derived', 'from', 'the',
'greek', 'without', 'archons', 'ruler', 'chief', 'king', 'anarchism', 
'as', 'a', 'political', 'philosophy', 'is', 'the', 'belief', 'that', 
'rulers', 'are', 'unnecessary', 'and', 'should', 'be', 'abolished',
'although', 'there', 'are', 'differing', 'interpretations', 'of', 
'what', 'this', 'means', 'anarchism', 'also', 'refers', 'to', 
'related', 'social', 'movements', 'that', 'advocate', 'the', 
'elimination', 'of', 'authoritarian', 'institutions', 'particularly',
'the', 'state', 'the', 'word', 'anarchy', 'as', 'most', 'anarchists', 
'use', 'it', 'does', 'not', 'imply', 'chaos', 'nihilism', 'or', 'anomie',
'but', 'rather', 'a', 'harmonious', 'anti', 'authoritarian', 'society', 
'in', 'place', 'of', 'what', 'are', 'regarded', 'as', 'authoritarian',
'political', 'structures', 'and', 'coercive', 'economic', 'institutions', 
'anarchists', 'advocate', 'social', 'relations', 'based', 'upon', 'voluntary',
'association', 'of', 'autonomous', 'individuals', 'mutual', 'aid', 'and', 
'self', 'governance', 'while', 'anarchism', 'is', 'most', 'easily', 'defined',
'by', 'what', 'it', 'is', 'against', 'anarchists', 'also', 'offer', 
'positive', 'visions', 'of', 'what', 'they', 'believe', 'to', 'be', 'a',
'truly', 'free', 'society', 'however', 'ideas', 'about', 'how', 'an', 'anarchist',
'society', 'might', 'work', 'vary', 'considerably', 'especially', 'with',
'respect', 'to', 'economics', 'there', 'is', 'also', 'disagreement', 'about', 
'how', 'a', 'free', 'society', 'might', 'be', 'brought', 'about', 'origins', 
'and', 'predecessors', 'kropotkin', 'and', 'others', 'argue', 'that', 'before',
'recorded', 'history', 'human', 'society', 'was', 'organized', 'on', 'anarchist', 
'principles', 'most', 'anthropologists', 'follow', 'kropotkin', 'and', 'engels', 
'in', 'believing', 'that', 'hunter', 'gatherer', 'bands', 'were', 'egalitarian',
'and', 'lacked', 'division', 'of', 'labour', 'accumulated', 'wealth', 'or', 'decreed',
'law', 'and', 'had', 'equal', 'access', 'to', 'resources', 'william', 'godwin', 
'anarchists', 'including', 'the', 'the', 'anarchy', 'organisation', 'and', 'rothbard',
'find', 'anarchist', 'attitudes', 'in', 'taoism', 'from', 'ancient', 'china', 
'kropotkin', 'found', 'similar', 'ideas', 'in', 'stoic', 'zeno', 'of', 'citium', 
'according', 'to', 'kropotkin', 'zeno', 'repudiated', 'the', 'omnipotence', 'of',
'the', 'state', 'its', 'intervention', 'and', 'regimentation', 'and', 'proclaimed',
'the', 'sovereignty', 'of', 'the', 'moral', 'law', 'of', 'the', 'individual', 'the',
'anabaptists', 'of', 'one', 'six', 'th', 'century', 'europe', 'are', 'sometimes',
'considered', 'to', 'be', 'religious', 'forerunners', 'of', 'modern', 'anarchism',
'bertrand', 'russell', 'in', 'his', 'history', 'of', 'western', 'philosophy', 
'writes', 'that', 'the', 'anabaptists', 'repudiated', 'all', 'law', 'since', 
'they', 'held', 'that', 'the', 'good', 'man', 'will', 'be', 'guided', 'at', 
'every', 'moment', 'by', 'the', 'holy', 'spirit', 'from', 'this', 'premise',
'they', 'arrive', 'at', 'communism', 'the', 'diggers', 'or', 'true', 'levellers', 
'were', 'an', 'early', 'communistic', 'movement',
(truncated…)

Inicializar el modelo

Una vez entrenado, ahora necesitamos inicializar el modelo. se puede hacer de la siguiente manera:

model = gensim.models.doc2vec.Doc2Vec(vector_size=40, min_count=2, epochs=30)

Ahora, construya el vocabulario de la siguiente manera:

model.build_vocab(data_for_training)

Ahora, entrenemos el modelo Doc2Vec de la siguiente manera:

model.train(data_for_training, total_examples=model.corpus_count, epochs=model.epochs)

Analizando la salida

Finalmente, podemos analizar la salida usando model.infer_vector () de la siguiente manera:

print(model.infer_vector(['violent', 'means', 'to', 'destroy', 'the','organization']))

Ejemplo de implementación completo

import gensim
import gensim.downloader as api
dataset = api.load("text8")
data = [d for d in dataset]
def tagged_document(list_of_list_of_words):
   for i, list_of_words in enumerate(list_of_list_of_words):
      yield gensim.models.doc2vec.TaggedDocument(list_of_words, [i])
data_for_training = list(tagged_document(data))
print(data_for_training[:1])
model = gensim.models.doc2vec.Doc2Vec(vector_size=40, min_count=2, epochs=30)
model.build_vocab(data_training)
model.train(data_training, total_examples=model.corpus_count, epochs=model.epochs)
print(model.infer_vector(['violent', 'means', 'to', 'destroy', 'the','organization']))

Salida

[
   -0.2556166 0.4829361 0.17081228 0.10879577 0.12525807 0.10077011
   -0.21383236 0.19294572 0.11864349 -0.03227958 -0.02207291 -0.7108424
   0.07165232 0.24221905 -0.2924459 -0.03543589 0.21840079 -0.1274817
   0.05455418 -0.28968817 -0.29146606 0.32885507 0.14689675 -0.06913587
   -0.35173815 0.09340707 -0.3803535 -0.04030455 -0.10004586 0.22192696
   0.2384828 -0.29779273 0.19236489 -0.25727913 0.09140676 0.01265439
   0.08077634 -0.06902497 -0.07175519 -0.22583418 -0.21653089 0.00347822
   -0.34096122 -0.06176808 0.22885063 -0.37295452 -0.08222228 -0.03148199
   -0.06487323 0.11387568
]