top of page

COSAS VEREDES

  • fjroar
  • 21 oct 2021
  • 2 Min. de lectura

A los que nos gusta observar el cielo, muchas veces debido a la contaminación lumínica de las grandes ciudades, donde por motivos laborales fundamentalmente nos toca vivir. Resulta que lo tenemos bastante crudo. Sin embargo hay medios que aún nos permiten ver más allá de esas iluminarias que excesivamente nuestros dirigentes políticos despliegan dado que ellos no se gastan el dinero.

Así pues, me propuse el 19 de Octubre de 2021 pegarle una fotaco a Júpiter desde la puerta de mi casa del barrio de manoteras y esto fue lo que obtuve en primera instancia (y que si sigues leyendo te explicaré como lo mejoré y conseguí una bonita mancha roja).


Para llegar a la anterior foto se necesita el siguiente material:


  • Un telescopio de gama iniciación al menos. El mío es un Celestron Nex Star 127 que es lo mínimo para hacer unas planetarias aceptables

  • Una cámara para engancharla al ocular del telescopio que en este caso es de 1.25'' La gama más baja y recomendable de este tipo de cámaras es la ASIC 120 MC Color

  • Un PC portátil donde se engancha la cámara vía USB y se proyecta la imagen del cielo

Además de los anteriores elementos, yo suelo usar una batería de energía que tiene salida para la montura del telescopio, lo que ahorra muchas pilas y permite hacer bien el seguimiento a 12V.


Pues bien, para llegar a la anterior foto de arriba, lo que se necesita es encontrar el planeta en el ocular y algo más difícil es que se vea en la cámara, para ello será necesario al menos una exposición tipo vídeo de 50ms y sobre todo enfocar bien. El cielo, aunque había casi Luna llena estaba muy limpio y por tanto, a diferencia de otros objetos astronómicos, Júpiter es muy agradecido para este tipo de fotos, así que gran parte del tiempo la pasé enfocando bien con el telescopio y ajustando los parámetros de la cámara de tipo contraste, saturación, brillo, ganancia, ... y los apunté en una libreta por si alguien tiene curiosidad.

Total tras un buen enfoque y ver que se veía en mi pantalla con cierta nitidez (aunque no con esos colores), me puse a grabar un vídeo de tan sólo 1 minuto una vez, tenía el telescopio en modo búsqueda.


Pero claro, si hago una foto como la anterior queda muy triste y es que en sus píxeles hay más información de lo que parece y en este sentido me puse a procesarla, algo fundamental en astrofotografía y para ello utilicé Pixinsight, un gran programa, que aunque parece caro, no lo es tanto si lo vas a usar asiduamente, ya que pagas una licencia y te olvidas.


Pues bien con un procesado bastante básico en menos de 20 min le saqué los colores y voilà, me encuentra con la Mancha Roja:



Encontrarse con la Mancha Roja es difícil, porque generalmente está por detrás (Ley de Murphy) y además conviene hacerlo con cierta planificación, lo cual yo no hice, prácticamente vine de trabajar y me entraron ganas de hacer la fotico.


Pues bien, espero a los que lean esta entrada, les haya gustado la foto del padre de los dioses y si alguien se interesa por el detalle del procesado aplicado con PixInsight, que me lo pregunte y se lo comento, que no es muy complicado.





  • fjroar
  • 25 ago 2021
  • 6 Min. de lectura

Hay un par de motivos importantes a la hora de escribir este post. Uno de ellos es tratar de hacer realmente entendible qué hay detrás de un modelo tipo knn o k-vecinos más próximos (en español) y otro no menos interesante es entender porque estos modelos, cuando se aplican a grandes cantidades de datos pueden resultar lentos e ineficientes.

El modelo knn no creáis que se ha inventado con la movida del ML y demás, sino que viene de principios de los 50 y fueron desarrollados por Evelyn Fix y Joseph Hodges.

Hay muchas variantes de este modelo y aquí se va a considerar sólo 1, quizás la más avanzada que es la que creo que es más esclarecedora una vez que se entiende, así pues, se considera que se tiene una variable explicada de tipo continuo como pueda ser la variable target del conocido dataset Boston que es una estimación del precio del metro cuadrado de la vivienda en función de otras 13 variables explicativas.

Para hacer más sencillo la comprensión de este algoritmo, de las anteriores 13 variables, se van a considerar sólo 2, las denominadas RM (número medio de habitaciones) y AGE (proporción de unidades ocupadas por sus propietarios construidas antes de 1940) que se ha visto que aparecen como significativas en cualquier regresión lineal.

