Maak een intelligente app met Google Cloud Speech en Natural Language API's

Een toepassing die echt een natuurlijke taal begrijpt, hebben sci-fi-enthousiasten, programmeurs en AI-onderzoekers al decennia gedroomd. Dankzij de grote vooruitgang op het gebied van technologie voor het leren van machines is deze droom vandaag de dag dichterbij dan ooit om werkelijkheid te worden. Bovendien hebben cloudgebaseerde services zoals Google Cloud Machine Learning deze technologieën vrij toegankelijk gemaakt voor iedereen.

In deze zelfstudie leert u hoe u twee krachtige op natuurlijke taal gebaseerde API's kunt gebruiken die worden aangeboden door het Google Cloud Machine Learning-platform: Cloud Speech API en Cloud Natural Language API. Door ze samen te gebruiken, kunt u apps maken die spraak kunnen verwerken in een groot aantal veel gesproken talen.

voorwaarden

Om mee te gaan, heb je nodig:

  • Android Studio 2.2 of hoger
  • een Google Cloud Platform-account
  • een apparaat met Android 4.4 of hoger

1. Waarom deze API's gebruiken?

Een toepassing die spraak kan verwerken, moet de volgende mogelijkheden hebben:

  • Het moet individuele woorden uit onbewerkte audiogegevens kunnen extraheren.
  • Het moet in staat zijn gissingen te maken over de grammaticale relaties tussen de woorden die het heeft geëxtraheerd.

Met de API's voor cloud-spraak en cloud-natuurlijke taal kunt u de bovenstaande functies binnen enkele minuten aan uw Android-app toevoegen.

De Cloud Speech-API dient als een geavanceerde spraakherkenner waarmee spraak in meer dan 80 talen nauwkeurig kan worden getranscribeerd. Het kan ook robuuste regionale accenten en lawaaierige omstandigheden verwerken.

Een soortgelijke opmerking is dat de Cloud Natural Language API een taalverwerkingssysteem is dat, met nauwkeurigheid op het niveau van de mens, de rollen kan bepalen die woorden spelen in zinnen die eraan worden gegeven. Het ondersteunt momenteel tien talen en biedt ook analyse van entiteiten en sentimenten.

2. Activering van de API's

Voordat u de API's Spraak en Natuurlijke taal gebruikt, moet u ze inschakelen in de Google Cloud-console. Dus log in op de console en navigeer naar API Manager> Bibliotheek.

Om de Speech API in te schakelen, klikt u op de Spraak-API link in de Google Cloud Machine Learning sectie. Op de volgende pagina opent u de in staat stellen knop.

Druk op de terugtoets van uw browser om terug te gaan naar de vorige pagina.

Schakel deze keer de Natural Language API in door op te klikken Natuurlijke taal-API link en druk op de in staat stellen knop op de volgende pagina.

U heeft een API-sleutel nodig tijdens de interactie met de API's. Als u er nog geen heeft, opent u de Geloofsbrieven tab, druk op de Aanmeldingsgegevens maken knop en kies API sleutel.

U ziet nu een pop-up met uw API-sleutel. Noteer het zodat je het later kunt gebruiken.

3. Uw project configureren

Beide API's zijn gebaseerd op JSON en hebben REST-eindpunten waarmee u rechtstreeks kunt communiceren via een netwerkbibliotheek. U kunt echter veel tijd besparen - en ook meer leesbare code schrijven - door de Google API Client-bibliotheken te gebruiken die voor hen beschikbaar zijn. Open dus de build.gradle bestand van uw project app module en voeg het volgende toe compileren afhankelijkheden ervan:

compileer 'com.google.api-client: google-api-client-android: 1.22.0' compileer 'com.google.apis: google-api-services-speech: v1beta1-rev336-1.22.0' compile 'com. google.apis: google-api-services-language: v1beta2-rev6-1.22.0 'compile' com.google.code.findbugs: jsr305: 2.0.1 '

