Creando una Red Neuronal en Python, con tensorflow.

Saludos y bienvenidos una semana más a vuestro blog sobre programación en lenguaje Python. En el día de hoy vamos a hablar de las Redes Neuronales, las cuales, constituyen una de las herramientas más importantes del aprendizaje automático moderno. Estas se inspiran en el funcionamiento básico del cerebro humano y permiten a los programas aprender patrones a partir de datos, en lugar de seguir reglas programadas de forma explícita. Aunque a menudo se asocian con problemas complejos como reconocimiento de imágenes o lenguaje natural, es posible construir una red neuronal útil y comprensible para resolver problemas reales relativamente simples.

El funcionamiento de estas redes es relativamente simple: Una red neuronal está formada por unidades llamadas neuronas artificiales. Cada una de las cuales recibe valores de entrada, los combina mediante unos coeficientes llamados pesos añadiendo un término adicional conocido como sesgo. El resultado de esa operación se transforma mediante una función matemática que introduce no linealidad, permitiendo que la red aprenda relaciones complejas. A su vez, durante el entrenamiento, estos pesos y sesgos se ajustan automáticamente para reducir el error entre la predicción de la red y el valor real esperado.

A continuación, abordaremos la implementación de una (muy) sencilla Red neuronal en Python mediante la que intentaremos aproximar una función matemática no lineal de una sola variable. El objetivo no es sustituir el cálculo exacto, sino entender cómo una red neuronal aprende patrones, cómo se evalúa su precisión y cómo se comparan los resultados obtenidos con los valores correctos. La función es la siguiente:

Así, a partir de un conjunto limitado de ejemplos, nuestro modelo deberá aprender la forma general de la función y ser capaz de realizar predicciones razonables para valores intermedios que no ha visto durante el entrenamiento. Finalmente, compararemos los valores reales con los valores predichos para evaluar el error de dicho modelo. Pero antes de todo ello, lo primero será importar las librerías a utilizar tensorflow y numpy. Lo haremos todo en Google Collab, por lo que no necesitaremos realizar ninguna instalación adicional.

Una vez hechas las importaciones pertinentes, procederemos a definir el conjunto de datos de entrada:

Aquí x contendrá una sola característica por muestra: el valor de la variable x. Por su parte, el vector y contendrá el valor exacto de la función para cada entrada (cada valor de x). Nos aseguraremos de que ambos arrays tengan el mismo número de muestras, condición imprescindible para entrenar el modelo.

Tras ello, pasaremos a definir la estructura de nuestra red neuronal. La cual construiremos utilizando el modelo secuencial de Keras, que permite definir capas de forma ordenada:

En este caso, la red constará de una única capa densa con una sola neurona. Aquí hemos de decir que aunque esta arquitectura es extremadamente simple, resulta suficiente para ilustrar el proceso de aprendizaje. Su mecánica será también, bastante simple: La neurona recibirá un valor de entrada para producir una salida escalar, ajustando sus pesos durante el entrenamiento. Hecho esto, pasaremos a compilar el modelo para definir el modo en que nuestro modelo va a aprender:

Aquí, el optimizador Adam se encarga de ajustar los pesos del modelo durante el entrenamiento. En este ejemplo se utiliza una tasa de aprendizaje relativamente alta para acelerar la convergencia. La función de pérdida elegida es el error cuadrático medio, adecuada para problemas de regresión numérica. Hecho todo esto, podemos pasar al fin al entrenamiento del modelo:

Aquí, a través de los 1000 epochs (iteraciones del modelo), la red neuronal va ajustando sus parámetros internos para minimizar el error entre los valores predichos y los valores reales. Por su parte, el parámetro verbose=0 evita mostrar información detallada del proceso, manteniendo la salida limpia.

Y con ello, ya tendríamos nuestro modelo, listo para efectuar predicciones con nuevos datos. En este punto, vamos a comparar los valores predichos por la red neuronal con los valores reales de la función que intentamos aprender, para evaluar qué tan bien el modelo aproxima la relación matemática:

Para ello, calculamos primero los valores exactos con la función real_function() para un conjunto de entradas de prueba x_test que no se usaron en el entrenamiento. Luego, obtendremos las predicciones del modelo con model.predict y calcularemos el error como la diferencia entre ambos, mostrando todo en una tabla alineada para visualizar claramente la precisión de la red.

OUTPUT:

Como puede verse, los resultados muestran que la red neuronal consigue aproximar razonablemente la función dentro del rango de valores estudiados, aunque no reproduce exactamente la ecuación matemática. Esto es esperable, ya que el modelo no conoce la fórmula, sino que aprende únicamente a partir de ejemplos.

A su vez podemos mostrar la forma en la que nuestro modelo ha ido aprendiendo durante el entrenamiento usando una gráfica de perdida:

Se genera así un gráfico donde el eje horizontal representa los epochs del entrenamiento y el eje vertical muestra el valor de la función de pérdida (error cuadrático medio). La curva permite observar cómo disminuye el error a medida que la red ajusta sus pesos, error que disminuye de manera muy pronunciada durante las primeras 150 iteraciones, para luego quedar casi estancado.

