Come posso creare un modello per distinguere i tweet su Apple (Inc.) dai tweet su apple (frutta)?


85

Vedi sotto per 50 tweet su "mela". Ho etichettato a mano le corrispondenze positive su Apple Inc. Sono contrassegnate come 1 di seguito.

Ecco un paio di righe:

1|“@chrisgilmer: Apple targets big business with new iOS 7 features http://bit.ly/15F9JeF ”. Finally.. A corp iTunes account!
0|“@Zach_Paull: When did green skittles change from lime to green apple? #notafan” @Skittles
1|@dtfcdvEric: @MaroneyFan11 apple inc is searching for people to help and tryout all their upcoming tablet within our own net page No.
0|@STFUTimothy have you tried apple pie shine?
1|#SuryaRay #India Microsoft to bring Xbox and PC games to Apple, Android phones: Report: Microsoft Corp... http://dlvr.it/3YvbQx  @SuryaRay

Ecco il set di dati totale: http://pastebin.com/eJuEb4eB

Ho bisogno di costruire un modello che classifichi "Apple" (Inc). dal resto.

Non sto cercando una panoramica generale dell'apprendimento automatico, piuttosto sto cercando un modello effettivo nel codice ( preferito Python ).


18
Fondamentalmente vuoi questo: en.wikipedia.org/wiki/Bayesian_spam_filtering
eddi

1
Tu etichetti manualmente i tuoi dati, ma vuoi librerie che scalano. Questo è supervisionato o non supervisionato?
dan

1
Eddi, grazie, per il commento. Vedere l'e-mail di filtraggio della posta ha davvero aiutato qualcosa a fare clic nel mio cervello. Sono stato in grado di vedere un esempio di vita reale di ciò che stavo cercando di fare, applicato in modo diverso.
SAL


1
Affascinante @NeilMcGuigan. Ho incollato parte del testo nella loro demo ( nlp.stanford.edu:8080/ner/process ) e sono rimasto colpito da come i diversi modelli classificassero le parole.
Ryan

Risposte:


39

Lo farei come segue:

  1. Dividi la frase in parole, normalizzale, costruisci un dizionario
  2. Con ogni parola, memorizza quante volte si sono verificati nei tweet sull'azienda e quante volte sono apparsi nei tweet sul frutto: questi tweet devono essere confermati da un essere umano
  3. Quando arriva un nuovo tweet, trova ogni parola del tweet nel dizionario, calcola un punteggio ponderato: le parole che vengono usate frequentemente in relazione all'azienda otterrebbero un punteggio aziendale alto e viceversa; le parole usate raramente, o usate sia con l'azienda che con la frutta, non avrebbero un gran punteggio.

2
Grazie per la tua risposta su questo. La tua risposta in combinazione con un commento sopra mi ha davvero aiutato ad arrivare a una soluzione. Puoi aiutarmi ad affinare questa soluzione?
SAL

10
Questa è una descrizione informale della classificazione bayesiana.
sanityinc

1
Preferisco "l'implementazione pseudo-codice della classificazione bayesiana" :)
AMADANON Inc.

73

Quello che stai cercando si chiama Named Entity Recognition . È una tecnica statistica che (più comunemente) utilizza i campi casuali condizionali per trovare entità denominate, in base all'essere stati addestrati a imparare cose sulle entità denominate.

Essenzialmente, esamina il contenuto e il contesto della parola (guardando avanti e indietro di alcune parole), per stimare la probabilità che la parola sia un'entità con nome.

Un buon software può esaminare altre caratteristiche delle parole, come la loro lunghezza o forma (come "Vcv" se inizia con "vocale-consonante-vocale")

Un'ottima libreria (GPL) è il NER di Stanford

Ecco la demo: http://nlp.stanford.edu:8080/ner/

Qualche testo di esempio da provare:

Stavo mangiando una mela al quartier generale della Apple e ho pensato ad Apple Martin, la figlia del ragazzo dei Coldplay

(i classificatori 3class e 4class lo fanno bene)


5
È stato davvero interessante. È possibile visualizzare il codice per english.conll.4class.distsim.crf.ser.gz? Mi piacerebbe vedere come si costruisce qualcosa di simile.
Ryan

