Una aplicación que realmente comprende un lenguaje natural es algo que los entusiastas de la ciencia ficción, los programadores y los investigadores de inteligencia artificial han soñado durante décadas. Hoy, gracias a los grandes avances en las tecnologías de aprendizaje automático, ese sueño está más cerca que nunca de convertirse en realidad. Además, los servicios basados en la nube como Google Cloud Machine Learning han hecho que esas tecnologías estén disponibles gratuitamente para que todos las puedan usar..
En este tutorial, aprenderá a utilizar dos API potentes orientadas al lenguaje natural que ofrece la plataforma de aprendizaje en la máquina de Google Cloud: la API de voz en la nube y la API de lenguaje natural de la nube. Al usarlos juntos, puede crear aplicaciones que pueden manejar el habla en una variedad de idiomas hablados ampliamente.
Para seguir adelante, necesitarás:
Una aplicación que puede procesar el habla debe tener las siguientes capacidades:
Las API de Cloud Speech y Cloud Natural Language le permiten agregar las capacidades anteriores a su aplicación de Android en cuestión de minutos.
La API de Cloud Speech sirve como un reconocedor de voz de última generación que puede transcribir con precisión el habla en más de 80 idiomas. También puede manejar de forma robusta los acentos regionales y las condiciones ruidosas.
En una nota similar, la API de lenguaje natural de la nube es un sistema de procesamiento de lenguaje que puede, con una precisión cercana al nivel humano, determinar los roles que desempeñan las palabras en las oraciones que se le asignan. Actualmente es compatible con diez idiomas, y también ofrece análisis de entidades y sentimientos..
Antes de utilizar las API de lenguaje natural y habla, debe habilitarlas en la consola de Google Cloud. Así que inicie sesión en la consola y navegue hasta Administrador de API> Biblioteca.
Para habilitar la API de voz, haga clic en API de voz enlace en el Google Cloud Machine Learning sección. En la página que se abre a continuación, presione Habilitar botón.
Presione el botón de retroceso de su navegador para volver a la página anterior.
Esta vez, habilite la API de lenguaje natural haciendo clic en el API de lenguaje natural enlace y presionando el Habilitar botón en la página siguiente.
Necesitará una clave de API mientras interactúa con las API. Si aún no tiene uno, abra el Cartas credenciales pestaña, presione la Crear credenciales botón y elija Clave API.
Ahora verás una ventana emergente que muestra tu clave API. Apúntalo para que puedas usarlo más tarde..
Ambas API están basadas en JSON y tienen puntos finales REST con los que puede interactuar directamente utilizando cualquier biblioteca de red. Sin embargo, puede ahorrar mucho tiempo y también escribir un código más legible utilizando las bibliotecas de cliente API de Google disponibles para ellos. Así que abre el construir.gradle archivo de su proyecto aplicación
módulo y añadir lo siguiente compilar
dependencias a ella:
compile 'com.google.api-client: google-api-client-android: 1.22.0' compile '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 '
Además, realizaremos algunas operaciones de E / S de archivos en este tutorial. Para simplificarlos, agregue un compilar
Dependencia para la biblioteca de Commons IO..
compilar 'commons-io: commons-io: 2.5'
Por último, no olvides solicitar el INTERNET
permiso en el AndroidManifest.xml expediente. Sin ella, su aplicación no podrá conectarse a los servidores de Google.
No hace falta decir que la API de Cloud Speech espera que los datos de audio sean una de sus entradas. Por lo tanto, ahora estaremos creando una aplicación de Android que puede transcribir archivos de audio..
Para mantenerlo simple, solo estaremos transcribiendo archivos FLAC, archivos que utilizan el formato de codificación de Free Lossless Audio Codec. Es posible que ya tenga dichos archivos en su dispositivo. Si no lo haces, te sugiero que descargues algunos de Wikimedia Commons.
El diseño de nuestra aplicación tendrá un Botón
los usuarios de widgets pueden presionar para mostrar un selector de archivos, una interfaz donde pueden navegar y seleccionar archivos de audio disponibles en sus dispositivos.
El diseño también tendrá un Vista de texto
Widget para mostrar la transcripción del archivo de audio seleccionado. En consecuencia, agregue el siguiente código al archivo XML de diseño de su actividad:
La interfaz del selector de archivos debe mostrarse cuando el usuario presiona el botón que creamos en el paso anterior, así que asocie un OnClickListener
objetar con ella Antes de hacerlo, asegúrese de inicializar el botón con la tecla findViewById ()
método.
Botón browseButton = (Botón) findViewById (R.id.browse_button); browseButton.setOnClickListener (new View.OnClickListener () @Override public void onClick (View view) // Más código aquí);
Con el Storage Access Framework de Android, que está disponible en dispositivos con un nivel de API 19 o superior, crear un selector de archivos requiere muy poco esfuerzo. Todo lo que necesitas hacer es crear una intención para el ACTION_GET_CONTENT
acción y pasarlo a la startActivityForResult ()
método. Opcionalmente, puede restringir el selector de archivos para que muestre solo los archivos FLAC pasando el tipo MIME apropiado a la setType ()
método de la Intención
objeto.
Intención filePicker = new Intent (Intent.ACTION_GET_CONTENT); filePicker.setType ("audio / flac"); startActivityForResult (filePicker, 1);
La salida del selector de archivos será otra. Intención
Objeto que contiene el URI del archivo que el usuario seleccionó. Para poder acceder a él, debes anular la onActivityResult ()
método de tu Actividad
clase.
@ Override protected void onActivityResult (int requestCode, int resultCode, Intent data) super.onActivityResult (requestCode, resultCode, data); if (resultCode == RESULT_OK) final Uri soundUri = data.getData (); // Más código aquí
La API de Cloud Speech espera que sus datos de audio estén en forma de una cadena Base64. Para generar tal cadena, puede leer el contenido del archivo que el usuario seleccionó en una byte
array y pasarlo a la encodeBase64String ()
método de utilidad ofrecido por la biblioteca de cliente API de Google.
Sin embargo, actualmente solo tiene el URI del archivo seleccionado, no su ruta absoluta. Eso significa que, para poder leer el archivo, primero debe resolver el URI. Puedes hacerlo pasándolo a la openInputStream ()
Método de resolución de contenido de su actividad. Una vez que tenga acceso al flujo de entrada del archivo, simplemente puede pasarlo a la toByteArray ()
método de la IOUtils
Clase para convertirlo en una matriz de bytes. El siguiente código le muestra cómo:
AsyncTask.execute (new Runnable () @Override public void run () InputStream stream = getContentResolver () .openInputStream (soundUri); byte [] audioData = IOUtils.toByteArray (stream); stream.close (); Base64.encodeBase64String (audioData); // Más código aquí
Como puede ver en el código anterior, estamos utilizando un nuevo hilo para ejecutar todas las operaciones de E / S. Es importante hacerlo para asegurarse de que la interfaz de usuario de la aplicación no se congele.
En mi opinión, reproducir el archivo de sonido que se transcribe, mientras se transcribe, es una buena idea. No requiere mucho esfuerzo y mejora la experiencia del usuario..
Puedes usar el Reproductor multimedia
Clase para reproducir el archivo de sonido. Una vez que lo apunta a la URI del archivo utilizando su setDataSource ()
método, debes llamar a su preparar()
Método para preparar sincrónicamente el reproductor. Cuando el jugador está listo, puedes llamar a su comienzo()
método para comenzar a reproducir el archivo.
Además, debes recordar liberar los recursos del jugador una vez que haya terminado de reproducir el archivo. Para ello, asigna un OnCompletionListener
objetar y llamar a su lanzamiento()
método. El siguiente código le muestra cómo:
Reproductor de MediaPlayer = nuevo MediaPlayer (); player.setDataSource (MainActivity.this, soundUri); player.prepare (); player.start (); // Libere el reproductor player.setOnCompletionListener (nuevo MediaPlayer.OnCompletionListener () @Override public void onCompletion (MediaPlayer mediaPlayer) mediaPlayer.release (););
En este punto, podemos enviar los datos de audio codificados en Base64 a la API de Cloud Speech para transcribirlos. Pero primero, sugiero que almacene la clave API que generó anteriormente como una variable miembro de su Actividad
clase.
cadena final privada CLOUD_API_KEY = "ABCDEF1234567890";
Para poder comunicarse con la API de Cloud Speech, debe crear un Habla
objeto utilizando un Speech.Builder
ejemplo. Como argumentos, su constructor espera un transporte HTTP y una fábrica JSON. Además, para asegurarse de que la clave API esté incluida en cada solicitud HTTP a la API, debe asociar un SpeechRequestInitializer
Objetar con el constructor y pasarle la llave..
El siguiente código crea un Habla
objeto usando el AndroidJsonFactory
clase como la fábrica de JSON y la NetHttpTransport
clase como el transporte HTTP:
Speech speechService = new Speech.Builder (AndroidHttp.newCompatibleTransport (), nuevo AndroidJsonFactory (), null) .setSpeechRequestInitializer (new SpeechRequestInitializer (CLOUD_API_KEY)) .build ();
La API de Cloud Speech debe saber qué idioma contiene el archivo de audio. Puedes hacerlo creando un Reconocimientoconfig
objeto y llamando a su setLanguageCode ()
método. Así es como lo configuras para transcribir solo inglés americano:
RecognitionConfig RecognitionConfig = new RecognitionConfig (); RecognConfig.setLanguageCode ("en-US");
Además, la cadena codificada en Base64 debe estar envuelta en un Reconocimiento audio
objeto antes de que pueda ser utilizado por la API.
RecognitionAudio RecognitionAudio = new RecognitionAudio (); RecognitionAudio.setContent (base64EncodedData);
A continuación, usando el Reconocimientoconfig
y Reconocimiento audio
objetos, debes crear un SyncRecognizeRequest
objeto. Como su nombre lo sugiere, le permite crear una solicitud HTTP para transcribir sincrónicamente datos de audio. Una vez que el objeto ha sido creado, puede pasarlo como un argumento a la syncrecognize ()
método y llamar al resultado Speech.SpeechOperations.Syncrecognize
objetos ejecutar()
Método para ejecutar realmente la solicitud HTTP.
El valor de retorno de la ejecutar()
método es un SyncRecognizeResponse
Objeto, que puede contener varias transcripciones alternativas. Por ahora, usaremos la primera alternativa solamente..
// Crear solicitud SyncRecognizeRequest request = new SyncRecognizeRequest (); request.setConfig (RecognitionConfig); request.setAudio (RecognitionAudio); // Generar respuesta SyncRecognizeResponse response = speechService.speech () .syncrecognize (request) .execute (); // Extraer la transcripción SpeechRecognitionResult result = response.getResults (). Get (0); transcripción final de cadena = result.getAlternatives (). get (0) .getTranscript ();
Finalmente, para mostrar la transcripción al usuario, puede pasarla a la Vista de texto
widget Por supuesto, debido a que los cambios en la interfaz de usuario siempre deben ocurrir en el hilo de la IU, asegúrese de hacerlo después de llamar a su actividad runOnUiThread ()
método.
runOnUiThread (new Runnable () @Override public void run () TextView speechToTextResult = (TextView) findViewById (R.id.speech_to_text_result); speechToTextResult.setText (transcript););
Ahora puede ejecutar su aplicación, seleccionar un archivo FLAC que contenga voz en inglés americano y ver que la API de Cloud Speech genere una transcripción para ella..
Vale la pena mencionar que la API de Cloud Speech actualmente puede procesar solo archivos de audio de un solo canal. Si le envía un archivo con varios canales, recibirá una respuesta de error..
Ahora que tenemos una transcripción, podemos pasarla a la API de lenguaje natural de la nube para analizarla. Para mantener este tutorial corto, solo estaremos ejecutando análisis de entidad y sentimiento en la transcripción. En otras palabras, vamos a determinar todas las entidades que se mencionan en la transcripción, como personas, lugares y profesiones, y también a decir si su sentimiento general es negativo, neutral o positivo..
Para permitir que el usuario inicie el análisis, nuestro diseño debe contener otra Botón
widget Por lo tanto, agregue el siguiente código al archivo XML de diseño de su actividad:
La API REST de Cloud Natural Language ofrece una opción de conveniencia llamada annotateText que le permite ejecutar análisis de sentimientos y entidades en un documento con solo una solicitud HTTP. Lo utilizaremos para analizar nuestra transcripción..
Debido a que el análisis debe comenzar cuando el usuario presiona el botón que creamos en el paso anterior, agregue un OnClickListener
lo.
Button analyButton = (Button) findViewById (R.id.analyze_button); analisisButton.setOnClickListener (new View.OnClickListener () @Override public void onClick (View view) // Más código aquí);
Para interactuar con la API utilizando la biblioteca del cliente API de Google, debe crear un CloudNaturalLanguage
objeto usando el CloudNaturalLanguage.Builder
clase. Su constructor también espera un transporte HTTP y una fábrica JSON..
Además, asignando un CloudNaturalLanguageRequestInitializer
Para ello, puede forzarlo a incluir su clave API en todas sus solicitudes..
final CloudNaturalLanguage naturalLanguageService = new CloudNaturalLanguage.Builder (AndroidHttp.newCompatibleTransport (), nuevo AndroidJsonFactory (), null) .setCloudNaturalLanguageRequestInitializer (CLOUDIp_Lication)
Todo el texto que desee analizar utilizando la API debe colocarse dentro de un Documento
objeto. los Documento
el objeto también debe contener información de configuración, como el idioma del texto y si está formateado como texto sin formato o HTML. En consecuencia, agregue el siguiente código:
Transcripción de cadena = ((TextView) findViewById (R.id.speech_to_text_result)) .getText (). ToString (); Documento documento = nuevo documento (); document.setType ("PLAIN_TEXT"); document.setLanguage ("en-US"); document.setContent (transcripción);
A continuación, debe crear un Caracteristicas
Objeto que especifica las características que le interesa analizar. El siguiente código le muestra cómo crear un Caracteristicas
objeto que dice que desea extraer entidades y ejecutar solo análisis de opiniones.
Características características = nuevas características (); features.setExtractEntities (true); features.setExtractDocumentSentiment (true);
Ahora puedes usar el Documento
y Caracteristicas
objetos para componer un AnnotateTextRequest
objeto, que puede ser pasado a la annotateText ()
método para generar un AnnotateTextResponse
objeto.
solicitud final AnnotateTextRequest = new AnnotateTextRequest (); request.setDocument (documento); request.setFeatures (características); AsyncTask.execute (new Runnable () @Override public void run () AnnotateTextResponse response = naturalLanguageService.documents () .annotateText (request) .execute (); // Más código aquí
Tenga en cuenta que estamos generando la respuesta en un nuevo hilo porque las operaciones de red no están permitidas en el hilo de la interfaz de usuario.
Puede extraer una lista de entidades de la AnnotateTextResponse
objeto llamando a su getEntities ()
método. Del mismo modo, puede extraer el sentimiento general de la transcripción llamando al getDocumentSentiment ()
método. Para obtener el puntaje real del sentimiento, sin embargo, también debe llamar al getScore ()
método, que devuelve un flotador
.
Como es de esperar, un puntaje de sentimiento igual a cero significa que el sentimiento es neutral, un puntaje mayor que cero significa que el sentimiento es positivo y un puntaje menor que cero significa que el sentimiento es negativo.
Lo que haga con la lista de entidades y la puntuación del sentimiento depende, por supuesto, de usted. Por ahora, solo mostrémoslos usando un AlertDialog
ejemplo.
lista finalentityList = response.getEntities (); final float sentiment = response.getDocumentSentiment (). getScore (); runOnUiThread (new Runnable () @Override public void run () String entidades = ""; para (Entidad entidad: entityList) entidades + = "\ n" + entity.getName (). toUpperCase (); = new AlertDialog.Builder (MainActivity.this) .setTitle ("Sentimiento:" + sentimiento) .setMessage ("Este archivo de audio habla de:" + entidades) .setNeutralButton ("Bien", nulo). show(); );
Con el código anterior, la puntuación del sentimiento se mostrará en el título del cuadro de diálogo y la lista de entidades se mostrará en su cuerpo..
Si ejecuta la aplicación ahora, debería poder analizar el contenido de los archivos de audio, así como transcribirlos.
Ahora sabe cómo utilizar las API de Cloud Speech y Cloud Natural Language para crear una aplicación para Android que no solo puede transcribir un archivo de audio, sino que también puede ejecutar análisis de entidades y sentimientos en él. En este tutorial, también aprendió cómo trabajar con el Storage Access Framework y las bibliotecas API de Google Client de Android.
Google ha estado agregando regularmente características nuevas e interesantes, junto con soporte para más idiomas, a ambas API. Para mantenerse actualizado sobre ellos, consulte la documentación oficial..
Y mientras esté aquí, consulte algunas de nuestras otras publicaciones sobre servicios en la nube de aplicaciones móviles y aprendizaje automático.!