Dado que es un conjunto muy limpio, no hay que hacer ningún tratamiento a priori especial con estas variables. Se hace una separación training-test del tipo 80%-20% que si se representa (tranquilos, he fijado una semilla de aleatorización para que podáis reproducirlo …) se obtiene la siguiente representación siempre y cuando se haya estandarizado las variables (en el training y aplicada dicha estandarización en el test):


Observación: Tanto el anterior dibujo, como análisis que aquí se muestran están realizados bajo entorno Spyder y os lo podéis descargar de mi git en: https://github.com/FJROAR/Ejemplo-Blog-KNN


Pues vamos a entrar en materia ¿Cómo funciona esto del knn en una variable continua? Para empezar a hablar, el entrenamiento de un knn no guarda una mayor dificultad ya que prácticamente lo que se hace es “memorizar instancias” qué, ¿Qué es eso de memorizar instancias? Pues que no cunda el pánico, simplemente lo que se hace en la fase de entrenamiento es guardar (en memoria o algún sitio, …) los puntos azules (en este caso el 80% de los datos) con todos sus valores (explicativa y target) y ya no se hace nada más, como veis el tema es rápido, sin embargo, ahora llega “el momento de la verdad” ¿Cómo predice un knn cuando llega un nuevo dato? “¡Eh, amigo!, aquí la cosa, aunque creo que se va a entender, es algo más enrevesado”.

En primer lugar, debe tenerse el dato de cuántos serán los vecinos para la interpolación, en este caso supongamos que k = 1, por tanto, el primer paso a dar es calcular la distancia de ese punto a todos los puntos del training para obtener el punto más cercano posible. Una vez obtenido este punto, el valor que se interpola es el que está almacenado en el training. En el supuesto de que k = 2, se hace la misma operación hasta que se consideran a los 2 puntos más cercanos posibles y en este caso se asocia una media de valores y así sucesivamente.

Como puede observarse, aunque estas operaciones son fáciles de entender, para un procesador resulta complicado el tema de las operaciones del cálculo de distancia, ya que para cada dato debe hacer tantos cálculos como datos existe en el training y por tanto imaginaros que estamos ante un dataset de tamaño medio de unos 100.000 registros donde se aplica un 70%-30%, el número de operaciones para predecir el test sería del orden de 2100 mill y eso que para muchos esto no es más que un aperitivo en el mundo del Big Data. Además está el problema de que cada vez que entre un dato nuevo, si se pone el knn en producción habría que esperar a que haga sus 70.000 operaciones y “resto de cositas” para tener un valor, lo que puede resultar en unos segundos que en el caso de ser un proceso de entrada continuo de datos, podría hacer colapsar el sistema. Por tanto aquí está la debilidad de este tipo de modelos que hay que tenerla muy en cuenta en función del problema que se vaya a tratar.

Siguiendo con el ejemplo de los datos de Boston, aquí no se tiene este problema ya que hay tan sólo unas 506 observaciones, cuyas variables estandarizadas han sido ya representadas anteriormente separando por training y por test. Para entender lo que he dicho anteriormente vamos a ver qué es lo que hace el algoritmo exactamente. Supongamos que k = 1 y consideramos el punto del test normalizado más a la derecha:

¿Qué valor se le va a asociar? Pues bien, habiendo elegido una distancia como es la euclídea, se tiene que buscar el punto azul más cercano. Si agudizamos bien la vista, se observa que sobre el punto rojo que está al lado parece que existe un punto azul por debajo, esto se puede observar en la siguiente representación ordenada de los dataset test y training ordenados de menor a mayor por la variable RM:


El punto de interés es justamente el que tiene por índice el número 25 en el X_test_norm (buena idea esta de los índices en Python, por cierto) Y el punto más cercano a este pero en X_train_norm es el que tiene por índice el número 218, de hecho si observamos en X_test_norm, se observa que el punto que tiene por índice el número 96, tiene las mismas coordenadas que el anterior, es decir, los puntos están superpuestos y como el rojo cae encima del azul, de ahí el hecho que no se vea este último.