Il codice per NER è open source, ma i dati che hanno usato nelle conferenze CONLL non lo sono. Tuttavia, puoi trovare il Reuters Corpus online sul NIST.
Neil McGuigan

31

Ho un sistema semi-funzionante che risolve questo problema, open source utilizzando scikit-learn, con una serie di post sul blog che descrivono cosa sto facendo. Il problema che sto affrontando è la disambiguazione del senso delle parole (scegliendo una delle più opzioni di senso delle parole ), che non è la stessa cosa del riconoscimento di entità nominate. Il mio approccio di base è piuttosto competitivo con le soluzioni esistenti e (soprattutto) è personalizzabile.

Esistono alcuni strumenti NER commerciali esistenti (OpenCalais, DBPedia Spotlight e AlchemyAPI) che potrebbero darti un risultato commerciale abbastanza buono: prova prima questi!

Ho usato alcuni di questi per un progetto cliente (consulto usando NLP / ML a Londra), ma non ero soddisfatto del loro richiamo ( precisione e richiamo ). Fondamentalmente possono essere precisi (quando dicono "Questa è Apple Inc" sono tipicamente corretti), ma con un basso richiamo (raramente dicono "Questa è Apple Inc" anche se per un essere umano il tweet riguarda ovviamente Apple Inc). Ho pensato che sarebbe stato un esercizio intellettualmente interessante costruire una versione open source su misura per i tweet. Ecco il codice attuale: https://github.com/ianozsvald/social_media_brand_disambiguator

Noterò: non sto cercando di risolvere il problema generalizzato della disambiguazione del senso delle parole con questo approccio, ma solo della disambiguazione del marchio (aziende, persone, ecc.) Quando hai già il loro nome. Ecco perché credo che questo approccio diretto funzionerà.

L'ho iniziato sei settimane fa ed è scritto in Python 2.7 usando scikit-learn. Utilizza un approccio molto semplice. Vettorizzo usando un vettorizzatore di conteggio binario (conto solo se una parola appare, non quante volte) con 1-3  n-grammi . Non scalo con TF-IDF (TF-IDF va bene quando hai una lunghezza del documento variabile; per me i tweet sono solo una o due frasi ei risultati dei miei test non hanno mostrato miglioramenti con TF-IDF).

Uso il tokenizer di base che è molto semplice ma sorprendentemente utile. Ignora @ # (quindi perdi un po 'di contesto) e ovviamente non espande un URL. Quindi mi alleno usando la regressione logistica e sembra che questo problema sia in qualche modo separabile linearmente (molti termini per una classe non esistono per l'altra). Attualmente sto evitando qualsiasi arginamento / pulizia (sto provando La cosa più semplice possibile che potrebbe funzionare).

Il codice ha un README completo e dovresti essere in grado di importare i tuoi tweet in modo relativamente semplice e quindi seguire i miei suggerimenti per i test.

Questo funziona per Apple in quanto le persone non mangiano o bevono computer Apple, né digitiamo o giochiamo con la frutta, quindi le parole sono facilmente suddivise in una categoria o nell'altra. Questa condizione potrebbe non valere se si considera qualcosa come #definance per il programma televisivo (dove le persone usano anche #definance in relazione alla Primavera Araba, partite di cricket, revisione degli esami e una banda musicale). Qui potrebbero essere necessari approcci più intelligenti.

Ho una serie di post sul blog che descrivono questo progetto, inclusa una presentazione di un'ora che ho tenuto al gruppo utenti BrightonPython (che si è trasformata in una presentazione più breve per 140 persone a DataScienceLondon).

Se usi qualcosa come LogisticRegression (dove ottieni una probabilità per ogni classificazione) puoi scegliere solo le classificazioni sicure, e in questo modo puoi forzare l'alta precisione scambiando contro il richiamo (in modo da ottenere risultati corretti, ma meno di essi). Dovrai sintonizzarlo sul tuo sistema.

