NLLanguageRecognizer
Cuando viajo, una de mis actividades favoritas es escuchar a la gente cuando pasa y tratar de adivinar en qué idioma hablan. Y me inclino a pensar que, con el tiempo, me he vuelvo muy bueno en ello (aunque rara vez llego a saber si acierto).
Con suerte, reconozco alguna palabra o frase del idioma en cuestión con la que puedo estar familiarizado y deduzco cosas a partir de ahí. En cualquier otro caso, lo que hago es construir un inventario fonético con los tipos de sonido presentes. Por ejemplo, ¿está usando el hablante vibrantes múltiples alveolares sonoras ⟨r⟩
,
vibrantes alveolares simples ⟨ɾ⟩
,
o aproximantes alveolares ⟨ɹ⟩
? ¿Son las vocales en su mayoría abiertas / cerradas; anteriores / posteriores? ¿Algún sonido inusual, como ⟨ʇ⟩
?
O al menos, eso es lo que creo que hago. Sinceramente, todo esto ocurre inconsciente y automáticamente para todos nosotros respecto a cualquier tarea de reconocimiento del lenguaje, de forma que solo tenemos una remota idea de cómo llegamos de la entrada a la salida.
Las computadoras funcionan de manera similar. Después de muchas horas de entrenamiento, los modelos de aprendizaje automático pueden predecir el idioma de un texto con una precisión mucho mayor de la que se obtiene con un enfoque formalizado y secuencial.
El Machine learning (Aprendizaje Automático) ha sido el núcleo del procesamiento del lenguaje natural en las plataformas de Apple durante mucho tiempo, pero ha sido recientemente cuando los desarrolladores externos han tenido acceso para su aprovechamiento.
El framework de Lenguaje Natural, nuevo en iOS 12 y macOS 10.14, refina APIs lingüísticas existentes y expone nueva funcionalidad a los desarrolladores.
NLTagger
es un NSLinguistic
renovado.
NLTokenizer
es un reemplazo de enumerate
(originalmente CFString
).
NLLanguage
extiende la funcionalidad comentada en NSLinguistic
a través de dominant
, brindándonos pistas y predicciones acerca del texto analizado.
Reconociendo el idioma de un texto
Así se utiliza NLLanguage
para adivinar el idioma dominante en un texto dado:
import Natural Language
let string = """
私はガラスを食べられます。それは私を傷つけません。
"""
let recognizer = NLLanguage Recognizer()
recognizer.process String(string)
recognizer.dominant Language // ja
Crea una instancia de NLLanguage
y llama al método process
pasándole una ristra. A partir de la propiedad dominant
se accede a un objeto de tipo NLLanguage
que contiene el tag BCP-47 del idioma predicho.
En este caso, "ja"
, del japonés (日本語).
Obteniendo hipótesis de varios idiomas
Si estudiaste lingüística en la universidad o cursaste latín en el instituto, estarás familiarizado con algunos de los ejemplos más graciosos de homonimia lingüística entre el latín y el italiano moderno.
Por ejemplo, considera la siguiente frase:
CANE NERO MAGNA BELLA PERSICA!
Idioma | Traducción |
---|---|
Latin | ¡Canta, Nero, la gran Guerra Pérsica! |
Italiano | ¡El perro negro se come un bonito melocotón! |
Para disgusto de Max Fisher,
el latín no es uno de los idiomas soportados por NLLanguage
, así que
no contaremos con ejemplos tan entretenidos como el anterior.
A poco que experimentes, te darás cuenta de que es bastante difícil que NLLanguage
adivine incorrectamente o con mala precisión. Es capaz de pasar de la desviación estándar al 95% de certeza con tan solo un puñado de palabras.
Después de un poco de ensayo y error, logramos que NLLanguage
se equivoque con un texto de tamaño no trivial, como el Artículo I de la Declaración Universal de Derechos Humanos en noruego bokmål:
let string = """
Alle mennesker er født frie og med samme menneskeverd og menneskerettigheter.
De er utstyrt med fornuft og samvittighet og bør handle mot hverandre i brorskapets ånd.
"""
let language Recognizer = NLLanguage Recognizer()
language Recognizer.process String(string)
recognizer.dominant Language // da (!)
La Declaración Universal de Derechos Humanos, es uno de los documentos más traducidos del mundo, con traducciones en más de 500 idiomas. Por esta razón, se usa muy a menudo para tareas de procesamiento del lenguaje natural.
El danés y el noruego bokmål son lenguajes muy similares, por lo que no es de extrañar que NLLanguage
predijera incorrectamente.
(Para comparar, aquí tienes el texto equivalente en danés)
Podemos usar el método language
para tener una idea de cuán segura era la conjetura de dominant
:
language Recognizer.language Hypotheses(with Maximum: 2)
Idioma | Fiabilidad |
---|---|
Danés (da ) |
56% |
Noruego bokmål (nb ) |
43% |
En el momento en que escribí este artículo, la propiedad language
no estaba documentada, así que no está muy claro cómo debería usarse. Sin embargo, si pasamos un diccionario ponderado de pistas, parece tener el efecto esperado, reforzando las hipótesis:
language Recognizer.language Hints = [.danish: 0.25, .norwegian: 0.75]
Idioma | Fiabilidad (con pistas) |
---|---|
Danish (da ) |
30% |
Noruego Bokmål (nb ) |
70% |
¿Y qué podemos hacer una vez sabemos el idioma de una ristra?
Aquí tienes algunos casos de uso a considerar:
Comprobación ortográfica
Combina NLLanguage
con UIText
para comprobar la ortografía de las palabras de una ristra:
Crea un NLLanguage
e inicialízalo con una ristra llamando al método process
:
let string = """
Wenn ist das Nunstück git und Slotermeyer?
Ja! Beiherhund das Oder die Flipperwaldt gersput!
"""
let language Recognizer = NLLanguage Recognizer()
language Recognizer.process String(string)
let dominant Language = language Recognizer.dominant Language! // de
Luego, pasa el raw
del objeto NLLanguage
devuelto por la propiedad dominant
al parámetro language
de
range
:
let text Checker = UIText Checker()
let ns String = NSString(string: string)
let string Range = NSRange(location: 0, length: ns String.length)
var offset = 0
repeat {
let word Range =
text Checker.range Of Misspelled Word(in: string,
range: string Range,
starting At: offset,
wrap: false,
language: dominant Language.raw Value)
guard word Range.location != NSNot Found else {
break
}
print(ns String.substring(with: word Range))
offset = word Range.upper Bound
} while true
Cuando se le pasa El chiste más gracioso del mundo, se identifican las siguientes palabras como mal escritas:
- Nunstück
- Slotermeyer
- Beiherhund
- Flipperwaldt
- gersput
Sintetización del habla
Puedes combinar NLLanguage
con AVSpeech
para escuchar cualquier texto de un idioma leído en voz alta:
let string = """
Je m'baladais sur l'avenue le cœur ouvert à l'inconnu
J'avais envie de dire bonjour à n'importe qui.
N'importe qui et ce fut toi, je t'ai dit n'importe quoi
Il suffisait de te parler, pour t'apprivoiser.
"""
let language Recognizer = NLLanguage Recognizer()
language Recognizer.process String(string)
let language = language Recognizer.dominant Language!.raw Value // fr
let speech Synthesizer = AVSpeech Synthesizer()
let utterance = AVSpeech Utterance(string: string)
utterance.voice = AVSpeech Synthesis Voice(language: language)
speech Synthesizer.speak(utterance)
No tiene la delicadeza lírica de Joe Dassin, pero ainsi va la vie.
Antes de entender algo, primero tienes que querer entender. Y el primer paso para entender el lenguaje natural es determinar su idioma.
NLLanguage
ofrece una potente interfaz a la funcionalidad responsable de muchas de las funciones inteligentes presentes en iOS y macOS. Intenta sacarle partido para tener un mayor entendimiento sobre tus usuarios.