PNL | Cómo puntuar palabras con Execnet y Redis

La puntuación de palabras distribuidas se puede realizar usando Redis y Execnet juntos. Para cada palabra en el corpus movie_reviews, FreqDist y ConditionalFreqDist se utilizan para calcular la ganancia de información. 
Usando >RedisHashFreqDist y RedisConditionalHashFreqDist , se puede hacer lo mismo con Redis. Luego, las puntuaciones se almacenan en un RedisOrderedDict . Para obtener un mejor rendimiento de Redis, se utiliza Execnet para distribuir el conteo. 
Redis y execnet se utilizan juntos para realizar la puntuación de palabras distribuidas. La ganancia de información de cada palabra en el se calcula utilizando FreqDist y ConditionalFreqDist. Ahora con Redis, se puede hacer lo mismo usando un RedisHashFreqDist y un RedisConditionalHashFreqDisty luego almacene las puntuaciones en un RedisOrderedDict . Execnet se puede utilizar para distribuir el conteo a fin de obtener un mejor rendimiento de Redis. La instancia de redis-server debe estar ejecutándose en localhost después de la instalación de Redis y execnet.
Pasos: 
 

  • Para cada etiqueta en el corpus movie_reviews (que solo tiene etiquetas pos y neg), comience por obtener una lista de tuplas: etiquetas y palabras.
  • Luego, desde el módulo dist_featx, obtenga word_scores usando score_words().
  • El número total de palabras es 39, 764 y la función word_scores es una instancia de RedisOrderedDict .
  • Luego obtenga las 1000 palabras principales e inspeccione las cinco principales usando el método keys() para ver cuáles son.
  • Elimine las claves en Redis después de obtener todas las necesarias de word_scores, ya que ya no se necesitan los datos.

Código: 
 

Python3

# importing libraries
from dist_featx import score_words
from nltk.corpus import movie_reviews
 
# finding category via categoreies
category = movie_reviews.categories()
 
print ("Categories : ", category)
category_words = [
        (l, movie_reviews.words(categories = [l]))
        for l in category]
 
# Scores
word_scores = score_words(category_words)
print ("Length : ", len(word_scores))
 
# top words
topn_words = word_scores.keys(end = 1000)
print ("Top Words : ", topn_words[0:5])
 
# Delete the keys in Redis after getting
# all the required from word_scores
from redis import Redis
r = Redis()
print ([r.delete(key) for
     key in ['word_fd', 'label_word_fd:neg',
             'label_word_fd:pos', 'word_scores']] )

Producción : 
 

Categories :  ['neg', 'pos']
Length : 39767
Top Words : [b'bad', b', ', b'and', b'?', b'movie']
[1, 1, 1, 1]

score_words () es una función de dist_featx. Pero se espera que espere un tiempo, ya que lleva algún tiempo completarlo. La sobrecarga de usar execnet y Redis significa que tomará mucho más tiempo que una versión en memoria no distribuida de la función.
¿Cómo funciona? 
El módulo dist_featx.py contiene la función score_words(), que hace lo siguiente: 
 

  • Abre puertas y canales.
  • Envía datos de inicialización a cada canal.
  • Para contar, envía cada tupla (etiqueta, palabras) por un canal.
  • Envía un mensaje de hecho a cada canal.
  • Espera una respuesta completa.
  • cierra los canales y las puertas de enlace.
  • En base a los recuentos calcula la puntuación de cada palabra.
  • Almacene la puntuación en un RedisOrderedDict.

Puntúe todas las palabras y guarde los resultados, una vez finalizado el conteo. El código se da a continuación: 
Código: 
 

Python3

# Importing library
import itertools, execnet, remote_word_count
from nltk.metrics import BigramAssocMeasures
from redis import Redis
from redisprob import RedisHashFreqDist, RedisConditionalHashFreqDist
from rediscollections import RedisOrderedDict
 
# Scoring the words
def score_words(category_words,
                score_fn = BigramAssocMeasures.chi_sq,
                host ='localhost', specs =[('popen', 2)]):
    gateways = []
    channels = []
     
    # counting
    for spec, count in specs:
        for i in range(count):
            gw = execnet.makegateway(spec)
            gateways.append(gw)
            channel = gw.remote_exec(remote_word_count)
            channel.send((host, 'word_fd', 'category_word_fd'))
            channels.append(channel)
             
    cyc = itertools.cycle(channels)
     
    # syncing the channel
    for category, words in category_words:
        channel = next(cyc)
        channel.send((category, list(words)))
         
    for channel in channels:
        channel.send('done')
        assert 'done' == channel.receive()
        channel.waitclose(5)
         
    for gateway in gateways:
        gateway.exit()
         
    r = Redis(host)
    # frequency distribution
    fd = RedisHashFreqDist(r, 'word_fd')
    cfd = RedisConditionalHashFreqDist(r, 'category_word_fd')
    word_scores = RedisOrderedDict(r, 'word_scores')
    n_xx = cfd.N()
     
    for category in cfd.conditions():
        n_xi = cfd[category].N()
     
    for word, n_ii in cfd[category].iteritems():
        word = word.decode()
        n_ix = fd[word]
         
        if n_ii and n_ix and n_xi and n_xx:
            score = score_fn(n_ii, (n_ix, n_xi), n_xx)
            word_scores[word] = score
    # final word scores       
    return word_scores

Se debe utilizar un método de puntuación diferente si hay más de dos etiquetas. Para comparar dos etiquetas, el método de puntuación solo será preciso. Los requisitos dictarán cómo almacena las puntuaciones de las palabras. 
Hay dos tipos de datos que se pueden recibir a través del canal después de tener la instancia: 
 

  1. Un mensaje hecho: Señala que no hay más datos entrando por el canal. 
    Responda con otro mensaje terminado, finalmente salga del bucle para cerrar el canal.
  2. Una tupla de 2 de (etiqueta, palabras): se usa para iterar para incrementar los recuentos tanto en RedisHashFreqDist como en RedisConditionalHashFreqDist

Publicación traducida automáticamente

Artículo escrito por mathemagic y traducido por Barcelona Geeks. The original can be accessed here. Licence: CCBY-SA

Deja una respuesta

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