Ecco un possibile approccio algoritmico usando scikit-learn:

  • Usa un Binary CountVectorizer (non credo che il conteggio dei termini nei messaggi brevi aggiunga molte informazioni poiché la maggior parte delle parole ricorre solo una volta)
  • Inizia con un classificatore dell'albero decisionale. Avrà prestazioni spiegabili (vedi Overfitting con un albero decisionale per un esempio).
  • Passa alla regressione logistica
  • Esaminare gli errori generati dai classificatori (leggere l'output esportato di DecisionTree o guardare i coefficienti in LogisticRegression, elaborare i tweet classificati erroneamente attraverso il Vectorizer per vedere come appare la rappresentazione del Bag of Words sottostante: ci saranno meno token di hai iniziato con il tweet grezzo - ce ne sono abbastanza per una classificazione?)
  • Guarda il mio codice di esempio in https://github.com/ianozsvald/social_media_brand_disambiguator/blob/master/learn1.py per una versione funzionante di questo approccio

Cose da considerare:

  • Hai bisogno di un set di dati più grande. Sto usando 2000 tweet etichettati (mi ci sono voluti cinque ore) e come minimo vuoi un set bilanciato con> 100 per classe (vedi la nota di overfitting sotto)
  • Migliora il tokeniser (molto facile con scikit-learn) per mantenere # @ nei token e magari aggiungi un rilevatore di marca in maiuscolo (come note user @ user2425429)
  • Considera un classificatore non lineare (come il suggerimento di @ oiez sopra) quando le cose si fanno più difficili. Personalmente ho trovato LinearSVC peggiore della regressione logistica (ma ciò potrebbe essere dovuto allo spazio delle caratteristiche ad alta dimensione che devo ancora ridurre).
  • Una parte specifica del tweet del tagger vocale (a mio modesto parere, non di Standford come suggerisce @Neil - si comporta male con la scarsa grammatica di Twitter nella mia esperienza)
  • Una volta che hai molti token, probabilmente vorrai fare un po 'di riduzione della dimensionalità (non l'ho ancora provato - vedi il mio post sul blog sulla penalizzazione LogisticRegression l1 l2)

Ri. overfitting. Nel mio set di dati con 2000 elementi ho un'istantanea di 10 minuti da Twitter di tweet "Apple". Circa 2/3 dei tweet sono per Apple Inc, 1/3 per altri usi della mela. Tiro fuori un sottoinsieme bilanciato (circa 584 righe credo) di ogni classe e faccio cinque volte la convalida incrociata per l'allenamento.

Dato che ho solo una finestra temporale di 10 minuti, ho molti tweet sullo stesso argomento, e questo è probabilmente il motivo per cui il mio classificatore funziona così bene rispetto agli strumenti esistenti: si adatterà eccessivamente alle funzionalità di formazione senza generalizzare bene (mentre lo spot pubblicitario esistente gli strumenti hanno prestazioni peggiori su questo snapshop, ma in modo più affidabile su un insieme più ampio di dati). Espanderò la mia finestra temporale per testarlo come lavoro successivo.


Non ho avuto il piacere di leggere il tuo codice e provare a duplicare / emulare / educare, ma ti devo delle scuse per non aver assegnato tutti i 50 punti della taglia. Sono stato via da SO durante il fine settimana e ho mancato la scadenza per assegnarlo. Per fortuna la comunità SO è intervenuta e ha ritenuto opportuno premiarti 25 punti.
Ryan

1
Nessun problema :-) Il codice, README e i post del blog dovrebbero darti un'idea del mio approccio. È deliberatamente semplice ma sembra funzionare bene.
Ian Ozsvald

12

Puoi fare quanto segue:

  1. Crea un dict di parole che contengano il conteggio delle occorrenze nei tweet relativi alla frutta e all'azienda. Ciò può essere ottenuto fornendogli alcuni tweet di esempio di cui conosciamo l'inclinazione.

  2. Utilizzando un numero sufficiente di dati precedenti, possiamo scoprire la probabilità che una parola ricorra in un tweet su apple inc.

  3. Moltiplica le probabilità individuali delle parole per ottenere la probabilità dell'intero tweet.

Un esempio semplificato:

p_f = Probabilità di tweet di frutta.

p_w_f = Probabilità che una parola ricorra in un tweet di frutta.

