#Artificial Intelligence (AI)

0 Seguidores · 81 Publicaciones

La Inteligencia Artificial (IA) es la simulación de los procesos de la inteligencia humana por parte de las máquinas, especialmente de los sistemas computacionales. Estos procesos incluyen el aprendizaje (la adquisición de información y las normas para utilizarla), el razonamiento (el uso de normas para llegar a conclusiones aproximadas o definitivas) y la autocorrección.

Obtener más información.

Artículo Luis Angel Pérez Ramos · mar 27, 2024 6m read

Como habréis visto en las últimas publicaciones de la comunidad, InterSystems IRIS ha incluido desde la versión 2024.1 la posibilidad de incluir tipos de datos vectoriales en su base de datos y basado en este tipo de datos se ha implementado las búsquedas vectoriales. Pues bien, estas nuevas funcionalidades me han recordado el artículo que publiqué hace un tiempo que se basaba en reconocimiento facial mediante Embedded Python.

Introducción

0
0 175
Artículo Maria Nesterenko · mar 15, 2024 8m read

La Inteligencia Artificial (IA) está recibiendo mucha atención últimamente porque puede cambiar muchos aspectos de nuestras vidas. Una mayor potencia informática y más datos han ayudado a la IA a hacer cosas asombrosas, como mejorar las pruebas médicas y fabricar coches que se conducen solos. La IA también puede ayudar a las empresas a tomar mejores decisiones y a trabajar de forma más eficiente, por lo que cada vez es más popular y se utiliza más. ¿Cómo se pueden integrar las llamadas a la API OpenAI en una aplicación de interoperabilidad IRIS existente?

 

0
0 261
Artículo Alberto Fuentes · ene 31, 2024 13m read

Tenemos un conjunto de datos bastante apetecible con recetas escritas por múltiples usuarios de Reddit, sin embargo, la mayor parte de la información está en texto libre en forma de título y descripción de un mensaje. Vamos a averiguar cómo podemos, de forma muy sencilla, cargar los datos, extraer algunas características y analizarlos empleando funcionalidades de LLM (Large Language Model) de OpenAI desde Python Embebido y el framework Langchain.

Cargar los datos

Lo primero es lo primero: ¿necesitamos cargar los datos o podemos sencillamente conectarnos a ellos?

Hay diferentes formas para plantearlo: por ejemplo, con el Mapeo de registros CSV que puedes utilizar en una producción de interoperabilidad o incluso instalar directamente una aplicación de OpenExchange como csvgen para que nos ayude.

Utilizaremos en este caso las Foreign Tables. Una funcionalidad muy útil para proyectar datos físicamente almacenados en otra parte y tenerlos accesibles desde el SQL de IRIS. Podemos utilizarlo directamente para echar un primer vistazo a los ficheros del conjunto de datos.

Creamos un Foreign Server:

CREATE FOREIGN SERVER dataset FOREIGN DATA WRAPPER CSV HOST '/app/data/'

Y a continuación, creamos una Foreign Table que se conecta al fichero CSV:

CREATE FOREIGN TABLE dataset.Recipes (
  CREATEDDATE DATE,
  NUMCOMMENTS INTEGER,
  TITLE VARCHAR,
  USERNAME VARCHAR,
  COMMENT VARCHAR,
  NUMCHAR INTEGER
) SERVER dataset FILE 'Recipes.csv' USING
{
  "from": {
    "file": {
       "skip": 1
    }
  }
}

¡Y ya está!, inmediatamente podemos lanzar consultas SQL sobre dataset.Recipes: image

## ¿Qué datos necesitamos? Los datos son muy interesantes y tenemos hambre. Sin embargo, si queremos decidir qué receta vamos a cocinar necesitamos algo más de información que podamos utilizar para analizar las recetas.

Vamos a trabajar con dos clases persistentes (tablas):

  • yummy.data.Recipe: una clase que contiene el título y la descripción de la receta así como algunas otras propiedades que queremos extraer y analizar (por ejemplo: Score, Difficulty, Ingredients, CuisineType, PreparationTime).
  • yummy.data.RecipeHistory: una clase sencilla para anotar un registro de qué estamos haciendo con la receta.

Podemos ahora cargar en nuestras tablas yummy.data* el contenido del conjunto de datos de recetas:

do ##class(yummy.Utils).LoadDataset()

Hasta aquí tiene buena pinta, pero aún debemos averiguar cómo vamos a generar los datos para los campos como: Score, Difficulty, Ingredients, PreparationTime and CuisineType.

## Analizar las recetas Queremos procesar el título y la descripción de cada receta y:

  • Extraer información como Difficulty, Ingredients, CuisineType, etc.
  • Construir nuestra propia puntuación de la receta basada en nuestro criterio, de forma que podamos decidir qué vamos a cocinar.

Vamos a utilizar lo siguiente:

  • yummy.analysis.Analysis - una estructura genérica de análisis que vamos a re-utilizar en caso de que queramos implementar diferentes tipos de análisis.
  • yummy.analysis.SimpleOpenAI - un análisis que usa Python Embebido + framework Langchain + OpenAI LLM.

Los LLM (Large Language Models) son una herramienta realmente increíble para procesar lenguaje natural.

LangChain está preparado para trabajar con Python, así que podemos utilizarlo directamente en InterSystems IRIS a través de Embedded Python.

La clase SimpleOpenAI tiene esta pinta:

