Come codificare l'elaborazione del linguaggio naturale su Android con IBM Watson

Grazie alla crescente ondata di intelligenza artificiale, gli utenti in questi giorni si aspettano app intelligenti e consapevoli dei contesti in cui vengono utilizzati. IBM Watson offre una varietà di servizi relativi alla lingua naturale che è possibile utilizzare per creare tali app.

Ad esempio, puoi utilizzare il suo servizio di comprensione delle lingue naturali per estrarre parole chiave, entità, sentimenti e molti altri dettagli semantici da qualsiasi testo che l'utente sta leggendo. E se il testo sembra essere in una lingua straniera, puoi usare il servizio di traduttore di lingue per identificare la lingua e tradurla in una che l'utente comprende.

In questo tutorial, ho intenzione di presentarti alcuni di questi servizi mostrandoti come creare un'applicazione in grado di tradurre pagine Web tedesche in inglese ed estrarre sentimenti, entità importanti ed emozioni da loro.

Prima di procedere, ti suggerisco di leggere il seguente tutorial introduttivo sui servizi IBM Watson:

1. Attivazione dei servizi

Lavoreremo oggi con tre servizi Watson e ognuno di questi deve essere attivato separatamente. Quindi aprire il cruscotto IBM Bluemix e premere il tasto Creare pulsante.

Il primo servizio che stiamo per attivare è il Conversione di documenti servizio, che ci consente di convertire documenti HTML, PDF e DOCX in testo normale o JSON. Selezionalo dal catalogo, assegnagli un nome significativo e premi il tasto Creare pulsante.

Quindi, torna al catalogo e scegli il Traduttore servizio. Supporta diverse lingue ampiamente parlate e può, di default, gestire il testo in tre domini: notizie, conversazioni e brevetti. Mentre i primi due domini sono adeguati per la maggior parte dei testi, l'ultimo dominio può essere più preciso per i testi contenenti molti termini tecnici o legali.

Nella sua pagina di configurazione, dare al servizio un nome significativo e premere il tasto Creare pulsante.

Torna al catalogo e scegli il Comprensione del linguaggio naturale servizio. Useremo questo servizio per estrarre sentimenti, entità ed emozioni dal testo non strutturato. Ancora una volta, dargli un nome significativo nella schermata di configurazione e premere il tasto Creare pulsante.

Se apri la dashboard ora, dovresti essere in grado di vedere qualcosa di simile a questo:

Tutti e tre i servizi hanno credenziali di accesso univoche ad essi associate. Devi annotarli tutti perché ne avrai bisogno in seguito. Per determinare le credenziali di qualsiasi servizio, selezionalo nella dashboard, aprilo Credenziali di servizio scheda e premere il tasto Visualizza credenziali pulsante.

2. Impostazione del progetto

Per poter utilizzare questi tre servizi in un progetto Android Studio, dobbiamo aggiungere Watson Java SDK come implementazione dipendenza nel App modulo di build.gradle file.

implementazione 'com.ibm.watson.developer_cloud: java-sdk: 3.9.1'

Inoltre, utilizzeremo la libreria Fuel come client HTTP, quindi aggiungila anche come implementazione dipendenza.

implementazione 'com.github.kittinunf.fuel: fuel-android: 1.10.0'

Sia Fuel che Watson Java SDK possono funzionare solo se la nostra app ha il INTERNET permesso, quindi chiedilo nel file manifest.

Quindi, aggiungere  tag contenenti i nomi utente e le password di tutti e tre i servizi al strings.xml file.

USERNAME1 password1 USERNAME2 password2 USERNAME3 Password3

Infine, per mantenere conciso il nostro codice, in questo tutorial useremo Kotlin anziché Java, quindi assicurati di aver abilitato il supporto di Kotlin.

3. Utilizzo del servizio di conversione documenti

