Un rápido y compacto corrector ortográfico en Scala

Construir un corrector ortográfico no es realmente una tarea muy difícil. Muchos inmediatamente mencionarán la distancia de Levenshtein para saber la distancia de edición entre 2 palabras.

Tomando el ejemplo de Wikipedia:

La distancia de Levenshtein entre “casa” y “calle” es de 3 porque se necesitan al menos tres ediciones elementales para cambiar uno en el otro.

  1. casa → cala (sustitución de ‘s’ por ‘l’)
  2. cala → calla (inserción de ‘l’ entre ‘l’ y ‘a’)
  3. calla → calle (sustitución de ‘a’ por ‘e’)

Entonces, buscar los posibles candidatos de una palabra mal escrita se convierte en buscar las palabras que tengan la menor distancia de edición con ella. Es simple, pero en el peor de los casos tendríamos que buscar entre todo el conjunto de palabras que tengamos (como un diccionario), lo cual hace que la búsqueda sea O(n).

Para alivianar el problema, existen los BK-Tree, que básicamente son árboles cuyos nodos son palabras y las aristas tienen el valor de la distancia de edición entre esos nodos. Acá hay una explicación (en inglés) que cubre lo necesario para entenderlos: http://blog.notdot.net/2007/4/Damn-Cool-Algorithms-Part-1-BK-Trees

El caso es que usar un BK-Tree para esta tarea acelera mucho la búsqueda de candidatos, puesto que no es necesario cubrir todos los nodos si la distancia máxima que se busca es relativamente pequeña (digamos, 1 o 2).

Buscando implementaciones en Scala, me doy cuenta de que en Scalaz existe la clase BKTree (aunque está deprecated en la versión 7). Viendo el código, y teniendo una lista de 90,000 palabras en inglés, me di a la tarea de implementar un muy sencillo corrector ortográfico en ese lenguaje. La distancia máxima entre palabras la puse en 1. El resultado:

package org.mmg.tests

import scala.io.Source._
import scalaz._
import Scalaz._

object SpellCorrector {

  def main(a: Array[String]) {
	  val words = fromFile("EnglishWords.txt").getLines.toList	  
	  val bt = words.foldLeft(BKTree[String]())((acc, w) => acc + w) 	  	  
	  val MAX_DIST = 1

	 while (true) {
    	print("Input the word you want to check (Ctrl-C to end): ")
    	Option(Console.readLine) filterNot {_.isEmpty} foreach {s => 
        	bt.valuesApproximate(s, MAX_DIST) foreach println
    	}
     }
  }

}

Y probando:

Input the word you want to check (Ctrl-C to end): tail
ail
til
bail
fail
Gail
hail
jail
kail
mail
nail
pail
rail
sail
tail
vail
wail
tall
tael
tain
toil
trail

Los resultados se obtienen relativamente rápido. El ejemplo anterior toma sólo algunas décimas de segundo (casi 90,000 palabras). Por supuesto que esto no quiere decir que sea óptimo, pero si no se busca un desempeño en áreas críticas, funciona.

Obviamente esto es muy simple, pero puede mejorar si por ejemplo le asignamos menos peso a operaciones de la distancia de Levenshtein entre letras que frecuentemente se escriben mal, como por ejemplo, entre la “o” y la “p”, que están juntas en un teclado QWERTY. Eso haría que la distancia fuera menor entre ciertas palabras y reduciría el número de candidatos que se muestran.

Por supuesto, si tenemos un modelo probabilístico podemos usar el teorema de Bayes para buscar mejores candidatos, y aunque no es en sí tan complicado, sí me tomaría más tiempo escribirlo aquí.

Como sea, esta implementación es rápida, y puede sacar de algún apuro.

Decisiones

Tanaka01

Masahiro Tanaka

Saito01

Yuki Saito.

2 nombres que en 2006 resonaron por primera vez en todo Japón. ¿La razón? La final del Koshien (campeonato nacional de béisbol de preparatorias) de verano de ese año. Una batalla tan reñida que aún después de 15 entradas seguía empatada, y por primera vez en 37 años se tuvo que decidir con un segundo encuentro el día siguiente.