/// Simple OpenAI analysis for recipes
Class yummy.analysis.SimpleOpenAI Extends Analysis
{

Property CuisineType As %String;

Property PreparationTime As %Integer;

Property Difficulty As %String;

Property Ingredients As %String;

/// Run
/// You can try this from a terminal:
/// set a = ##class(yummy.analysis.SimpleOpenAI).%New(##class(yummy.data.Recipe).%OpenId(8))
/// do a.Run()
/// zwrite a
Method Run()
{
    try {
        do ..RunPythonAnalysis()

        set reasons = ""

        // mis estilos de cocina favoritos
        if "spanish,french,portuguese,italian,korean,japanese"[..CuisineType {
            set ..Score = ..Score + 2
            set reasons = reasons_$lb("It seems to be a "_..CuisineType_" recipe!")
        }

        // no quiero estar el día entero cocinando :)
        if (+..PreparationTime < 120) {
            set ..Score = ..Score + 1
            set reasons = reasons_$lb("You don't need too much time to prepare it") 
        }
        
        // bonus para mis ingredientes favoritos!
        set favIngredients = $listbuild("kimchi", "truffle", "squid")
        for i=1:1:$listlength(favIngredients) {
            set favIngred = $listget(favIngredients, i)
            if ..Ingredients[favIngred {
                set ..Score = ..Score + 1
                set reasons = reasons_$lb("Favourite ingredient found: "_favIngred)
            }
        }

        set ..Reason = $listtostring(reasons, ". ")

    } catch ex {
        throw ex
    }
}

/// Update recipe with analysis results
Method UpdateRecipe()
{
    try {
        // call parent class implementation first
        do ##super()

        // add specific OpenAI analysis results
        set ..Recipe.Ingredients = ..Ingredients
        set ..Recipe.PreparationTime = ..PreparationTime
        set ..Recipe.Difficulty = ..Difficulty
        set ..Recipe.CuisineType = ..CuisineType

    } catch ex {
        throw ex
    }
}

/// Run analysis using embedded Python + Langchain
/// do ##class(yummy.analysis.SimpleOpenAI).%New(##class(yummy.data.Recipe).%OpenId(8)).RunPythonAnalysis(1)
Method RunPythonAnalysis(debug As %Boolean = 0) [ Language = python ]
{
    # load OpenAI APIKEY from env
    import os
    from dotenv import load_dotenv, find_dotenv
    _ = load_dotenv('/app/.env')

    # account for deprecation of LLM model
    import datetime
    current_date = datetime.datetime.now().date()
    # date after which the model should be set to "gpt-3.5-turbo"
    target_date = datetime.date(2024, 6, 12)
    # set the model depending on the current date
    if current_date > target_date:
        llm_model = "gpt-3.5-turbo"
    else:
        llm_model = "gpt-3.5-turbo-0301"

    from langchain.chat_models import ChatOpenAI
    from langchain.prompts import ChatPromptTemplate
    from langchain.chains import LLMChain

    from langchain.output_parsers import ResponseSchema
    from langchain.output_parsers import StructuredOutputParser

    # init llm model
    llm = ChatOpenAI(temperature=0.0, model=llm_model)

    # prepare the responses we need
    cuisine_type_schema = ResponseSchema(
        name="cuisine_type",
        description="What is the cuisine type for the recipe? \
                     Answer in 1 word max in lowercase"
    )
    preparation_time_schema = ResponseSchema(
        name="preparation_time",
        description="How much time in minutes do I need to prepare the recipe?\
                     Anwer with an integer number, or null if unknown",
        type="integer",
    )
    difficulty_schema = ResponseSchema(
        name="difficulty",
        description="How difficult is this recipe?\
                     Answer with one of these values: easy, normal, hard, very-hard"
    )
    ingredients_schema = ResponseSchema(
        name="ingredients",
        description="Give me a comma separated list of ingredients in lowercase or empty if unknown"
    )
    response_schemas = [cuisine_type_schema, preparation_time_schema, difficulty_schema, ingredients_schema]

    # get format instructions from responses
    output_parser = StructuredOutputParser.from_response_schemas(response_schemas)
    format_instructions = output_parser.get_format_instructions()
    
    analysis_template = """\
    Interprete and evaluate a recipe which title is: {title}
    and the description is: {description}
    
    {format_instructions}
    """
    prompt = ChatPromptTemplate.from_template(template=analysis_template)

    messages = prompt.format_messages(title=self.Recipe.Title, description=self.Recipe.Description, format_instructions=format_instructions)
    response = llm(messages)

    if debug:
        print("======ACTUAL PROMPT")
        print(messages[0].content)
        print("======RESPONSE")
        print(response.content)

    # populate analysis with results
    output_dict = output_parser.parse(response.content)
    self.CuisineType = output_dict['cuisine_type']
    self.Difficulty = output_dict['difficulty']
    self.Ingredients = output_dict['ingredients']
    if type(output_dict['preparation_time']) == int:
        self.PreparationTime = output_dict['preparation_time']

    return 1
}

}

El método RunPythonAnalysis es donde sucede todo lo relativo a OpenAI :). Puedes probarlo directamente desde tu terminal utilizando una receta en particular:

do ##class(yummy.analysis.SimpleOpenAI).%New(##class(yummy.data.Recipe).%OpenId(12)).RunPythonAnalysis(1)

Obtendremos un resultado como el siguiente:

USER>do ##class(yummy.analysis.SimpleOpenAI).%New(##class(yummy.data.Recipe).%OpenId(12)).RunPythonAnalysis(1)
======ACTUAL PROMPT
                    Interprete and evaluate a recipe which title is: Folded Sushi - Alaska Roll
                    and the description is: Craving for some sushi but don't have a sushi roller? Try this easy version instead. It's super easy yet equally delicious!
[Video Recipe](https://www.youtube.com/watch?v=1LJPS1lOHSM)
# Ingredients
Serving Size:  \~5 sandwiches      
* 1 cup of sushi rice
* 3/4 cups + 2 1/2 tbsp of water
* A small piece of konbu (kelp)
* 2 tbsp of rice vinegar
* 1 tbsp of sugar
* 1 tsp of salt
* 2 avocado
* 6 imitation crab sticks
* 2 tbsp of Japanese mayo
* 1/2 lb of salmon  
# Recipe     
* Place 1 cup of sushi rice into a mixing bowl and wash the rice at least 2 times or until the water becomes clear. Then transfer the rice into the rice cooker and add a small piece of kelp along with 3/4 cups plus 2 1/2 tbsp of water. Cook according to your rice cookers instruction.
* Combine 2 tbsp rice vinegar, 1 tbsp sugar, and 1 tsp salt in a medium bowl. Mix until everything is well combined.
* After the rice is cooked, remove the kelp and immediately scoop all the rice into the medium bowl with the vinegar and mix it well using the rice spatula. Make sure to use the cut motion to mix the rice to avoid mashing them. After thats done, cover it with a kitchen towel and let it cool down to room temperature.
* Cut the top of 1 avocado, then slice into the center of the avocado and rotate it along your knife. Then take each half of the avocado and twist. Afterward, take the side with the pit and carefully chop into the pit and twist to remove it. Then, using your hand, remove the peel. Repeat these steps with the other avocado. Dont forget to clean up your work station to give yourself more space. Then, place each half of the avocado facing down and thinly slice them. Once theyre sliced, slowly spread them out. Once thats done, set it aside.
* Remove the wrapper from each crab stick. Then, using your hand, peel the crab sticks vertically to get strings of crab sticks. Once all the crab sticks are peeled, rotate them sideways and chop them into small pieces, then place them in a bowl along with 2 tbsp of Japanese mayo and mix until everything is well mixed.
* Place a sharp knife at an angle and thinly slice against the grain. The thickness of the cut depends on your preference. Just make sure that all the pieces are similar in thickness.
* Grab a piece of seaweed wrap. Using a kitchen scissor, start cutting at the halfway point of seaweed wrap and cut until youre a little bit past the center of the piece. Rotate the piece vertically and start building. Dip your hand in some water to help with the sushi rice. Take a handful of sushi rice and spread it around the upper left hand quadrant of the seaweed wrap. Then carefully place a couple slices of salmon on the top right quadrant. Then place a couple slices of avocado on the bottom right quadrant. And finish it off with a couple of tsp of crab salad on the bottom left quadrant. Then, fold the top right quadrant into the bottom right quadrant, then continue by folding it into the bottom left quadrant. Well finish off the folding by folding the top left quadrant onto the rest of the sandwich. Afterward, place a piece of plastic wrap on top, cut it half, add a couple pieces of ginger and wasabi, and there you have it.
                    
                    The output should be a markdown code snippet formatted in the following schema, including the leading and trailing "```json" and "```":
json
{
        "cuisine_type": string  // What is the cuisine type for the recipe?                                  Answer in 1 word max in lowercase
        "preparation_time": integer  // How much time in minutes do I need to prepare the recipe?                                    Anwer with an integer number, or null if unknown
        "difficulty": string  // How difficult is this recipe?                               Answer with one of these values: easy, normal, hard, very-hard
        "ingredients": string  // Give me a comma separated list of ingredients in lowercase or empty if unknown
}

                    
======RESPONSE
json
{
        "cuisine_type": "japanese",
        "preparation_time": 30,
        "difficulty": "easy",
        "ingredients": "sushi rice, water, konbu, rice vinegar, sugar, salt, avocado, imitation crab sticks, japanese mayo, salmon"
}

Tiene muy buena pinta. Parece que nuestro prompt o pregunta a OpenAI es capaz de devolvernos información que realmente podemos utilizar. Vamos a ejecutar el análisis completo desde el terminal:

set a = ##class(yummy.analysis.SimpleOpenAI).%New(##class(yummy.data.Recipe).%OpenId(12))
do a.Run()
zwrite a
USER>zwrite a
a=37@yummy.analysis.SimpleOpenAI  ; <OREF>
+----------------- general information ---------------
|      oref value: 37
|      class name: yummy.analysis.SimpleOpenAI
| reference count: 2
+----------------- attribute values ------------------
|        CuisineType = "japanese"
|         Difficulty = "easy"
|        Ingredients = "sushi rice, water, konbu, rice vinegar, sugar, salt, avocado, imitation crab sticks, japanese mayo, salmon"
|    PreparationTime = 30
|             Reason = "It seems to be a japanese recipe!. You don't need too much time to prepare it"
|              Score = 3
+----------------- swizzled references ---------------
|           i%Recipe = ""
|           r%Recipe = "30@yummy.data.Recipe"
+-----------------------------------------------------

## Analizar todas las recetas Naturalmente, querremos ejecutar el análisis para todas las recetas que hemos cargado.

Puedes analizar un rango de recetas (utilizando sus identificadores), de esta forma:

USER>do ##class(yummy.Utils).AnalyzeRange(1,10)
> Recipe 1 (1.755185s)
> Recipe 2 (2.559526s)
> Recipe 3 (1.556895s)
> Recipe 4 (1.720246s)
> Recipe 5 (1.689123s)
> Recipe 6 (2.404745s)
> Recipe 7 (1.538208s)
> Recipe 8 (1.33001s)
> Recipe 9 (1.49972s)
> Recipe 10 (1.425612s)

Después de eso, vamos a echar un vistazo de nuevo a la tabla de recetas y comprobemos los resultados:

select * from yummy_data.Recipe

image

Creo que podría intentar la Pizza con calabaza o el Tofu con Kimchi y cerdo al estilo coreano :). De todas formas, debo asegurarme y preguntar en casa antes de empezar a cocinar :)