Utilizzeremo il servizio di conversione documenti di Watson per convertire pagine Web HTML in testo normale. Per consentire all'utente di digitare un indirizzo di una pagina web, aggiungere un Modifica il testo widget per il layout della tua attività. Inoltre, includi a TextView widget per visualizzare i contenuti della pagina Web come testo normale. Per assicurarti che i contenuti di lunghe pagine web non vengano troncati, ti suggerisco di posizionarli all'interno di ScrollView widget di.

   

Nel codice sopra, puoi vedere che il imeOptions attributo del Modifica il testo il widget è impostato su actionGo. Permette agli utenti di premere un pulsante "Vai" sulle loro tastiere virtuali quando hanno finito di digitare l'indirizzo. Per ascoltare quell'evento premere il tasto, aggiungi il seguente codice Kotlin alle tue attività onCreate () metodo:

documentURL.setOnEditorActionListener _, action, _ -> if (action == EditorInfo.IME_ACTION_GO) // Altro codice qui false

All'interno del listener di eventi, la prima cosa che dobbiamo fare è determinare l'URL che l'utente ha digitato. Possiamo farlo facilmente accedendo al testo proprietà del Modifica il testo widget di. Una volta ottenuto l'URL, possiamo utilizzare Carburante HttpGet () metodo per scaricare il contenuto della pagina web.

Perché noi vogliamo il HttpGet () metodo per eseguire in modo asincrono, dobbiamo aggiungere un callback ad esso utilizzando il responseString () metodo, che ci consente anche di elaborare i contenuti scaricati come una stringa.

val url: String = documentURL.text.toString () url.httpGet (). responseString _, _, result -> val (document, _) = result if (err == null) // Altro codice qui

È giunto il momento di creare un'istanza di DocumentConversion classe, che ha tutti i metodi necessari per interagire con il servizio di conversione di documenti. Il suo costruttore si aspetta una data di versione insieme alle credenziali di accesso del servizio.

val documentConverter = DocumentConversion (DocumentConversion.VERSION_DATE_2015_12_01, resources.getString (R.string.document_conversion_username), resources.getString (R.string.document_conversion_password))

L'SDK Java Watson non ci consente di passare direttamente le stringhe al servizio di conversione documenti. Ha bisogno File oggetti invece. Pertanto, cerchiamo ora di creare un file temporaneo utilizzando il createTempFile () metodo del File classe, e scrivere il contenuto della pagina web che abbiamo scaricato ad esso utilizzando il writeText () metodo.

val tempFile = File.createTempFile ("temp_file", null) tempFile.writeText (document, Charsets.UTF_8)

A questo punto, possiamo chiamare il convertDocumentToText () metodo e passare il file temporaneo ad esso per avviare la conversione. Il metodo prevede anche il tipo MIME del file temporaneo, quindi non dimenticare di includerlo. Una volta completata la conversione, è possibile visualizzare il testo semplice assegnandolo semplicemente al testo proprietà del TextView widget di.

Il seguente codice mostra come eseguire la conversione all'interno di una nuova discussione e aggiornare la TextView nel thread dell'interfaccia utente:

AsyncTask.execute val plainText = documentConverter .convertDocumentToText (tempFile, "text / html") .execute () runOnUiThread documentContents.text = plainText

È possibile eseguire l'app ora e digitare l'URL di una pagina Web tedesca per vedere il funzionamento del servizio di conversione documenti.

4. Utilizzo del servizio di traduttore lingue

Con il servizio di traduttore di lingue, ora convertiremo il testo in chiaro, che è in tedesco, in inglese.

Invece di aggiornare il nostro layout, per consentire all'utente di avviare manualmente la traduzione, aggiungiamo un menu alla nostra attività. Per fare ciò, inizia creando un nuovo file di risorse di menu e aggiungendo il seguente codice:

    

Come puoi vedere, il codice precedente crea un menu con due opzioni: traduci e analizza. In questo passaggio, lavoreremo solo con la prima opzione.