El ganador fue Saito, ponchando justamente a Tanaka y dándole la victoria a Waseda por primera vez.

[youtube]http://www.youtube.com/watch?v=jtF6dgTjmVQ[/youtube]

Saito llamó mucho la atención durante ese campeonato tanto por su habilidad en el pitcheo, como por usar un pañuelo para limpiarse el sudor en medio de los partidos. Algo simple, sí, pero que a fin de cuentas le hizo ganarse el mote de “ハンカチ王子” (Hankachi ouji, el príncipe del pañuelo).

Todos auguraban un futuro brillante para ambos jóvenes, especialmente para Saito. Estaban a punto de graduarse de la preparatoria y de escoger el camino que seguirían de ahí en delante.

¿La decisión? Tanaka escogió convertirse en beisbolista profesional, mientras que Saito escogió entrar a la universidad a estudiar una carrera, sin dejar el béisbol. Su idea era seguir jugando en la liga universitaria mientras conseguía un título universitario, y al graduarse, convertirse en beisbolista profesional.

2013.

Tanaka impone un récord al no perder ni un partido en la temporada, consolidándose como una estrella del béisbol en Japón, y expresa su deseo de irse a las grandes ligas en Estados Unidos para el próximo año, lo que en Japón significa que es élite, y que su nivel es realmente alto, independientemente de cómo le vaya por allá (obviamente si le va bien, como a Ichiro Suzuki o Hideki Matsui, mejor).

¿Saito? Se graduó de la universidad hace un par de años, y como estaba planeado, expresó su deseo de convertirse en beisbolista profesional. Causó mucho revuelo en el draft, y varios equipos se pelearon el derecho de negociar con él. A fin de cuentas entró en el equipo de Hokkaido. Durante las prácticas, la gente abarrotaba el lugar solamente para verlo, tomarse una foto, saber de él. Los medios de comunicación le prestaron una atención que era exagerada. Pero cuando hizo su debut como profesional, inmediatamente se notó que no tenía el nivel requerido, y de ser tratado como una estrella, en poco tiempo bajó de rango y entró a lo que serían las reservas. Este 2013 sólo jugó un partido, 4 entradas, y terminó perdiendo.

Ahora bien: no, no me picó ningún insecto extraño para escribir de béisbol aquí 😛

Haber visto el principio de estos jóvenes y la situación que viven actualmente, aunado con lo que ya conocemos de Bill Gates, Mark Zuckerberg, Steve Jobs y demás (que no terminaron la universidad), me recuerda la importancia de aprovechar las oportunidades y de tomar decisiones en el momento acertado.

¿Por qué me impacta todo esto? Porque por mucho tiempo fui un persona que creyó que el camino al éxito está 100% relacionado con los estudios (excluyendo obviamente a los deportistas), pero gente como la mencionada en el párrafo anterior, aunada con mi experiencia personal y corroborada con Tanaka y Saito, están para comprobarme que no siempre es así.

Estudiar es muy importante, cierto, pero no ir a la escuela, no tener un título ni un gran historial escolar no tienen para nada qué ver con el éxito que pueda tener alguien en la vida, ni tampoco para sentirse pleno. Y de la misma forma, tener todos los títulos del mundo no te hace ni más ni mejor persona que el ñor que hace la limpieza de tu escuela, trabajo o cuadra.

Ciertamente mi forma de pensar cambió hace mucho, pero lo menciono ahora justamente porque lo que está sucediendo con Tanaka y Saito me lo recordó. Si el segundo ya sabía qué quería seguirle como profesional, ¿cuál era el motivo para dedicarle 4 años a una carrera que a fin de cuentas no va a ejercer? Ojo: no es lo mismo que estudiar o graduarse de una carrera y después darte cuenta que no es lo tuyo y dedicarte a algo completamente diferente; nadie sabe el futuro y la situación de cada persona puede cambiar de la noche a la mañana. Me refiero al caso donde sabes que te quieres dedicar a algo pero por lo que quieras y gustes te desvías voluntariamente del camino, y no para probar suerte.

