In che misura R scala le attività di classificazione del testo? [chiuso]


30

Sto cercando di accelerare con R. Alla fine voglio usare le librerie R per fare la classificazione del testo. Mi stavo solo chiedendo quali sono le esperienze delle persone riguardo alla scalabilità di R quando si tratta di fare una classificazione del testo.

Probabilmente incapperò in dati ad alta dimensione (dimensioni ~ 300k). Sto cercando di utilizzare SVM e Random Forest in particolare come algoritmi di classificazione.

Le librerie R si ridimensionerebbero alla mia dimensione del problema?

Grazie.

EDIT 1: Solo per chiarire, è probabile che il mio set di dati abbia 1000-3000 righe (forse un po 'di più) e 10 classi.

EDIT 2: Dato che sono molto nuovo su R, chiederò ai poster di essere più specifici ove possibile. Ad esempio, se stai suggerendo un flusso di lavoro / pipeline, assicurati di menzionare le librerie R coinvolte in ogni passaggio, se possibile. Alcuni suggerimenti aggiuntivi (ad esempio, codice di esempio ecc.) Sarebbero la ciliegina sulla torta.

EDIT 3: prima di tutto, grazie a tutti per i vostri commenti. E in secondo luogo, chiedo scusa, forse avrei dovuto dare più contesto al problema. Sono nuovo di R ma non tanto per la classificazione del testo. Ho già eseguito la pre-elaborazione (stemming, rimozione di stopword, conversione tf-idf ecc.) Su alcune parti dei miei dati utilizzando il pacchetto tm , solo per avere un'idea delle cose. Sono stato così lento anche su circa 200doc che mi sono preoccupato per la scalabilità. Poi ho iniziato a giocare con FSelector e anche quello è stato molto lento. E questo è il punto in cui ho realizzato il mio PO.

EDIT 4: Mi è appena venuto in mente che ho 10 classi e circa ~ 300 documenti di formazione per classe, e in effetti sto costruendo la matrice termXdoc dall'intero set di formazione risultando in un'altissima dimensionalità. Ma che ne dite di ridurre ogni problema di classificazione 1-su-k a una serie di problemi di classificazione binaria? Ciò ridurrebbe drasticamente il numero di documenti di formazione (e quindi la dimensionalità) in ciascuna delle fasi del k-1 considerevolmente, no? Quindi questo approccio è valido? Come si confronta in termini di precisione con la solita implementazione multi-classe?


1
300k dimensioni con quante righe? Sfortunatamente, gli oggetti R devono essere in memoria (almeno a meno che non si considerino importanti modifiche, che richiedono sostanzialmente di riscrivere questi algoritmi da soli). Ciò significa che con, diciamo, 8 concerti di ram, non credo che tu possa memorizzare più di qualche centinaio di file con 300.000 colonne.
Crayola,

@crayola: il numero di righe può variare da 1000-3000.
Andy,

2
Non è necessario che gli oggetti R siano in memoria. La mappatura della memoria è molto semplice. Le dimensioni di 300k non sono un problema. Presumo anche che i tuoi dati siano scarsi, come nel caso di quasi tutti i problemi di testo.
Iteratore

Ho appena notato il commento sopra: solo 1000-3000 righe? Questo è molto piccolo. Puoi spiegare qual è il tuo corpus? Una serie di email? Descrizioni dei pacchetti in CRAN? Potresti avere più problemi statistici con P >> N che con qualsiasi problema di archiviazione.
Iteratore

1
@Iteratore: abbiamo alcune risorse educative (tesine, saggi, ecc.) Che vogliamo classificare.
Andy,

Risposte:


17

Come richiesto in un commento, ecco alcuni suggerimenti per le fasi di elaborazione. Numerosi strumenti sono disponibili nella Visualizzazione attività CRAN per l'elaborazione del linguaggio naturale . Si consiglia inoltre di guardare questo documento sulla tmconfezione (text mining) per R .

  1. Prima dell'elaborazione, considerare la normalizzazione dei token di parole. openNLP(per cui esiste un pacchetto R) è un percorso.
  2. Per l'elaborazione del testo, una fase di pre-elaborazione comune è quella di normalizzare i dati tramite tf.idf- frequenza inversa * frequenza inversa del documento - vedere la voce di Wikipedia per maggiori dettagli. Esistono altre normalizzazioni più recenti, ma questo è un metodo pane e burro, quindi è importante conoscerlo. Puoi implementarlo facilmente in R: basta archiviare (docID, wordID, freq1, freq2) dove freq1 è il conteggio delle volte in cui la parola indicizzata da wordID è apparsa nel documento dato e freq2 è il numero di documenti in cui appare. Non è necessario memorizzare questo vettore per parole che non compaiono in un determinato documento. Quindi, prendi solo freq1 / freq2 e avrai il tuo valore tf.idf.
  3. Dopo aver calcolato i valori tf.idf, puoi lavorare con la piena dimensionalità dei tuoi dati o filtrare quelle parole che sono essenzialmente non informative. Ad esempio, qualsiasi parola che appare in 1 solo documento non fornirà molte informazioni. Ciò può ridurre sostanzialmente la tua dimensionalità. Dato il numero limitato di documenti in esame, è possibile che sia appropriato ridurre a 1K dimensioni.
  4. Non aggiornerei entrambi i dati (ad esempio per PCA), ma ora puoi archiviare i dati in una matrice di termini (dove le voci sono ora valori tf.idf) con facilità, usando le matrici sparse, come supportato dal Matrixpacchetto.

A questo punto, hai un set di dati ben pre-elaborato. Consiglierei di procedere con gli strumenti citati nella vista attività CRAN o nel pacchetto di mining di testo. Il clustering dei dati, ad esempio proiettando sui primi 4 o 6 componenti principali, potrebbe essere molto interessante per il tuo gruppo quando i dati vengono tracciati.

Un'altra cosa: potresti scoprire che la riduzione della dimensionalità secondo le linee del PCA (*) può essere utile quando usi vari metodi di classificazione, dato che stai essenzialmente aggregando le parole correlate. I primi 10-50 componenti principali potrebbero essere tutto ciò che serve per la classificazione dei documenti, date le dimensioni del campione.

(*) Nota: PCA è solo un primo passo. Può essere molto interessante per qualcuno che ha appena iniziato con il mining di testo e PCA, ma alla fine potresti scoprire che è un po 'fastidioso per i set di dati sparsi. Come primo passo, però, dai un'occhiata, soprattutto tramite le funzioni prcompe princomp.

Aggiornamento: non ho indicato una preferenza in questa risposta - consiglio prcomppiuttosto che princomp.


+1 bella risposta; Sono solo curioso perché dici che un numero limitato di dock implica un numero inferiore di variabili importanti - non sembra un po 'troppo adatto?

Non sono sicuro di capire cosa intendi. Mantenerli è sicuramente troppo adatto, quindi queste variabili verrebbero eliminate in qualsiasi ragionevole regolarizzazione. Inoltre, il vocabolario (P) cresce con il numero di documenti o campioni (N), quindi la prima volta che appare un termine non è indicativo di molto. Continuare ad aggiungere documenti e quindi la ricorrenza di un termine tra i documenti diventerà informativa.
Iteratore

@Iteratore: grazie per la risposta. Quindi prcompe / o princompscalerai a questo tipo di dati che ritieni? Inoltre ho appena modificato la mia domanda e aggiunto alcune informazioni aggiuntive.
Andy,

No, probabilmente questi non si ridimensioneranno quando colpisci le colonne da 300K. :) (Solo per sottolineare: X'X in quel caso avrà 90B voci - un problema di archiviazione.) Invece, prima filtrare per tf.idf. Se ci sono solo, diciamo, 10 classi distinte, un piccolo multiplo di 10 dovrebbe essere adeguato per una dimensionalità più ampia per separare le classi. Quindi, 1000 dimensioni dovrebbero essere più che sufficienti. Entrambi i metodi PCA (a proposito, mi raccomando prcomp) andranno bene.
Iteratore

Una volta che ti limiti a 1000 dimensioni o forse qualche altro (ad esempio 2K) e fai PCA, puoi prendere le proiezioni su diciamo 100 dimensioni (che possono essere eccessive, ma c'è poco danno in questo) e quindi fare una classificazione. A questo punto, non c'è niente di troppo eccitante.
Iteratore

5

Innanzitutto, benvenuto! L'elaborazione del testo è molto divertente e farlo in R è sempre più facile.

La risposta breve: sì - gli strumenti in R ora sono abbastanza buoni per gestire questo tipo di dati. In effetti, non c'è niente di speciale in R, C ++, Groovy, Scala o in qualsiasi altra lingua quando si tratta di archiviazione dei dati nella RAM: ogni lingua memorizza un doppio float da 8 byte in ... aspetta ... aspetta. .. 8 byte!

Gli algoritmi e la loro implementazione sono importanti, soprattutto se implementati in modo molto scadente per quanto riguarda le strutture dei dati e la complessità computazionale. Se stai implementando i tuoi algoritmi, fai attenzione. Se si utilizza un altro codice, si applica l'emettitore di avvertimento, come in qualsiasi ambiente.

Per R, dovrai considerare:

  1. La tua rappresentazione dei dati (guarda le matrici sparse, specialmente nel Matrixpacchetto)
  2. Archiviazione dei dati (forse memoria mappata, usando bigmemoryo ff; o distribuita, usando Hadoop)
  3. Il partizionamento dei dati (quanto puoi inserire nella RAM dipende da quanta RAM hai)

L'ultimo punto è davvero sotto il tuo controllo.

Quando si tratta di questa dimensionalità, non è più particolarmente grande. Il numero di osservazioni avrà un impatto maggiore, ma è possibile partizionare i dati per adattarli all'utilizzo della RAM, quindi non c'è davvero molto di cui preoccuparsi troppo.


3

Concordo con Crayola sul fatto che il numero di righe è cruciale qui. Per RF avrai bisogno di almeno 3 volte più RAM dei pesi del tuo set di dati e probabilmente molto tempo (tale numero di attributi richiede solitamente molti alberi nella foresta - e nota che non c'è implementazione parallela di RF in R).

A proposito di SVM, dubito che sia una buona idea combattere con dimensioni di 300k mentre probabilmente puoi sviluppare una funzione del kernel che sarà equivalente ai tuoi descrittori di testo.

EDIT: la matrice 3k x 30k (reale) occuperebbe qualcosa come 7Gb, quindi tutto ciò che devi fare RF (usando randomForest) su questi dati è un computer con 16 GB di RAM, un po 'di fortuna e un po' di tempo o solo un computer con 24 GB RAM e un bel po 'di tempo.


Beh, sicuramente avrei fatto la selezione delle caratteristiche (chi al quadrato, basato sull'entropia) ma ancora una volta non sono riuscito a trovare alcuna libreria R adattabile a questo compito. Tenendo conto di tutto ciò, è corretto quindi dire che forse dovrei iniziare a cercare soluzioni non-R?
Andy,

1
"nota che non esiste un'implementazione parallela di RF in R". Questo è solo parzialmente corretto, poiché il foreachpacchetto gioca bene con il randomForestpacchetto. Penso che ci sia uno di questi esempi nella vignetta per foreach. (O forse doMC.)
Crayola,

@Andy Il fatto è che, a parte riscrivere gli algoritmi in un linguaggio di programmazione di basso livello, non sono sicuro di quale software sarà in grado di applicare questi algoritmi ai tuoi dati. Se fossi nella tua situazione, immagino che mi atterrei a R e riscriverei parti di randomForesttale che interrogherebbe le colonne scelte casualmente da, ad esempio, un database SQL ad ogni iterazione (in modo che le dimensioni di 300k non avrebbero mai avuto essere in ariete). Ma questo è probabilmente principalmente perché so di più su R piuttosto che sulle altre possibili opzioni.
Crayola,

Cosa intendi esattamente affermando che non sei riuscito a trovare una biblioteca adatta per questo? I filtri come questo sono algebra di base che dovrebbero funzionare senza problemi (a condizione che tu abbia abbastanza RAM).

@crayola Vero, ma la parte di fusione è terribile. Inoltre non si tratta di parallelismo a mem condivisa, quindi sarebbe probabilmente doloroso (se non impossibile) in questo contesto.
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.