WolframClientForPython | Новая клиентская библиотека Wolfram Language для Python

Original author: Arnoud Buzing и Dorian Birraux
  • Translation

Оригинал перевода в моём блоге

Получение полного доступа к языку Wolfram Language из языка Python


Язык Wolfram (Wolfram Language) дает программистам в руки уникальный язык с огромным множеством сложных алгоритмов, а также встроенных знаний об окружающем мире. На протяжении многих лет люди спрашивают нас, как получить доступ ко всем возможностям нашей технологии из других программных сред и языков программирования. Шли годы и мы создали множество таких решений как Wolfram CloudConnector для Excel, WSTP (протокол символьной передачи Wolfram) для программ на C/C++ и, конечно, J/Link, который обеспечивает доступ к Wolfram Language непосредственно из Java.

Поэтому сегодня мы рады официально представить вам новое долгожданное решение по объединению языков, что позволит напрямую и эффективно вызывать Wolfram Language из языка Python: Клиентскую библиотеку Wolfram для Python. И что особенно важно, это клиентская библиотека имеет полностью открытый исходный код размещенный на git-хранилище WolframClientForPython под лицензией MIT, так что вы можете сколько угодно копировать ее и как угодно использовать ее по своему усмотрению.

Это легко и просто


Клиентская библиотека Wolfram позволяет легко интегрировать большую коллекцию алгоритмов языка Wolfram Language, а также базу знаний Wolfram непосредственно в любой уже существующий код Python, что значительно экономит ваше время и силы при разработке нового кода. В этой статье мы сначала покажем вам, как настроить соединение между Python и Wolfram Language, рассмотрим несколько методов и примеров, которые могут быть использованы для вычислений на языке Wolfram Language, а затем и вызова его для использования из Python. Для получения более полной справочной информации перейдите по ссылке: домашняя страница документации для клиентской библиотеки Wolfram для Python.

Оцените, не отходя от кассы...


Начнем с простого примера, который вычисляет среднее значение и стандартное отклонение миллиона чисел, взятых из нормального распределения. В этом примере показано, как вызвать функцию языка Wolfram из Python и сравнить результаты из языка Python с тем же вычислением на языке Wolfram Language, для того чтобы показать, что они имеют высокую сходимость.

Статистический анализ данных


Во-первых, чтобы подключиться к языку Wolfram Language, вам нужно создать новый сеанс с Wolfram Engine (бесплатным движком языка Wolfram):

from wolframclient.evaluation import WolframLanguageSession
session=WolframLanguageSession()

Для вызова функций Wolfram Language вам необходимо импортировать движок `wl`:

from wolframclient.language import wl

Теперь вы можете выполнить любой код языка Wolfram. Присвойте переменной sample из Python значение списка из одного миллиона случайных чисел, взятых из нормального распределения, со средним значением 0 и стандартным отклонением 1:

sample = session.evaluate(wl.RandomVariate(wl.NormalDistribution(0,1), 1e6))

Рассмотрим первые пять из них:

sample[:5]

[0.44767075774581,
 0.9662810005828261,
 -1.327910570542906,
 -0.2383857558557122,
 1.1826399551062043]

Вы можете вычислить среднее значение этой sample с помощью Wolfram Language. Как и ожидалось, оно будет близко к нулю:

session.evaluate(wl.Mean(sample))

0.0013371607703851515

Вы также можете напрямую вычислить то же самое в Python, чтобы убедиться, что получите похожий результат:

from statistics import mean
mean(sample)

0.0013371607703851474

Точно так же вы можете вычислить стандартное отклонение sample с помощью языка Wolfram Language:

session.evaluate(wl.StandardDeviation(sample))

1.0014296230797068

Затем запустите следующий код в Python, чтобы убедиться, что вы получите похожий результат:

stdev(sample)

1.0014296230797068

Не может не радовать, что результаты сходятся. Теперь вы знаете, как вызывать простые функции языка Wolfram Language из Python. Давайте же продолжим на более интересном примере.

Использование базы знаний Wolfram


Давайте рассмотрим встроенную функцию Wolfram Language, которая недоступна в Python, WolframAlpha:

moons = session.evaluate(wl.WolframAlpha('moons of Saturn', 'Result'))

Функция WolframAlpha является одной из функций высокого уровня в языке Wolfram Language, которая взаимодействует с серверами Wolfram|Alpha через web-API. Вы можете использовать этот API напрямую из Python, что делает вызов функции WolframAlpha намного более мощным и удобнее, поскольку вы получаете доступ ко всем функциям обработки данных непосредственно из Wolfram Language. Давайте посмотрим на то, что содержит переменная moon в Python:

moons