Bovendien zullen we een paar bestands-I / O-bewerkingen uitvoeren in deze zelfstudie. Voeg a toe om ze te vereenvoudigen compileren afhankelijkheid van de Commons IO-bibliotheek.

compileer 'commons-io: commons-io: 2.5'

Vergeet ten slotte niet te vragen om de INTERNET toestemming in de AndroidManifest.xml het dossier. Zonder dit kan uw app geen verbinding maken met de servers van Google.

4. De Cloud Speech-API gebruiken

Het spreekt voor zich dat de Cloud Speech API audiodata verwacht als een van zijn ingangen. Daarom zullen we nu een Android-app maken die audiobestanden kan transcriberen. 

Om het simpel te houden, zullen we alleen FLAC-bestanden transcriberen, bestanden die het coderingsformaat Free Lossless Audio Codec gebruiken. Mogelijk hebt u dergelijke bestanden al op uw apparaat. Als u dat niet doet, raad ik u aan een paar van Wikimedia Commons te downloaden.

Stap 1: maak een lay-out

De lay-out van onze app heeft een Knop widget gebruikers kunnen op drukken om een ​​bestandskiezer te tonen, een interface waar ze door kunnen bladeren en audiobestanden kunnen selecteren die beschikbaar zijn op hun apparaten.

De lay-out heeft ook een Tekstweergave widget om het transcript van het geselecteerde audiobestand weer te geven. Voeg daarom de volgende code toe aan het lay-out XML-bestand van uw activiteit:

 

Stap 2: maak een bestandskiezer

De interface van de bestandskiezer moet worden weergegeven wanneer de gebruiker op de knop drukt die we in de vorige stap hebben gemaakt, dus associeer een OnClickListener object ermee. Voordat u dit doet, moet u de knop initialiseren met behulp van de findViewById () methode.

