Python Gateway at InterSystems IRIS

This article is about Python Gateway, an open source community project for the InterSystems IRIS data platform. This project allows you to orchestrate any machine learning algorithms created in Python (the main environment for many Data Scientists), use numerous ready-made libraries to quickly create adaptive, robotic analytical AI / ML solutions on the InterSystems IRIS platform. In this article, I'll show you how InterSystems IRIS can orchestrate Python processes, perform efficient two-way data transfer, and create intelligent business processes.

Plan

  1. Introduction.
  2. Tools.
  3. Installation.
  4. API.
  5. Interoperability.
  6. Jupyter Notebook.
  7. Conclusions.
  8. References
  9. M.L.Toolkit.

Introduction

Python is a high-level, general-purpose programming language focused on improving developer productivity and code readability. In this series of articles, I will talk about the possibilities of using the Python language on the InterSystems IRIS platform, while the main focus of this article is the use of Python as a language for creating and applying machine learning models.

Machine learning (ML) is a class of artificial intelligence methods, the characteristic feature of which is not the direct solution of a problem, but learning in the process of solving many similar problems.

Machine learning algorithms and models are becoming more and more common. There are many reasons for this, but it all comes down to accessibility, simplicity, and achieving practical results. Is clustering or even neural network modeling a new technology?

Of course not, but nowadays there is no need to write hundreds of thousands of lines of code to run one model, and the costs of creating and using models are getting smaller and smaller.

Tools are evolving - while we don't have fully GUI oriented AI/ML tools, the progress we've seen with many other classes of information systems like BI (from writing code to using frameworks and GUI oriented configurable solutions) , is also seen in AI/ML creation tools. We have already passed the stage of writing code and today we use frameworks for building and training models.

Other improvements, such as the ability to propagate a pre-trained model where the end user must simply finish training the model on their specific data, also make it easier to start applying machine learning. These advances make it much easier to learn machine learning, both for professionals and for companies as a whole.

On the other hand, we collect more and more data. With a unified data platform such as InterSystems IRIS, all this information can be immediately prepared and used as input for machine learning models.

With the transition to the cloud, launching AI/ML projects is easier than ever. We can only consume the resources we need. Moreover, thanks to the parallelization offered by cloud platforms, we can save wasted time.

But what about results? This is where things get more complicated. There are many tools for building models, which I will discuss next. Building a good model is not easy, but what next? Profiting from the use of the model by a business is also a non-trivial task. The root of the problem is the separation of analytical and transactional workloads and data models. When we train a model, we usually do it on historical data. But the place for the constructed model is in transactional data processing. What good is the best fraudulent transaction detection model if we run it once a day? The scammers have long since left with the money. We need to train the model on historical data, but we also need to apply it in real time on new incoming data so that our business processes can act according to the predictions made by the model.

ML Toolkit is a toolkit that does just that: bringing models together and a transactional environment so that the models you build can be easily used directly in your business processes. Python Gateway is part of the ML Toolkit and provides integration with the Python language (similar to R Gateway, being part of the ML Toolkit provides integration with the R language).

Инструментарий

Before we continue, I would like to describe a few Python tools and libraries that we will be using later.

Technologies

  • Python is an interpreted, general-purpose, high-level programming language. The main advantage of the language is a large library of mathematical, ML and AI libraries. Like ObjectScript, it's an object-oriented language, but everything is defined dynamically, not statically. Also everything is an object. Later articles assume a passing familiarity with the language. If you want to start learning, I recommend starting with documentation.
  • For our next exercises, set Python 3.6.7 64bit.
  • IDE: I use PyCharm, but in general lot. If you are using Atelier, there is an Eclipse plugin for Python developers. If you are using VS Code, then there is an extension for Python.
  • Notebook: Instead of an IDE, you can write and share your scripts in online notebooks. The most popular of them is Jupyter.

Libraries

Here is a (partial) list of machine learning libraries:

  • Numpy — a fundamental package for exact calculations.
  • pandas — high-performance data structures and data analysis tools.
  • Matplotlib - Creation of charts.
  • Seaborn - data visualization based on matplotlib.
  • Sklearn — machine learning methods.
  • XGBoost — machine learning algorithms within the Gradient Boosting methodology.
  • Gensim — NLP.
  • Hard - neural networks.
  • Tensorflow is a platform for creating machine learning models.
  • PyTorch is a platform for creating machine learning models focused on Python.
  • nyoka - PMML from various models.