EntityClass['PlanetaryMoon', 'SaturnMoon']

На выходе здесь представление в Python выражения из Wolfram Language, которое можно будет использоваться в любом последующем расчете. Например, если вы хотите получить список первых четырех спутников Сатурна (по их степени близости к Сатурну) для этого Вам необходимо выполнить следующий код:

session.evaluate(wl.EntityList(moons))[:4]

[Entity['PlanetaryMoon', 'S2009S1'],
 Entity['PlanetaryMoon', 'Pan'],
 Entity['PlanetaryMoon', 'Daphnis'],
 Entity['PlanetaryMoon', 'Atlas']]

Или вы можете вывести четыре крупнейших по массе спутника Сатурна с помощью этого кода:

bigmoons = session.evaluate(wl.EntityList(wl.SortedEntityClass(moons, wl.Rule("Mass","Descending"),4)))
bigmoons

[Entity['PlanetaryMoon', 'Titan'],
 Entity['PlanetaryMoon', 'Rhea'],
 Entity['PlanetaryMoon', 'Iapetus'],
 Entity['PlanetaryMoon', 'Dione']]

Или вы можете получить массив строк с именами этих спутников, например:

session.evaluate(wl.Map(wl.Function( wl.Slot()("Name")), bigmoons))

['Titan', 'Rhea', 'Iapetus', 'Dione']

Все это весьма впечатляет. Давайте рассмотрим другой пример, использующий встроенные в язык Wolfram Language функции обработки изображений и машинного обучения.

Обработка изображений и машинное обучение


Во-первых, давайте переключимся в другой режим, чтобы выполнять оценки непосредственно на языке Wolfram Language. До сих пор вы использовали движок `wl` для создания выражений Wolfram Language в Python, но также можно выполнить строки кода, написанные на Python, содержащие код языка Wolfram Language, и иногда это даже воспринимается гораздо легче:

from wolframclient.language import wlexpr


Например вычислим 1+1 на языке Wolfram Language, отправив его в виде строки:

session.evaluate('1+1')

2


Используя этот способ, вы можете написать небольшой код на языке Wolfram Language, который получает на входе изображение и использует встроенный алгоритм обнаружения лиц, для того чтобы найти местоположение лица на изображении. Здесь изображение, которое мы используем, — это знаменитая картина «Девушка с жемчужной сережкой» голландского художника Йоханнеса Вермеера (следует отметить, естественно что этот алгоритм сработает также практически на любом изображении с объектами, в которых можно распознать лица). Поскольку интерфейс терминала Python не поддерживает вывод изображений, нам потребуется использовать Jupyter Notebook вместе с пакетом Python Image Library (PIL), для того чтобы иметь возможность вывода результата:

from PIL import Image
import io

session.evaluate(wlexpr('''
image = ImageResize[ Import["Girl_with_a_Pearl_Earring.jpg"], 300];
boxes = FindFaces[image];
face = ImageAssemble[{{image,HighlightImage[image, boxes, "Blur"]}}];
''') )

data = session.evaluate( wlexpr('ExportByteArray[ face, "PNG" ]') )

Image.open(io.BytesIO)



В результате все получилось довольно легко и при этом мощно. Но что же делать, если у вас нет Wolfram Engine установленного на Вашем компьютере локально, а вы хотите использовать клиентскую библиотеку Wolfram для Python? В этом случае вы всегда можете использовать язык Wolfram Language непосредственно вызывая его из Wolfram Cloud (облака).

Итак, переходим к облаку


Wolfram Cloud обеспечивает легкий доступ к языку Wolfram Language без предустановке локально. Wolfram Cloud предоставляет различные сервисы, включая веб-интерфейс для программирования на языке Wolfram Language, а также возможность развертывания произвольных веб-API Wolfram Language.

В следующем примере мы это и проделаем, развернув web-API Wolfram Language. Например API принимает на входе названия двух стран ( country1 и country2 ), находит столицу для каждой страны и затем вычисляет расстояние между ними (в километрах):