Conclusión

Puedes encontrar el ejemplo completo en https://github.com/isc-afuentes/recipe-inspector

Con este ejemplo sencillo hemos aprendido cómo utilizar técnicas LLM para extraer características y analizar ciertas partes de nuestros datos en InterSystems IRIS.

Con esto como punto de partida, podrías plantearte cosas como:

  • Utilizar InterSystems BI para explorar y navegar tus datos utilizando cubos y cuadros de mando.
  • Crear una aplicación web y añadir una interfaz gráfica (e.g. con Angular) para esta aplicación, podrías utilizar paquetes como RESTForms2 para generar automáticamente APIs REST para tus clases persistentes.
  • ¿Qué tal si almacenas si una receta te gusta o no, y después intentas determinar si una nueva receta te gustará? Podrías plantearlo con IntegratedML, o incluso con LLM pasándole algunos datos de ejemplo e implementando un caso de uso tipo RAG (Retrieval Augmented Generation).

¿Qué otras cosas se os ocurren?

0
0 190
Artículo Kurro Lopez · ene 19, 2024 2m read

Actualmente, muchos artistas digitales utilizan la tecnología de IA generativa como soporte para acelerar la entrega de sus trabajos. Hoy en día es posible generar una imagen correspondiente a partir de una frase de texto. Existen varias soluciones en el mercado para esto, incluidas algunas disponibles para ser utilizadas a través de API. Mira algunos en este enlace: https://www.analyticsvidhya.com/blog/2023/08/ai-image-generators/.

0
0 106
Artículo Alberto Fuentes · ene 15, 2024 5m read

La invención y popularización de LLMs (Large Language Models) como GPT-4 de OpenAI ha desencadenado una ola de soluciones innovadoras que permiten aprovechar grandes volúmenes de datos no estructurados, que eran prácticamente imposibles de procesar manualmente hasta hace poco. Estas aplicaciones pueden incluir la recuperación de datos (echad un vistazo al curso sobre ML301 de Don Woodlock, con una excelente introducción a la Generación Aumentada de Recuperación), el análisis de sentimientos, e incluso agentes de IA totalmente autónomos, por nombrar sólo algunos ejemplos!

En este artículo, quiero demostrar cómo la funcionalidad de Python Embebido de IRIS puede ser utilizada para interactuar directamente con la librería Python de OpenAI, a través de la creación de una sencilla aplicación de etiquetado de datos que asignará automáticamente palabras clave a los registros que metamos en una tabla de IRIS. Estas palabras clave pueden después ser usadas para buscar y categorizar los datos, así como para analítica de datos. Utilizaré reseñas de productos realizadas por clientes como ejemplo de caso de uso.

0
0 127
Artículo Kurro Lopez · dic 8, 2023 9m read

 

La inteligencia artificial no se limita solo a generar imágenes a través de texto con instrucciones o crear narrativas con instrucciones sencillas.

También puedes hacer variaciones de una imagen o incluir un fondo especial a una ya existente.

Adicionalmente, podrás obtener la transcripción del audio sin importar su idioma y la velocidad del hablante.

Por tanto, analicemos cómo funciona la gestión de archivos.

0
0 194
Artículo Alberto Fuentes · nov 16, 2023 7m read

Ejemplo de demostración para el Gran Premio de Programación de InterSystems, sobre el uso de plantillas más complejas para probar funcionalidades de IA.

Preguntas para la entrevista

Hay documentación. Para un puesto de trabajo, una persona de recursos humanos quiere evaluar rápidamente a los candidatos con varias preguntas técnicas relevantes para el puesto.

¿Puede automatizar el trabajo haciendo una lista de preguntas y respuestas a partir de la documentación disponible?

0
0 142
Artículo Ricardo Paiva · nov 9, 2023 3m read

El problema

En un entorno clínico acelerado, en el que la toma rápida de decisiones es crucial, la falta de sistemas eficientes de almacenamiento y acceso a los documentos plantea varios obstáculos. Aunque existen soluciones de almacenamiento de documentos (por ejemplo, FHIR), el acceso y la búsqueda eficaz de datos específicos de pacientes dentro de esos documentos puede suponer todo un reto.

La motivación

La IA ha hecho que la búsqueda de documentos sea extraordinariamente potente. Preguntar y responder sobre documentos nunca ha sido tan fácil con herramientas de código abierto como Chroma y Langchain para almacenar y utilizar incrustación de palabras (vector embeddings) para consultas a las APIs de IA generativa. Con un esfuerzo más dedicado, las organizaciones están indexando sus documentos existentes y construyendo versiones ajustadas de GPT con fines empresariales. La charla de Andrej Karpathy sobre el estado de GPT ofrece un excelente resumen general sobre este tema.

Este proyecto fue nuestro intento de reducir la fricción en todos los puntos de contacto en los que el personal médico tiene que interactuar con documentos. Desde la entrada y la gestión hasta el almacenamiento y la recuperación, hemos aprovechado IRIS FHIR y la IA para ayudarles a almacenar y encontrar la información que necesitan sin esfuerzo.

La solución

Hemos creado una aplicación web full-stack que permite a los médicos grabar notas de voz. A continuación, estas notas pueden transcribirse y resumirse mediante Open AI y almacenarse en servidores FHIR. Después, los documentos almacenados se indexan y están disponibles para la búsqueda semántica.  

Video de demostración

<iframe width="560" height="315" src="https://www.youtube.com/embed/3Th6bR4rw0w?si=Fc2dCaYuUte0ZCQ7" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen></iframe>

Características principales

  1. Aplicación web - Para ver información clínica sobre pacientes, observaciones y encuentros. Está construida utilizando Vue.js.
  2. Transcripción de voz - Open AI Whisper API se utiliza para transcribir con precisión las grabaciones de voz a texto.
  3. Resumen de texto - A continuación, el contenido transcrito puede resumirse y darle un título en el formato requerido. Por ejemplo, secciones específicas como síntomas, diagnóstico, etc. Esto se consigue mediante la API de completado de texto de Open AI utilizando el modelo text-da-vinci-003.
  4. Almacenamiento de documentos - A continuación, los documentos resumidos se almacenan en FHIR utilizando el recurso Document Reference.
  5. Búsqueda semántica de documentos - Los documentos almacenados se indexan y almacenan en Chroma como fragmentos. Esto se utiliza después para limitar el espacio de búsqueda y utilizar los tokens GPT con moderación para la búsqueda semántica mediante Langchain. Actualmente, cargamos los documentos en el momento de la búsqueda debido al menor número de documentos disponibles. Esto puede modificarse para indexar en segundo plano de forma asíncrona.
  6. Exportación de documentos - Por último, existe una opción para exportar documentos a Google Docs y otros datos a Google Sheets. Los usuarios pueden iniciar sesión con sus cuentas específicas mediante OAuth y exportar los documentos para facilitar la colaboración y la comunicación con otros médicos o pacientes.

Probadlo

Clonad el repositorio del proyecto desde este enlace de GitHub: https://github.com/ikram-shah/iris-fhir-transcribe-summarize-export. Seguid las instrucciones proporcionadas para configurar el proyecto localmente en vuestros equipos. Y hacednos saber si algo no funciona como se esperaba.