AI/ML technologies make business more efficient and adaptable. Moreover, today these technologies are becoming easier to develop and implement. Start learning about AI/ML technologies and how they can help your organization grow.

Installation

There are several ways to install and use Python Gateway:

  • OS
    • Windows
    • Linux
    • Mac
  • Docker
    • Use the image from DockerHub
    • Create your own image

Regardless of the installation method, you will need the source code. The only place to download the code is releases page. It contains tested stable releases, just grab the latest one. At the moment it is 0.8, but over time there will be new ones. Don't clone/download the repository, download the latest release.

OS

If you are installing Python Gateway on an operating system, then first (regardless of the operating system) you will need to install Python. For this:

  1. Install Python 3.6.7 64 bit. It is recommended to install Python in the default directory.
  2. Install the module dill: pip install dill.
  3. Download the ObjectScript code (i.e. do $system.OBJ.ImportDir("C:InterSystemsReposPythoniscpy", "*.cls", "c",,1)) to any area with products. In case you want an existing area to support products, run: write ##class(%EnsembleMgr).EnableNamespace($Namespace, 1).
  4. Place callout DLL/SO/DYLIB to folder bin your InterSystems IRIS instance. The library file must be available in the path returned by write ##class(isc.py.Callout).GetLib().

Windows

  1. Make sure the environment variable is PYTHONHOME points to Python 3.6.7.
  2. Make sure the system environment variable is PATH contains a variable PYTHONHOME (or the directory it points to).

Linux (Debian/Ubuntu)

  1. Check if the environment variable is PATH contains /usr/lib и /usr/lib/x86_64-linux-gnu. Use File /etc/environment to set environment variables.
  2. In case of errors undefined symbol: _Py_TrueStruct set the setting PythonLib. also in Readme there is a Troubleshooting section.

Mac

  1. Currently only python 3.6.7 is supported from Python.org. Check Variable PATH.

If you have changed environment variables, restart your InterSystems product.

Docker

Using containers has a number of advantages:

  • Portability
  • Efficiency
  • Insulation
  • Lightness
  • Immutability

Check out this a series of articles for more information on using Docker with InterSystems products.

All Python Gateway builds are currently container based. 2019.4.

Ready image

Run: docker run -d -p 52773:52773 --name irispy intersystemscommunity/irispy-community:latestto download and run Python Gateway with InterSystems IRIS Community Edition. That's all.

Create your own image