CONCLUSION:

Este ejemplo demuestra de manera clara cómo una red neuronal sencilla puede aprender a aproximar una función matemática a partir de datos de entrenamiento. La comparación entre valores reales y predichos permite evaluar la precisión del modelo, mientras que la gráfica de pérdida muestra cómo el error disminuye a lo largo de los epochs, evidenciando el proceso de aprendizaje. Aunque la arquitectura es mínima, el ejercicio ilustra conceptos clave del aprendizaje automático: definición de datos, entrenamiento, predicción, evaluación y visualización del rendimiento, sentando una base sólida para trabajar con problemas más complejos y funciones desconocidas.

Saludos.

Extracción de Colores de Imágenes en Python.

La extracción de colores de una imagen es una técnica fundamental en el procesamiento digital que permite identificar, cuantificar y analizar los tonos predominantes en una fotografía o en cualquier recurso gráfico. En un mundo cada vez más orientado al análisis visual —desde el diseño hasta la visión por computadora— comprender la paleta cromática de una imagen se ha vuelto una herramienta indispensable para múltiples disciplinas. Así, en nuestro artículo de esta semana, nos proponemos a realizar la extracción de los colores principales de la siguiente imagen:

En esta ocasión haremos uso de google colab, para nuestra practica, donde, como es natural, comenzaremos realizando las importaciones pertinentes:

Como se ve, realizamos la importación de varias librerías y recursos: ‘from PIL import Image‘ (Para cargar la imagen), ‘import numpy as np‘ (para manipular arrays y hacer reshape), ‘import matplotlib.pyplot as plt‘ (para mostrar la imagen y paleta resultante) y ‘from sklearn.cluster import KMeans‘ (que nos permitirá emplear el algoritmo K-Means de scikit-learn, para agrupa píxeles por similitud de color).

A continuación, pasaremos a abrir la imagen con image.open() y la convertimos inmediatamente a un array con np.array():

