Wörter zu Zahlen schneller suchen
-
16-10-2019 - |
Frage
Ich trainiere eine LSTM für die Sentiment -Analyse in einem von heruntergeladenen Überprüfungsdatensatz hier. Der Music Review -Datensatz enthält etwa 150K -Datenpunkte (Bewertungen der unterschiedlichen Länge mit der Bezeichnung POS oder NEG). Nachdem ich ein Wörterbuch erstellt habe, führe ich ein Skript in Python aus, um Zeichenfolgen (Wörter) durch Zahlen zu ersetzen, die Keras/Theano später einbetten wird.
Das Problem ist, dass ein so großer Datensatz viel Zeit für die Suche erfordert. Ich würde mich freuen, wenn jemand einen Vorschlag für ein Tool für eine schnellere Suche oder ähnliches hätte. Derzeit habe ich einfach jedes Wort im Korpus durchlief und es durch die entsprechende Zahl aus dem Wörterbuch ersetze (1-Hot-Codierung im Wesentlichen)
BEARBEITEN:
Ich mache ungefähr Folgendes: Jede Python -Liste ist ein Satz (vor der Tokenisierung hier):
'Noble', 'interessant_superlatives', ..., 'the_idea'
was ich zu einer Liste von Ganzzahlen konvergieren möchte, wie:
[143599, 12387,...,7582]
Ich habe es (wahrscheinlich fälschlicherweise) als One-Hot-Codierung bezeichnet, da für jedes Wort genau eine Nummer im Wörterbuch vorhanden ist.
Lösung
Ich möchte ausdehnen Die Antwort des großen @emres Antwort Mit einem anderen Beispiel - wir werden alle tokenisierten Wörter aus dem "1984" (c) George Orwell (120k Wörter) ersetzen:
In [163]: %paste
import requests
import nltk
import pandas as pd
# source: https://github.com/dwyl/english-words
fn = r'D:\temp\.data\words.txt'
url = 'http://gutenberg.net.au/ebooks01/0100021.txt'
r = requests.get(url)
# read words into Pandas DataFrame
df = pd.read_csv(fn, header=None, names=['word'])
# shuffle DF, so we will have random indexes
df = df.sample(frac=1)
# convert Pandas DF into dictionary: {'word1': unique_number1, 'word2': unique_number2, ...}
lkp = df.reset_index().set_index('word')['index'].to_dict()
# tokenize "1984" (c) George Orwell
words = nltk.tokenize.word_tokenize(r.text)
print('Word Dictionary size: {}'.format(len(lkp)))
print('We have tokenized {} words...'.format(len(words)))
## -- End pasted text --
Word Dictionary size: 354983
We have tokenized 120251 words...
In [164]: %timeit [lkp.get(w, 0) for w in words]
10 loops, best of 3: 66.3 ms per loop
Fazit: Es dauerte 66 ms, um eine Liste von Nummern für die Liste mit 120K -Wörtern aus dem Wörterbuch mit 354,983 Einträgen zu erstellen.
Andere Tipps
Du machst etwas falsch. Ich kann in Nanosekunden ein 100K -Wortdiktieren abfragen
word_list = open('/usr/share/dict/words').read().split()
len(word_list)
> 99171
word_dict = {word: hash(word) for word in word_list}
%timeit word_dict['blazing']
> 10000000 loops, best of 3: 33.8 ns per loop
Sie könnten a verwenden Trie Aus der Wikipedia -Definition:
ist eine Art Suchbaum - eine geordnete Baumdatenstruktur, mit der ein dynamisches Satz oder ein assoziatives Array gespeichert wird, in dem die Schlüssel normalerweise Saiten sind.
Pygtrie Bietet eine Implementierung von Versuchen mit einer Diktierschnittstelle. Hier geht ein Beispiel
import pygtrie as trie
words = ['cat', 'caterpillar', 'dog', 'mouse']
structure = trie.Trie()
for i, word in enumerate(words):
structure[word] = i
print structure['caterpillar']