Tengo un iPhone desde hace diez años y me encanta. A diferencia de algunas personas, disfruto mucho de Siri y lo uso con frecuencia. Pero después de diez años, Siri no se ha dado cuenta de que cuando transcribe mis mensajes de texto, debe saber que el nombre de mi esposa no es Aaron, sino Erin. Perdono la implementación de voz a texto, que consume muchos recursos, pero después de corregir ese error una vez y enviar un mensaje de texto revisado, esa corrección debería haberse almacenado en un historial de correcciones en mi teléfono, un pequeño archivo utilizado por un modelo de transformador de posprocesamiento, junto con otras pistas, para que este error sea mucho menos probable. Sé que llamar Siri a la función de voz a texto del iPhone es simplificar demasiado, pero así es como mis hijos piensan sobre la "IA en mi iPhone".
Los sistemas de conversión de voz a texto suelen tener problemas con los homófonos (palabras que suenan igual pero tienen diferente ortografía y significado). Estos errores pueden ser frustrantes, especialmente cuando afectan a nombres personales o términos de uso común. La clave para solucionar este problema no radica en revisar el motor de reconocimiento de voz, sino en una capa de procesamiento de texto postranscripción liviana que se adapte a las correcciones del usuario con el tiempo. Aquí está el código basado en PyTorch que diseñé para solucionar este problema.
Es muy compacto y fácil de implementar en un teléfono después de compilarlo para dispositivos móviles. Sé que detrás de Siri hay un conjunto muy complejo de modelos encadenados, por lo que este código podría usarse simplemente para proporcionar una nueva característica como entrada para esos modelos, una puntuación que ayude a personalizar la transcripción cuando surjan homófonos particulares. Pero sería más simple usarlo como una capa de posprocesamiento.
No hace falta esperar a que se lance una nueva versión del teléfono. Me facilitaría la vida en la próxima actualización que Apple lance para mi iPhone.
El sistema calcula una puntuación de probabilidad para cada candidato homófono en función de estos tres factores y selecciona la corrección más probable. A continuación se muestra la implementación de Python dividida en secciones con explicaciones.
El primer paso es crear o cargar una base de datos de homófonos, es decir, pares (o grupos) de palabras que es probable que se confundan durante la transcripción.
# Homophones database homophones_db = { "Aaron": ["Erin"], "bare": ["bear"], "phase": ["faze"], "affect": ["effect"], }
Se trata de un diccionario sencillo en el que la clave es la palabra transcrita incorrectamente y el valor es una lista de alternativas homófonas. Por ejemplo, "phase" se puede confundir con "faze". Más adelante, se consultará esta base de datos cuando se encuentre una palabra ambigua.
El código rastrea las correcciones del usuario en un diccionario donde cada clave es una tupla de (palabra_original, palabra_corregida) y el valor es el recuento de veces que el usuario corrigió ese error.
# Correction history tracker correction_history = { ("phase", "Faye's"): 3, ("bear", "bare"): 2, }
Si el usuario corrige “fase” a “Faye” tres veces, el sistema prioriza esta corrección para futuras transcripciones.
Otro factor que influye en la selección de homófonos es la frecuencia con la que se utiliza una palabra en particular. Pueden ser nombres personales o términos que el usuario escribe con frecuencia.
# Frequent contact tracker frequent_contacts = { "faye": 15, "phase": 5, "erin": 10, "aaron": 2, }
El sistema da más peso a las palabras de uso frecuente al desambiguar homófonos. Por ejemplo, si "faye" aparece 15 veces pero "phase" aparece solo 5 veces, se preferirá "faye".
Las pistas de contexto se extraen de la oración circundante para refinar aún más la selección. Por ejemplo, si la oración contiene el pronombre "ella", el sistema podría favorecer "Erin" en lugar de "Aaron". from transformers import pipeline
from transformers import pipeline # Load an NLP model for context analysis context_analyzer = pipeline("fill-mask", model="bert-base-uncased") def detect_context(sentence): """Detect context-specific clues in the sentence.""" pronouns = ["he", "she", "his", "her", "their"] tokens = sentence.lower().split() return [word for word in tokens if word in pronouns]
Esta función escanea la oración en busca de pronombres específicos de género u otras pistas que puedan indicar el significado previsto de la palabra.
A cada candidato homófono se le asigna una puntuación de probabilidad basada en:
def calculate_likelihood(word, candidate, sentence): """Calculate a likelihood score for a homophone candidate.""" correction_score = correction_history.get((word, candidate), 0) * 3 frequency_score = frequent_contacts.get(candidate, 0) * 2 context = detect_context(sentence) context_clues = homophones_db.get(candidate, []) context_score = sum(1 for clue in context if clue in context_clues) return correction_score + frequency_score + context_score
Esta puntuación combina los tres factores para determinar el homófono más probable.
Con los puntajes de probabilidad calculados, el sistema selecciona el homófono con el puntaje más alto.
def prioritize_homophones(word, candidates, sentence): """Prioritize homophones based on their likelihood scores.""" likelihoods = { candidate: calculate_likelihood(word, candidate, sentence) for candidate in candidates } return max(likelihoods, key=likelihoods.get) def disambiguate_homophone(word, sentence): """Disambiguate homophones using likelihood scores.""" candidates = homophones_db.get(word, []) if not candidates: return word return prioritize_homophones(word, candidates, sentence)
Este proceso garantiza que se elija la palabra más apropiada según el historial, la frecuencia y el contexto.
El sistema procesa una oración completa, aplicando la lógica de desambiguación a cada palabra.
def process_transcription(transcription): """Process the transcription to correct homophones.""" words = transcription.split() corrected_words = [disambiguate_homophone(word, transcription) for word in words] return " ".join(corrected_words)
# Example transcription and correction raw_transcription = "This is phase one plan." corrected_transcription = process_transcription(raw_transcription) print("Original Transcription:", raw_transcription) print("Corrected Transcription:", corrected_transcription) # Simulate user feedback update_correction_history("phase", "faye") print("Updated Correction History:", correction_history) print("Updated Frequent Contacts:", frequent_contacts)
Cuando el usuario corrige un error, el historial de correcciones y los contactos frecuentes se actualizan para mejorar las predicciones futuras.
def update_correction_history(original, corrected): """Update correction history and frequent contacts.""" correction_history[(original, corrected)] = correction_history.get((original, corrected), 0) + 1 frequent_contacts[corrected] = frequent_contacts.get(corrected, 0) + 1 frequent_contacts[original] = max(0, frequent_contacts.get(original, 0) - 1)
Original Transcription: This is phase one plan. Corrected Transcription: This is Faye's one plan. Updated Correction History: {('phase', 'Faye's'): 4} Updated Frequent Contacts: {'Faye's': 16, 'phase': 4}
Esta capa liviana de procesamiento de texto mejora la precisión de las aplicaciones de conversión de voz a texto al aprender de las correcciones del usuario, aprovechar el uso frecuente y analizar el contexto. Es lo suficientemente compacta como para ejecutarse en dispositivos móviles y se adapta a las necesidades individuales de los usuarios, lo que ofrece una alternativa más inteligente a los modelos estáticos tradicionales. Con un mínimo esfuerzo, Apple (o cualquier otra empresa) podría integrar esta funcionalidad para hacer que los asistentes virtuales como Siri sean más receptivos y personalizados.