El resultado es un array de forma (ancho, alto, canales) (normalmente (w, h, 3) para RGB. Usar Pillow y convert(RGB) es recomendable si hay posibilidad de canal alfa; en ese caso conviene forzar Image.open(file_name).convert(«RGB») para garantizar 3 canales.

Tras ello, pasaremos a convertir nuestra imagen en una matriz de 2 dimensiones en donde cada fila es un pixel y cada columna viene representada por los canales (R. G . B.). De este modo, teniendo nuestra imagen 501 x 501 pixeles y 3 canales, el formato que pasaremos al algoritmo KMeans, será (251001, 3) que es el formato que espera para realizar la agrupación por colores.

El paso siguiente será el de seleccionar el número de colores dominantes que queremos extraer. Número que almacenaremos en la variable n_colors y que en nuestro caso será 15:

Por fin, en este paso se crea y entrena el modelo K-Means que identificará los colores dominantes de la imagen. Instanciando, primero, el algoritmo con KMeans(n_clusters=n_colors, random_state=42), donde n_clusters es el número de colores que queremos extraer (definidos antes) y random_state garantiza resultados reproducibles. Finalmente, con .fit(pixels), el modelo agrupa todos los píxeles de la imagen en clusters según la similitud de sus valores RGB; cada iteración ajusta los centroides para minimizar la distancia entre los píxeles y el centro del grupo al que pertenecen. Al finalizar, el modelo queda entrenado y listo para proporcionar los colores representativos de la imagen:

Una vez entrenado el modelo, K-Means almacena en kmeans.cluster_centers_ los centroides de cada grupo, que representan los colores dominantes encontrados en la imagen. Estos valores se obtienen como arreglos de tipo float, por lo que primero se convierten a enteros de 0 a 255 mediante np.uint8, generando así colores válidos en formato RGB. El resultado es un arreglo llamado palette, donde cada fila es un color característico detectado por el algoritmo. Esta paleta condensada es una representación compacta de los tonos predominantes de la imagen original y servirá para su visualización o para cualquier aplicación posterior, como diseño gráfico, clasificación o análisis cromático:

Obtenida nuestra paleta de colores principales, simplemente nos restará representarla con nuestra librería matplotlib, mediante el procedimiento habitual:

ORDENANDO COLORES POR IMPORTANCIA.

Como hemos dicho, tras todo el proceso hemos obtenido los 15 colores más representativos de nuestra imagen. No obstante, tal y como está presentado el resultado, quizás no nos diga gran cosa, al no estar estos ordenados ni contar con el porcentaje que cada uno representa en el conjunto. Por ello, vamos a añadir algunas líneas justo después de la definición de la paleta extraída (variable palette):

Aquí, partiendo del resultado antes obtenido por K-Means, cada píxel de la imagen recibe una etiqueta numérica que indica a qué cluster (o color) pertenece. Etiqueta, la cual, se almacena una a una en kmeans.labels_. Para saber qué colores aparecen más en la imagen, primero contamos cuántas veces aparece cada etiqueta usando np.unique(labels, return_counts=True), lo que devuelve los identificadores de los clusters y cuántos píxeles corresponden a cada uno. Luego, para convertir esas cantidades absolutas en proporciones, dividimos cada conteo entre el número total de píxeles (len(labels)) y lo multiplicamos por 100 para obtener el porcentaje que representa cada color sobre el total.

Una vez obtenidas las proporciones, podemos ordenar los colores según su presencia en la imagen. Para ello usamos np.argsort(-frequencies), que devuelve los índices que ordenarían el array de frecuencias de mayor a menor; el signo negativo se usa para invertir el orden, ya que argsort normalmente ordena de menor a mayor:

Así, al aplicar estos índices tanto al array de colores (palette) como al array de frecuencias, generamos una paleta reordenada (palette_sorted) donde el primer color es el más predominante y el último el menos frecuente. Esta ordenación es especialmente útil para representar la paleta de manera más intuitiva, ya que los colores principales aparecen primero.

Ahora ya lo único que deberemos hacer es volver a la parte del código que usamos para mostrar la paleta. Solo que usando en esta ocasión, la variable palette_sorted para la representación:

Finalmente, si lo deseamos, podemos mostrar el porcentaje de cada color (esta vez redondeado a dos decimales con .2f) valiéndonos de un ciclo for que recorra la paleta y frecuencias ordenadas:

Así, lo que esta salida nos está diciendo es que el 23,13% de los pixeles de la imagen tienen un color que vendría determinado por los valores RGB, 12 para el canal rojo, 4 para el verde y 11 para el azul y así con el resto de la salida.

CONCLUSIÓN:

En conjunto, calcular y ordenar las frecuencias de color permite obtener una paleta no solo representativa, sino también informativa sobre la estructura cromática de una imagen. Este proceso facilita identificar los tonos predominantes y comprender mejor la composición visual, lo que resulta especialmente útil en tareas de diseño, análisis estético, clasificación de imágenes y generación de estilos visuales coherentes.

Saludos.

Detección de Esquinas en Python, con OpenCV y numpy.

La detección de esquinas es una de las técnicas fundamentales en visión por computadora, ya que permite identificar puntos de interés en una imagen que se mantienen estables frente a cambios de iluminación, rotación o escala. Estos puntos son especialmente útiles en tareas como el reconocimiento de patrones, la reconstrucción 3D o la calibración de cámaras. En Python, gracias a la librería OpenCV, podemos implementar de manera sencilla y eficiente el algoritmo de Harris (cornerHarris), uno de los métodos clásicos y más influyentes en la detección de esquinas. En este artículo exploraremos cómo funciona este algoritmo, cómo aplicarlo en imágenes con OpenCV y qué parámetros ajustar para obtener los mejores resultados en distintos escenarios.

Pero entes de empezar, deberemos asegurarnos de tener instalados en nuestro sistema, los recursos y librerías necesarios. Que en este caso serán las librerías OpenCV y numpy:

Una vez que tengamos ambas librerías listas para usar en nuestro equipo, crearemos un nuevo script de Python en el que empezaremos importando ambas:

Hecho esto, ya podemos pasar a cargar la imagen cuyas esquinas queremos detectar. Para ello utilizaremos el método imread(), pasándole el nombre del archivo a leer. Tras lo cual, usaremos imshow() para que se muestre en pantalla nuestra imagen original:

OUTPUT:

Una practica habitual a la hora de realizar operaciones sobre imágenes es la de reducir las dimensiones de sus datos, pasando estas a escala de grises, para agilizar los cálculos a realizar. Eso mismo es lo que haremos a continuación empleando el método cvtColor() almacenando esta nueva versión en la variable gray que, como antes, mostraremos en pantalla con imshow():

OUTPUT:

Tal y como hemos expresado mas arriba, para la detección, vamos a hacer uso del algoritmo de Harris Corner, el cual, para los cálculos de gradientes, necesita que la imagen de entrada esté en un formato numérico de punto flotante. Es por ello que el siguiente paso será utilizar numpy para realizar dicha conversión:

Ahora ya estamos en condiciones de aplicar el referido algoritmo sobre nuestra imagen. Para esta operación usaremos el método de OpenCV, cornerHarris() el cual tomará los siguientes argumentos: 1. La imagen en escala de grises convertida a formato numérico en coma flotante, 2. El tamaño del vecindario considerado para el cálculo de las derivadas, 3. El tamaño del bloque utilizado en la detección y 4. El parámetro libre de Harris que influye en la sensibilidad de la detección de esquinas:

Esto almacenará en la variable dst, una matriz que indica la respuesta del algoritmo en cada punto de la imagen, de modo que donde haya valores más altos, mayores probabilidades habrá de que se correspondan con una esquina en la imagen:

Tras ello pasaremos a dilatar la imagen, expandiendo los valores máximos locales, para resaltar mejor las esquinas detectadas. Con ello, buscamos que las esquinas aparezcan más visibles y definidas en la imagen resultante:

Como último paso en el proceso de detección, estableceremos un umbral para establecer que puntos de la imagen pueden considerarse esquinas:

Aquí estamos utilizando dst.max() para obtener el valor máximo de la respuesta de Harris, de modo que al ser multiplicado por 0.27 se fijará un limite, de modo que los puntos que lo superen serán considerados esquinas que serán marcadas en rojo usando los valores rgb [0,0,255].

Una vez establecidos los puntos que serán considerados esquinas, ya solo restará mostrarlos en pantalla utilizando las mismas funciones que más arriba empleamos para mostrar la imagen en original y escala de grises:

OUTPUT:

Obtenemos así una imagen en la que la mayoría de las esquinas han sido detectadas por nuestro algoritmo. A su vez, podemos intentar mejorar el resultado probando con valores distintos al que hemos multiplicado por dst.max(), de modo que cuanto más bajo sea este más puntos serán detectados (y también más posibilidades habrá de establecer como esquina, puntos que no lo sean).

Para más información al respecto, no duden en consultar la información oficial de OpenCV:

https://docs.opencv.org/4.x/dc/d0d/tutorial_py_features_harris.html

Saludos.

VISUALIZACIÓN DE SEÑALES DE AUDIO EN PYTHON CON ‘Matplotlib’ Y ‘librosa’.

Destacado

El procesamiento digital de señales de audio es un campo emocionante que abarca una amplia gama de aplicaciones, desde la música y el entretenimiento hasta la comunicación y la ingeniería de audio. Con Python y algunas bibliotecas especializadas, como ‘NumPy‘ y ‘librosa‘, podemos realizar una variedad de tareas de procesamiento de señales de audio de manera efectiva. En este artículo, expondremos algunos ejemplos de cómo podemos utilizar Python para trabajar con señales de audio y realizar tareas como carga, visualización y análisis de dichas señales, ayudándonos de las librerías ‘Matplotlib‘ (de la que ya hemos hablado en repetidas ocasiones) y ‘librosa‘. La cual deberemos instalar previamente en nuestro sistema:

CARGA Y VISUALIZACIÓN DE SEÑALES DE AUDIO:

El primer paso para trabajar con señales de audio en Python es cargarlas desde archivos de audio. Con la biblioteca ‘librosa‘, podemos cargar fácilmente archivos de audio en matrices ‘NumPy‘ para su manipulación posterior. Veamos un ejemplo:

Este código carga un archivo de audio llamado «guitar2.wav» y visualiza su forma de onda utilizando la librería ‘Matplotlib‘. La forma de onda muestra la amplitud de la señal de audio en función del tiempo, lo que nos permite visualizar la señal de audio en dicho dominio.

OUTPUT:

ANALISIS DE LA SEÑAL DE AUDIO:

Una vez que hemos cargado una señal de audio, podemos realizar una variedad de análisis para extraer información útil de dicha señal. Por ejemplo, podemos calcular y visualizar su correspondiente espectrograma, lo cual, nos mostrará el modo en que varía la energía de la señal en diferentes frecuencias a lo largo del tiempo:

Este código calcula el espectrograma de la señal de audio y lo visualiza utilizando nuevamente ‘Matplotlib‘. Aquí, el espectrograma muestra la energía de la señal en diferentes frecuencias a lo largo del tiempo, lo que nos permite identificar características importantes en la señal, como tonos y patrones de sonido.

OUTPUT:

A la representación anterior, podemos, también, añadir las líneas de beat que indican la ubicación de los beats o pulsos rítmicos en la señal de audio. Aquí, los marcadores de beat se mostrarán como líneas verticales discontinuas en la forma de onda de la señal de audio:

OUTPUT:

Un tipo especial de espectrograma que también podemos obtener es el conocido como Espectrograma de Mel, el cual también muestra la variación de energía de una señal de audio en el tiempo y en diferentes bandas de frecuencia, pero con una representación más adaptada a la percepción auditiva humana:

OUTPUT:

Otra representación que puede ser de gran utilidad para el análisis de la señal es el cromagrama, el cual puede proporcionar información valiosa sobre la estructura armónica y rítmica de la señal de audio:

OUTPUT:

CONCLUSIÓN:

Python proporciona una amplia variedad de herramientas y bibliotecas para trabajar con señales de audio de manera efectiva. En este artículo, exploramos cómo podemos cargar, visualizar y analizar señales de audio utilizando Python y librerías como ‘librosa‘ y ‘Matplotlib‘. Al comprender estas técnicas, podemos realizar una amplia gama de tareas de procesamiento de señales de audio y explorar nuevos enfoques para trabajar con datos de audio en nuestros proyectos.

Saludos.

USANDO ‘TRADINGVIEW’ EN PYTHON PARA ANALISIS TECNICO FINANCIERO.

Destacado

La obtención de información financiera mediante el uso de diversos recursos en Python ha venido siendo una constante en la vida de este blog. En el día de hoy vamos a añadir un nuevo nuevo recurso a nuestra lista, con ‘tradingview‘. Una librería que nos permitirá realizar de un modo rápido y sencillo nuestros propios análisis técnicos en Python mediante el acceso a un gran elenco de indicadores técnicos, tal y como tendremos ocasión de comprobar. Pero antes de empezar deberemos proceder a la instalación de esta librería en nuestro sistema:

Una vez instalada, podremos empezar a explorar la información que nos ofrece esta librería, para un ‘ticker‘ determinado. Para ello, crearemos un objeto ‘TA_Handler()‘ al que podremos pasar una serie de parámetros, siendo los principales el ‘symbol‘ (con el que se especifica el activo financiero que se pretense analizar), el ‘screener‘ (la región geográfica de la bolsa de valores donde se busca el símbolo), ‘exchange‘ (la bolsa de valores en la que cotiza el activo) e ‘interval‘ (el intervalo se tiempo que va usarse para el análisis técnico que puede ser 1 minuto, 5 minutos o 1 hora):

A partir de aquí, podremos utilizar ‘get_analysis().indicators‘ para acceder a un amplio de indicadores técnicos calculados para el activo e intervalo antes definidos:

Para mostrar los datos de un modo más claro, podemos utilizar un ciclo que itere sobre el diccionario devuelto por la función:

Obtendremos así una lista de resultados de una amplia gama de indicadores tales como los precios máximo, mínimo y de cierre, las medias móviles, el índice de fuerza relativa (RSI)..etc.

Otra de las características más interesantes que ofrece esta librería son las recomendaciones de compra o venta de acciones para dicho activo que podemos obtener con ‘get_analysis().summary‘:

Obtenemos en este caso una fuerte recomendación de venta, apoyada en el hecho de que 17 de los indicadores calculados la avalan, ninguno de ellos avalan la operación de compra y 9 no obtienen valores significativos para decantarse por ninguna de las opciones.

CONCLUSION:

En el artículo de hoy hemos visto brevemente en que consiste la librería ‘tradingview‘, una herramienta con la que podréis acceder a una amplia gama de indicadores técnicos y otras métricas para evaluar el rendimiento y la volatilidad de los activos en diferentes bolsas de valores de todo el mundo. Además, proporciona una interfaz sencilla y flexible para personalizar la obtención de datos según las necesidades específicas del usuario, lo que la convierte en una herramienta versátil para aquellos que buscan automatizar y mejorar sus estrategias de inversión y trading.

Saludos.

TRABAJANDO CON ARCHIVOS EXCEL CON PYTHON Y ‘openpyxl’.

Destacado

Saludos y bienvenidos una semana más a vuestro blog sobre programación en lenguaje Python: En el día de hoy os presentamos ‘openpyxl‘. Una librería para Python que nos permitirá trabajar con archivos excel (‘xlsx‘) de un modo cómodo y sencillo que instalaremos en nuestro equipo usando el comando ‘pip’:

Una vez instalada, lo primero que haremos será crear nuestro primer libro mediante la selección de la hoja activa:

Estas líneas generarán un nuevo archivo excel, en el directorio en el que estemos trabajando, con el nombre que hayamos pasado como argumento de la función ‘save()‘. En nuestro caso ‘mi_libro.xlsx‘):