Pues bien, ¿Cuál es el valor que se le asociaría al punto anterior bajo un 1-nn? En este caso, dado que ya se ha averiguado el punto más cercano, se va al dataset training y es cuando se mira el valor en el target en el dataset y_train que resulta ser (buscando por el índice 218) el valor 11.9, para verlo en el código se genera una variable kpred1 donde en su valor índice 25, se obtiene dicho valor de hecho, como habrá deducido el lector, también en el índice con valor 96, el valor va a ser exactamente el mismo por razones obvias. Y ahora se da un pasito más ¿Cuál es el valor que se asociaría al punto anterior bajo un 2-nn? En este caso hay que buscar el 2º punto más cercano que resulta ser el punto azul más a la izquierda cuyo índice en X_train_norm es 165, cuyo valor de target, si se mira en y_train (en el índice 165) es igual a 27.5, por lo que la predicción a asociar en este caso en el índice 25 de y_test debe ser la media 11.9 y 27.5 que resulta ser igual a 19.7 tal y como se observa:

Llegados a este punto sabemos cómo actúa un knn y cómo asocia sus valores en el caso de una variable target de tipo continuo, pero se ha comentado que hay una limitación y es cuando el dataset es muy grande, pero ¿Y cuando tal limitación no existe? ¿Funciona bien para casos como el aquí tratado?

Bueno, en el código hacía una comparación usando esas mismas variables para una regresión lineal y probando con varias opciones para k, en dicho test obtuve los siguientes resultados cuando se había aplicado una estandarización de variables:

Mientras que, sin estandarizar variables, los resultados habían sido los siguientes:

Por lo que en definitiva cabe concluir las siguientes líneas generales:


-Los knn pueden dar lugar a problemas cuando se trata de modelizar datos masivos debido a que el cálculo de distancias es un proceso intensivo en cálculo, además adolecen del problema del curse of dimensionality (que no se ha tratado), con lo que son efectivos si hay pocas variables explicativas que rellenen suficientemente el espacio


-Como regla general, un preprocesado de variables es recomendable en estos modelos para que funcionen correctamente, observándose efectos muy negativos cuando las escalas de las variables son dispares


-Con pocos datos, estos modelo pueden mejorar a las regresiones lineales, pero debe hacerse comprobación con varios órdenes k, no hay regla general de elección de dicho parámetro y se recomienda en aplicaciones reales, si es que no hay mucho datos, hacer uso de cross-validaciones (que no se ha tratado aquí)

Uno de los modelos que se engloba dentro de esta vorágine del Machine Learning son las denominadas Redes Bayesianas.

En mi opinión, son unos modelos aún muy desconocidos por la empresa y la verdad es que posiblemente sea porque se desconoce el potencial real que pueden llegar a tener.


Un ejemplo de red bayesiana realizada con python a través de la librería pybbn, sería el siguiente ejemplo (donde interviene notablemente la librería networkx para el diseño del grafo):



La red invención mía, y por tanto mejorable, quiere poner foco en cómo se interrelacionan algunas variables con el pago o no de un crédito hipotecario. En este caso se hacen los siguientes supuestos como:


  • La edad (elevada a partir de 50 años), influye en el nivel de ahorro y en la posibilidad de tener o encontrar trabajo

  • El hecho de tener trabajo influye en que se tenga un nivel de ahorro y de que se tenga o no dificultades económicas

  • La marcha positiva o no de la economía influye en que sea fácil tener o encontrar trabajo y también en la marcha del sector de inmobiliario

  • Finalmente el pago o no del crédito dependerá de si se tiene o no dificultades económicas y si la garantía (el bien bajo hipoteca) está bajo un mercado líquido porque el sector inmobiliario marche bien o no


La posibilidad de plantear supuestos, como se puede imaginar el lector, es prácticamente infinita y es básicamente el punto de partida de toda red bayesiana, es decir, aquí un grupo de expertos de negocio se reúne y dibuja, incluso en un papel si es necesario un grafo como el anterior.


Una vez hecho lo anterior llega el momento de darle vida, para ello hay que plantear una serie de suposiciones que pueden venir de los datos o no y justamente esto es lo grande de este tipo de modelos, la posibilidad de introducir de modo sencillo suposiciones de ocurrencia de los hechos. Así pues, en los nodos superiores se parte de probabilidades, donde el nivel de clientes de edad elevada puede ser la proporción de clientes de la entidad y en el caso de la situación de la economía, puede ser la visión que tenga de ésta el servicio de estudios, por tanto, supóngase que se tienen las siguientes tablas:


En este caso se estaría diciendo que de la población de solicitantes, la proporción de clientes con edad elevada es del 60% y que la probabilidad de que la economía tenga un año positivo es también del 60%.