Los 4 años de experiencia que le lleva Tanaka a Saito pesan mucho, y todavía más por el hecho de que los deportistas tienen el tiempo más contado que otras profesiones: ya como a las 30 años eres veterano, y por más que quieras, es cada vez más difícil mantener el cuerpo en forma, mientras que nacen nuevas estrellas a las que la juventud les da una gran ventaja. Ambos tenían claro lo que querían hacer en el futuro, pero la diferencia es que Tanaka tomó la decisión en el momento adecuado y concentró sus esfuerzos en ello, mientras que Saito tomó una desviación y ahora tiene, además de un gran camino por recorrer, luchar contra el tiempo para poder lograr lo que Tanaka ha hecho durante este lapso. Es posible, y de todo corazón espero que lo logre, pero sin lugar a dudas no la tiene fácil.

Muchas veces estamos indecisos sobre lo que viene y lo que queremos hacer en el futuro. Tomar decisiones, equivocarse y rectificar es el pan de cada día al ir creciendo. Eso nos ayuda a visualizar objetivos, fijarnos metas y crear nuevos sueños. Da miedo tomar una decisión errónea, y ese miedo crece conforme los años pasan, pero mientras no se venza, encontrar lo que de corazón queremos hacer en el futuro se torna cada vez más difícil. Y esto no necesariamente tiene que ser en lo que respecta a trabajo o estudio. Simples sueños como “viajar a Japón”, “dar la vuelta al mundo”, “abrir un changarro propio”, pueden nacer de algo muy simple, y aunque no se tengan los recursos o conocimientos necesarios para cristalizarlos en ese momento, fijarse como meta algo y concentrar los esfuerzos en lograrlo trae consigo una gran satisfacción, y el cansancio que nace de todo eso hace que recordemos lo chido que es estar vivo, y que no importa el número de errores que se hayan cometido en el pasado, ni tampoco si al final se logra lo que uno se propone (hay factores externos que querramos o no también juegan un papel importante), el chiste es, creo yo, tratar de darle rumbo a la forma de pasar el tiempo que estaremos en este mundo.

No hay día en el que no me repita a mí mismo el párrafo anterior.

Recomendaciones turísticas en Japón

Mucha gente me pregunta con frecuencia lo siguiente:

  • ¿Qué lugares visitar en Japón?
  • ¿Dónde puedo encontrar hospedaje barato?
  • ¿Cuál es la manera más económica de moverse dentro de Japón?

He respondido varias veces de forma similar, pero generalmete por correo. Así que para evitar escribir lo mismo varias veces, aquí dejo una mini guía al respecto. Tengan en cuenta que esto es basado en experiencia personal; puede haber mejores opciones, pero al menos se pueden dar una idea.

http://manuel.midoriparadise.com/recomendaciones-turisticas-en-japon/

El fenónemo llamado “Koisuru Fortune Cookie”

La gente que conoce algo de Japón seguramente ha escuchado hablar de un grupo de idols llamado AKB48, el más famoso en este momento. Y así como alrededor del mundo hay gente que simplemente las aborrece, en Japón no a todos les caen bien. “Artistas prefabricadas”, “ni cantan”, “unas ni están tan bonitas” y ahí usted póngale más comentarios. Vamos: el precio de la fama y que no se es monedita de oro.

Con todo y las críticas que se cargan, este verano ocurrió un fenómeno interesante: el grupo lanzó una canción titulada 恋するフォーチュンクッキー (Koisuru Fortune Cookie, literalmente “La galleta de la suerte para enamorarse”). La letra no es en sí nada del otro mundo, pero el ritmo y el baile atrapó la atención de muchos, al grado de que algunos que simplemente no soportan al grupo exclamaron que escuchar la canción los hacía sentir bien.

El grupo lanzó el video original apenas en octubre:

[youtube]http://www.youtube.com/watch?v=dFf4AgBNR1E[/youtube]