Ahora que tenemos creado nuestro primer archivo excel, podemos empezar a introducir alguna información en el. En este punto podemos empezar introduciendo datos en sus celdas, lo cual, podemos hacer de dos maneras: O bien introduciendo directamente la referencia a la celda en cuestión, o bien indicando numéricamente su posición por fila y columna:

A su vez, mientras estemos trabajando con nuestro excel, siempre tendremos la posibilidad de acceder desde nuestro código a la información ya introducida: Para esto podremos utilizar las dos modalidades de referencia a las celdas que vimos a la hora de escribir:

Otra interesante posibilidad es la de poder aplicar un formato determinado a una celda. Cosa que haremos con ‘.font‘ antes de guardar los cambios realizados:

Una vez que hayamos guardado los cambios (con la función ‘save()‘ ya vista) podremos comprobar como en nuestro archivo excel, se encuentra la información que hemos ido introduciendo:

Pero continuemos trabajando sobre nuestro archivo. Para ello deberemos acceder a el nuevamente usando el método ‘load_workbook()‘ para a continuación agregar una formula a la celda ‘C1‘:

A su vez, podemos proceder a la creación de una nueva hoja para nuestro documento excel (mediante la función ‘create_sheet()’) y utilizar un bucle ‘for‘ para copiar los datos de nuestra primera hoja a la nueva para finalmente guardar los cambios antes de poder abrirlo para ver su contenido:

CONCLUSION:

En conclusión, la biblioteca ‘openpyxl‘ de Python emerge como una herramienta esencial para manipular hojas de cálculo Excel de manera eficiente y programática. Su interfaz amigable y su amplia gama de funciones permiten a los desarrolladores trabajar con documentos Excel de una manera intuitiva, desde la creación de libros y hojas hasta la modificación y formateo de celdas. La capacidad de leer y escribir en archivos Excel, así como la compatibilidad con características avanzadas, como gráficos y formatos condicionales, hacen que ‘openpyxl‘ sea una elección de gran utilidad para aquellos que buscan automatizar tareas relacionadas con hojas de cálculo en Python. Además, la comunidad activa y el continuo desarrollo respaldan su fiabilidad y versatilidad, consolidando ‘openpyxl‘ como una herramienta valiosa para profesionales y entusiastas que desean incorporar la manipulación de Excel en sus proyectos.

Saludos.

ALGORITMOS DE ORDENACIÓN EN PYTHON: ORDENACIÓN POR ARBOL BINARIO DE BUSQUEDA.

Destacado

Continuamos hoy con nuestra serie de artículos acerca de los principales algoritmos existentes para la ordenación de elementos de una lista y su implementación usando el lenguaje Python. En la presente ocasión hablaremos de la ordenación por ‘Arbol Binario de Busqueda‘ (‘BST‘ por sus siglas en inglés), donde combinaremos la estructura de árbol binario con la propiedad de búsqueda de datos, ofreciendo un enfoque efectivo para organizar y recuperar información. Tras ello, mostraremos un sencillo ejemplo de implementación en Python.