Si se investiga el código, se observa fácilmente cómo este se puede manipular y poner cualquier dato en lugar correspondiente:



Ahora cabe hacer supuestos con algo más de elaboración. El nodo trabajo depende tal y como se observa en grafo anterior, de edad y economía, en este caso hay que hacer 4 supuestos (o derivarlos de los datos), como pueden ser los de la siguiente tabla:


En este caso se indica cuál es la probabilidad de que encontrar o tener trabajo sea positiva dado que, en el primer caso se tenga una edad elevada y la economía tenga una marcha positiva, siendo dicha estimación del 30%. Dicha estimación bajaría al 10% si bajo el mismo supuesto de edad, se tiene que la economía marcha de modo negativo. La anterior tabla se introduciría en python del siguiente modo sencillo:



Pues bien haciendo todo una serie de supuestos podemos introducir una estructura completa como la siguiente:


Cuya codificación en python al completo la tenéis en:



Como se puede observar, a diferencia de los árboles de decisión, aquí no se está optimizando una función para maximizar la separación de datos más o menos, aquí se implementan unos supuestos y por debajo, claro está, se aplica el Teorema de Bayes y se hace un supuesto de interrelación markoviano, de modo, que por interrelaciones, que podemos denominar, matemáticamente sencillas, podemos hacernos distintos tipos de pregunta como la que se hacen en los siguientes business cases:


BC 0: La primera pregunta sería ¿Cómo es la situación de morosidad para un desconocido que “entre por la puerta” sin mayor información sobre esta persona?

BC 1: Supóngase que las previsiones de evolución positiva de la economía son robustas y cabe esperar una evolución positiva de ésta¿Cómo afectaría lo anterior a ese supuesto cliente? evidence('ev1', 'economia', 'P', 1)

BC 2: Además de lo anterior se sabe que es una persona joven con trabajo ¿Cómo afectaría a su posible pago-impago? evidence('ev2’, 'edad', 'N', 1) evidence('ev3', 'trabajo', 'S', 1)



BC 3: Si además se tiene evidencia que el mercado de la vivienda va a evolucionar positivamente (con lo que por Markov, el tema de la economía daría igual), se tendría que la probabilidad de pago aumentaría hasta: evidence('ev4', 'vivienda', 'P', 1)

Nótese que en este último caso no se tiene seguridad de que el cliente tenga o no un colchón de ahorro, con lo que aún la duda de impago es elevada en torno a un 10%, con lo que se necesitaría tener más información al respecto o marcar un tipo de interés elevado de modo directo (o indirecto con algún tipo de comisiones)


BC 4: Sin embargo lo interesante en las redes bayesianas no es lo anterior, lo interesante es poder conocer por ejemplo elementos causales, así por ejemplo cabe preguntarse que si por ejemplo un cliente a impagado (o un grupo de éstos) ¿Cómo alteraría las previsiones a priori sobre el estado del sector de la vivienda? Se sabe también que dicho cliente tenía ahorros en el momento bajo análisis y que su edad era elevada, pero no se sabe si tiene o no ahorros en ese momento y además no se tiene evidencia sobre la situación actual de la economía evidence('ev1', 'paga', 'N', 1) evidence('ev2', 'edad', 'S', 1) evidence('ev3', 'ahorro', 'S', 1)


Momento inicial, sector vivienda:

Momento final:

En este caso se observa que debería re-actualizarse las impresiones sobre el estado de situación de la situación del mercado de la vivienda, es muy probable que el impago haya sido causado justamente por la crisis donde posiblemente se encuentre la economía (un análisis somero de la situación implicaría que lo anterior se confirmaría o habría razones para incluir nuevos elementos a explicar el impago)


En fin, sin ánimo de meterme en interpretar este ejemplo de juguete, simplemente animar al planteamiento de los problemas de negocio desde esta perspectiva, rica porque se puede introducir supuestos tanto subjetivos, como fundamentados en datos y observaciones, pudiendo crear funciones que actualicen de modo automático o manual los valores de las probabilidades totales y condicionadas de las tablas de la red. Lo complicado claro de estos modelos es que si una variable depende de muchas, el problema de decisión crece exponencialmente, por tanto son buenos cuando hay que crear un mapa conceptual sencillo y se complica, si no se es capaz de extraer lo esencial.

© 2021 by Francisco J. Rodríguez Aragón. Proudly created with Wix.com

bottom of page