Pero como ya se habían presentado en varios lugares y la canción originalmente salió en verano, mucha gente conocía la coreografía. ¿El resultado? La canción se volvió viral y muchas compañías, tiendas, marcas  y hasta dependencias de gobierno haciendo su versión del baile.

¿Qué tiene esto de especial? Estamos hablando de una cultura que no baila, y que aunque reconoce que grupo como AKB48 y cosas “otaku” mueven mucho dinero nomás no les cabe en la cabeza ese tipo de ideas. Cierto: seguramente no todos los que aparecen en los videos participaron voluntariamente en ellos, pero independientemente de eso, el hecho de unirse para participar en algo así (aunque concuerde con la idea de “pertenecer al grupo” y de hacer lo que los demás están haciendo) es digno de ser mencionado.

Por cierto, he de mencionar que se siente raro ver el video y darte cuenta que sabes exactamente dónde es y que muchas veces pasaste por ahí, caminando y en carro. Se grabó en Fukuoka, al lado del centro comercial Hawks Town, muy cerca del estadio de béisbol Yahoo! Dome, que es el que se ve al fondo.

A continuación algunos de los videos de la canción, en versiones de grupos que sorprenden por haberse unido al “hype”. La letra de la canción está al final, por si se les antoja cantarla.

Continue reading “El fenónemo llamado “Koisuru Fortune Cookie””

¿Sabías que…? – Parte 18

Huelga decir que me gustan mucho los videojuegos, ya que tienen un significado especial para mí. En ese sentido, estar en Japón, que es el paraíso de las arcadias, significa poder disfrutar de lo que los famosos “centros de juegos” ofrecen, aunque sólo sea en teoría (ya he comentado antes cómo está el rollo de los trabajos por acá).

Generalmente, la idea de hacer un videojuego de cualquier actividad cotidiana me parece muy buena, ya que acerca a los videojuegos a gente que en su vida había tocado uno, o bien a quienes tenían una idea errónea respecto a ellos. No obstante, me gustaría saber su opinión respecto a lo siguiente.

¿Sabías en que en Japón existen videojuegos en los mingitorios, en los que lo único que tienes que hacer es atinarle al blanco?

 

Sé que esto no es nuevo, pero me intriga saber cómo los ven desde fuera de Japón. ¿Excesivos? ¿Da igual? ¿Divertido?.

Las fotos anteriores son del “juego” llamado 小便小僧, literalmente “el niño de la orina”. Este en sí sólo calcula la cantidad de orina y la compara con la capacidad que tienen los café en lata. Existen otros, pero todos se basan precisamente en la cantidad de orina que sale de tu cuerpo.

Aquí vemos las imágenes de otros juegos similares. De izquierda a derecha, de arriba a abajo:

  • Puzzle Quiz, Chonyoryoku. No lo conozco. No me ha tocado encontrármelo.
  • Bukkake Battle: Hana kara Gyunyuu. El que me parece más interesante por incluir el elemento de competencia. Eres un chico malo en la escuela, y compites por ver quién saca más leche por la nariz. La cantidad de orina es tu poder, y compites con el que haya usado el baño antes que tú. Les diría mi récord, pero no creo que nadie quiera saberlo.[youtube]http://www.youtube.com/watch?v=nQyr4ue-mAU[/youtube]
  • Nyonai Checker. Supuestamente “analiza” los elementos que contiene tu orina y con base en eso te dice tu “verdadera” personalidad.
  • Boufuu Keihou Hatsurei. Una repotera del estado del tiempo de repente se encuentra con el anuncio de vientos violentos en el área. Obviamente, la cantidad de tu orina es lo fuerte del viento que la reportera tendrá que soportar. Por cierto, su falda es muy corta 😛

Estos juegos se encuentran en los baños de cualquier centro de arcadias, así como en izakayas (bares estilo japonés) y en algunos clubes nocturnos. Si les toca andar por acá y se encuentran con uno, no duden en “jugar”: es gratis 😛

¿Chicas? Lo siento, creo que todavía no hay para ustedes 🙁

Funciones como ciudadanos de primera clase y expresiones lambda