QUE ES UN ARBOL BINARIO DE BUSQUEDA:

Un Árbol Binario de Búsqueda (‘BST‘ en adelante) es una estructura de datos jerárquica en la que cada nodo tiene, a lo sumo, dos nodos secundarios: Un nodo izquierdo, cuyo valor es menor y un nodo derecho, cuyo valor es superior al nodo principal. Siendo este principio de organización el que facilita la búsqueda y ordenación de datos de manera eficiente:

Para ordenar elementos en un árbol binario de búsqueda, se siguen reglas simples. Al insertar un nuevo elemento, se compara con el nodo actual. Si es menor, se inserta a la izquierda; si es mayor, a la derecha. Este proceso se repite recursivamente hasta encontrar un nodo sin hijo en la dirección adecuada, donde se inserta el nuevo elemento.

IMPLEMENTACIÓN EN PYTHON:

A continuación pasaremos a ver un sencillo ejemplo de implementación de este algoritmo, en Python, en la que empezaremos definiendo una clase (a la que llamaremos ‘Nodo‘), la cual, representará un nodo en nuestro ‘BST‘, en donde cada nodo tendrá un valor, así como referencias a sus respectivos nodos secundarios izquierdo (‘self.izquierdo‘) y derecho (‘self.derecho‘), que inicialmente no tendrán ninguno:

A continuación, definiremos la función ‘insertar()‘ que se encargará de insertar un nuevo nodo al árbol. De modo que si la variable ‘raiz‘ es ‘None‘, significará que estamos insertando el primer nodo, creándose un nuevo nodo con el valor proporcionado. Por su parte, si la raíz ya existe, se comparará el valor a insertar con el valor de la raíz. Así, dependiendo de si es menor o mayor, se llamará recursivamente a la función ‘insertar()‘ en el subárbol izquierdo o derecho, devolviéndose finalmente la raíz actualizada del árbol:

Por último, definiremos la función ‘inorden()‘, la cual, realiza un recorrido por los elementos del árbol. Recorriendo primero el subárbol izquierdo, luego la raíz y finalmente el subárbol derecho. En este caso, se utiliza para imprimir los elementos del árbol en orden ascendente:

Una vez definida la clase y sendas funciones, definiremos la lista de elementos a ordenar, la cual iremos recorriendo, utilizando la función ‘insertar()‘ para ir incluyéndolos en el árbol, para, finalmente, proceder a su ordenación mediante el la función ‘inorden()‘:

OUTPUT:

CONCLUSIÓNES:

Las ventajas de utilizar un árbol binario de búsqueda (‘BST‘) radican en su eficiencia y simplicidad conceptual. Permite la rápida búsqueda y ordenación de elementos, con operaciones como inserción y eliminación. Además, la estructura jerárquica facilita la comprensión y manipulación de datos ordenados. Además, se puede adaptar para aplicaciones específicas, como árboles ‘AVL‘ o árboles ‘rojo-negro‘, para mantener un equilibrio y mejorar aún más la eficiencia.

No obstante, existen desventajas importantes. La eficiencia está sujeta a la estructura del árbol, y si este degenera en una lista enlazada, las operaciones pueden volverse lineales, perdiendo la ventaja logarítmica. Además, la complejidad en la gestión de memoria y la necesidad de mantener la propiedad de búsqueda pueden complicar la implementación. Además, en comparación con otras estructuras de datos, como las tablas hash, la búsqueda puede volverse menos eficiente en ciertos casos.

En resumen, aunque los árboles binarios de búsqueda ofrecen una solución eficaz para ciertos escenarios, su rendimiento óptimo depende de la gestión de su estructura y su implementación precisa.

Saludos.

