2015-03-22 11 views
5

Sto provando ad usare il classificatore lineare SVM e K Neighbors per eseguire la disambiguazione del senso della parola (WSD). Ecco un segmento di dati che sto usando per addestrare i dati:Implementare K Neighbors Classifier e SVM lineare in scikit-learn per disambiguazione senso parola

<corpus lang="English"> 

<lexelt item="activate.v"> 


<instance id="activate.v.bnc.00024693" docsrc="BNC"> 
<answer instance="activate.v.bnc.00024693" senseid="38201"/> 
<context> 
Do you know what it is , and where I can get one ? We suspect you had seen the Terrex Autospade , which is made by Wolf Tools . It is quite a hefty spade , with bicycle - type handlebars and a sprung lever at the rear , which you step on to <head>activate</head> it . Used correctly , you should n't have to bend your back during general digging , although it wo n't lift out the soil and put in a barrow if you need to move it ! If gardening tends to give you backache , remember to take plenty of rest periods during the day , and never try to lift more than you can easily cope with . 
</context> 
</instance> 


<instance id="activate.v.bnc.00044852" docsrc="BNC"> 
<answer instance="activate.v.bnc.00044852" senseid="38201"/> 
<answer instance="activate.v.bnc.00044852" senseid="38202"/> 
<context> 
For neurophysiologists and neuropsychologists , the way forward in understanding perception has been to correlate these dimensions of experience with , firstly , the material properties of the experienced object or event (usually regarded as the stimulus) and , secondly , the patterns of discharges in the sensory system . Qualitative Aspects of Experience The quality or modality of the experience depends less upon the quality of energy reaching the nervous system than upon which parts of the sensory system are <head>activated</head> : stimulation of the retinal receptors causes an experience of light ; stimulation of the receptors in the inner ear gives rise to the experience of sound ; and so on . Muller 's nineteenth - century doctrine of specific energies formalized the ordinary observation that different sense organs are sensitive to different physical properties of the world and that when they are stimulated , sensations specific to those organs are experienced . It was proposed that there are endings (or receptors) within the nervous system which are attuned to specific types of energy , For example , retinal receptors in the eye respond to light energy , cochlear endings in the ear to vibrations in the air , and so on . 
</context> 
</instance> 
..... 

La differenza tra la formazione e dati di prova è che i dati di test non hanno il tag "risposta". Ho creato un dizionario per memorizzare le parole che sono i vicini della parola "testa" per ogni istanza con una dimensione della finestra di 10. Quando ci sono più per una istanza, prenderò in considerazione solo la prima. Ho anche creato un set per registrare tutto il vocabolario nel file di allenamento in modo da poter calcolare un vettore per ogni istanza. Ad esempio, se il vocabolario totale è [a, b, c, d, e] e un'istanza contiene parole [a, a, d, d, e], il vettore risultante per tale istanza sarebbe [2,0 , 0,2,1]. Ecco il un segmento del dizionario ho costruito per ogni parola:

{ 
    "activate.v": { 
     "activate.v.bnc.00024693": { 
      "instanceId": "activate.v.bnc.00024693", 
      "senseId": "38201", 
      "vocab": { 
       "although": 1, 
       "back": 1, 
       "bend": 1, 
       "bicycl": 1, 
       "correct": 1, 
       "dig": 1, 
       "general": 1, 
       "handlebar": 1, 
       "hefti": 1, 
       "lever": 1, 
       "nt": 2, 
       "quit": 1, 
       "rear": 1, 
       "spade": 1, 
       "sprung": 1, 
       "step": 1, 
       "type": 1, 
       "use": 1, 
       "wo": 1 
      } 
     }, 
     "activate.v.bnc.00044852": { 
      "instanceId": "activate.v.bnc.00044852", 
      "senseId": "38201", 
      "vocab": { 
       "caus": 1, 
       "ear": 1, 
       "energi": 1, 
       "experi": 1, 
       "inner": 1, 
       "light": 1, 
       "nervous": 1, 
       "part": 1, 
       "qualiti": 1, 
       "reach": 1, 
       "receptor": 2, 
       "retin": 1, 
       "sensori": 1, 
       "stimul": 2, 
       "system": 2, 
       "upon": 2 
      } 
     }, 
     ...... 

Ora, ho solo bisogno di fornire l'input a K vicini Classificatore e lineare SVM dal scikit-learn per addestrare il classificatore. Ma non sono sicuro di come dovrei creare il vettore di funzionalità e l'etichetta per ciascuno. La mia comprensione è che l'etichetta dovrebbe essere una tupla di tag di istanza e tag senseid nella "risposta". Ma non sono sicuro del vettore di funzionalità. Devo raggruppare tutti i vettori della stessa parola che ha lo stesso tag di istanza e tag senseid nella "risposta"? Ma ci sono circa 100 parole e centinaia di istanze per ogni parola, come posso comportarmi con questo?

Inoltre, il vettore è una funzionalità, ho bisogno di aggiungere più funzionalità in seguito, ad esempio, synset, hypernms, iponimi ecc.. Come dovrei farlo?

Grazie in anticipo!

+0

Non ho mai lavorato con i dati di testo in ML ma scikit-learn ha questo bell'esempio (http://scikit-learn.org/stable/tutorial/text_analytics/working_with_text_data.html) che potrebbe essere utile. So, tuttavia, che KNN funziona con un vettore di funzioni (e una di risposte) per ogni esempio. Come input dovresti avere 2 matrici M x N (dove M sono il numero di esempi e N il numero di caratteristiche/etichette) – pekapa

risposta

2

I problemi di Machine Learning sono un tipo di attività di ottimizzazione, in cui non si dispone di algoritmi predefiniti best-for-all, ma si preferiscono cercare il risultato migliore utilizzando approcci, parametri e elaborazione dei dati diversi. Quindi hai assolutamente ragione partendo dal compito più semplice - prendendo solo una parola e molti sensi.

Ma io non sono sicuro di come dovrei creare il vettore di funzionalità e l'etichetta per ciascuno.

È possibile prendere solo questi valori come componenti vettoriali. Enumerare parole vettoriali e scrivere numeri di tale parola in ciascun testo. Se la parola è assente, inserisci un valore vuoto. Ho leggermente modificato il tuo esempio per chiarire l'idea:

vocab_38201= { 
      "although": 1, 
      "back": 1, 
      "bend": 1, 
      "bicycl": 1, 
      "correct": 1, 
      "dig": 1, 
      "general": 1, 
      "handlebar": 1, 
      "hefti": 1, 
      "lever": 1, 
      "nt": 2, 
      "quit": 1, 
      "rear": 1, 
      "spade": 1, 
      "sprung": 1, 
      "step": 1, 
      "type": 1, 
      "use": 1, 
      "wo": 1 
     } 

vocab_38202 = { 
      "caus": 1, 
      "ear": 1, 
      "energi": 1, 
      "experi": 1, 
      "inner": 1, 
      "light": 1, 
      "nervous": 1, 
      "part": 1, 
      "qualiti": 1, 
      "reach": 1, 
      "receptor": 2, 
      "retin": 1, 
      "sensori": 1, 
      "stimul": 2, 
      "system": 2, 
      "upon": 2, 
      "wo": 1  ### added so they have at least one common word 
     } 

Copriamolo per rappresentare il vettore. Enumerare tutte le parole e segnare quante volte questa parola è nel vocabolario.

from collections import defaultdict 
words = [] 

def get_components(vect_dict): 
    vect_components = defaultdict(int) 
    for word, num in vect_dict.items(): 
     try: 
      ind = words.index(word) 
     except ValueError: 
      ind = len(words) 
      words.append(word) 
     vect_components[ind] += num 
    return vect_components 


# 
vect_comps_38201 = get_components(vocab_38201) 
vect_comps_38202 = get_components(vocab_38202) 

Vediamo:

>>> print(vect_comps_38201) 
defaultdict(<class 'int'>, {0: 1, 1: 1, 2: 1, 3: 1, 4: 1, 5: 1, 6: 1, 7: 1, 8: 1, 9: 2, 10: 1, 11: 1, 12: 1, 13: 1, 14: 1, 15: 1, 16: 1, 17: 1, 18: 1}) 

>>> print(vect_comps_38202) 
defaultdict(<class 'int'>, {32: 1, 33: 2, 34: 1, 7: 1, 19: 2, 20: 2, 21: 1, 22: 1, 23: 1, 24: 1, 25: 1, 26: 1, 27: 2, 28: 1, 29: 1, 30: 1, 31: 1}) 

>>> vect_38201=[vect_comps_38201.get(i,0) for i in range(len(words))] 
>>> print(vect_38201) 
[1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] 

>>> vect_38202=[vect_comps_38202.get(i,0) for i in range(len(words))] 
>>> print(vect_38202) 
[0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 2, 1] 

Questi vect_38201 e vect38202 sono vettori si possono utilizzare nel montaggio di modello:

from sklearn.svm import SVC 
X = [vect_38201, vect_38202] 
y = [38201, 38202] 
clf = SVC() 
clf.fit(X, y) 
clf.predict([[0, 0, 1, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 2, 1]]) 

uscita:

array([38202]) 

Naturalmente è un esempio molto molto semplice mostra solo il concetto.

Cosa si può fare per migliorarlo?

  1. Normalizza le coordinate del vettore.

  2. Utilizzare lo strumento eccellente Tf-Idf vectorizer per estrarre le funzionalità di dati dal testo.

  3. Aggiungi altri dati.

Buona fortuna!

2

Passaggio successivo: implementazione del classificatore lineare multidimentale.

Purtroppo non ho accesso a questo database, quindi questo è un po 'teorico. Posso proporre questo approccio:

costringere tutti i dati in un file CSV in questo modo:

SenseId,Word,Text,IsHyponim,Properties,Attribute1,Attribute2, ... 
30821,"BNC","For neurophysiologists and ...","Hyponym sometype",1,1 
30822,"BNC","Do you know what it is ...","Antonym type",0,1 
... 

Poi si può utilizzare sklearn strumenti:

import pandas as pd 
df.read_csv('file.csv') 

from sklearn.feature_extraction import DictVectorizer 
enc=DictVectorizer() 
X_train_categ = enc.fit_transform(df[['Properties',]].to_dict('records')) 

from sklearn.feature_extraction.text import TfidfVectorizer 
vec=TfidfVectorizer(min_df=5) # throw out all terms which present in less than 5 documents - typos and so on 
v=vec.fit_transform(df['Text']) 

# Join all date together as a sparsed matrix 
from scipy.sparse import csr_matrix, hstack 
train=hstack((csr_matrix(df.ix[:, 'Word':'Text']), X_train_categ, v)) 
y = df['SenseId'] 

# here you have an matrix with really huge dimensionality - about dozens of thousand columns 
# you may use Ridge regression to deal with it: 
from sklearn.linear_model import Ridge 
r=Ridge(random_state=241, alpha=1.0) 

# prepare test data like training one 

Maggiori dettagli su: Ridge, Ridge Classifier.

Altre tecniche per risolvere il problema high dimensionality.

Esempio di codice su text classification using sparse feature matrices.

Problemi correlati