Spark NLP è una libreria di elaborazione del linguaggio naturale open source, costruita su Apache Spark e Spark ML. Fornisce un’API semplice da integrare con ML Pipelines ed è commercialmente supportato da John Snow Labs. Gli annotatori di Spark NLP utilizzano algoritmi basati su regole, machine learning e alcuni di loro Tensorflow corrono sotto il cofano per alimentare specifiche implementazioni di deep learning.
La libreria copre molte attività NLP comuni, tra cui tokenizzazione, derivazione, lemmatizzazione, parte del tagging vocale, analisi del sentiment, controllo ortografico, riconoscimento di entità nominate e altro ancora. L’elenco completo di annotatori, pipeline e concetti è descritto nel riferimento online . Tutti sono inclusi come open-source e possono essere utilizzati dai modelli di training con i tuoi dati. Fornisce inoltre pipeline e modelli pre-addestrati, sebbene servano da modo per avere un’idea del funzionamento della libreria e non per l’uso in produzione.
La libreria NLP Spark è scritta in Scala e include API Scala e Python per l’uso da Spark. Non ha alcuna dipendenza da qualsiasi altra libreria NLP o ML. Per ogni tipo di annotatore, facciamo una revisione della letteratura accademica per trovare lo stato dell’arte (SOTA), fare una discussione di gruppo e decidere quale algoritmo / i implementare. Le implementazioni sono valutate in base a tre criteri:
- Precisione: non ha senso in un ottimo framework se ha algoritmi o modelli sub-par.
- Prestazioni: il runtime dovrebbe essere alla pari o migliore di qualsiasi benchmark pubblico. Nessuno dovrebbe rinunciare alla precisione perché gli annotatori non funzionano abbastanza velocemente per gestire un caso d’uso di streaming o non si adattano bene in un’impostazione di cluster.
- Allenabilità o configurabilità: la NLP è un problema inerentemente specifico del dominio. Diverse grammatiche e vocabolari sono utilizzati nei post sui social media rispetto ai documenti accademici rispetto alle cartelle cliniche elettroniche rispetto agli articoli di giornale.
Spark NLP è orientato all’uso della produzione in sistemi software che superano le librerie più vecchie come spaCy, NLTK e CoreNLP. A partire da febbraio 2019, la biblioteca è utilizzata dal 16% delle aziende e la biblioteca NLP più utilizzata da tali società.
Costruita nativamente su Apache Spark e TensorFlow , la libreria fornisce notazioni NLP semplici, performanti e accurate per pipeline di machine learning che possono essere ridimensionate facilmente in un ambiente distribuito. Questa libreria sta riutilizzando la pipeline Spark ML insieme all’integrazione della funzionalità NLP.
In un recente sondaggio annuale di O’Reilly, ha identificato diverse tendenze tra le aziende per l’adozione dell’intelligenza artificiale. Secondo i risultati del sondaggio, la libreria Spark NLP è stata elencata come la settima più popolare in tutti i framework e strumenti di intelligenza artificiale. È anche di gran lunga la libreria NLP più utilizzata – due volte più comune di spaCy. È stata anche trovata la libreria AI più popolare dopo scikit-learn, TensorFlow, Keras e PyTorch.
L’ascesa del deep learning per l’elaborazione del linguaggio naturale negli ultimi anni ha comportato che gli algoritmi implementati nelle biblioteche popolari, come spaCy , Stanford CoreNLP , NLTK e OpenNLP , sono meno accurati di quanto reso possibile dagli ultimi articoli scientifici.
Affermare di fornire precisione e velocità all’avanguardia ci spinge costantemente a caccia per produrre i più recenti progressi scientifici.
Spark NLP fornisce annotatori e modelli con licenza già addestrati dagli algoritmi SOTA per Healthcare Analytics
Le ottimizzazioni vengono fatte per avvicinare le prestazioni di Apache Spark al bare metal , sia su una singola macchina che su un cluster, il che significa che le condotte NLP comuni potrebbero eseguire ordini di grandezza più velocemente di quanto consentito dalle limitazioni intrinseche di progettazione delle librerie legacy.
Il benchmark più completo fino ad oggi, Confronto delle librerie NLP di livello produttivo , è stato pubblicato un anno fa su O’Reilly Radar. A sinistra è il confronto dei runtime per l’addestramento di una semplice pipeline (rilevamento del limite di frasi, tokenizzazione e parte del tag vocale) su una singola macchina di memoria Intel i5, 4 core, 16 GB
Essere in grado di sfruttare le GPU per la formazione e l’inferenza è diventato una posta in gioco. L’uso di TensorFlow sotto il cofano per un apprendimento approfondito consente a Spark NLP di sfruttare al meglio le piattaforme di computer moderne, dal DGX-1 di nVidia ai processori Intel Cascade Lake . Le librerie più vecchie, che utilizzino o meno alcune tecniche di deep learning, richiederanno una riscrittura per sfruttare queste nuove innovazioni hardware che possono aggiungere miglioramenti alla velocità e alle dimensioni delle pipeline NLP di un altro ordine di grandezza.
Essere in grado di ridimensionare l’addestramento del modello, l’inferenza e le pipeline di intelligenza artificiale complete da un computer locale a un cluster con poche o nessuna modifica del codice è diventato anche una posta in gioco. La creazione nativa su Apache Spark ML consente a Spark NLP di scalare su qualsiasi cluster Spark, on-premise o in qualsiasi provider cloud. Gli speedup sono ottimizzati grazie alla pianificazione dell’esecuzione distribuita e alla memorizzazione nella cache di Spark, che è stata testata praticamente su qualsiasi piattaforma di archiviazione e calcolo corrente.
Ecco come si confronta la funzionalità delle più popolari librerie NLP:
Spark NLP include anche un pacchetto OCR in grado di leggere sia i file PDF che le immagini scansionate (richiede Tesseract 4.x+). Questa è la prima libreria NLP che include funzionalità OCR out-of-package. ( * da 2.2.2, la funzione OCR viene spostata nella versione con licenza. )
3. Componenti di base e tecnologie sottostanti
Poiché Spark NLP è seduto sulle spalle di Apache Spark, è meglio spiegare i componenti Spark NLP con un riferimento a Spark stesso.
Apache Spark , una volta un componente dell’ecosistema Hadoop , sta ora diventando la piattaforma di big data preferita dalle aziende principalmente grazie alla sua capacità di elaborare i dati di streaming. È un potente motore open source che offre elaborazione di flussi in tempo reale, elaborazione interattiva, elaborazione di grafici, elaborazione in memoria, nonché elaborazione batch con velocità molto elevata, facilità d’uso e interfaccia standard.
Nel settore, esiste una grande richiesta di un motore potente in grado di fare tutto quanto sopra. Prima o poi, la tua azienda o i tuoi clienti useranno Spark per sviluppare modelli sofisticati che ti consentano di scoprire nuove opportunità o evitare i rischi. Spark non è difficile da imparare, se conosci già Python e SQL, è molto facile iniziare. Per familiarizzare con Spark e il suo wrapper Pyspark Python , puoi trovare le risorse aggiuntive in fondo a questo articolo.
Spark ha un modulo chiamato Spark ML che introduce diversi componenti ML. Stimatori , che sono algoritmi addestrabili e trasformatori che sono il risultato dell’addestramento di uno stimatore o di un algoritmo che non richiede alcun addestramento. Sia gli stimatori che i trasformatori possono far parte di una pipeline , che non è altro che una sequenza di passaggi che vengono eseguiti in ordine e che dipendono probabilmente dal risultato reciproco.
Spark-NLP introduce gli annotatori NLP che si fondono in questo framework e che i suoi algoritmi dovrebbero prevedere in parallelo. Ora, iniziamo spiegando ogni componente in dettaglio.
A. Annotatori
In Spark NLP, tutti gli Annotatori sono Estimatori o Transformer, come vediamo in Spark ML. Uno stimatore in Spark ML è un algoritmo che può essere adattato a un DataFrame per produrre un trasformatore. Ad esempio, un algoritmo di apprendimento è uno stimatore che si allena su un DataFrame e produce un modello. Un Transformer è un algoritmo che può trasformare un DataFrame in un altro DataFrame. Ad esempio, un modello ML è un Transformer che trasforma un DataFrame con funzionalità in un DataFrame con previsioni.
In Spark NLP, esistono due tipi di annotatori: AnnotatorApproach e AnnotatorModel
AnnotatorApproach estende gli stimatori da Spark ML, che devono essere addestrati tramite fit () , e AnnotatorModel estende Transformers che hanno lo scopo di trasformare i frame di dati attraverso transform ().
Alcuni degli annotatori Spark NLP hanno un suffisso Model e altri no. Il suffisso del modello viene esplicitamente dichiarato quando l’annotatore è il risultato di un processo di formazione. Alcuni annotatori, come Tokenizer, sono trasformatori ma non contengono il suffisso Modello poiché non sono addestrati, annotatori. Gli annotatori di modelli hanno un pre-training () sul suo oggetto statico, per recuperare la versione pre-training pubblica di un modello.
Per farla breve, se si allena su un DataFrame e produce un modello, si tratta di un AnnotatorApproach; e se trasforma un DataFrame in un altro DataFrame attraverso alcuni modelli, è un AnnotatorModel (ad esempio WordEmbeddingsModel ) e non accetta il suffisso del modello se non si basa su un annotatore pre-addestrato durante la trasformazione di un DataFrame (ad esempio Tokenizer ).
Ecco l’elenco degli annotatori offerti da Spark NLP v2.2.2
* Questi annotatori contrassegnati non prendono il suffisso “Approccio” alla fine mentre tutti gli altri prendono questo suffisso. Tutti i modelli Annotator accettano il suffisso “Modello” alla fine.
Per convenzione, ci sono tre nomi possibili:
Approccio : annotatore allenabile
Modello : annotatore addestrato
niente : un annotatore non addestrabile con fase di pre-elaborazione o scorciatoia per un modello
Quindi, ad esempio, Stemmer non dice Approccio né Modello , tuttavia, è un Modello . D’altra parte, Tokenizer non dice Approccio né Modello , ma ha un TokenizerModel (). Perché non sta “addestrando” nulla, ma sta facendo un po ‘di preelaborazione prima di convertirlo in un Modello.
In caso di dubbi, consultare la documentazione ufficiale e il riferimento API .
Anche se faremo molte pratiche pratiche nei seguenti articoli, diamo uno sguardo per farvi capire la differenza tra AnnotatorApproach e AnnotatorModel .
Come detto sopra, Tokenizer è un AnnotatorModel . Quindi dobbiamo chiamare fit () e quindi transform () .
tokenizer = Tokenizer () \ .setInputCols (["document"]) \ .setOutputCol ("token") tokenizer.fit (df) .transform (df)
D’altra parte, Stemmer è un approccio di annotazione . Quindi dobbiamo solo chiamare transform () .
stemmer = Stemmer () \ .setInputCols (["token"]) \ .setOutputCol ("stem") stemmer.transform (df)
In seguito imparerai tutti questi parametri e sintassi. Quindi, non preoccuparti di provare a riprodurre questi frammenti di codice prima di entrare in quella parte.
Un altro punto importante è che ogni annotatore accetta determinati tipi di colonne e genera nuove colonne in un altro tipo (questo si chiama AnnotatorType ). In Spark NLP, abbiamo i seguenti tipi: Document, token, chunk, pos, word_embeddings, date, entity, sentiment, named_entity, dependency, labeled_dependency. Cioè, il DataFrame che hai deve avere una colonna da uno di questi tipi se quella colonna verrà inserita in un annotatore; in caso contrario, è necessario utilizzare uno dei trasformatori Spark NLP . Parleremo di questo concetto in dettaglio più avanti.
b. Modelli pre-addestrati
Abbiamo detto che gli annotatori addestrati sono chiamati AnnotatorModel e l’obiettivo qui è trasformare un DataFrame in un altro attraverso il modello specificato (annotatore addestrato). Spark NLP offre i seguenti modelli pre-addestrati in quattro lingue ( inglese, francese, tedesco, italiano ) e tutto ciò che devi fare è caricare il modello pre-addestrato sul disco specificando il nome del modello e quindi configurando i parametri del modello come secondo il vostro caso d’uso e set di dati. Quindi non dovrai preoccuparti di addestrare un nuovo modello da zero e potrai goderti gli algoritmi SOTA pre-addestrati applicati direttamente ai tuoi dati con transform () . Nella documentazione ufficiale, puoi trovare informazioni dettagliate su come questi modelli vengono addestrati utilizzando quali algoritmi e set di dati.
Ecco l’elenco dei modelli pre-addestrati offerti da Spark NLP v2.2.2
# carica il modello NER addestrato dall’approccio di apprendimento profondo e incorporamenti di parole GloVe ner_dl = NerDLModel.pretrained (‘ner_dl’) # carica il modello NER addestrato dall’approccio di apprendimento profondo e incorporamenti di parole BERT ner_bert = NerDLModel.pretrained (‘ner_dl_bert’) ner_bert.transform ( df)
c. trasformatori
Ricorda che abbiamo parlato di alcuni tipi di colonne che ogni Annotatore accetta o produce. Quindi, cosa faremo se il nostro DataFrame non ha colonne in quel tipo? Ecco che arrivano i trasformatori. In Spark NLP, abbiamo cinque diversi trasformatori che vengono utilizzati principalmente per ottenere i dati o trasformarli da un AnnotatorType a un altro. Ecco l’elenco dei trasformatori :
DocumentAssembler : per superare il processo di NLP, è necessario annotare i dati non elaborati. Questo è un trasformatore speciale che fa questo per noi; crea la prima annotazione di tipo Document che può essere utilizzata dagli annotatori lungo la strada.
TokenAssembler : questo trasformatore ricostruisce un’annotazione di tipo Documento da token, di solito dopo che questi sono stati normalizzati, lemmatizzati, normalizzati, controllati da un incantesimo, ecc., Per utilizzare questa annotazione del documento in ulteriori annotatori.
Doc2Chunk : converte le annotazioni del tipo DOCUMENT nel tipo CHUNK con il contenuto di un chunkCol.
Chunk2Doc : converte una colonna di tipo CHUNK in DOCUMENT. Utile quando si tenta di ricodificare o fare ulteriori analisi su un risultato CHUNK.
Stazione di finitura : una volta pronta la pipeline della NLP, potremmo voler utilizzare i risultati delle nostre annotazioni altrove, dove è facile da usare. La stazione di finitura genera i valori delle annotazioni in una stringa.
# Ottenere il dataframe con colonna di testo, e trasformare in un altro dataframe con una nuova colonna tipo di documento allegato
documentAssembler = DocumentAssembler () \ .setInputCol ( “testo”) \ .setOutputCol ( “documento”) documentAssembler.transform (df)
d. conduttura
Abbiamo accennato in precedenza che Spark NLP fornisce un’API semplice da integrare con Spark ML Pipelines e tutti gli annotatori e trasformatori Spark NLP possono essere utilizzati all’interno di Spark ML Pipelines. Quindi, è meglio spiegare il concetto di Pipeline attraverso la documentazione ufficiale di Spark ML.
Che cos’è comunque una pipeline ? Nell’apprendimento automatico, è comune eseguire una sequenza di algoritmi per elaborare e apprendere dai dati. Ad esempio, un semplice flusso di lavoro per l’elaborazione di documenti di testo potrebbe includere diverse fasi:
- Dividi il testo di ogni documento in frasi e token (parole).
- Normalizza i token applicando alcune tecniche di preelaborazione del testo (pulizia, lemmatizzazione, derivazione ecc.)
- Converti ogni token in un vettore di funzione numerica (ad es. Parole incorporate, tfidf, ecc.).
- Scopri un modello di previsione utilizzando i vettori e le etichette delle caratteristiche.
Ecco come un tale flusso può essere scritto come una pipeline con sklearn, una popolare libreria Python ML.
da sklearn.pipeline import Pipeline da sklearn.feature_extraction.text import CountVectorizer, TfidfTransformer da sklearn.linear_model import LogisticRegression def text_processing (): # le tue fasi di preelaborazione del testo .. return elabor_text mypipeline = Pipeline ([ ("preelaborazione", text_)) , (“Vect”, CountVectorizer ()), (“tfidf”, TfidfTransformer ()), (“model”, LogisticRegression ()), ]) mypipeline.fit (X_train, y_train)
Apache Spark ML rappresenta un flusso di lavoro come una pipeline, che consiste in una sequenza di pipeline stage (trasformatori e stimatori) da eseguire in un ordine specifico.
In parole povere, una pipeline mette insieme più Transformer ed Estimatori per specificare un flusso di lavoro ML. Usiamo Pipeline per concatenare più trasformatori e stimatori insieme per specificare il nostro flusso di lavoro di apprendimento automatico.
La figura seguente è per l’utilizzo del tempo di addestramento di una pipeline.
Una pipeline è specificata come una sequenza di stadi e ogni fase è un trasformatore o uno stimatore. Queste fasi vengono eseguite in ordine e l’input DataFrame viene trasformato mentre passa attraverso ciascuna fase. Cioè, i dati vengono passati attraverso la pipeline montata in ordine. Il metodo transform () di ogni fase aggiorna il set di dati e lo passa alla fase successiva. Con l’aiuto di Pipeline, possiamo garantire che i dati di addestramento e test passino attraverso identiche fasi di elaborazione delle funzionalità.
Ora vediamo come eseguire questa operazione in Spark NLP usando Annotatori e Transformer . Supponiamo di avere i seguenti passaggi che devono essere applicati uno per uno su un frame di dati.
- Dividi il testo in frasi
- tokenize
- Normalizzare
- Ottieni incorporamenti di parole
Ed ecco come codifichiamo questa pipeline in Spark NLP.
da pyspark.ml import Pipeline
document_assembler = DocumentAssembler () \ .setInputCol (“text”) \ .setOutputCol (“document”) pronoDetector = FraseDetector ( ) \ .setInputCols ([“documento”]) \ .setOutputCol (“frasi”) tokenizer = Tokenizer () \ .setInputCols (["frasi"]) \ .setOutputCol ("token") normalizzatore = Normalizer () \ .setInputCols (["token"]) \ .setOutputCol ("normal") word_embeddings = WordEmbeddingsModel. pretrained () \ .setInputCols (["document", "normal"]) \ .setOutputCol ("embeddings") nlpPipeline = Pipeline (stages = [ document_assembler, pronoDetector , tokenizer, normalizer, word_embeddings, ]) pipelineModel = nlpPipeline.fit (df)
Vediamo cosa sta succedendo qui. Come si puo vedere dal diagramma di flusso qui sotto, ogni colonna (output) generata viene puntata al successivo annotatore come input in base alle specifiche della colonna di input. È come blocchi di costruzione e lego attraverso i quali puoi creare fantastiche condotte con un po ‘di creatività.
Cosa sta realmente succedendo sotto il cofano?
Quando si inserisce () sulla pipeline con il frame di dati Spark (df), è testo la colonna viene inizialmente inserita nel trasformatore DocumentAssembler (), quindi in una nuova colonna “documento“È stato creato in Documento genere (AnnotatorType). Come accennato in precedenza, questo trasformatore è sostanzialmente il punto di ingresso iniziale di Spark NLP per qualsiasi frame di dati Spark. Quindi viene inserita la relativa colonna del documentoSentenceDetector () (AnnotatorApproach) e il testo viene suddiviso in una matrice di frasi e una nuova colonna “frasi “nel documento genere è creato. Quindi viene inserita la colonna “frasi”Tokenizer () (AnnotatorModel) e ogni frase è tokenizzata e una nuova colonna “token “in token genere è creato. E così via.Imparerai tutte queste regole e passaggi in dettaglio nei seguenti articoli, quindi non stiamo elaborando molto qui.
Oltre alle condutture personalizzate, Spark NLP dispone anche di condutture pre-addestrate che sono già installate utilizzando determinati annotatori e trasformatori in base a vari casi d’uso.
Ecco l’elenco delle condutture pre-addestrate.
Spiegheremo tutte queste condutture nei seguenti articoli, ma diamo un esempio usando una di queste condutture.
Ecco gli annotatori della NLP che abbiamo nella pipeline “spiega_documento_dl” :
- DocumentAssembler
- SentenceDetector
- tokenizer
- LemmatizerModel
- Stemmer
- PerceptronModel
- ContextSpellCheckerModel
- WordEmbeddings (GloVe 6B 100)
- NerDLModel
- NerConverter (chunking)
Tutti questi annotatori sono già addestrati e sintonizzati con algoritmi SOTA e pronti ad accendersi al tuo servizio. Quindi, quando si chiama questa pipeline, questi annotatori verranno eseguiti sotto il cofano e otterrai un sacco di nuove colonne generate attraverso questi annotatori. Per utilizzare pipeline pre-addestrate, è sufficiente specificare il nome della pipeline e quindi transform () . È inoltre possibile progettare e addestrare questo tipo di condutture e quindi salvare sul disco per utilizzarlo in seguito.
print (df.columns) >> ['text'] da sparknlp.pretrained import PretrainedPipeline pipeline = PretrainedPipeline ("spiega_documento_dl", lang = "en") Transform_df = pipeline.transform (df) stampa (Transform_df.columns) >> [ 'testo', 'documento', 'frase', 'token', 'controllato', 'lemma', 'stem', 'pos', 'embeddings', 'ner', 'entity']
Mentre diciamo algoritmi SOTA, intendiamo sul serio. Ad esempio, NERDLModel è formato dall’annotatore NerDLApproach con Char CNNs – BiLSTM – CRF e GloVe Embeddings sul corpus WikiNER e supporta l’identificazione di entità PER, LOC, ORG e MISC. Secondo un recente sondaggio , questa architettura DL ha ottenuto i punteggi più alti per NER. Quindi, con una sola riga di codice, ottieni un risultato SOTA!
s and enabled data.