web-dev-qa-db-de.com

Verwenden von Word2vec zum Klassifizieren von Wörtern in Kategorien

HINTERGRUND

Ich habe Vektoren mit einigen Beispieldaten und jeder Vektor hat einen Kategorienamen (Orte, Farben, Namen).

['john','jay','dan','nathan','bob']  -> 'Names'
['yellow', 'red','green'] -> 'Colors'
['tokyo','bejing','washington','mumbai'] -> 'Places'

Mein Ziel ist es, ein Modell zu trainieren, das eine neue Eingabezeichenfolge verwendet und vorhersagt, zu welcher Kategorie es gehört. Wenn zum Beispiel eine neue Eingabe "violett" ist, sollte ich in der Lage sein, "Farben" als die richtige Kategorie vorherzusagen. Wenn die neue Eingabe "Calgary" ist, sollte "Places" als die richtige Kategorie vorhergesagt werden.

ANSATZ

Ich habe etwas recherchiert und bin auf Word2vec gestoßen. Diese Bibliothek hat eine "Ähnlichkeits-" und "Mostsimilarity" -Funktion, die ich verwenden kann. Ich dachte an eine Brute-Force-Methode:

  1. Nehmen Sie neue Eingaben auf.
  2. Berechne die Ähnlichkeit mit jedem Wort in jedem Vektor und nimm einen Durchschnitt.

So zum Beispiel für die Eingabe "pink" kann ich die Ähnlichkeit mit Wörtern in Vektor "Namen" berechnen, einen Durchschnitt nehmen und dann das für die anderen 2 Vektoren auch tun. Der Vektor, der den höchsten Ähnlichkeitsmittelwert ergibt, wäre der korrekte Vektor, zu dem die Eingabe gehört.

PROBLEM

Aufgrund meiner begrenzten Kenntnisse in NLP und maschinellem Lernen bin ich nicht sicher, ob dies der beste Ansatz ist. Daher suche ich Hilfe und Vorschläge für bessere Lösungsansätze für mein Problem. Ich bin offen für alle Vorschläge und weise auch auf mögliche Fehler hin, die ich gemacht habe, da ich im Bereich des maschinellen Lernens und der NLP-Welt neu bin.

11
Dinero

Wenn Sie nach der einfachsten/schnellsten Lösung suchen, empfiehlt es sich, die vorbereiteten Word-Einbettungen (Word2Vec oder GloVe) zu nutzen und einfach ein einfaches Abfragesystem darauf aufzubauen. Die Vektoren wurden an einem riesigen Korpus trainiert und enthalten wahrscheinlich eine hinreichende Annäherung an Ihre Domain-Daten.

Hier ist meine Lösung unten:

import numpy as np

# Category -> words
data = {
  'Names': ['john','jay','dan','nathan','bob'],
  'Colors': ['yellow', 'red','green'],
  'Places': ['tokyo','bejing','washington','mumbai'],
}
# Words -> category
categories = {Word: key for key, words in data.items() for Word in words}

# Load the whole embedding matrix
embeddings_index = {}
with open('glove.6B.100d.txt') as f:
  for line in f:
    values = line.split()
    Word = values[0]
    embed = np.array(values[1:], dtype=np.float32)
    embeddings_index[Word] = embed
print('Loaded %s Word vectors.' % len(embeddings_index))
# Embeddings for available words
data_embeddings = {key: value for key, value in embeddings_index.items() if key in categories.keys()}

# Processing the query
def process(query):
  query_embed = embeddings_index[query]
  scores = {}
  for Word, embed in data_embeddings.items():
    category = categories[Word]
    dist = query_embed.dot(embed)
    dist /= len(data[category])
    scores[category] = scores.get(category, 0) + dist
  return scores

# Testing
print(process('pink'))
print(process('frank'))
print(process('moscow'))

Um es auszuführen, müssen Sie die vorab trainierten GloVe-Daten von hier (vorsichtig, 800 MB!) Herunterladen und auspacken. Beim Laufen sollte es so etwas erzeugen:

{'Colors': 24.655489603678387, 'Names': 5.058711671829224, 'Places': 0.90213905274868011}
{'Colors': 6.8597321510314941, 'Names': 15.570847320556641, 'Places': 3.5302454829216003}
{'Colors': 8.2919375101725254, 'Names': 4.58830726146698, 'Places': 14.7840416431427}

... das sieht ziemlich vernünftig aus. Und das ist es! Wenn Sie kein so großes Modell benötigen, können Sie die Wörter in glove nach ihrem tf-idf score filtern. Beachten Sie, dass die Modellgröße nur von den Daten und Wörtern abhängt, die Sie möglicherweise abfragen möchten.

18
Maxim

Und was ist es wert, PyTorch hat eine gute und schnellere Implementierung von Glove in diesen Tagen.

0
mithunpaul