Per rendere il menu, dobbiamo gonfiarlo all'interno del onCreateOptionsMenu () metodo della nostra attività.

override fun onCreateOptionsMenu (menu: Menu?): Boolean menuInflater.inflate (R.menu.my_menu, menu) restituisce super.onCreateOptionsMenu (menu)

Sovrascrivendo il onOptionsItemSelected () metodo, possiamo sapere quando l'utente usa il menu. Inoltre, possiamo determinare quale elemento l'utente ha premuto controllando il numero identificativo dell'oggetto. Il seguente codice controlla se l'utente ha scelto l'opzione di traduzione.

override fun onOptionsItemSelected (item: MenuItem?): Boolean if (item? .itemId == R.id.action_translate) // Altro codice qui return true

Proprio come il Document Service, anche il servizio Language Translator ha una classe dedicata che ci consente di interagire con esso. Come avrai intuito, si chiama Traduttore. Per creare un'istanza della classe, è necessario passare solo le credenziali di accesso del servizio al suo costruttore.

val translator = LanguageTranslator (resources.getString (R.string.language_translator_username), resources.getString (R.string.language_translator_password))

La classe ha un tradurre() metodo che ora possiamo usare per tradurre il nostro testo tedesco in inglese. Come argomenti, si aspetta che il testo venga tradotto come una stringa, la lingua corrente del testo e la lingua desiderata.

Dopo il completamento della traduzione, avremo accesso a a TranslationResult oggetto, di chi firstTranslation la proprietà contiene il testo tradotto.

Il seguente codice mostra come eseguire la traduzione e rendere il risultato nel file TextView widget di.

AsyncTask.execute val translatedDocument = traduttore .translate (documentContents.text .toString (), Language.GERMAN, Language.ENGLISH) .execute () runOnUiThread documentContents.text = translatedDocument .firstTranslation

Ora puoi eseguire nuovamente l'app, digitare l'URL di una pagina web tedesca e utilizzare il menu per tradurne il contenuto in inglese.

5. Utilizzo del servizio di comprensione del linguaggio naturale

Infine, per eseguire un'analisi semantica sul testo tradotto ed estrarne vari dettagli importanti, possiamo usare il NaturalLanguageUnderstanding classe, che funge da cliente per il servizio di comprensione delle lingue naturali.

Il codice seguente mostra come inizializzare il client solo quando l'utente preme la seconda opzione del menu che abbiamo creato nel passaggio precedente:

if (item? .itemId == R.id.action_analyze) val analyzer = NaturalLanguageUnderstanding (NaturalLanguageUnderstanding.VERSION_DATE_2017_02_27, resources.getString (R.string.natural_language_understanding_username), resources.getString (R.string.natural_language_understanding_password)) // Altro codice Qui 

Rispetto agli altri servizi relativi alla lingua naturale, l'uso del servizio di comprensione delle lingue naturali è un po 'più complicato, soprattutto perché ha un gran numero di funzioni.

Per ora, diciamo che vogliamo determinare il sentimento generale del testo tradotto ed estrarre tutte le principali entità che menziona. Ogni entità stessa può avere un'emozione e un sentimento associati ad essa, quindi diciamo che vogliamo estrarre anche quelle.

Per dire al servizio che vogliamo estrarre tutte le entità e le emozioni e i sentimenti associati a loro, abbiamo bisogno di un EntitiesOptions oggetto, che può essere creato usando il EntitiesOptions.Builder classe.

val entityOptions = EntitiesOptions.Builder () .emotion (true) .sentiment (true) .build ()

Allo stesso modo, per dire al servizio che vogliamo il sentimento generale del testo, abbiamo bisogno di un SentimentOptions oggetto.

val sentimentOptions = SentimentOptions.Builder () .document (true) .build ()

