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:
- 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. - 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