p_t_f = probabilità combinata che tutte le parole in tweet si verifichino un tweet di frutta = p_w1_f * p_w2_f * ...

p_f_t = Probabilità di frutta dato un particolare tweet.

p_c, p_w_c, p_t_c, p_c_t sono i rispettivi valori per la società.

Viene aggiunto uno smorzatore laplaciano di valore 1 per eliminare il problema della frequenza zero delle nuove parole che non sono presenti nel nostro database.

old_tweets = {'apple pie sweet potatoe cake baby https://vine.co/v/hzBaWVA3IE3': '0', ...}
known_words = {}
total_company_tweets = total_fruit_tweets =total_company_words = total_fruit_words = 0

for tweet in old_tweets:
    company = old_tweets[tweet]
    for word in tweet.lower().split(" "):
        if not word in known_words:
            known_words[word] = {"company":0, "fruit":0 }
        if company == "1":
            known_words[word]["company"] += 1
            total_company_words += 1
        else:
            known_words[word]["fruit"] += 1
            total_fruit_words += 1

    if company == "1":
        total_company_tweets += 1
    else:
        total_fruit_tweets += 1
total_tweets = len(old_tweets)

def predict_tweet(new_tweet,K=1):
    p_f = (total_fruit_tweets+K)/(total_tweets+K*2)
    p_c = (total_company_tweets+K)/(total_tweets+K*2)
    new_words = new_tweet.lower().split(" ")

    p_t_f = p_t_c = 1
    for word in new_words:
        try:
            wordFound = known_words[word]
        except KeyError:
            wordFound = {'fruit':0,'company':0}
        p_w_f = (wordFound['fruit']+K)/(total_fruit_words+K*(len(known_words)))
        p_w_c = (wordFound['company']+K)/(total_company_words+K*(len(known_words)))
    p_t_f *= p_w_f
    p_t_c *= p_w_c

    #Applying bayes rule
    p_f_t = p_f * p_t_f/(p_t_f*p_f + p_t_c*p_c)
    p_c_t = p_c * p_t_c/(p_t_f*p_f + p_t_c*p_c)
    if p_c_t > p_f_t:
        return "Company"
    return "Fruit"

9

Se non hai problemi con l'utilizzo di una libreria esterna, consiglierei scikit-learn poiché probabilmente può farlo meglio e più velocemente di qualsiasi cosa tu possa programmare da solo. Farei qualcosa del genere:

Costruisci il tuo corpus. Ho fatto le comprensioni dell'elenco per chiarezza, ma a seconda di come vengono archiviati i tuoi dati potresti dover fare cose diverse:

def corpus_builder(apple_inc_tweets, apple_fruit_tweets):
    corpus = [tweet for tweet in apple_inc_tweets] + [tweet for tweet in apple_fruit_tweets]
    labels = [1 for x in xrange(len(apple_inc_tweets))] + [0 for x in xrange(len(apple_fruit_tweets))]
    return (corpus, labels)

La cosa importante è che ti ritroverai con due elenchi che assomigliano a questo:

([['apple inc tweet i love ios and iphones'], ['apple iphones are great'], ['apple fruit tweet i love pie'], ['apple pie is great']], [1, 1, 0, 0])

[1, 1, 0, 0] rappresentano le etichette positive e negative.

Quindi, crei una pipeline! Pipeline è una classe di apprendimento scikit che semplifica il concatenamento delle fasi di elaborazione del testo in modo da dover chiamare solo un oggetto durante l'addestramento / previsione:

def train(corpus, labels)
    pipe = Pipeline([('vect', CountVectorizer(ngram_range=(1, 3), stop_words='english')),
                        ('tfidf', TfidfTransformer(norm='l2')),
                        ('clf', LinearSVC()),])
    pipe.fit_transform(corpus, labels)
    return pipe