En la entrada anterior, varias personas me hicieron el apunte de que debería haber puesto la última parte (donde explico para qué puede ser útil ese conocimiento) en el principio. Otros comentaron que aunque es posible entender el escrito, sí es necesario conocer ciertos conceptos, como mapeo, para “agarrar el hilo”.

Agradezco mucho sus comentarios 🙂

Aunque no pretendo hacer (de momento) una guía exhaustiva sobre programación funcional, sí me gustaría plasmar algunos conceptos básicos que puedan servir para despertar el interés de investigar más.

Cabe mencionar que programar en forma funcional no necesariamente es mejor que la programación orientada a objetos. Cada paradigma tiene pros y contras, pero conocer lo que cada uno ofrece nos permite tomar mejores decisiones a la hora de crear código o de seleccionar un lenguaje para ciertas tareas.

Vayamos al grano:

Continue reading “Funciones como ciudadanos de primera clase y expresiones lambda”

Monads – Yo también tenía que escribir al respecto

Seguí la tradición: cuentan las leyendas que cuando una persona comienza a ver la luz al usar Monads, invariablemente escribe un tutorial. Pero en mi caso, no es un tutorial, sino más bien una breve explicación de lo que son, junto con algunos ejemplos. Esto es con el fin de que yo mismo compruebe si entiendo el concepto general, y al mismo tiempo de que salgan gurús en programación funcional y me corrijan y me digan en qué estoy mal.

Ésta no es una guía exhaustiva, y omitiré muchos conceptos, pero pondré referencias por aquello de que haya interesados en el tema.

Como nota, sé que en español los términos son Funtor mónadas, pero nada más no me entran en la cabeza, por lo que los usaré en inglés. Además, aunque no está dirigido a un lenguaje en particular, la mayoría de los ejemplos mostrados están en Scala.

Continue reading “Monads – Yo también tenía que escribir al respecto”

Seguir soñando

A lo largo de los ya 9 años que tiene el blog (y que no he escrito nada en especial al respecto), no sólo ustedes, quienes me hacen el favor de leerme, han visto una serie de cambios en mi vida. También yo he recordado cómo pasé de ser un olvidado estudiante de maestría y luego de doctorado en un laboratorio de una universidad en un pequeña ciudad en la prefectura de Fukuoka, a alguien que persigue muchos objetivos pero sigue teniendo dudas.

Los años pasan, y al tiempo no hay forma de ganarle (todavía). Crecer en México y desarrollarme en Japón me ha dado una visión única y especial de la vida en ambos países. He tenido la fortuna de conocer a grandes personas tanto aquí como en mi país, de reconocer debilidades que hasta hace años habían pasado desapercibidas, y al mismo tiempo, de debatir lo que quiero para el futuro.

Hace ya más de medio año, un mexicano radicado en Kanagawa me invitó a comer a su casa. Al evento asistieron otras personas, entre ellas una chica oriental (no japonesa), quién se encontraba ante la difícil decisión de qué es lo que quería hacer con su vida, y con base en ello decidir qué es lo que debía de estudiar y en dónde debería estar. Ella me preguntó: “¿cómo fue que tomaste la decisión de saber qué es lo que querías hacer el resto de tu vida?”, a lo que respondí: “Simplemente haz lo que te gusta. Si no sabes qué hacer, al menos creo que tienes una idea más o menos clara de lo que NO quieres hacer. Eso es un buen comienzo.”. Pero mientras respondia, me percataba de que yo también estaba ante una situación similar.

Hasta aproximadamente julio de este año tuve días, semanas y meses muy pesados. Me eché demasiada carga emocional al respecto. Sentía que se me cerraba el mundo, que tenía que apresurar cualquier decisión que tomara, y creía que la situación en la que vivo actualmente era la responsable de que me sintiera así. Platiqué con varias personas, escuché opiniones y consejos, y lo primero que decidí fue tomar las cosas un poco más a la ligera. Necesitaba darme cuenta de que, aunque es cierto que hay decisiones que se tienen que hacer en determinado momento, había otras (especialmente las que invariablemente trazarán una buena parte del camino que hay que seguir por una cantidad de tiempo considerable) en las que era necesario respirar profundo y no sentirse atado a ningún tipo de reloj. Decidí bajarle el ritmo a muchos objetivos, sobre todo porque mi salud se estaba viendo afectada (dormir no está tan sobrevalorado como muchos dicen).