DETECCIÓN DE TEXTO EN IMAGENES EN PYTHON, CON ‘EasyOCR’.

Destacado

El Reconocimiento óptico de caracteres (‘ROC‘ u ‘OCR‘ por sus siglas en inglés), consiste en la extracción y detección de texto en imágenes. Se trata una tarea común en el campo de la visión por computadora que es ampliamente utilizada en aplicaciones tales como la captura y digitalización de documentos, traducción, detección de fraudes o reconocimiento de información en imágenes medicas. Así, esta semana vamos a aprender a extraer texto de una imagen, utilizando ‘EasyOCR‘ una librería en Python que nos permitirá realizar dicha tarea de una forma rápida y sencilla. Librería que deberemos instalar previamente en nuestro sistema, mediante el comando ‘pip install easyocr‘.

USO BASICO:

Una vez explicado el objetivo de nuestra practica, pasaremos a la extracción de texto de archivos de imagen. En esta ocasión usaremos el entorno de ‘Google Colab‘ en el que empezaremos realizando la instalación de ‘EasyOCR‘:

Tras ello pasaremos a importar la librería en cuestión, para a continuación, crear el objeto ‘reader‘ especificando el idioma (inglés en este caso) del texto que vamos a extraer:

Empezaremos extrayendo texto, en distintos tamaños, de una imagen en blanco y negro:

image.png

Para la lectura del texto en la imagen, usaremos aquí, la función «readtext()» pasando como argumento la ruta al archivo que contiene el texto que queremos obtener:

Esta función nos devolverá tres informaciones de cada línea de texto detectada: Las coordenadas de la imagen en las que se encuentra el área de texto (concebida como caja), el texto detectado y e nivel de confianza entendida como la probabilidad de que el texto detectado por el algoritmo ‘OCR‘ sea correcto. A su vez, podemos usar un bucle para acceder a estas tres informaciones de modo aislado:

Como se ve, el texto detectado en las líneas coincide con el presente en la imagen, lo que resulta coherente con los valores de probabilidad obtenidos.

A su vez, podemos usar «matplotlib» para mostrar el texto detectado en una etiqueta, para cada línea detectada en la imagen:

También podemos utilizar la información almacenada en la variable ‘bbox‘, para dibujar un recuadro que enmarque el área de la imagen ocupada por el texto:

Lo que hemos hecho sobre una imagen en blanco y negro, podremos hacerlo igualmente sobre una imagen a color como esta a la que hemos dado el nombre de «color_image.png«:

color_image.png

CONCLUSIÓN:

EasyOCR es una herramienta poderosa y fácil de usar para detectar texto en imágenes. Su capacidad para manejar múltiples idiomas, su precisión y su facilidad de integración lo hacen útil para una variedad de aplicaciones, desde la automatización de tareas hasta el procesamiento de documentos. En este artículo hemos visto, de un modo básico, como podemos usarle para extraer la información inherente al texto presente un un archivo de imagen y el modo en que podemos usar dicha información para mostrar gráficamente dicho texto en la imagen.

Saludos.

APLICANDO LA ‘TRANSFORMADA DE FOURIER’ EN PYTHON, CON ‘numpy’.

Destacado

La ‘Transformada de Fourier‘ (cuyo nombre proviene del matemático y físico francés Joseph Fourier) es un método matemático que descompone una señal en sus componentes de frecuencia. En otras palabras, toma una señal en el dominio del tiempo y la convierte en su representación en el dominio de la frecuencia. Esto es útil para analizar las frecuencias presentes en una señal, como ondas sonoras y señales eléctricas, entre otras.

Joseph Fourier (1768-1830)

En las siguientes líneas vamos a ver un sencillo ejemplo de aplicación de esta técnica sobre una serie de tiempo que definiremos nosotros.

Antes de continuar, deberemos asegurarnos de tener instaladas las librerías que vamos a necesitar: ‘numpy‘ para la aplicación de la transformada y ‘matplotlib‘ para las representaciones gráficas:

Una ves instaladas las librerías que vayamos a emplear, crearemos un archivo de nombre ‘fourier.py‘ en el que tras hacer las importaciones pertinentes, empezaremos definiendo la serie de tiempo sobre la que vamos a aplicar la transformada. Serie de tiempo que crearemos con ‘np.arange()‘ y que irá de 0 a 10, incrementándose 0.01 cada vez:

Lo que hará nuestro script es mostrar simultáneamente la gráfica de la señal original y la resultante, tras aplicarle la transformada. Por ello utilizaremos a continuación ‘matplotlib‘ para mostrar dicha señal en una ventana destinada también a mostrar la gráfica resultado:

Una vez definida la señal original y su representación gráfica, es el momento de aplicarle la ‘Transformada de Fourier‘ con ‘numpy‘. Para lo cual, usaremos la función ‘fft()‘ del módulo ‘np.fft‘ a la que pasaremos nuestra señal original, definiendo las frecuencias con la función ‘fftfreq()‘ con un intervalo de muestreo de 0.01:

Tras ello, volveremos a emplear las funciones de ‘matplotlib‘ para generar la gráfica de la serie transformada, la cual mostraremos junto a la original:

Así, con todo, nuestro sencillo script quedaría de la siguiente manera:

OUTPUT:

En este ejercicio nos hemos limitado a utilizar la función ‘fft()‘ para calcular la ‘Transformada de Fourier’ discreta de una secuencia unidimensional. Sin embargo, hemos de tener en cuenta que el módulo ‘np.fft‘ de ‘numpy‘ ofrece una gran variedad de funciones para trabajar con la ‘Transformada de Fourier’. A continuación os mostramos algunas de las más comunes:

1-‘np.fft.fft()‘: Calcula la Transformada de Fourier discreta de una secuencia unidimensional.

2-‘np.fft.ifft()’: Calcula las Transformada Inversa de Fourier discreta de una secuencia unidimensional.

3-‘np.fft.fft2()’: Calcula la Transformada de Fourier bidimensional de una matriz.

4-‘np.fft.ifft2()’: Calcula la Transformada Inversa de Fourier bidimensional de una matriz.

5-‘np.fft.fftfreq()’: Genera las frecuencias correspondientes a las salidas de ‘fft‘.

6-‘np.fft.shift()’: Cambia el dominio de frecuencia de salida para centrarlo alrededor de cero.

7-‘np.fft.ishift()’: Deshacer el cambio generados por la función ‘shift()‘.

8-‘np.fft.rfft()’: Calcula la Transformada de Fourier discreta de valores reales.

9-‘np.fft.irfft()’: Calcula la Transformada Inversa de Fourier discreta para valores reales.

Estos métodos son ampliamente utilizados para realizar cálculos de transformadas de Fourier en diferentes dimensiones y tipos de datos, desde datos unidimensionales hasta matrices bidimensionales y valores reales. Permiten realizar análisis frecuencial, filtrado de señales, entre otros procesamientos fundamentales en el procesamiento de señales y el análisis de datos.

Saludos.

OPTIMIZACION DE FUNCIONES CON PYTHON Y ‘SciPy’: EXPLORANDO EL METODO ‘SLSQP’ PARA MINIMIZACIÓN DE UNA FUNCION

Destacado

La minimización de funciones es un proceso matemático que busca encontrar el valor mínimo de una función, es decir, el punto donde la función alcanza su valor más bajo. Este valor mínimo puede representar un punto crítico, como un máximo o mínimo local, o el mínimo absoluto de la función en un intervalo determinado. Esta se usa para un amplio abanico de problemas como puede ser el ajuste de modelos, procesamiento de señales y optimización de funciones en finanzas.

Para ello, contamos en Python con ‘SciPy‘. Una herramienta poderosa que ofrece diversas técnicas para encontrar mínimos y máximos de funciones. En este artículo, usaremos el método ‘Sequential Least Squares Programming‘ (SLSQP) para encontrar el mínimo de una función cuadrática (concretamente de la expresión «Y=(x−1.5)**2«), usando dicha librería, que deberemos tener instalada en nuestro sistema:

Para ello, crearemos un nuevo archivo Python con el nombre «optimize_example.py» que constará de dos funciones:

La primera de ellas es la que hemos llamado «f()«. Esta se encarga de calcular el valor de «Y» en función de «x» según la expresión antes referida, utilizando la fórmula cuadrática. El propósito principal de esta función es representar una función objetivo para el método de optimización. Esta función irá mostrando los valores de «Y» y «x» cada vez que vaya siendo llamada, permitiéndonos rastrear el modo en que van cambiando estos durante el proceso de optimización.

La otra función que utiliza nuestro código es la que hemos llamado «test_run()«:

Esta es la función principal, que se encarga de ejecutar el código de prueba llevándose a cabo la optimización de la función «f()» empleando para ello, el método «spo.minimize()» de la librería «scipy» usando el referido método «SLSQP» y partiendo de un valor inicial para «x» (que será el que tome «f()«) definido en la variable «Xguess«. La ejecución del script nos devolverá una serie de datos (valor mínimo encontrado, el número de iteraciones, evaluación de funciones y gradientes…) entre los que se destaca los valores mínimos de «x» e «Y» (siendo estos 1.5 y 0.5 respectivamente).

OUTPUT:

A su vez, podemos usar la librería «matplotlib» (que deberemos tener también instalada) para representar graficamente dicho punto dentro de la función. Quedando nuestro script de la siguiente manera:

OUTPUT:

Representación grafica del valor mínimo de ‘x’ e ‘Y’.

CONCLUSION:

El método «SLSQP» de «SciPy» es una herramienta de gran utilidad para encontrar mínimos de funciones, especialmente en problemas no lineales. Este ejemplo ilustra cómo utilizar este método para optimizar una función cuadrática y visualizar el resultado. En resumen, «SciPy» proporciona una amplia gama de métodos de optimización que pueden ser aplicados a diferentes problemas, ofreciendo soluciones eficientes y precisas.

Saludos.