title | author | translator | category | tags | excerpt | status | ||
---|---|---|---|---|---|---|---|---|
NLLanguageRecognizer |
Mattt |
Juan F. Sagasti |
Cocoa |
language |
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.
|
|
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 NSLinguisticTagger
renovado.
NLTokenizer
es un reemplazo de enumerateSubstrings(in:options:using:)
(originalmente CFStringTokenizer
).
NLLanguageRecognizer
extiende la funcionalidad comentada en NSLinguisticTagger
a través de dominantLanguage
, brindándonos pistas y predicciones acerca del texto analizado.
Así se utiliza NLLanguageRecognizer
para adivinar el idioma dominante en un texto dado:
import NaturalLanguage
let string = """
私はガラスを食べられます。それは私を傷つけません。
"""
let recognizer = NLLanguageRecognizer()
recognizer.processString(string)
recognizer.dominantLanguage // ja
Crea una instancia de NLLanguageRecognizer
y llama al método processString(_:)
pasándole una ristra. A partir de la propiedad dominantLanguage
se accede a un objeto de tipo NLLanguage
que contiene el tag BCP-47 del idioma predicho.
En este caso, "ja"
, del japonés (日本語).
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 NLLanguageRecognizer
, 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 NLLanguageRecognizer
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 NLLanguageRecognizer
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 languageRecognizer = NLLanguageRecognizer()
languageRecognizer.processString(string)
recognizer.dominantLanguage // 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 NLLanguageRecognizer
predijera incorrectamente.
(Para comparar, aquí tienes el texto equivalente en danés)
Podemos usar el método languageHypotheses(withMaximum:)
para tener una idea de cuán segura era la conjetura de dominantLanguage
:
languageRecognizer.languageHypotheses(withMaximum: 2)
Idioma | Fiabilidad |
---|---|
Danés (da ) |
56% |
Noruego bokmål (nb ) |
43% |
En el momento en que escribí este artículo, la propiedad languageHints
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:
languageRecognizer.languageHints = [.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:
Combina NLLanguageRecognizer
con UITextChecker
para comprobar la ortografía de las palabras de una ristra:
Crea un NLLanguageRecognizer
e inicialízalo con una ristra llamando al método processString(_:)
:
let string = """
Wenn ist das Nunstück git und Slotermeyer?
Ja! Beiherhund das Oder die Flipperwaldt gersput!
"""
let languageRecognizer = NLLanguageRecognizer()
languageRecognizer.processString(string)
let dominantLanguage = languageRecognizer.dominantLanguage! // de
Luego, pasa el rawValue
del objeto NLLanguage
devuelto por la propiedad dominantLanguage
al parámetro language
de
rangeOfMisspelledWord(in:range:startingAt:wrap:language:)
:
let textChecker = UITextChecker()
let nsString = NSString(string: string)
let stringRange = NSRange(location: 0, length: nsString.length)
var offset = 0
repeat {
let wordRange =
textChecker.rangeOfMisspelledWord(in: string,
range: stringRange,
startingAt: offset,
wrap: false,
language: dominantLanguage.rawValue)
guard wordRange.location != NSNotFound else {
break
}
print(nsString.substring(with: wordRange))
offset = wordRange.upperBound
} 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
Puedes combinar NLLanguageRecognizer
con AVSpeechSynthesizer
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 languageRecognizer = NLLanguageRecognizer()
languageRecognizer.processString(string)
let language = languageRecognizer.dominantLanguage!.rawValue // fr
let speechSynthesizer = AVSpeechSynthesizer()
let utterance = AVSpeechUtterance(string: string)
utterance.voice = AVSpeechSynthesisVoice(language: language)
speechSynthesizer.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.
NLLanguageRecognizer
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.