Algunos meses han pasado desde entonces. He comprendido que lo primero que tengo que hacer es evitar perder es la capacidad de seguir soñando. No hay presiones externas (algunas se podrían tomar como tal, pero mientras uno no las considere, no cuentan), pero la premura con la que quería alcanzar ciertas metas opacaba esa parte de mí que me trajo a Japón hace 10 años y medio. Y sin ella, definitivamente no hay rumbo qué seguir; solamente me encontraría navegando sin rumbo durante quién sabe cuánto tiempo.

Además, recuperé el gusto por varias actividades que consideraba casi perdido. Nadie lo sabe, pero en esto tienen mucho que ver personas que están en México y que ni siquiera conozco en persona. Es más: ni siquiera ellos están enterados de cómo ciertas actividades que realizan me han ayudado a reenforcarme, y gracias a eso pude disfrutar como nunca un par de eventos por esta parte del mundo.

No obstante, pienso que lo más importante de este tiempo ha sido dejar de ser duro conmigo mismo y culparme por algo en lo que no tenía control. Y eso no es nada críptico, ni tampoco un secreto: mi doctorado. Cumplí ese sueño, pero no de la manera que habría querido, y lo que pasó después de obtenerlo no significa que no le haya echado las ganas necesarias. Le hice caso a muchas personas que se cansaron de sugerirme que mirara hacia atrás y viera el camino que he seguido. Gracias a eso, entendí de dónde viene mi disgusto y que no era nada más una excusa que había inventado.

Todavía tengo mucho, pero mucho que aprender.

Más de alguno de los que me leen seguramente está pensando: “¿Y ahora qué fumó Manuel?”, y la respuesta es: “serenidad”, aunque no toda la que necesito. La vida continúa y hay que enfrentarse todos los días a diferentes retos. Pero sobre todo eso, quiero seguir siendo alguien que cree que puede comerse el mundo; que, de alguna forma, puede cambiarlo; quiero volver a soñar que puedo ser astronauta, bombero, futbolista, y quiero decirme a mí mismo que sí puedo, y que es sólo cuestión de que ponga el objetivo en la mira para poder alcanzarlo.

Sigo creyendo que siempre tengo la edad perfecta para realizar algo. Estuve cerca de perder esa idea. Pero nel, no me dejo. Hoy a los 35 años, y siendo el décimo aniversario que celebro en Japón (porque uno me tocó estar en México) estoy fresco (ignoren por favor el estado físico – piernas sobre todo. Recuerdo del monte Fuji), y creo que sí, me puedo comer el mundo. Lo que sigue es ver los cubiertos que usaré.

Nintendo 3DS modelo de Zelda – Difícil de apartar

Esta belleza fue anunciada primero para Europa. Esperaba que dieran el anuncio de que también saldría en Japón, ya que sería la oportunidad perfecta para comprar uno después de tanto tiempo de andar cazando el modelo de Mario y no encontrarlo en ningún lado, o encontrarlo a precio exhorbitante. Dieron el aviso oficial y dije, “¡sí!”.

Voy a Amazon Japón, lo busco, nada. Veo otras tiendas en línea, lo busco, y nada. No estaba todavía disponible para ser apartado. Esto fue el miércoles. Ayer viernes me meto de nuevo a buscar y ¡sí está!, pero AGOTADO en todos los lugares conocidos.

Sí, me tardé (unas horas). Pensaba que ya estaba todo perdido cuando se me ocurre buscarlo en tiendas auspiciadas por Rakuten, y que me encuentro un lugar donde todavía se podía apartar, y a un precio razonable (aunque no el oficial). Ya no le quise dar más vueltas y lo aparté.

Tendré Nintendo 3DS LL con Zelda para fin de año. Ya era justo.