Reflexiones y comentarios

Los avanzados modelos de lenguaje disponibles actualmente, combinados con el enorme volumen de datos disponibles, encierran un inmenso potencial para revolucionar la atención sanitaria, especialmente en lo relativo a los documentos.

Dejadnos vuestros comentarios a continuación. Publicaremos más artículos con los detalles técnicos de este proyecto.

0
0 116
Artículo Alberto Fuentes · jul 19, 2023 3m read

Este artículo es un sencillo ejemplo para probar SqlDatabaseChain pidiéndole a OpenAI cierta información y que escriba consultas SQL sobre una base de datos IRIS.

Quizá despierte el interés de alguno de vosotros.

Muchas gracias a sqlalchemy-iris (autor @Dmitry Maslennikov). Ese proyecto ha sido indispensable para esta prueba. 

El script de este artículo usa la API de OpenAI así que tenedlo en cuenta para no compartir la información de vuestras tablas externamente en el caso de que no queráis hacerlo. Podría llegar a implementarse un modelo local en caso que lo necesitaseis.

1
0 489
Artículo Alberto Fuentes · oct 18, 2023 3m read

Hoy os traigo otro ejemplo de aplicación de LangChain.

Inicialmente buscaba generar una "chain" o cadena para lograr hacer búsquedas dinámicas en la documentación en HTML, pero al final resultó más sencillo utilizar la versión en PDF de la documentación .

Crear un nuevo entorno virtual

mkdir chainpdf

cd chainpdf

python -m venv .

scripts\activate 

pip install openai
pip install langchain
pip install wget
pip install lancedb
pip install tiktoken
pip install pypdf

set OPENAI_API_KEY=[ Your OpenAI Key ]

python

Preparar los documentos

0
0 323
Artículo Ricardo Paiva · ago 17, 2023 5m read

FHIR ha revolucionado la industria de la atención médica al proporcionar un modelo de datos estandarizado para crear aplicaciones y promocionar el intercambio de datos entre diferentes sistemas. El estándar FHIR se basa en enfoques modernos impulsados por APIs, lo que lo hace más accesible para los desarrolladores web y móviles. Sin embargo, interactuar con las API de FHIR aún puede ser un desafío, especialmente cuando se trata de consultar datos usando lenguaje natural.

0
0 196
Artículo Jose-Tomas Salvador · jun 29, 2023 2m read

¡Hola Comunidad!

Me gustaría compartir con vosotros un ejercicio que he hecho para crear "mi propio" chat con ChatGPT en Telegram.

Ha sido posible gracias a dos componentes de Open Exchange: Telegram Adapter, de @Nikolay Solovyev e IRIS Open-AI, de @Kurro Lopez 

Así que con este ejemplo podréis configurar vuestro propio chat con ChatGPT en Telegram. 

¡Veamos cómo hacerlo funcionar!

0
0 313
Artículo Kurro Lopez · jun 19, 2023 9m read

 

Como todos ya conocéis, el mundo de la inteligencia artificial ya está aquí y todos quieren usarlo para su beneficio.

Hay muchas plataformas que ofertan servicios de inteligencia artificial de forma gratuita, por suscripción o privadas, pero la que mas “ruido” ha hecho en el mundo de la informática es Open AI, sobre todo por sus más famosos servicios: ChatGPT y DALL-E

<--break->¿Qué es Open AI?

1
0 407
Comentarios Miqueias Santos · mayo 18, 2023

¡Hola, chicos!
Estoy buscando buenas personas para dar su opinión sobre mi artículo, solo acceda al enlace a continuación, traduzca del portugués brasileño a su idioma si es necesario y deje su opinión.

Enlace: https://pt.community.intersystems.com/post/veremos-seguir-como-o-intersystems-iris-aliado-com-machine-learning-pode-transformar-para

Deja tu comentario en el artículo, no aquí.

¡Gracias!

0
0 95
Anuncio Esther Sanchez · mar 30, 2023

¡Hola desarrolladores!

Nos gustaría invitaros a un nuevo concurso de programación, dedicado a crear soluciones de Inteligencia Artificial (IA)/Machine Learning (ML) que utilicen Cloud SQL para trabajar con los datos: 

🏆 Concurso de Programación: InterSystems IRIS Cloud SQL con IntegratedML🏆

Duración: del 3 al 23 de abril, 2023

Total en premios: $13,500

 

0
0 127
Artículo Henry Pereira · sep 26, 2021 8m read

https://media.giphy.com/media/Nxu57gIbNuYOQ/giphy.gif

Calma, calma, no estoy promoviendo una guerra contra las máquinas como en las películas de ciencia ficción, para evitar la dominación mundial de Ultron o Skynet. Todavía no, todavía no 🤔

Os invito a retar a las máquinas a través de la creación de un juego muy sencillo usando ObjectScript con Python embebido.

Tengo que deciros que me emocioné mucho con la función de Python integrado en InterSystems IRIS. Es increíble el montón de posibilidades que se abren para crear aplicaciones fantásticas.

Vamos a construir un juego "tres en raya". Las reglas son bastante sencillas y creo que todo el mundo sabe jugar.

Es lo que me salvó del tedio en mi infancia, durante los largos viajes en coche con la familia antes de que los niños tuvieran teléfonos móviles o tabletas. ¡Nada como retar a mis hermanos a jugar unas partidas en el cristal borroso!

Así que... ¡abrochaos el cinturón y vámonos!

Normas

Como he comentado, las reglas son bastante simples:

  • solo 2 jugadores por set
  • se juega por turnos en una cuadrícula de 3x3
  • el jugador humano siempre será la letra X y la computadora la letra O
  • los jugadores solo podrán poner las letras en los espacios vacíos
  • el primero en completar una secuencia de 3 letras iguales en horizontal, o en vertical o en diagonal, es el ganador
  • cuando se ocupen los 9 espacios, será un empate y el final de la partida

https://media4.giphy.com/media/3oriNKQe0D6uQVjcIM/giphy.gif?cid=790b761123702fb0ddd8e14b01746685cc0059bac0bc66e9&rid=giphy.gif&ct=g

Todo el mecanismo y las reglas lo escribiremos en ObjectScript, el mecanismo del jugador de la máquina se escribirá en Python.

Vamos a trabajar

Controlaremos el tablero en un global, en el que cada fila estará en un nodo y cada columna en una pieza.

Nuestro primer método es iniciar el tablero, para que sea fácil iniciaré el global ya con los nodos (filas A, B y C) y con las 3 piezas:

/// Iniciar un juego nuevo
ClassMethod NewGame() As %Status
{
  Set sc = $$$OK
  Kill ^TicTacToe
  Set ^TicTacToe("A") = "^^"
  Set ^TicTacToe("B") = "^^"
  Set ^TicTacToe("C") = "^^"
  Return sc
}

en este momento crearemos un método para añadir las letras en los espacios vacíos, para esto cada jugador dará la ubicación del espacio en el tablero.

Cada fila una letra y cada columna un número, para poner la X en el medio, por ejemplo, pasamos B2 y la letra X al método.

ClassMethod MakeMove(move As %String, player As %String) As %Boolean
{
  Set $Piece(^TicTacToe($Extract(move,1,1)),"^",$Extract(move,2,2)) = player
}

Vamos a comprobar si la coordinación es válida, la forma más simple que veo es usando una expresión regular:

ClassMethod CheckMoveIsValid(move As %String) As %Boolean
{
  Set regex = ##class(%Regex.Matcher).%New("(A|B|C){1}[0-9]{1}")
  Set regex.Text = $ZCONVERT(move,"U")
  Return regex.Locate()
}

Necesitamos garantizar que el espacio seleccionado está vacío.

ClassMethod IsSpaceFree(move As %String) As %Boolean
{
  Quit ($Piece(^TicTacToe($Extract(move,1,1)),"^",$Extract(move,2,2)) = "")
}

¡Muy bien!

Ahora comprobamos si algún jugador ganó el set o si el juego ya está terminado, para esto creemos el método CheckGameResult.