All'interno della pipeline ci sono tre fasi di elaborazione. CountVectorizer tokenizza le parole, le divide, le conta e trasforma i dati in una matrice sparsa. Il TfidfTransformer è opzionale e potresti volerlo rimuovere a seconda della valutazione dell'accuratezza (fare test di convalida incrociata e una ricerca sulla griglia dei parametri migliori è un po 'complicato, quindi non lo approfondirò qui). LinearSVC è un algoritmo di classificazione del testo standard.

Infine, prevedi la categoria dei tweet:

def predict(pipe, tweet):
    prediction = pipe.predict([tweet])
    return prediction

Di nuovo, il tweet deve essere in un elenco, quindi ho pensato che stesse inserendo la funzione come stringa.

Metti tutti quelli in una classe o qualsiasi altra cosa e il gioco è fatto. Almeno, con questo esempio molto semplice.

Non ho testato questo codice, quindi potrebbe non funzionare se copi e incolla, ma se vuoi usare scikit-learn dovrebbe darti un'idea di dove iniziare.

EDIT: ho cercato di spiegare i passaggi in modo più dettagliato.


6

L'uso di un albero decisionale sembra funzionare abbastanza bene per questo problema. Almeno produce una precisione maggiore di un classificatore bayes ingenuo con le mie caratteristiche scelte.

Se vuoi giocare con alcune possibilità, puoi usare il seguente codice, che richiede l'installazione di nltk. Il libro nltk è anche disponibile gratuitamente online, quindi potresti voler leggere un po 'come funziona effettivamente tutto questo: http://nltk.googlecode.com/svn/trunk/doc/book/ch06.html

#coding: utf-8
import nltk
import random
import re

def get_split_sets():
    structured_dataset = get_dataset()
    train_set = set(random.sample(structured_dataset, int(len(structured_dataset) * 0.7)))
    test_set = [x for x in structured_dataset if x not in train_set]

    train_set = [(tweet_features(x[1]), x[0]) for x in train_set]
    test_set = [(tweet_features(x[1]), x[0]) for x in test_set]
    return (train_set, test_set)

def check_accurracy(times=5):
    s = 0
    for _ in xrange(times):
        train_set, test_set = get_split_sets()
        c = nltk.classify.DecisionTreeClassifier.train(train_set)
        # Uncomment to use a naive bayes classifier instead
        #c = nltk.classify.NaiveBayesClassifier.train(train_set)
        s += nltk.classify.accuracy(c, test_set)

    return s / times


def remove_urls(tweet):
    tweet = re.sub(r'http:\/\/[^ ]+', "", tweet)
    tweet = re.sub(r'pic.twitter.com/[^ ]+', "", tweet)
    return tweet

def tweet_features(tweet):
    words = [x for x in nltk.tokenize.wordpunct_tokenize(remove_urls(tweet.lower())) if x.isalpha()]
    features = dict()
    for bigram in nltk.bigrams(words):
        features["hasBigram(%s)" % ",".join(bigram)] = True
    for trigram in nltk.trigrams(words):
        features["hasTrigram(%s)" % ",".join(trigram)] = True  
    return features

def get_dataset():
    dataset = """copy dataset in here
"""
    structured_dataset = [('fruit' if x[0] == '0' else 'company', x[2:]) for x in dataset.splitlines()]
    return structured_dataset

if __name__ == '__main__':
    print check_accurracy()

1
come funziona? Non vedo le tue "caratteristiche scelte" nel tuo codice. Sceglie automaticamente le funzionalità in base al set di allenamento? O è conservato dict()da qualche altra parte? Penso che se il proprio set di allenamento è abbastanza grande, un computer non dovrebbe essere in grado di capire le funzionalità da solo? (senza supervisione?)
Ryan

2
Le caratteristiche vengono estratte utilizzando la funzione tweet_features. Fondamentalmente rimuove gli URL dai tweet e quindi crea un dict di funzionalità le cui voci leggono qualcosa come "hasBigram (foo, bar)" = True.
Paul Dubs

1
Allora, 'hasBigram(foo,bar)' = Truedove include la stringa tweet foo bar? Quindi crea bigram e trigram per ogni tweet e lo contrassegna nella funzione positiva dict()? Pertanto, dato il tweet, "alpha beta gamma delta"creerà dict () bigram per alpha,beta; beta,gamma; and gamma,delta;e trigrammi per alpha,beta,gammae beta,gamma,delta? E dai dati bi e tri grammi positivi e negativi, i classificatori decisiontree o bayes possono fare la loro magia?
Ryan

2
Esattamente. Quando si utilizza il classificatore bayes è anche possibile ottenere le funzioni più utili chiamando "show_most_informative_features ()" su di esso.
Paul Dubs

Paul, ho creato una versione php grezza di questo e hai assolutamente ragione. Questo è un modo super efficiente per creare un dizionario ponderato. Penso che questo potrebbe facilmente ridimensionarsi senza dover creare manualmente tutte le parole chiave. Non vedo l'ora di saperne di più su come farlo all'interno di librerie di machine learning standard.
Ryan

5

Grazie per i commenti finora. Ecco una soluzione funzionante che ho preparato con PHP. Sarei comunque interessato a sentire da altri un approccio più algoritmico a questa stessa soluzione.

<?php

// Confusion Matrix Init
$tp = 0;
$fp = 0;
$fn = 0;
$tn = 0;
$arrFP = array();
$arrFN = array();

// Load All Tweets to string
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'http://pastebin.com/raw.php?i=m6pP8ctM');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$strCorpus = curl_exec($ch);
curl_close($ch);