Knop browseButton = (Button) findViewById (R.id.browse_button); browseButton.setOnClickListener (nieuwe View.OnClickListener () @Override public void onClick (View view) // Meer code hier);

Met Android's Storage Access Framework, dat beschikbaar is op apparaten met API-niveau 19 of hoger, kost het maken van een bestandskiezer weinig moeite. Het enige wat u hoeft te doen is een intentie creëren voor de ACTION_GET_CONTENT actie en geef deze door aan de startActivityForResult () methode. Optioneel kunt u de bestandskiezer beperken om alleen FLAC-bestanden weer te geven door het juiste MIME-type door te geven aan de settype () methode van de voornemen voorwerp.

Intent filePicker = new Intent (Intent.ACTION_GET_CONTENT); filePicker.setType ( "audio / flac"); startActivityForResult (filePicker, 1);

De uitvoer van de bestandskiezer zal een andere zijn voornemen object met de URI van het bestand dat de gebruiker heeft geselecteerd. Om toegang te krijgen, moet u de onActivityResult () methode van uw Activiteit klasse.

@Override beschermde leegte onActivityResult (int requestCode, int resultCode, Intent-gegevens) super.onActivityResult (requestCode, resultCode, data); if (resultCode == RESULT_OK) final Uri soundUri = data.getData (); // Meer code hier

Stap 3: Codeer het bestand

De Cloud Speech API verwacht dat de audiogegevens de vorm hebben van een Base64-reeks. Om een ​​dergelijke reeks te genereren, kunt u de inhoud van het bestand lezen dat de gebruiker heeft geselecteerd in a byte array en geef deze door aan de encodeBase64String () hulpprogramma-methode aangeboden door de Google API Client-bibliotheek.

U hebt momenteel echter alleen de URI van het geselecteerde bestand en niet het absolute pad. Dat betekent dat u eerst de URI moet kunnen oplossen om het bestand te kunnen lezen. U kunt dit doen door het door te geven aan de openInputStream () methode van de inhoudsoplosser van uw activiteit. Zodra u toegang hebt tot de invoerstroom van het bestand, kunt u het gewoon doorgeven aan de toByteArray () methode van de IOUtils klasse om het in een array van bytes om te zetten. De volgende code laat zien hoe:

AsyncTask.execute (nieuw Runnable () @Override public void run () InputStream stream = getContentResolver () .openInputStream (soundUri); byte [] audioData = IOUtils.toByteArray (stream); stream.close (); String base64EncodedData = Base64.encodeBase64String (audioData); // Meer code hier

Zoals je kunt zien in de bovenstaande code, gebruiken we een nieuwe thread om alle I / O-bewerkingen uit te voeren. Dit is belangrijk om ervoor te zorgen dat de gebruikersinterface van de app niet vastloopt.

Stap 4: speel het bestand

Naar mijn mening is het een goed idee om het geluidsbestand af te spelen dat wordt getranscribeerd terwijl het wordt getranscribeerd. Het kost niet veel moeite en het verbetert de gebruikerservaring.

U kunt de Mediaspeler klasse om het geluidsbestand af te spelen. Zodra u het naar de URI van het bestand verwijst met behulp van zijn setDataSource () methode, je moet het bellen bereiden() methode om de speler synchroon voor te bereiden. Wanneer de speler klaar is, kunt u bellen met de begin() methode om het bestand af te spelen.

Bovendien moet u eraan denken om de bronnen van de speler vrij te geven nadat het afspelen van het bestand voltooid is. Om dit te doen, wijst u een OnCompletionListener er bezwaar tegen hebben en het zijn vrijlating() methode. De volgende code laat zien hoe:

MediaPlayer-speler = nieuwe MediaPlayer (); player.setDataSource (MainActivity.this, soundUri); player.prepare (); player.start (); // Laat de speler player.setOnCompletionListener (nieuwe MediaPlayer.OnCompletionListener () @Override public unfid onCompletion (MediaPlayer mediaPlayer) mediaPlayer.release (););

Stap 5: synchroon transcriberen van het bestand

Op dit punt kunnen we de Base64-gecodeerde audiogegevens naar de Cloud Speech API verzenden om deze te transcriberen. Maar eerst stel ik voor dat u de API-sleutel die u eerder hebt gegenereerd, opslaat als een ledvariabele van uw Activiteit klasse.

private finale String CLOUD_API_KEY = "ABCDEF1234567890";

Om te kunnen communiceren met de Cloud Speech API, moet u een Toespraak object met behulp van een Speech.Builder aanleg. Als argumenten verwacht de constructor een HTTP-transport en een JSON-fabriek. Bovendien moet u een koppeling maken om ervoor te zorgen dat de API-sleutel wordt opgenomen in elk HTTP-verzoek aan de API SpeechRequestInitializer object met de bouwer en geef de sleutel door.

De volgende code maakt een Toespraak object met behulp van de AndroidJsonFactory klasse als de JSON-fabriek en de NetHttpTransport klasse als het HTTP-transport:

Speech speechService = nieuwe Speech.Builder (AndroidHttp.newCompatibleTransport (), nieuwe AndroidJsonFactory (), null) .setSpeechRequestInitializer (nieuwe SpeechRequestInitializer (CLOUD_API_KEY)) .build ();

De Cloud Speech API moet worden verteld in welke taal het audiobestand zich bevindt. U kunt dit doen door een RecognitionConfig object en noem het setLanguageCode () methode. Zo configureer je het om alleen Amerikaans Engels te transcriberen:

RecognitionConfig recognitionConfig = new RecognitionConfig (); recognitionConfig.setLanguageCode ( "en-US");

Bovendien moet de Base64-gecodeerde string worden ingepakt in een RecognitionAudio object voordat het door de API kan worden gebruikt.

RecognitionAudio recognitionAudio = new RecognitionAudio (); recognitionAudio.setContent (base64EncodedData);

Vervolgens gebruikt u de RecognitionConfig en RecognitionAudio objecten, moet je een maken SyncRecognizeRequest voorwerp. Zoals de naam al doet vermoeden, kunt u hiermee een HTTP-verzoek maken om audiodata synchroon te transcriberen. Nadat het object is gemaakt, kunt u het als argument doorgeven aan de syncrecognize () methode en bel de resulterende Speech.SpeechOperations.Syncrecognize voorwerpen execute () methode om het HTTP-verzoek daadwerkelijk uit te voeren.

De retourwaarde van de execute () methode is een SyncRecognizeResponse object, dat verschillende alternatieve transcripten kan bevatten. Voorlopig gebruiken we alleen het eerste alternatief.

// Aanvraag creëren SyncRecognizeRequest-aanvraag = nieuwe SyncRecognizeRequest (); request.setConfig (recognitionConfig); request.setAudio (recognitionAudio); // Reactie genereren SyncRecognizeResponse response = speechService.speech () .syncrecognize (request) .execute (); // Transcript uitpakken SpeechRecognition Resultaatresultaat = response.getResults (). Get (0); final String transcript = result.getAlternatives (). get (0) .getTranscript ();

Als laatste, om het transcript naar de gebruiker weer te geven, kunt u het doorgeven aan de Tekstweergave widget. Natuurlijk, omdat wijzigingen in de gebruikersinterface altijd moeten gebeuren in de UI-thread, moet u dit doen nadat u uw activiteiten heeft gebeld runOnUiThread () methode.

runOnUiThread (nieuw Runnable () @Override public void run () TextView speechToTextResult = (TextView) findViewById (R.id.speech_to_text_result); speechToTextResult.setText (transcript););

U kunt nu uw app uitvoeren, een FLAC-bestand selecteren dat spraak in Amerikaans-Engels bevat en de Cloud Speech-API een transcript voor het zien genereren.

 

Het is de moeite waard te vermelden dat de Cloud Speech API momenteel alleen audiobestanden met één kanaal kan verwerken. Als u een bestand met meerdere kanalen ernaar verzendt, krijgt u een foutantwoord.

5. Gebruik van de Cloud Natural Language API

Nu we een transcript hebben, kunnen we het doorgeven aan de Cloud Natural Language API om het te analyseren. Om deze tutorial kort te houden, zullen we alleen entiteits- en sentimentanalyse uitvoeren op het transcript. Met andere woorden, we gaan alle entiteiten bepalen die in het transcript worden genoemd, zoals mensen, plaatsen en beroepen, en ook vertellen of het algemene sentiment negatief, neutraal of positief is.

Stap 1: werk de lay-out bij

Om de gebruiker toe te staan ​​de analyse te starten, moet onze lay-out een andere bevatten Knop widget. Voeg daarom de volgende code toe aan het XML-bestand met de lay-out van uw activiteit:

Stap 2: Annoteer het transcript

De Cloud Natural Language REST API biedt een geroemde gemaksoptie annotateText waarmee u zowel sentiment- als entiteitsanalyse op een document kunt uitvoeren met slechts één HTTP-verzoek. We zullen het gebruiken om ons transcript te analyseren.

Omdat de analyse moet beginnen wanneer de gebruiker op de knop drukt die we in de vorige stap hebben gemaakt, voegt u een toe OnClickListener ernaar toe.

Button analysisButton = (Button) findViewById (R.id.analyze_button); analyzeButton.setOnClickListener (nieuwe View.OnClickListener () @Override public void onClick (View view) // Meer code hier);

Als u wilt communiceren met de API met behulp van de Google API Client-bibliotheek, moet u een CloudNaturalLanguage object met behulp van de CloudNaturalLanguage.Builder klasse. De constructeur verwacht ook een HTTP-transport en een JSON-fabriek.

Verder door het toewijzen van een CloudNaturalLanguageRequestInitializer In dit geval kunt u het dwingen om uw API-sleutel in al zijn aanvragen op te nemen.

final CloudNaturalLanguage naturalLanguageService = new CloudNaturalLanguage.Builder (AndroidHttp.newCompatibleTransport (), new AndroidJsonFactory (), null) .setCloudNaturalLanguageRequestInitializer (new CloudNaturalLanguageRequestInitializer (CLOUD_API_KEY)) .build ();

Alle tekst die u met de API wilt analyseren, moet in een. Worden geplaatst Document voorwerp. De Document object moet ook configuratie-informatie bevatten, zoals de taal van de tekst en of deze is opgemaakt als platte tekst of HTML. Voeg daarom de volgende code toe:

String transcript = ((TextView) findViewById (R.id.speech_to_text_result)) .getText (). ToString (); Document document = nieuw document (); document.setType ( "PLAIN_TEXT"); document.setLanguage ( "en-US"); document.setContent (transcript);

Vervolgens moet u een maken Kenmerken object met de functies die u wilt analyseren. De volgende code laat zien hoe u een maakt Kenmerken object dat zegt dat u entiteiten wilt extraheren en alleen een sentimentanalyse wilt uitvoeren.

Functies kenmerken = nieuwe functies (); features.setExtractEntities (true); features.setExtractDocumentSentiment (true);

U kunt nu de Document en Kenmerken objecten om een ​​te vormen AnnotateTextRequest object, dat kan worden doorgegeven aan de annotateText () methode om een ​​te genereren AnnotateTextResponse voorwerp.

final AnnotateTextRequest request = new AnnotateTextRequest (); request.setDocument (document); request.setFeatures (kenmerken); AsyncTask.execute (nieuw Runnable () @Override public void run () AnnotateTextResponse response = naturalLanguageService.documents () .annotateText (request) .execute (); // Meer code hier

Merk op dat we het antwoord in een nieuwe thread genereren omdat netwerkbewerkingen niet zijn toegestaan ​​in de UI-thread.

U kunt een lijst met entiteiten extraheren uit de AnnotateTextResponse object door het te bellen getEntities () methode. Evenzo kunt u het algemene sentiment van het transcript extraheren door het getDocumentSentiment () methode. Om de werkelijke score van het sentiment te krijgen, moet u echter ook het getScore () methode, die a retourneert vlotter

Zoals je zou verwachten, betekent een sentimentscore gelijk aan nul: het sentiment is neutraal, een score groter dan nul betekent dat het sentiment positief is en een score kleiner dan nul betekent dat het sentiment negatief is.

Wat u doet met de lijst van entiteiten en de sentimentscore is natuurlijk aan u. Laten we ze nu allebei weergeven met een AlertDialog aanleg.

laatste lijst entityList = response.getEntities (); laatste float-sentiment = response.getDocumentSentiment (). getScore (); runOnUiThread (nieuw Runnable () @Override openbare ongeldige run () String entities = ""; for (Entiteit entiteit: entityList) entities + = "\ n" + entity.getName (). toUpperCase (); Dialoogvenster AlertDialog = new AlertDialog.Builder (MainActivity.this) .setTitle ("Sentiment:" + sentiment) .setMessage ("Dit audiobestand spreekt over:" + entiteiten) .setNeutralButton ("Okay", null) .create (); dialoogvenster. laten zien();  );

Met de bovenstaande code wordt de sentimentscore weergegeven in de titel van het dialoogvenster en wordt de lijst met entiteiten weergegeven in de body.

Als u de app nu uitvoert, moet u de inhoud van audiobestanden kunnen analyseren en deze ook kunnen transcriberen.

 

Conclusie

U weet nu hoe u de API's Cloud Speech en Cloud Natural Language samen kunt gebruiken om een ​​Android-app te maken die niet alleen een audiobestand kan transcriberen, maar ook een entiteits- en sentimentanalyse kan uitvoeren. In deze zelfstudie leer je ook hoe je kunt werken met het Storage Access Framework en Google Client API-bibliotheken van Android.

Google heeft regelmatig nieuwe en interessante functies toegevoegd, samen met ondersteuning voor meer talen, aan beide API's. Raadpleeg de officiële documentatie om op de hoogte te blijven.

En terwijl je hier bent, bekijk een aantal van onze andere berichten over cloudservices voor mobiele apps en machine learning!