Primero verificamos si hubo algún ganador completando por la horizontal, usaremos una lista con las filas y un simple $ Find resuelve

    Set lines = $ListBuild("A","B","C")
    // Check Horizontal
    For i = 1:1:3 {
      Set line = ^TicTacToe($List(lines, i))
      If (($Find(line,"X^X^X")>0)||($Find(line,"O^O^O")>0)) {
        Return $Piece(^TicTacToe($List(lines, i)),"^", 1)_" won"
      }
    }

Con otro For comprobamos la vertical

For j = 1:1:3 {
      If (($Piece(^TicTacToe($List(lines, 1)),"^",j)'="") &&
        ($Piece(^TicTacToe($List(lines, 1)),"^",j)=$Piece(^TicTacToe($List(lines, 2)),"^",j)) &&
        ($Piece(^TicTacToe($List(lines, 2)),"^",j)=$Piece(^TicTacToe($List(lines, 3)),"^",j))) {
        Return $Piece(^TicTacToe($List(lines, 1)),"^",j)_" won"
      }
    }

para comprobar la diagonal:

    If (($Piece(^TicTacToe($List(lines, 2)),"^",2)'="") &&
      (
        (($Piece(^TicTacToe($List(lines, 1)),"^",1)=$Piece(^TicTacToe($List(lines, 2)),"^",2)) &&
          ($Piece(^TicTacToe($List(lines, 2)),"^",2)=$Piece(^TicTacToe($List(lines, 3)),"^",3)))||
        (($Piece(^TicTacToe($List(lines, 1)),"^",3)=$Piece(^TicTacToe($List(lines, 2)),"^",2)) &&
        ($Piece(^TicTacToe($List(lines, 2)),"^",2)=$Piece(^TicTacToe($List(lines, 3)),"^",1)))
      )) {
      Return ..WhoWon($Piece(^TicTacToe($List(lines, 2)),"^",2))
    }

por fin, comprobamos si hubo un empate

    Set gameStatus = ""
    For i = 1:1:3 {
      For j = 1:1:3 {
        Set:($Piece(^TicTacToe($List(lines, i)),"^",j)="") gameStatus = "Not Done"
      }
    }
    Set:(gameStatus = "") gameStatus = "Draw"

¡Genial!

Es hora de construir la máquina

Vamos a crear a nuestro oponente, necesitamos crear un algoritmo capaz de calcular todos los movimientos disponibles y usar una métrica para saber cuál es el mejor movimiento.

Lo ideal es utilizar un algoritmo de decisión llamado MiniMax (Wikipedia: MiniMax)

https://media3.giphy.com/media/WhTC5v5qQP4yAUvGKz/giphy.gif?cid=ecf05e47cx92yiew8vsig62tjq738xf7hfde0a2ygyfdl0xt&rid=giphy.gif&ct=g

El algoritmo MiniMax es una regla de decisión utilizada en teoría de juegos, teoría de decisiones e inteligencia artificial.

Básicamente, necesitamos saber cómo jugar asumiendo cuáles serán los posibles movimientos del oponente y coger el mejor escenario posible.

En detalle, tomamos la escena actual y comprobamos de forma recurrente el resultado del movimiento de cada jugador. En caso de que la máquina gane el juego, puntuamos con +1, en caso de que pierda, puntuamos con -1 y con 0 si empata.

Si no es el final del juego, abrimos otro árbol con el estado actual del juego. Después de eso, encontramos la jugada con el valor máximo para la máquina y el mínimo para el oponente.

Mira el siguiente gráfico - hay 3 movimientos disponibles: B2, C1 y C3.

Al elegir C1 o C3, el oponente tiene la oportunidad de ganar en el siguiente turno, pero si elige B2 no importa el movimiento que elija el oponente, la máquina gana la partida.

minimaxp

Es como tener la gema del tiempo en nuestras manos e intentar encontrar la mejor línea de tiempo.

https://pa1.narvii.com/7398/463c11d54d8203aac94cda3c906c40efccf5fd77r1-460-184_hq.gif

Convirtiendo a Python

ClassMethod ComputerMove() As %String [ Language = python ]
{
  import iris
  from math import inf as infinity
  computerLetter = "O"
  playerLetter = "X"

  def isBoardFull(board):
    for i in range(0, 8):
      if isSpaceFree(board, i):
        return False
    return True

  def makeMove(board, letter, move):
    board[move] = letter

  def isWinner(brd, let):
    # check horizontals
    if ((brd[0] == brd[1] == brd[2] == let) or \
      (brd[3] == brd[4] == brd[5] == let) or \
      (brd[6] == brd[7] == brd[8] == let)):
        return True
    # check verticals
    if ((brd[0] == brd[3] == brd[6] == let) or \
        (brd[1] == brd[4] == brd[7] == let) or \
        (brd[2] == brd[5] == brd[8] == let)):
        return True
    # check diagonals
    if ((brd[0] == brd[4] == brd[8] == let) or \
        (brd[2] == brd[4] == brd[6] == let)):
        return True
    return False

  def isSpaceFree(board, move):
    #Retorna true se o espaco solicitado esta livre no quadro
    if(board[move] == ''):
      return True
    else:
      return False

  def copyGameState(board):
    dupeBoard = []
    for i in board:
      dupeBoard.append(i)
    return dupeBoard

  def getBestMove(state, player):
    done = "Done" if isBoardFull(state) else ""
    if done == "Done" and isWinner(state, computerLetter): # If Computer won
      return 1
    elif done == "Done" and isWinner(state, playerLetter): # If Human won
      return -1
    elif done == "Done":    # Draw condition
      return 0

    # Minimax Algorithm
    moves = []
    empty_cells = []
    for i in range(0,9):
      if state[i] == '':
        empty_cells.append(i)

    for empty_cell in empty_cells:
      move = {}
      move['index'] = empty_cell
      new_state = copyGameState(state)
      makeMove(new_state, player, empty_cell)

      if player == computerLetter:
          result = getBestMove(new_state, playerLetter)
          move['score'] = result
      else:
          result = getBestMove(new_state, computerLetter)
          move['score'] = result

      moves.append(move)

    # Find best move
    best_move = None
    if player == computerLetter:
        best = -infinity
        for move in moves:
            if move['score'] > best:
                best = move['score']
                best_move = move['index']
    else:
        best = infinity
        for move in moves:
            if move['score'] < best:
                best = move['score']
                best_move = move['index']

    return best_move

  lines = ['A', 'B', 'C']
  game = []
  current_game_state = iris.gref("^TicTacToe")

  for line in lines:
    for cell in current_game_state[line].split("^"):
      game.append(cell)

  cellNumber = getBestMove(game, computerLetter)
  next_move = lines[int(cellNumber/3)]+ str(int(cellNumber%3)+1)
  return next_move
}

Primero, convierto el global en una matriz simple, ignorando columnas y filas, dejándolo plano para facilitar.

En cada movimiento analizado llamamos al método copyGameState que, como su nombre indica, copia el estado del juego en ese momento, donde aplicamos el MiniMax.

El método getBestMove que se llamará repetidamente hasta que finalice el juego encontrando un ganador o un empate.

Primero se mapean los espacios vacíos y verificamos el resultado de cada movimiento, cambiando entre los jugadores.

Los resultados se almacenan en move ['puntuación'] para, después de comprobar todas las posibilidades, encontrar el mejor movimiento.

¡Espero que os haya divertido! Es posible mejorar la inteligencia usando algoritmos como Alpha-Beta Pruning (Wikipedia: AlphaBeta Pruning) o redes neuronales. ¡Solo tened cuidado de no darle vida a Skynet!

https://media4.giphy.com/media/mBpthYTk5rfbZvdtIy/giphy.gif?cid=790b761181bf3c36d85a50b84ced8ac3c6c937987b7b0516&rid=giphy.gif&ct=g

No dudeis en dejar cualquier comentario o pregunta.

¡Esto es todo, amigos!

Código fuente completo: InterSystems Iris version 2021.1.0PYTHON

1
0 866
InterSystems Official Jose-Tomas Salvador · abr 13, 2022

Hola!! Hemos abierto una plaza de Sales Engineer en InterSystems para nuestra oficina de Madrid.

No se requieren conocimientos de nuestra tecnología aunque, por supuesto, tenerlos puede ser un gran plus. Lo más importante es que te apasione la tecnología, te guste compartir conocimiento, aprender de otros y enseñar,... y no te asusten los retos, para encontrar soluciones innovadoras junto con nuestros partners a las necesidades que se les plantean, en areas como rendimiento de BBDDs, interoperabilidad, desarrollo de aplicaciones críticas, IA,....

0
0 192
Artículo Pierre-Yves Duquesnoy · ene 5, 2022 1m read

Esta serie de artículos describe el uso del Python Gateway para InterSystems. Ejecuta el código de Python y mucho más desde InterSystems IRIS. Este proyecto te trae toda la potencia de Python directamente a tu entorno InterSystems IRIS:

  • Ejecuta cualquier código de Python
  • Transfiere datos de forma transparente desde InterSystems IRIS a Python
  • Crea procesos empresariales de interoperabilidad inteligentes, con el Adaptador de interoperabilidad de Python
  • Guarda, examina, modifica y restaura el contexto de Python desde InterSystems IRIS
# Otros artículos

El plan para la serie hasta el momento es el siguiente (sujeto a cambios):

  • Parte I: Resumen, entorno e introducción
  • Parte II: Instalación y resolución de problemas <-- estamos aquí
  • Parte III: Funcionalidades básicas
  • Parte IV: Adaptador de interoperabilidad
  • Parte V: Cómo ejecutar una función
  • Parte VI: Jupyter Notebook
  • Parte VII: Soporte a Jupyter

Instalación

Este artículo te ayudará a instalar el Python Gateway. Hay varias formas de instalarlo y utilizarlo:

  • Host
  • Windows
  • Linux
  • Mac
  • Docker
  • Extrae la imagen prediseñada
  • Crea tu propia imagen

Independientemente del método que utilices para la instalación, necesitarás el código. El único sitio donde se puede descargar es en la página de actualizaciones, que contiene versiones estables probadas. Coge siempre la más reciente. No clones/descargues el repositorio, descarga la última versión.

Host

Si instalas Python Gateway en el sistema operativo del host, primero (independientemente del sistema operativo) debes instalar Python.

  1. Instala Python 3.6.7 64 bits. Se recomienda instalar Python en la ubicación predeterminada.
  2. Instala el módulo dill: pip install dill.
  3. Carga el código ObjectScript (es decir, ejecutar $system.OBJ.ImportDir("C:\InterSystems\Repos\Python\isc\py\", "*.cls", "c",,1)) en el namespace Production (Ensemble-enabled). En caso de que quieras habilitar Production en la llamada del namespace: escribe ##class(%EnsembleMgr).EnableNamespace($Namespace, 1).
  4. Sitúa callout DLL/SO/DYLIB en la carpeta bin en la que está instalado InterSystems IRIS. El archivo de la librería se debe colocar en una ruta que devuelve write ##class(isc.py.Callout).GetLib().

Windows

  1. Revisa que tu variable de entorno PYTHONHOME señala a Python 3.6.7.
  2. Verifica que tu variable de entorno SYSTEM PATH incluye la variable PYTHONHOME (o el directorio al que señala).

Linux

  1. Comprueba que tu variable de entorno SYSTEM PATH incluye /usr/lib y /usr/lib/x86_64-linux-gnu, preferiblemente al principio. Utiliza el archivo /etc/environment para establecer las variables de entorno.
  2. En caso de error, consulta la sección Troubleshooting (Resolución de problemas) undefined symbol: _Py_TrueStruct y especifica la propiedad PythonLib.

Mac

  1. Por el momento, solo está soportada la versión python 3.6.7 de Python.org. Comprueba la variable PATH.

Si modificaste las variables de entorno, reinicia tu producto de InterSystems.

Docker

Hay muchas ventajas en utilizar contenedores:

  • Portabilidad
  • Eficiencia
  • Aislamiento
  • Diseño ligero
  • Inmutabilidad

Consulta esta serie de artículos para obtener más información sobre Docker.

Todas las creaciones de Docker para Python Gateway se basan en contenedores 2019.1.

Cómo extraer la imagen prediseñada

Ejecuta: docker run -d -p 52773:52773 --name irispy intersystemscommunity/irispy:latest para extraer y ejecutar Python Gateway sobre InterSystems IRIS Community Edition. Eso es todo.

Crea tu propia imagen

Para crear la imagen de Docker, ejecuta en el repositorio raíz: <code>docker build --force-rm --tag intersystemscommunity/irispy:latest .

De forma predeterminada, la imagen se crea a partir de la imagen intersystems/iris:2019.1.0.510.0-1. Sin embargo, se puede cambiar si se proporciona la variable <0>IMAGE.

Si quieres crearla desde InterSystems IRIS Community Edition, ejecuta: docker build --build-arg IMAGE=store/intersystems/iris:2019.1.0.510.0-community --force-rm --tag intersystemscommunity/irispy:latest.

Después, puedes ejecutar tu imagen de Docker:

docker run -d \
  -p 52773:52773 \
  -v /<HOST-DIR-WITH-iris.key>/:/mount \
  --name irispy \
  intersystemscommunity/irispy:latest \
  --key /mount/iris.key

Si estás ejecutando una imagen basada en InterSystems IRIS Community Edition, puedes omitir el proporcionar la clave.

Notas de Docker

Información sobre Docker:

  • El proceso de prueba isc.py.test.Process guarda la image artifact en el directorio temporal. Tal vez quieras cambiar esa ruta a un directorio que ya esté instalado. Para ello, edita la nota correspondiente a la llamada de la Correlation Matrix: Graph, donde se especifica una ruta de archivo válida para la función f.savefig.
  • Para acceder al terminal, ejecuta: docker exec -it irispy sh.
  • Accede al Multiprocesamiento simétrico (SMP) con el usuario/contraseña SuperUser/SYS o Admin/SYS.
  • Para detener el contenedor, ejecuta: docker stop irispy && docker rm --force irispy.

Cómo validar tu instalación

Después de que hayas instalado Python Gateway es hora de comprobar que funciona. Ejecuta este código:

set sc = ##class(isc.py.Callout).Setup() 
set sc = ##class(isc.py.Main).SimpleString("x='HELLO'", "x", , .var)
write var

La salida debería ser HELLO - valor de la variable x de Python. En caso de que el estado de respuesta/devolución sea un error o que var esté vacío, consulta la sección de resolución de problemas del archivo Readme.

Conclusión

La instalación de Python Gateway es rápida y sencilla. Si estás familiarizado con Docker, coge la última imagen. Si no, hay paquetes para los principales sistemas operativos de InterSystems IRIS: Windows, Linux y Mac. En el siguiente artículo comenzaremos a utilizar Python Gateway.

Guía ilustrada

También hay una guía de instalación ilustrada en el grupo de usuarios de ML Toolkit. El grupo de usuarios de ML Toolkit es un repositorio privado de GitHub que se estableció como parte del GitHub corporativo de InterSystems. Está dirigido a los usuarios externos que instalan, aprenden o ya utilizan los componentes del ML Toolkit. Si quieres unirte al grupo de usuarios de ML Toolkit, envía un email a la dirección MLToolkit@intersystems.com e indica los siguientes datos (son necesarios para que los miembros del grupo te puedan conocer e identificar durante los debates):

  • Nombre de usuario de GitHub
  • Nombre completo (tu nombre seguido de tu apellido en caracteres latinos)
  • Organización (para la que trabajas, estudias, o tu oficina en casa)
  • Cargo (tu cargo real en tu empresa, o "Estudiante", o "Independiente")
  • País (en el que resides)
0
0 235
Anuncio Esther Sanchez · oct 4, 2021

¡Hola Comunidad!

Hemos grabado el webinar que hicimos la semana pasada y lo hemos subido al canal de YouTube de la Comunidad de Desarrolladores en español. Si os perdisteis el webinar o lo queréis volver a ver con más detalle, ya está disponible la grabación!

Eduardo Anglada ha trabajado diez años en la Agencia Espacial Europea y nos descubrió muchas cosas interesantes sobre el espacio profundo. Así que... si queréis descubrir de forma práctica cómo crear modelos de Machine Learning, ¡no os perdáis el vídeo!

IntegratedML - Cómo crear modelos de Machine Learning en minutos

0
0 78
Anuncio Esther Sanchez · sep 15, 2021

¡Hola desarrolladores!

Os invitamos a un nuevo webinar en español: "IntegratedML - Cómo crear modelos de Machine Learning en minutos", el jueves 30 de septiembre, a las 4:00 PM (CEST).

 

El webinar está dirigido a programadores que quieran empezar a crear modelos de Machine Learning (no hace falta ser un experto, con saber un mínimo de SQL es suficiente).

1
0 571
Artículo Jose-Tomas Salvador · jul 7, 2021 8m read

Palabras clave PyODBC, unixODBC, IRIS, IntegratedML, Jupyter Notebook, Python 3

Propósito

Hace unos meses traté el tema de la "conexión con JDBC desde Python a la base de datos de IRIS", y desde entonces utilicé ese artículo con más frecuencia que mi propia nota oculta en mi PC. Por eso, traigo aquí otra nota de 5 minutos sobre cómo hacer una "conexión con JDBC desde Python a la base de datos de IRIS". ODBC y PyODBC parecen bastante fáciles de configurar en un cliente de Windows, sin embargo, siempre me atasco un poco en la configuración de un cliente unixODBC y PyODBC en un servidor de estilo Linux/Unix. ¿Existe un enfoque tan sencillo y consistente como se supone que debe ser para hacer que el trabajo de instalación de PyODBC/unixODBC funcione en un cliente linux estándar sin ninguna instalación de IRIS, contra un servidor IRIS remoto?

Alcance

Hace poco tuve que dedicar un tiempo a hacer funcionar desde cero una demo de PyODBC dentro de Jupyter Notebook en un entorno Docker en Linux. De ahí me surgió la idea de realizar esta nota detallada, para futuras consultas.

En el alcance:

En esta nota vamos a tratar los siguientes componentes:

  • PyODBC sobre unixODBC 
  • El servidor de Jupyter Notebook con Tensorflow 2.2 y Python 3
  • Servidor IRIS2020.3 CE con IntegratedML, incluyendo datos de prueba de ejemplo.
  • dentro de este entorno
  • El motor Docker con Docker-compose sobre AWS Ubuntu 16.04 
  • Docker Desktop para MacOS, y la Docker Toolbos for Windows 10 también están probadas

Fuera del alcance:

De nuevo, los aspectos no funcionales no se evalúan en este entorno de demo. Son importantes y pueden tratarse por separado, como:

  • Seguridad y auditoría de extremo a extremo.
  • Rendimiento y escalabilidad
  • Licencias y soporte, etc.

Entorno

Se puede usar cualquier imagen en Docker para Linux en las configuraciones y los pasos de prueba que se indican a continuación, pero una forma sencilla de configurar un entorno de este tipo en 5 minutos es:

  1. Clonar en Git esta plantilla de demostración
  2. Ejecutar "docker-compose up -d" en el directorio clonado que contiene el archivo docker-compose.yml. Simplemente creará un entorno de demostración, como se muestra en la siguiente imagen, de 2 contenedores. Uno para el servidor de Jupyter Notebook como cliente PyODBC, y otro para un servidor IRIS2020.3 CE.

En el entorno anterior, el tf2jupyter solo contiene una configuración de cliente "Python sobre JDBC", todavía no contiene ninguna configuración de cliente ODBC o PyODBC. Así que ejecutaremos los siguientes pasos para configurarlo, directamente desde Jupyter Notebook para que sea autoexplicativo.

Pasos

Ejecuté las siguientes configuraciones y pruebas en un servidor AWS Ubuntu 16.04. Mi colega @Thomas Dyar los ejecutó en MacOS. También lo probé brevemente en Docker Toolbox for Windows. Pero haznos saber si encuentras algún problema. Los siguientes pasos se pueden automatizar de forma sencilla en tu Dockerfile. Lo grabé manualmente aquí en caso de que se me olvide cómo se hacía después de unos meses.

1. Documentación oficial:

  • Soporte de ODBC para IRIS
  • Cómo definir la fuente de datos ODBC en Unix
  • Soporte PyODBC para IRIS
  • 2. Conectarse al servidor Jupyter

    Utilicé el SSH tunneling de Putty en forma local en el puerto 22 de AWS Ubuntu remoto, después mapeé al puerto 8896 como en la imagen anterior. (Por ejemplo, en el entorno local de Docker también se puede utilizar http directamente en la IP:8896 del equipo Docker).

    3. Ejecutar la instalación de ODBC desde Jupyter Notebook

    Ejecuta la siguiente línea de comando directamente desde una celda en Jupyter:

    !apt-get update !apt-get install gcc !apt-get install -y tdsodbc unixodbc-dev !apt install unixodbc-bin -y !apt-get clean -y

    Instalará el compilador gcc (incluyendo g++), FreeTDS, unixODBC y unixodbc-dev , que son necesarios para volver a compilar el driver PyODBC en el siguiente paso. Este paso no es necesario en un servidor nativo de Windows o PC para la instalación de PyODBC.

    4. Ejecutar la instalación de PyODBC desde Jupyter

    !pip install pyodbc
    Collecting pyodbc
      Downloading pyodbc-4.0.30.tar.gz (266 kB)
         |████████████████████████████████| 266 kB 11.3 MB/s eta 0:00:01
    Building wheels for collected packages: pyodbc
      Building wheel for pyodbc (setup.py) ... done
      Created wheel for pyodbc: filename=pyodbc-4.0.30-cp36-cp36m-linux_x86_64.whl size=273453 sha256=b794c35f41e440441f2e79a95fead36d3aebfa74c0832a92647bb90c934688b3
      Stored in directory: /root/.cache/pip/wheels/e3/3f/16/e11367542166d4f8a252c031ac3a4163d3b901b251ec71e905
    Successfully built pyodbc
    Installing collected packages: pyodbc
    Successfully installed pyodbc-4.0.30

    Lo anterior es la instalación mínima de PIP para esta demostración de Docker. En la documentación oficial, para la "Instalación de MacOS X", se proporcionan instrucciones para una instalación de PIP más detallada.

    5. Volver a configurar los archivos y enlaces ODBC INI en Linux:

    Ejecuta las siguientes líneas de comando para volver a crear los enlaces odbcinst.ini y odbc.ini

    !rm /etc/odbcinst.ini !rm /etc/odbc.ini
    !ln -s /tf/odbcinst.ini /etc/odbcinst.ini !ln -s /tf/odbc.ini /etc/odbc.ini

    Nota: La razón de realizar lo anterior es que los pasos 3 y 4 normalmente crearían 2 archivos ODBC en blanco (por lo tanto, no válidos) en el directorio \etc. A diferencia de la instalación de Windows, estos archivos ini en blanco causan problemas, por lo tanto, debemos eliminarlos y luego simplemente volver a crear un enlace a los archivos ini reales proporcionados en un volumen Docker mapeado: /tf/odbcinst.ini, y /tf/odbc.ini Revisemos estos 2 archivos ini - en este caso, son la forma más simple para las configuraciones ODBC de Linux:

    !cat /tf/odbcinst.ini
    [InterSystems ODBC35]
    UsageCount=1
    Driver=/tf/libirisodbcu35.so
    Setup=/tf/libirisodbcu35.so
    SQLLevel=1
    FileUsage=0
    DriverODBCVer=02.10
    ConnectFunctions=YYN
    APILevel=1
    DEBUG=1
    CPTimeout=<not Pooled>
    !cat /tf/odbc.ini
    [IRIS PyODBC Demo]
    Driver=InterSystems ODBC35
    Protocol=TCP
    Host=irisimlsvr
    Port=51773
    Namespace=USER
    UID=SUPERUSER
    Password=SYS
    Description=Sample namespace
    Query Timeout=0
    Static Cursors=0
    Los archivos anteriores están pre-configurados y se proporcionan en la unidad mapeada. Esto se refiere al driver **libirisodbcu35.so,** que también se puede conseguir en la instancia del contenedor del servidor IRIS (en su directorio {iris-installation}/bin). Por lo tanto, para que la instalación ODBC anterior funcione, **deben existir estos 3 archivos** en la unidad mapeada (o en cualquier unidad de Linux) **con los permisos de los archivos adecuados**:
  • libirisodbcu35.so
  • odbcinst.ini
  • odbc.ini
  • 6. Verificar la instalación de PyODBC 

    !odbcinst -j
    unixODBC 2.3.4
    DRIVERS............: /etc/odbcinst.ini
    SYSTEM DATA SOURCES: /etc/odbc.ini
    FILE DATA SOURCES..: /etc/ODBCDataSources
    USER DATA SOURCES..: /root/.odbc.ini
    SQLULEN Size.......: 8
    SQLLEN Size........: 8
    SQLSETPOSIROW Size.: 8
    import pyodbc print(pyodbc.drivers())
    ['InterSystems ODBC35']
    Por ahora, las salidas anteriores indicarán que el *driver* ODBC tiene los enlaces válidos. Deberíamos poder ejecutar alguna prueba de ODBC de Python en Jupyter Notebook.

    7. Ejecutar la conexión ODBC de Python en las muestras de IRIS:

    import pyodbc import time
    ### 1. Get an ODBC connection #input("Hit any key to start") dsn = 'IRIS PyODBC Demo' server = 'irisimlsvr' #IRIS server container or the docker machine's IP port = '51773' # or 8091 if docker machine IP is used database = 'USER' username = 'SUPERUSER' password = 'SYS'
    #cnxn = pyodbc.connect('DSN='+dsn+';') # use the user DSN defined in odbc.ini, or use the connection string below cnxn = pyodbc.connect('DRIVER={InterSystems ODBC35};SERVER='+server+';PORT='+port+';DATABASE='+database+';UID='+username+';PWD='+ password)
    ###ensure it reads strings correctly. cnxn.setdecoding(pyodbc.SQL_CHAR, encoding='utf8') cnxn.setdecoding(pyodbc.SQL_WCHAR, encoding='utf8') cnxn.setencoding(encoding='utf8')
    ### 2. Get a cursor; start the timer cursor = cnxn.cursor() start= time.clock()
    ### 3. specify the training data, and give a model name dataTable = 'DataMining.IrisDataset' dataTablePredict = 'Result12' dataColumn = 'Species' dataColumnPredict = "PredictedSpecies" modelName = "Flower12" #chose a name - must be unique in server end
    ### 4. Train and predict #cursor.execute("CREATE MODEL %s PREDICTING (%s) FROM %s" % (modelName, dataColumn, dataTable)) #cursor.execute("TRAIN MODEL %s FROM %s" % (modelName, dataTable)) #cursor.execute("Create Table %s (%s VARCHAR(100), %s VARCHAR(100))" % (dataTablePredict, dataColumnPredict, dataColumn)) #cursor.execute("INSERT INTO %s SELECT TOP 20 PREDICT(%s) AS %s, %s FROM %s" % (dataTablePredict, modelName, dataColumnPredict, dataColumn, dataTable)) #cnxn.commit()
    ### 5. show the predict result cursor.execute("SELECT * from %s ORDER BY ID" % dataTable) #or use dataTablePredict result by IntegratedML if you run step 4 above row = cursor.fetchone() while row: print(row) row = cursor.fetchone()
    ### 6. CLose and clean cnxn.close() end= time.clock() print ("Total elapsed time: ") print (end-start)
    (1, 1.4, 0.2, 5.1, 3.5, 'Iris-setosa')
    (2, 1.4, 0.2, 4.9, 3.0, 'Iris-setosa')
    (3, 1.3, 0.2, 4.7, 3.2, 'Iris-setosa')
    (4, 1.5, 0.2, 4.6, 3.1, 'Iris-setosa')
    (5, 1.4, 0.2, 5.0, 3.6, 'Iris-setosa')
    ... ...
    ... ...
    ... ...
    (146, 5.2, 2.3, 6.7, 3.0, 'Iris-virginica')
    (147, 5.0, 1.9, 6.3, 2.5, 'Iris-virginica')
    (148, 5.2, 2.0, 6.5, 3.0, 'Iris-virginica')
    (149, 5.4, 2.3, 6.2, 3.4, 'Iris-virginica')
    (150, 5.1, 1.8, 5.9, 3.0, 'Iris-virginica')
    Total elapsed time: 
    0.023873000000000033

    Un par de consejos:

    1. cnxn = pyodbc.connect() - en el entorno Linux, la cadena de conexión expresada en esta llamada debe ser literalmente correcta y sin espacios.
    2. Establece la codificación de la conexión correctamente con, por ejemplo, utf8. En este caso, el valor predeterminado no funcionaría para las cadenas.
    3. libirisodbcu35.so - lo ideal es que este driver esté estrechamente alineado con la versión del servidor IRIS remoto.

    Siguiente

    Ahora tenemos un entorno Docker con un Jupyter notebook que incluye Python3 y Tensorflow2.2 (sin GPU) a través de una conexión PyODBC (así como JDBC) en un servidor IRIS remoto. Deben funcionar para todas las sintaxis SQL personalizadas, como las que son propiedad de IntegratedML en IRIS, así que ¿por qué no explorar un poco más en IntegratedML y ser creativo con su forma SQL de conducir ciclos de vida ML? Además, me gustaría que pudiéramos volver a tratar o recapitular el enfoque más sencillo sobre IRIS nativo o incluso Magic SQL en el entorno Python, que se conectará con el servidor IRIS. Y, el extraordinario Python Gateway está disponible ahora, así que incluso podemos intentar invocar las aplicaciones y servicios externos de Python ML, directamente desde el servidor IRIS. Me gustaría que pudiéramos probar más sobre eso también.

    ##Anexo El archivo del bloc de notas anterior se revisará en este repositorio de Github, y también en Open Exchange.

    0
    0 561
    Anuncio Jose-Tomas Salvador · jun 17, 2021

    ¡Estamos buscando desarrolladores en Python para participar en nuestro programa de acceso preliminar a Python embebido (EAP IRIS Embedded Python)! Si tu, o alguien que conozcas, es un desarrollador en Python y estais interesados, por favor, ponte en contacto con nosotros a través del email que indicamos abajo.

    InterSystems está incorporando la potencia y simplicidad de Python a IRIS. Estamos trabajando decididamente para integrar Python en el kernel de IRIS, poniéndose a la par con ObjectScript.

    0
    0 126
    Artículo Alberto Fuentes · mayo 14, 2019 3m read

    Hola a todos, me gustaría compartir una guía rápida publicada en el Developer Community sobre cómo conectar Apache Spark +  Apache Zeppelin con InterSystems IRIS. 

    Introducción

    Apache Spark es un framework opensource para computación en cluster. Proporciona una interfaz para desarrollar sobre clusters incluyendo paralelismo y tolerancia a fallos. Por ello es muy utilizado en Big Data.

    Apache Zeppelin es un bloc de notas, que cuenta con una excelente interfaz de usuario para trabajar con diversos tipos análisis y machine learning.

    1
    0 1542
    Anuncio Esther Sanchez · ene 18, 2021

    ¡Hola Comunidad!

    Estamos encantados de invitaros a InterSystems AI+ML Summit 2021, un encuentro virtual sobre Inteligencia Artificial y Machine Learning, que tendrá lugar del 25 de enero al 4 de febrero.

    Participa en dos semanas de ponencias, ofrecidas tanto por profesionales de reconocido prestigio como por técnicos de InterSystems. También habrá encuentros virtuales privados  (“Ask the Expert”). 

    Las sesiones serán en alemán e inglés. Y el evento es gratuito.

    Más información:

    0
    0 97