// Load Tweets as Array
$arrCorpus = explode("\n", $strCorpus);
foreach ($arrCorpus as $k => $v) {
    // init
    $blnActualClass = substr($v,0,1);
    $strTweet = trim(substr($v,2));

    // Score Tweet
    $intScore = score($strTweet);

    // Build Confusion Matrix and Log False Positives & Negatives for Review
    if ($intScore > 0) {
        if ($blnActualClass == 1) {
            // True Positive
            $tp++;
        } else {
            // False Positive
            $fp++;
            $arrFP[] = $strTweet;
        }
    } else {
        if ($blnActualClass == 1) {
            // False Negative
            $fn++;
            $arrFN[] = $strTweet;
        } else {
            // True Negative
            $tn++;
        }
    }
}

// Confusion Matrix and Logging
echo "
           Predicted
            1     0
Actual 1   $tp     $fp
Actual 0    $fn    $tn

";

if (count($arrFP) > 0) {
    echo "\n\nFalse Positives\n";
    foreach ($arrFP as $strTweet) {
        echo "$strTweet\n";
    }
}

if (count($arrFN) > 0) {
    echo "\n\nFalse Negatives\n";
    foreach ($arrFN as $strTweet) {
        echo "$strTweet\n";
    }
}

function LoadDictionaryArray() {
    $strDictionary = <<<EOD
10|iTunes
10|ios 7
10|ios7
10|iPhone
10|apple inc
10|apple corp
10|apple.com
10|MacBook
10|desk top
10|desktop
1|config
1|facebook
1|snapchat
1|intel
1|investor
1|news
1|labs
1|gadget
1|apple store
1|microsoft
1|android
1|bonds
1|Corp.tax
1|macs
-1|pie
-1|clientes
-1|green apple
-1|banana
-10|apple pie
EOD;

    $arrDictionary = explode("\n", $strDictionary);
    foreach ($arrDictionary as $k => $v) {
        $arr = explode('|', $v);
        $arrDictionary[$k] = array('value' => $arr[0], 'term' => strtolower(trim($arr[1])));
    }
    return $arrDictionary;
}

function score($str) {
    $str = strtolower($str);
    $intScore = 0;
    foreach (LoadDictionaryArray() as $arrDictionaryItem) {
        if (strpos($str,$arrDictionaryItem['term']) !== false) {
            $intScore += $arrDictionaryItem['value'];
        }
    }
    return $intScore;
}
?>

Le uscite di cui sopra:

           Predicted
            1     0
Actual 1   31     1
Actual 0    1    17


False Positives
1|Royals apple #ASGame @mlb @ News Corp Building http://instagram.com/p/bBzzgMrrIV/


False Negatives
-1|RT @MaxFreixenet: Apple no tiene clientes. Tiene FANS// error.... PAGAS por productos y apps, ergo: ERES CLIENTE.

4