To build a docker image, run in the root of the repository: docker build --force-rm --tag intersystemscommunity/irispy:latest ..
By default, the image is built based on the image store/intersystems/iris-community:2019.4.0.383.0, however you can change this by setting the variable IMAGE.
To build from InterSystems IRIS run: `docker build --build-arg IMAGE=store/intersystems/iris:2019.4.0.383.0 --force-rm --tag intersystemscommunity/irispy:latest'.

After that, you can run the docker image:

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

If you are using an image based on InterSystems IRIS Community Edition, you do not need to specify a key.

Comments

  • Test Process isc.py.test.Process saves a number of images to a temporary directory. You may want to change this path to a mounted directory. To do this, edit the setting WorkingDir specifying the mounted directory.
  • To access the terminal, run: docker exec -it irispy sh.
  • Access to the System Management Portal by login SuperUser/SYS.
  • To stop a container, run: docker stop irispy && docker rm --force irispy.

Checking the installation

Once you've installed Python Gateway, it's worth checking that it's working. Run this code in the InterSystems IRIS terminal:

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

The result should be HELLO - the value of the Python variable x. If the return status sc is a mistake or var empty, check Readme—Troubleshooting section.

API

Python Gateway is installed and you have verified that it is working. Time to start using it!
The main interface to Python is isc.py.Main. It offers the following groups of methods (all return %Status):

  • Code execution
  • Data transfer
  • ancillary

Code execution

These methods allow you to execute arbitrary Python code.

SimpleString

SimpleString is the main method. It takes 4 optional arguments:

  • code is the line of code to execute. Line feed character: $c(10).
  • returnVariable is the name of the variable to return.
  • serialization - how to serialize returnVariable. 0 - string (default), 1 - repr.
  • result - ByRef reference to the variable in which the value is written returnVariable.

Above we have done:

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

In this example, we are assigning to a Python variable x value Hello and want to return the value of a Python variable x to an ObjectScript variable var.

ExecuteCode

ExecuteCode is a safer and less restrictive alternative SimpleString.
Lines in the InterSystems IRIS platform are limited to 3 characters, and if you want to execute a longer piece of code, you need to use streams.
It takes two arguments:

  • code — a string or stream of Python code to be executed.
  • variable - (optional) assigns the result of execution code this Python variable.

Suggest to use:

set sc = ##class(isc.py.Main).ExecuteCode("2*3", "y").

In this example, we multiply 2 by 3 and store the result in a Python variable y.

Data transfer

Pass data to and from Python.

Python -> InterSystems IRIS

There are 4 ways to get the value of a Python variable in InterSystems IRIS, depending on the serialization you need:

  • String for simple data types and debugging.
  • Repr for storing simple objects and debugging.
  • JSON for easy data manipulation on the InterSystems IRIS side.
  • Pickle to save objects.

These methods allow you to receive variables from Python as a string or as streams.

  • GetVariable(variable, serialization, .stream, useString) - get serialization variable variable в stream. If useString is 1 and the serialization is placed in a string, then a string is returned, not a stream.
  • GetVariableJson(variable, .stream, useString) — get JSON serialization of a variable.
  • GetVariablePickle(variable, .stream, useString, useDill) -Get a Pickle (or Dill) serialization of a variable.

Let's try to get our variable y.

set sc = ##class(isc.py.Main).GetVariable("y", , .val, 1)
write val
>6

InterSystems IRIS -> Python

Loading data from InterSystems IRIS into Python.

  • ExecuteQuery(query, variable, type, namespace) - creates a dataset (pandas dataframe or list) from sql query and set it to python variable variable... Package isc.py should be available in the area namespace - the request will be executed there.
  • ExecuteGlobal(global, variable, type, start, end, mask, labels, namespace) - loads global data global from subscript start to end in Python as type variable type: list, or pandas dataframe. Description of optional arguments mask and labels available in class documentation and repository Data Transfer docs.
  • ExecuteClass(class, variable, type, start, end, properties, namespace) - loads class data class from id start to end in Python as type variable type: list, or pandas dataframe. properties — list (separated by comma) of class properties to be loaded into the data set. Masks supported * и ?. Default - * (all properties). Property %%CLASSNAME ignored.
  • ExecuteTable(table, variable, type, start, end, properties, namespace) - loads table data table from id start to end in python.

ExecuteQuery - universal (any valid SQL query will be passed to Python). However, ExecuteGlobal and his wraps ExecuteClass и ExecuteTable work with a number of restrictions. They are much faster (3-5 times faster than the ODBC driver and 20 times faster than ExecuteQuery). More information in Data Transfer docs.
All of these methods support the transfer of data from any area. Plastic bag isc.py must be available in the target area.

ExecuteQuery

ExecuteQuery(request, variable, type, namespace) - passing the results of any valid SQL query to Python. This is the slowest data transfer method. Use it if ExecuteGlobal and its wrappers are not available.

Arguments:

  • query - sql query.
  • variable - the name of the Python variable in which the data is written.
  • typelist or pandas dataframe.
  • namespace - the area in which the request will be executed.

ExecuteGlobal

ExecuteGlobal(global, variable, type, start, end, mask, labelels, namespace) - passing a global to Python.

Arguments:

  • global is the name of the global without ^
  • variable - the name of the Python variable in which the data is written.
  • typelist or pandas dataframe.
  • start — the first subscript of the global. Necessarily %Integer.
  • end is the last subscript of the global. Necessarily %Integer.
  • mask — mask of global values. The mask can be shorter than the number of fields in the global (in which case the fields at the end will be skipped). How to format the mask:
    • + pass the value as is.
    • - skip value.
    • b — Boolean type (0False, all the rest - True).
    • d — Date (from $horolog, on Windows from 1970, on Linux from 1900).
    • t - Time ($horolog, seconds after midnight).
    • m — Timestamp (YEAR-MONTH-DAY HOUR:MINUTE:SECOND format string).
  • labels - %List of column names. The first element is the name of the subscript.
  • namespace - the area in which the request will be executed.

ExecuteClass

wrap over ExecuteGlobal. Prepares a call based on the class definition ExecuteGlobal and calls him.

ExecuteClass(class, variable, type, start, end, properties, namespace) - passing class data to Python.

Arguments:

  • class - class name
  • variable - the name of the Python variable in which the data is written.
  • typelist or pandas dataframe.
  • start — starting Id.
  • end - final Id
  • properties — list (separated by comma) of class properties to be loaded into the data set. Masks supported * и ?. Default - * (all properties). Property %%CLASSNAME ignored.
  • namespace - the area in which the request will be executed.

All properties are passed as is except type properties %Date, %Time, %Boolean и %TimeStamp - they are converted to the corresponding Python classes.

ExecuteTable

wrap over ExecuteClass. Translates the table name into a class name and calls ExecuteClass. Signature:

ExecuteTable(table, variable, type, start, end, properties, namespace) - passing table data to Python.

Arguments:

  • table - table name.
    All other arguments are passed as is. ExecuteClass.

Notes

  • ExecuteGlobal, ExecuteClass и ExecuteTable work equally fast.
  • ExecuteGlobal 20 times faster than ExecuteQuery on large datasets (transfer time >0.01 second).
  • ExecuteGlobal, ExecuteClass и ExecuteTable work on globals with this structure: ^global(key) = $lb(prop1, prop2, ..., propN) where key is an integer.
  • For ExecuteGlobal, ExecuteClass и ExecuteTable supported value range %Date corresponds to the range mktime and depends on the OSwindows: 1970-01-01, linux 1900-01-01, mac). Use %TimeStampto pass data outside this range or use pandas dataframe as this limitation is only for the list.
  • For ExecuteGlobal, ExecuteClass и ExecuteTable all arguments except data source (global, class or table) and variable are optional.

Examples

test class isc.py.test.Person contains a method that demonstrates all data transfer options:

set global = "isc.py.test.PersonD"
set class = "isc.py.test.Person"
set table = "isc_py_test.Person"
set query = "SELECT * FROM isc_py_test.Person"

// Общие аргументы
set variable = "df"
set type = "dataframe"
set start = 1
set end = $g(^isc.py.test.PersonD, start)

// Способ 0: ExecuteGlobal без аргументов
set sc = ##class(isc.py.Main).ExecuteGlobal(global, variable _ 0, type)

// Способ 1: ExecuteGlobal с аргументами    
// При передаче глобала названия полей задаются вручную
// globalKey - название сабсткрипта 
set labels = $lb("globalKey", "Name", "DOB", "TS", "RandomTime", "AgeYears", "AgeDecimal", "AgeDouble", "Bool")

// mask содержит на 1 элемент меньше чем labels потому что "globalKey" - название сабскипта
// Пропускаем %%CLASSNAME
set mask = "-+dmt+++b"

set sc = ##class(isc.py.Main).ExecuteGlobal(global, variable _ 1, type, start, end, mask, labels)

// Способ 2: ExecuteClass
set sc = ##class(isc.py.Main).ExecuteClass(class, variable _ 2, type, start, end)

// Способ 3: ExecuteTable
set sc = ##class(isc.py.Main).ExecuteTable(table, variable _ 3, type, start, end)

// Способ 4: ExecuteTable
set sc = ##class(isc.py.Main).ExecuteQuery(query, variable _ 4, type)

call method do ##class(isc.py.test.Person).Test() to see how all data transfer methods work.

Auxiliary methods

  • GetVariableInfo(variable, serialization, .defined, .type, .length) - get information about the variable: whether it is defined, class and serialization length.
  • GetVariableDefined(variable, .defined) - whether the variable is defined.
  • GetVariableType(variable, .type) - get the class of the variable.
  • GetStatus() - get and remove the last exception on the Python side.
  • GetModuleInfo(module, .imported, .alias) — get module variable and import status.
  • GetFunctionInfo(function, .defined, .type, .docs, .signature, .arguments) - get information about the function.

Interoperability

You have learned how to call Python Gateway from the terminal, now let's start using it in production. The basis for interacting with Python in this mode is isc.py.ens.Operation. It allows us:

  • Execute Python code
  • Save/Restore Python Context
  • Load and receive data from Python

Basically, a Pyhton operation is a wrapper over isc.py.Main. Operation isc.py.ens.Operation allows interaction with the Python process from InterSystems IRIS products. Five requests are supported:

  • isc.py.msg.ExecutionRequest to execute Python code. returns isc.py.msg.ExecutionResponse with the execution result and the values ​​of the requested variables.
  • isc.py.msg.StreamExecutionRequest to execute Python code. returns isc.py.msg.StreamExecutionResponse the result of execution and the values ​​of the requested variables. Analog isc.py.msg.ExecutionRequest, but accepts and returns streams instead of strings.
  • isc.py.msg.QueryRequest to transfer the result of executing an SQL query. returns Ens.Response.
  • isc.py.msg.GlobalRequest/isc.py.msg.ClassRequest/isc.py.msg.TableRequest to pass global/class/table data. returns Ens.Response.
  • isc.py.msg.SaveRequest to save Python context. returns Ens.StringResponse with context ID.
  • isc.py.msg.RestoreRequest to restore the Python context.

    Additionally, isc.py.ens.Operation has two settings:

    • Initializer - choosing a class that implements the interface isc.py.init.Abstract. It can be used to load functions, modules, classes, and the like. It is executed once when the process starts.
    • PythonLib - (Linux only) if you see boot errors, set its value to libpython3.6m.so or even in the full path to the Python library.

Creation of business processes

There are two classes available that facilitate the development of business processes:

  • isc.py.ens.ProcessUtils allows you to extract annotations from activities with variable substitution.
  • isc.py.util.BPEmulator makes it easy to test business processes with Python. It can execute a business process (Python parts) in the current process.

Variable substitution

All business processes inherited from isc.py.ens.ProcessUtils, can use the method GetAnnotation(name) to get the value of an activity annotation by its name. The activity annotation may contain variables that will be evaluated on the InterSystems IRIS side before being passed to Python. Here is the syntax for variable substitution:

  • ${class:method:arg1:...:argN} - method call
  • #{expr} - execute code in the ObjectScript language.

An example is available in the test business process isc.py.test.Process, for example, in activity Correlation Matrix: Graph: f.savefig(r'#{process.WorkDirectory}SHOWCASE${%PopulateUtils:Integer:1:100}.png'). In this example:

  • #{process.WorkDirectory} returns the object's WorkDirectory property process, which is an instance of the class isc.py.test.Process those. current business process.
  • ${%PopulateUtils:Integer:1:100} calls a method Integer Class %PopulateUtils, passing arguments 1 и 100, returning a random integer in the range 1...100.

Test business process

The test production and test business process are available by default as part of the Python Gateway. To use them:

  1. In OS terminal run: pip install pandas matplotlib seaborn.
  2. In the InterSystems IRIS terminal, run: do ##class(isc.py.test.CannibalizationData).Import() to populate test data.
  3. Launch products isc.py.test.Production.
  4. Send request type Ens.Request в isc.py.test.Process.

Let's see how it all works together. open isc.py.test.Process in the BPL editor:

Python Gateway at InterSystems IRIS

Code execution

The most important call is the execution of Python code:

Python Gateway at InterSystems IRIS

Request used isc.py.msg.ExecutionRequest, here are its properties:

  • Code — Python code.
  • SeparateLines - whether to split the code into lines for execution. $c(10) (n) is used to separate strings. Note that it is NOT recommended to process the entire message at once, this function is only for processing def and similar multiline expressions. Default 0.
  • Variables is a comma-separated list of variables that will be added to the response.
  • Serialization - How to serialize the variables we want to return. Options: Str, Repr, JSON, Pickle и Dill, default Str.

In our case, we only set the property Code, so that all other properties use their default values. We set it up by calling process.GetAnnotation("Import pandas"), which at runtime returns an annotation after variable substitution has been performed. Finally the code import pandas as pd will be passed to Python. GetAnnotation can be useful for getting multi-line Python scripts, but there are no restrictions on this way of getting code. You can set the property Code in any way convenient for you.

Getting Variables

Another interesting challenge using isc.py.msg.ExecutionRequestCorrelation Matrix: Tabular:

Python Gateway at InterSystems IRIS

It calculates the Correlation Matrix on the Python side and extracts the variable corrmat back to InterSystems IRIS in JSON format by setting the request properties:

  • Variables: "corrmat"
  • Serialization: "JSON"

We can see the results in Visual Trace:

Python Gateway at InterSystems IRIS

And if we need this value in the BP, it can be obtained like this: callresponse.Variables.GetAt("corrmat").

Data transfer

Next, let's talk about transferring data from InterSystems IRIS to Python, all data transfer requests implement the interface isc.py.msg.DataRequest, which provides the following properties:

  • Variable is a Python variable to which the data is written.
  • Type - variable type: dataframe (pandas dataframe) or list.
  • Namespace - the area from which we receive data. Plastic bag isc.py should be available in this area. This may be an area without product support.

Based on this interface, 4 classes of requests are implemented:

  • isc.py.msg.QueryRequest - set property Query to send a SQL query.
  • isc.py.msg.ClassRequest - set property Class to pass class data.
  • isc.py.msg.TableRequest - set property Table to pass table data.
  • isc.py.msg.GlobalRequest - set property Global to transfer data globally.

In the test process, look at the activity RAWWhere isc.py.msg.QueryRequest shown in action.

Python Gateway at InterSystems IRIS

Saving/Restoring a Python Context

Finally, we can store the Python context in InterSystems IRIS, to do this, send isc.py.msg.SaveRequest with arguments:

  • Mask — Only variables that satisfy the mask are saved. Supported * и ?. Example: "Data*, Figure?"... Default *.
  • MaxLength — The maximum length of the stored variable. If the serialization of a variable is longer, then it will be ignored. Set to 0 to get variables of any length. Default $$$MaxStringLength.
  • Name — Context name (optional).
  • Description — Description of the context (optional).

Returns Ens.StringResponse с Id saved context. In the test process, look at the activity Save Context.

Matching request isc.py.msg.RestoreRequest loads a context from InterSystems IRIS into Python:

  • ContextId is the context identifier.
  • Clear — clear the context before restoring.

Jupyter Notebook

Jupyter Notebook is an open source web application that allows you to create and publish notebooks containing code, visualizations, and text. Python Gateway allows you to view and edit BPL processes as a Jupyter Notebook. Note that the regular Python 3 executor is currently being used.

This extension assumes that annotations contain Python code and use activity names as preceding titles. It is now possible to develop PythonGateway business processes in Jupyter Notebook. Here's what's possible:

  • Create new business processes
  • Delete business processes
  • Create new activities
  • Change activities
  • Delete activities

Here demo video. And some screenshots:

Process Explorer

Python Gateway at InterSystems IRIS

Process editor

Python Gateway at InterSystems IRIS

Installation

  1. You will need InterSystems IRIS 2019.2+.
  2. Install PythonGateway v0.8+ (requires only isc.py.util.Jupyter, isc.py.util.JupyterCheckpoints и isc.py.ens.ProcessUtils).
  3. Update the ObjectScript code from the repository.
  4. Perform do ##class(isc.py.util.Jupyter).Install() and follow the prompts.

Documentation.

Conclusions

MLToolkit is a set of tools that aims to combine models and a transactional environment so that the built models can be easily used directly in your business processes. Python Gateway is part of MLToolkit and provides integration with the Python language, allowing you to orchestrate any machine learning algorithms created in Python (the main environment for many Data Scientists), use numerous ready-made libraries to quickly create adaptive, robotic analytical AI / ML solutions on the InterSystems platform IRIS.

references

MLToolkit

The MLToolkit user group is a private GitHub repository created as part of the InterSystems corporate GitHub organization. It is addressed to external users who are installing, learning, or already using MLToolkit components, including Python Gateway. The group has a number of implemented cases (with source code and test data) in the fields of marketing, manufacturing, medicine and many other industries. To join the ML Toolkit user group, please send a short email to the following address: [email protected] and include the following information in your letter:

  • GitHub username
  • Organization (you work or study)
  • Position (your actual position in your organization, either "Student" or "Independent").
  • Country

For those who have read the article and are interested in InterSystems IRIS as a platform for developing or hosting artificial intelligence and machine learning mechanisms, we invite you to discuss possible scenarios of interest to your enterprise. We will readily analyze the needs of your enterprise and jointly determine an action plan; contact email address of our AI/ML expert group – [email protected].

Source: habr.com

Add a comment