CloudDeploy[
APIFunction[{"country1"->"String","country2"->"String"},
QuantityMagnitude[
       GeoDistance[
            EntityValue[Entity["Country", #country1], "CapitalCity"],
            EntityValue[Entity["Country", #country2], "CapitalCity"]
        ],
       "Kilometers"
   ]&,
"WXF"
],
CloudObject["api/public/capital_distance"],
Permissions->"Public"]



После развертывания этого API вы можете начать новый сеанс языка Wolfram Language, но на этот раз вы подключаетесь к Wolfram Cloud вместо локального движка:

from wolframclient.evaluation WolframCloudSession
cloud = WolframCloudSession()

Чтобы вызвать API, вы должны указать имя пользователя (user1) и конечную точку API (api/ public/capital_distance). Используя эти данные вы можете подключиться к облаку…

api = ('user1', 'api/public/capital_distance')
result = cloud.call(api, {'country1': 'Netherlands', 'country2': 'Spain'})

… и затем получить требуемый результат:
result.get()

1481.4538329484521

Оцените еще раз, как это легко и просто.

Если вы хотите сохранить развернутый API-интерфейс языка Wolfram Language так, чтобы его могли использовать только вы, вы можете развернуть API с помощью команды Permissions→ «Private». Для этого в частном API вы можете сгенерировать (в Wolfram Language) защитный ключ аутентификации:

image
key = GenerateSecuredAuthenticationKey["myapp"]

Скопируйте ответы от этих двух строк ввода:

key["ConsumerKey"]
key["ConsumerSecret"]

Затем вставьте их в ваш сеанс Python:

SecuredAuthenticationKey('<<paste-consumer-key-here>>', '<<paste-consumer-secret-here>>')

И затем запустите новый облачный сеанс с аутентификацией:

cloud = WolframCloudSession(credentials=sak)
cloud.start()
cloud.authorized()

True

Теперь вы (и только вы) можете использовать любой API языка Wolfram Language, который вы развернули для частного использования.

Поговорим немного о базовых понятиях сериализации


Для того чтобы все сделать быстро и эффективно, клиентская библиотека языка Wolfram для Python использует открытый формат WXF для обмена выражениями между Python и Wolfram. WXF — это двоичный формат для точной сериализации выражений на языке Wolfram Language в форме, пригодной для обмена с внешними программами. Функция библиотечной команды Export может сериализовать объекты Python в строковую форму ввода и WXF, а также поддерживает набор встроенных классов Python, таких как dict, list и strings:

from wolframclient.serializers import export
export({
    'list': [1,2,3],
    'string': u'abc',
    'etc': [0, None, -1.2]
})

b'<|"list" -> {1, 2, 3}, "string" -> "abc", "etc" -> {0, None, -1.2}|>'

WXF представляет собой числовые массивы с упакованными данными, что позволяет эффективно поддерживать массивы NumPy.

Например, создайте массив из 255-ти 8-битных положительных целых чисел:

import numpy
array=numpy.arange(255, dtype='uint8')

Сериализуйте его в байты WXF и вычислите количество байтов:

wxf=export(array, target_format='wxf')
len(wxf)

262

NumPy позволяет обращаться ко множеству библиотек Python. Следовательно эта эффективная и компактная сериализация помогает связать систему Python с языком Wolfram Language, прямым следствием чего является поддержка в NumPy того, что сериализация изображений PIL в целом очень эффективна. Большинство режимов пиксельных данных отображаются как один из типов числовых массивов, заданных в виде NumericArrayType.

Стоит также отметить, что pandas Series и DataFrame при этом поддерживаются здесь изначально. Библиотека также предоставляет расширяемый механизм для сериализации произвольных классов.

Что доступно уже сейчас?


Установите последнюю версию клиентской библиотеки Wolfram для Python с помощью команды pip:

$ pip install wolframclient

Для этого Вам потребуется Python 3.5.3 (или более новая версия) и Wolfram Language 11.3 (или более новая версия). Ознакомьтесь с документацией по клиентской библиотеке Wolfram для Python. Весь исходный код размещен в репозитории WolframClientForPython на сайте Wolfram Research GitHub.

Если у вас есть предложения по его улучшению и вы можете и хотите помочь нам это сделать, вы может это сделать отправив нам запрос на обновление данных в этот репозиторий.
Мы очень рады что этот релиз наконец состоялся и надеемся, что он окажется для вас полезным. Сообщите, пожалуйста, нам ваше мнение в разделе комментариев или в сообществе Wolfram, и мы сделаем все возможное, чтобы связаться с вами лично.

О переводе
Выражаю огромную благодарность Петру Тенишеву и Галине Никитиной за помощь в переводе и подготовке публикации.

Хотите научиться программировать на языке Wolfram Language?
Смотрите еженедельные вебинары.
Регистрация на новые курсы. Готовый онлайн курс.
Заказ решения на Wolfram Language.
Wolfram Research
158.56
Wolfram Language, Mathematica, Wolfram Alpha и др.
Support the author
Share post

Comments 6

    0
    А для Julia такого не ожидается?
      0
      Пока сложно сказать.
      0
      Ссылки на вольфрам не рабочие( 404…
        0
        Какие именно? Я посмотрел, не нашел таковых.
          0
          « Девушка с жемчужной сережкой» и на автора Йоханнеса Вермеера 

    Only users with full accounts can post comments. Log in, please.