In tutti gli esempi che hai fornito, Apple (inc) è stato indicato come A pple o apple inc , quindi un modo possibile potrebbe essere quello di cercare:

  • una "A" maiuscola in Apple

  • un "inc" dopo la mela

  • parole / frasi come "OS", "sistema operativo", "Mac", "iPhone", ...

  • o una combinazione di essi


1
Nella funzione ho fatto uno strtolower per filtrare le lettere maiuscole. Un po 'rozzo, ma ha funzionato.
SAL

@SAL Non mi aspettavo che fosse molto utile, ma se hai un limite di tempo, allora ...
user2425429

4

Per semplificare un po 'le risposte basate sui campi casuali condizionali ... il contesto è enorme qui. Ti consigliamo di scegliere in quei tweet che mostrano chiaramente ad Apple l'azienda contro Apple il frutto. Consentitemi di delineare qui un elenco di funzionalità che potrebbero esservi utili per iniziare. Per ulteriori informazioni, cercare chunking di frasi nominali e qualcosa chiamato etichette BIO. Vedi ( http://www.cis.upenn.edu/~pereira/papers/crf.pdf )

Parole circostanti: costruisci un vettore di caratteristiche per la parola precedente e la parola successiva, o se desideri più funzioni, forse le 2 parole precedenti e le 2 successive. Non vuoi troppe parole nel modello o non corrisponderà molto bene ai dati. In Natural Language Processing, vorrai mantenerlo il più generale possibile.

Altre caratteristiche da ottenere dalle parole circostanti includono quanto segue:

Se il primo carattere è una capitale

Se l'ultimo carattere della parola è un punto

La parte del discorso della parola (cerca la parte dell'etichetta vocale)

Il testo stesso della parola

Non lo consiglio, ma per fornire altri esempi di funzionalità specifiche per Apple:

WordIs (Apple)

NextWordIs (Inc.)

Hai capito il punto. Pensa a Named Entity Recognition come a descrivere una sequenza e quindi a usare un po 'di matematica per dire a un computer come calcolarla.

Tieni presente che l'elaborazione del linguaggio naturale è un sistema basato su pipeline. In genere, si suddividono le cose in frasi, si passa alla tokenizzazione, quindi si esegue parte dell'etichettatura vocale o persino dell'analisi delle dipendenze.

Questo è tutto per ottenere un elenco di funzionalità che puoi utilizzare nel tuo modello per identificare ciò che stai cercando.


3

C'è una libreria davvero buona per l'elaborazione del testo in linguaggio naturale in Python chiamato nltk. Dovresti dargli un'occhiata.

Una strategia che potresti provare è guardare gli n-grammi (gruppi di parole) contenenti la parola "mela". È più probabile che alcune parole vengano utilizzate accanto a "mela" quando si parla del frutto, altre quando si parla dell'azienda e si possono usare quelle per classificare i tweet.


1
Grazie Manetheran. Non sono il poster originale, ma mi interessa anche la risposta. Per la ricompensa sto cercando del codice (anche usando nltk) che possa aiutarmi a iniziare nella giusta direzione con un'attività di machine learning "hello world". La mela (inc) contro la mela (frutta) sembra un incarico perfetto.
Ryan

3

Usa LibShortText . Questa utility Python è già stata ottimizzata per funzionare per brevi attività di categorizzazione del testo e funziona bene. Il massimo che dovrai fare è scrivere un ciclo per scegliere la migliore combinazione di flag. L'ho usato per eseguire la classificazione degli atti linguistici supervisionati nelle e-mail ei risultati erano accurati fino al 95-97% (durante la convalida incrociata 5 volte!).

E proviene dai creatori di LIBSVM e LIBLINEAR la cui implementazione di support vector machine (SVM) viene utilizzata in sklearn e cran, quindi puoi essere ragionevolmente certo che la loro implementazione non è difettosa.


2

Crea un filtro AI per distinguere Apple Inc (l'azienda) dalla mela (il frutto). Poiché si tratta di tweet, definisci il tuo set di allenamento con un vettore di 140 campi, ogni campo è il carattere scritto nel tweet alla posizione X (da 0 a 139). Se il tweet è più breve, dai un valore per essere vuoto.

Quindi costruisci un set di allenamento abbastanza grande da ottenere una buona precisione (soggettiva ai tuoi gusti). Assegna un valore di risultato a ogni tweet, un tweet di Apple Inc ottiene 1 (vero) e un tweet di mela (frutta) ottiene 0. Sarebbe un caso di apprendimento supervisionato in una regressione logistica .

Questo è l'apprendimento automatico, generalmente è più facile da programmare e funziona meglio. Deve imparare dal set che gli dai e non è codificato.

Non conosco Python , quindi non posso scrivere il codice per esso, ma se dovessi dedicare più tempo alla logica e alla teoria dell'apprendimento automatico potresti voler guardare la classe che sto seguendo.

Prova il corso Coursera Machine Learning di Andrew Ng . Imparerai l'apprendimento automatico su MATLAB o Octave , ma una volta acquisite le basi sarai in grado di scrivere l'apprendimento automatico in qualsiasi lingua se comprendi la matematica semplice (semplice nella regressione logistica).

Cioè, ottenere il codice da qualcuno non ti renderà in grado di capire cosa sta succedendo nel codice di apprendimento automatico. Potresti voler investire un paio d'ore sull'argomento per vedere cosa sta realmente accadendo.


Grazie Fawar. Speravo in un codice su questo "ciao mondo" per questo preciso scopo - per imparare come funziona il ML. Cercherò comunque la classe. Sembra buono.
Ryan

0

Consiglierei di evitare risposte che suggeriscano il riconoscimento dell'entità. Perché questa attività è prima una classificazione del testo e poi un riconoscimento dell'entità (puoi farlo senza il riconoscimento dell'entità).

Penso che il percorso più veloce per i risultati sarà spacy + prodigy . Spacy ha ben studiato il modello per la lingua inglese, quindi non devi crearne uno tuo. Mentre prodigy consente di creare rapidamente set di dati di formazione e ottimizzare il modello di spazio per le tue esigenze.

Se hai abbastanza campioni, puoi avere un modello decente in 1 giorno.


Allo stesso tempo, spaCyha un nercomponente pipeline, non sarebbe vantaggioso per questa classificazione? Presumo che il loro modello possa riconoscere Apple(dato che è una delle aziende più grandi e conosciute al mondo) molto meglio di un modello che puoi inventare in un giorno.
Szymon Maszke

@Szymon: NER può o non può aiutare. A quanto ho capito, vuoi usare entità denominate (il fatto che siano presenti nel testo) come funzionalità per l'attività di classificazione principale. Apparentemente, il NER non avrà una precisione del 100% in quanto vi è un alto livello di ambiguità. Quindi il modello di classificazione principale deciderà in quali circostanze si fiderà di questa caratteristica. Potrebbe risultare (penso che sia molto probabile) che un modello di classificazione di base darà un peso molto basso ai risultati del modello NER. E questo significa che trascorrerai del tempo su NER, che (quasi) non viene utilizzato.
Dim

Non quello che intendevo. Crea e bastaspacy.Doc da ogni testo, iterare sui loro NER con doc.entse verificare se qualsiasi NER ha un .textattributo uguale a Apple. Fatto divertente, il loro primo esempio è costituito da Apple.
Szymon Maszke

E se qualcuno volesse creare un modello, molto probabilmente coinvolgerebbe RNN / CNN e simili, li sintonizzerebbe di conseguenza, troverebbe l'architettura, i tipi di cellule ecc., Non penso che i modelli più facili gestiscano bene la disambiguazione e il contesto. Perché semplificarti la vita (a meno che tu non voglia imparare qualcosa lungo la strada), se qualcuno l'ha già fatto per te?
Szymon Maszke

@SzymonMaszke il tuo modello è più complicato e più difficile da addestrare. Affinché il tuo modello funzioni per lo scopo menzionato, non devi solo trovare un NE, ma anche trovarlo in un posto corretto (token). Con il modello di categorizzazione che ti suggerisco di ottimizzare il modello per il tuo obiettivo principale: identifica che è un'azienda Apple o frutta Apple. È più facile da addestrare e quindi molto probabilmente sarà più preciso.
Dim
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.