2017-12-06 124 views
7

TLEKorzystanie word2vec klasyfikowanie słów w kategoriach

mam wektory z niektórych przykładowych danych i każdy wektor ma nazwę kategorii (Miejsca, kolorów, nazw).

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

Moim celem jest wyszkolenie modelu, który pobierze nowy łańcuch wejściowy i określi, do której kategorii należy. Na przykład, jeśli nowe wejście jest "fioletowe", powinienem być w stanie przewidzieć "Kolory" jako właściwą kategorię. Jeśli nowy sygnał wejściowy to "Calgary", powinien przewidzieć "Miejsca" jako właściwą kategorię.

PODEJŚCIE

Zrobiłem rozeznanie i natknąłem Word2vec. Ta biblioteka ma funkcję "podobieństwa" i "najbardziej podobną", z której mogę korzystać. Tak więc jeden z podejść o brutalnej sile, o którym myślałem, jest następujący:

  1. Weź nowe wejście.
  2. Obliczyć podobieństwo z każdym słowem w każdym wektorze i wziąć średnią.

Na przykład dla danych wejściowych "różowy" mogę obliczyć jego podobieństwo ze słowami w wektorach "nazwy" wziąć średnią, a następnie zrobić to dla pozostałych 2 wektory również. Wektor, który daje mi najwyższą średnią podobieństwa, byłby prawidłowym wektorem dla danych wejściowych.

WYDANIE

Biorąc moja ograniczona wiedza w NLP i maszynowego uczenia nie jestem pewien, czy jest to najlepsze podejście, a więc szukam pomocy i sugestie na lepszych metod, aby rozwiązać mój problem. Jestem otwarty na wszelkie sugestie, a także proszę wskazać wszelkie błędy, które mogłem popełnić, ponieważ jestem nowy w świecie uczenia maszynowego i NLP.

+2

użyj spacy's ner i możesz również trenować model spacy z Twoimi danymi. –

+1

@AyodhyankitPaul będę google teraz! dziękuję za opinie i jeśli to możliwe, bardzo by mi się podobało, gdybyś mógł dostarczyć małe demo, chciałbym to zobaczyć – Dinero

Odpowiedz

7

Jeśli szukasz najprostszego/najszybszego rozwiązania, proponuję, abyś wziął wcześniej wyszkolone słowa osadzania (Word2Vec lub GloVe) i po prostu zbudował prosty system zapytań na nim. Wektory zostały wyszkolone w ogromnym korpusie i prawdopodobnie zawierają wystarczająco dobre przybliżenie do danych twojej domeny.

Oto moje rozwiązanie poniżej:

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')) 

Aby go uruchomić, trzeba będzie pobrać i rozpakować wstępnie przeszkolony danych rękawica z here (uważać, 800MB!). Po uruchomieniu powinien on wygenerować coś takiego:

{'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} 

... który wygląda całkiem rozsądnie. I to wszystko! Jeśli nie potrzebujesz tak dużego modelu, możesz filtrować słowa w postaci glove zgodnie z ich wynikiem tf-idf. Pamiętaj, że rozmiar modelu zależy tylko od posiadanych danych i słów, które możesz chcieć zadać.

+1

To jest bardzo interesujące. Najwyraźniej słowo embeddings zostało już stworzone.Kiedy próbowałem drukowania (proces ("Kobe")) zaklasyfikował "Kobe" jako miejsce, mimo że "Kobe" to nazwa, jednak gdy dodałem "Kobe" do słownika danych jako nazwę typu sklasyfikowano Kobe jako nazwę. Próbuję zrozumieć, co dzieje się pod maską. Dało to najwyższy wynik (9.38), ale wynik dla kategorii miejsca był dość blisko (9.08). – Dinero

+2

Niektóre terminy są naturalnie na granicy. Pamiętaj, że z tekstów można wyciągnąć wnioski. Np. "Paryż" jest często używana zarówno jako miasto, jak i nazwa, Paris Hilton. To samo dotyczy Kobe: znam tylko jedno użycie jako imię, choć bardzo popularne, ale jest to również miejsce w Japonii - https://en.wikipedia.org/wiki/Kobe. Jest to powszechny problem w klasyfikacji. Jeśli chodzi o ogólne zrozumienie, zobacz tę odpowiedź - https://stackoverflow.com/a/46727571/712995 i dalsze odnośniki do niej odnoszą się do – Maxim

+0

Zauważyłem także, że kiedy zrobiłem wydruk (proces ("a2")) otrzymałem wyniki negatywne dla wszystkich 3 kategorii. Następnie dodałem nową kategorię o nazwie "Id", w której dodałem wartości takie jak a1, a2, b1, b2. Następnie wydrukowałem (proces ("a2")) i wydrukowałem (proces ("c2")) i uzyskałem wysoki wynik dla kategorii "id" w obu przypadkach. Tak więc powyższy kod oznacza uczenie się znaczenia nowych wartości pod maską? Ponieważ dodałem nową kategorię o nazwie Id, to w jakiś sposób można się domyślić, że wartości takie jak a1, b2, c3 są ze sobą ściśle powiązane. – Dinero