Il SentimentOptions e EntitiesOptions gli oggetti devono ora essere raggruppati insieme per formare un Caratteristiche oggetto, che può essere usato per comporre un AnalyzeOptions oggetto. Il AnalyzeOptions l'oggetto è il più importante di tutti gli oggetti di cui sopra perché è dove si specifica il testo che si desidera analizzare.

val features = Features.Builder () .entities (entityOptions) .sentiment (sentimentOptions) .build () val analyzerOptions = AnalyzeOptions.Builder () .text (documentContents.text.toString ()) .features (features) .build ()

Una volta il AnalyzeOptions l'oggetto è pronto, possiamo passarlo analizzare() metodo per iniziare l'analisi.

AsyncTask.execute val results = analyzer.analyze (analyzerOptions) .execute () // Altro codice qui

Il risultato dell'analisi è un AnalysisResults oggetto, contenente tutte le informazioni richieste.

Per determinare il sentimento generale del testo, dobbiamo prima estrarre il punteggio complessivo di sentimento usando il sentiment.document.score proprietà. Un punteggio sentiment non è altro che un numero in virgola mobile. Se è zero, il sentimento è neutrale. Se è negativo o positivo, anche il sentimento è negativo o positivo.

val overallSentimentScore = results.sentiment.document.score var overallSentiment = "Positive" if (overallSentimentScore < 0.0) overallSentiment = "Negative" if(overallSentimentScore == 0.0) overallSentiment = "Neutral" var output = "Overall sentiment: $overallSentiment\n\n"

Quindi, scorrendo attraverso il entità lista presente nel AnalysisResults oggetto, possiamo elaborare ogni entità individualmente. Per impostazione predefinita, a ciascuna entità è associato un tipo. Ad esempio, il servizio può stabilire se un'entità è una persona, un'azienda o un veicolo. Attualmente, è in grado di identificare oltre 450 diversi tipi di entità.

Poiché le abbiamo richieste, ogni entità avrà ora anche un punteggio sentimentale e le emozioni associate.

Possiamo determinare il punteggio di sentimento semplicemente usando il sentiment.score proprietà. Determinare l'emozione associata a un'entità, tuttavia, non è così semplice. Watson supporta attualmente cinque emozioni: rabbia, gioia, disgusto, paura e tristezza. Ogni entità avrà tutte e cinque le emozioni, ma diversi valori associati a ciascuna di esse, specificando quanto sia sicuro il servizio che l'emozione è corretta. Pertanto, per determinare l'emozione giusta, dobbiamo scegliere quella con il valore più alto.

Il seguente codice elenca ciascuna entità insieme al suo tipo, punteggio di sentimento ed emozione:

for (entity in results.entities) output + = "$ entity.text ($ entity.type) \ n" val validEmotions = arrayOf ("Anger", "Joy", "Disgust", "Fear" , "Tristezza") val emotionValues ​​= arrayOf (entity.emotion.anger, entity.emotion.joy, entity.emotion.disgust, entity.emotion.fear, entity.emotion.sadness) val currentEmotion = validEmotions [emotionValues.indexOf (emotionValues .max ())] output + = "Emotion: $ currentEmotion," + "Sentiment: $ entity.sentiment.score" + "\ n \ n"

Per visualizzare l'output che abbiamo generato, possiamo aggiornare di nuovo il file TextView widget di.

runOnUiThread documentContents.text = output

A questo punto, puoi eseguire nuovamente l'app per vedere tutti e tre i servizi che lavorano insieme.

Conclusione

Ora sai come utilizzare tre dei servizi più diffusi relativi alla lingua naturale offerti da Watson. In questo tutorial hai anche visto quanto sia facile usare Watson Java SDK per far lavorare tutti i servizi insieme per creare un'app Android intelligente.

Per ulteriori informazioni sui servizi e sull'SDK, è possibile fare riferimento al repository GitHub dell'SDK. E per saperne di più sull'utilizzo dell'apprendimento automatico di Watson nelle tue app, consulta alcuni dei nostri altri post qui su Envato Tuts+!