...

суббота, 22 августа 2020 г.

[Из песочницы] Отслеживаем состояние своего портфеля у брокера «Тинькофф Инвестиции» через Google Таблицы

Наверняка многие ведут учет сделок и следят за состоянием своего портфеля в Google-таблицах или в Excel. Раньше мне приходилось вручную вносить информацию о каждом купленном или проданном инструменте и это отнимало значительную часть моего времени. Тогда мне захотелось автоматизировать этот процесс и я начал искать способы реализации данной идеи.

Я обнаружил статью пользователя ErhoSen. Из неё я узнал, что брокер «Тинькофф Инвестиции» предлагает своим клиентам API для взаимодействия с брокерским счетом с индивидуально-инвестиционным счетом (ИИС). С его помощью можно получить список акций, валютных пар, узнать стоимость бумаги по тикеру, просмотреть список операций по счету, получить информацию о своем портфеле и т.д. Однако, мне не хватило существующего функционала скрипта и я решил дописать его, добавив туда свои функции.

Получение токена


Работа с API происходит через токен. Процесс получения токена описан в документации на GitHub’е. Для его получения нужно:
  1. Перейти на сайт Тинькоффа и выполнить вход в свой аккаунт.
  2. Убедиться, что функция «Подтверждение сделок кодом» отключена.
  3. Пролистать вниз страницы до пункта токен для OpenAPI и нажать на «Токен для торговли»
  4. Скопировать и сохранить токен. Он отображается только один раз, но можно выпускать неограниченное количество токенов.

После получения токена можно приступить к работе с таблицей. Перейдите по ссылке и скопируйте к себе таблицу, в которой будете вести учёт.

Вставьте свой токен в ячейку B1 в листе «Настройки».

Важно! После вставки токена не удаляйте и не переименовывайте лист “Настройки”. Если в ячейке B3 появится текущий курс доллара — поздравляем, все готово к работе.
Основные функции скрипта:

  • getPrice() — получить текущую стоимость инструмента по тикеру
  • getTrades (ticker) — получить список всех операций по определенному инструменту. В скобках необходимо указать тикер инструмента, по которому надо увидеть список операций
  • getAllTrades() — получить список всех операций по всем инструментам. В скобках можно указать временной промежуток и посмотреть операции с определенного момента
  • getPortfolio() — получение текущего портфеля
  • getCurrencies() — получение валютных активов
  • getTradesIIS (ticker) — получить список всех операций по определенному инструменту (ИИС). В скобках необходимо указать тикер инструмента, по которому надо увидеть список операций
  • getAllTradesIIS() — получить список всех операций по всем инструментам (ИИС). В скобках можно указать временной промежуток и посмотреть операции с определенного момента
  • getIISPort() — получение текущего портфеля на ИИС
  • getCurrenciesIIS() — получение валютных активов на ИИС
  • getUSDval() — получить текущий курс доллара (по стакану)

После получения нужных данных Вы можете скопировать полученные значения и продолжить работу с ними на других листах или в другой таблице, в том числе и в Excel-e.


Пример работы функции getPortfolio для получения портфеля

Ручное обновление данных


По умолчанию Google не предоставляет инструмент для обновления пользовательских скриптов, поэтому пришлось воспользоваться решением сторонних разработчиков. Для того, чтобы иметь возможность обновлять данные по нажатию, при использовании функций в скобках нужно задавать ячейку $Z$1, в которую записывается текущая дата и время, что в дальнейшем используется для ручного обновления. Ниже я представлю фрагмент кода, который отвечает за обновление данных.
function onOpen() {
  var sheet = SpreadsheetApp.getActiveSpreadsheet()
  var entries = [{
    name : "Обновить",
    functionName : "refresh"
  }]
  sheet.addMenu("TI", entries)
};

function refresh() {
  SpreadsheetApp.getActiveSpreadsheet().getRange('Z1').setValue(new Date().toTimeString());
}

Сначала нужно нажать на кнопку Обновить в подменю TI (появится справа от вкладки Справка).
После этого появится окно с предупреждением:

Нажимаем Продолжить. Далее появится еще одно предупреждающее окно, где нужно будет нажать на Дополнительные настройки и в раскрывшемся поле выбрать Перейти на страницу «Tinkoff Invest» (небезопасно):

Данные действия необходимо выполнять потому, что скрипт для изменения значения ячейки Z1 должен сначала получить доступ к текущей таблице, чтобы он исполнялся только в ней. После этого у нас есть возможность по запросу обновить данные в таблице. Пример ручного обновления для функции getPrice(«AMD»;$Z$1):

ВНИМАНИЕ! У разработчика данного скрипта не будет доступа к Вашему Google-аккаунту, к списку таблиц на Диске или к токену. Если Вы опасаетесь за сохранность своих данных, то можете скопировать мой скрипт и вставить его в свою таблицу. Для этого в Google Sheets откройте свою таблицу и в верхнем меню нажмите на Инструменты, а затем на Редактор скриптов.

У вас откроется среда для создания скриптов Google. Сотрите в окне код, расположенный по умолчанию, скопируйте код по ссылке и вставьте его в окно.

После этого сохраните скрипт, задав любое название проекту и самому скрипту. Затем перейдите обратно в таблицу, создайте лист “Настройки” и в ячейку В1 вставьте свой токен для OpenAPI. После этого Вы можете работать с таблицей.

Заключение


Хочу выразить благодарность ErhoSen за его статью и исходный код, который был доработан мною.

Также для личного пользования я создал Telegram бота, в планах на будущее довести эту идею до ума, если идея найдет отклик. Бот удобен в случаях, когда не хочется терять время на вход в приложение Тинькофф Инвестиции, кто часто сидит за ноутбуком и не хочет постоянно авторизовываться на сайте, или же для хранения истории изменений содержимого портфеля.

Let's block ads! (Why?)

[Перевод] Почему разработчики влюбляются в функциональное программирование?

Функциональное программирование (ФП) существует уже лет 60, но до сих пор оно всегда имело достаточно узкую сферу использования. Хотя компании, меняющие мир, вроде Google, полагаются на его ключевые концепции, средний современный программист знает об этом феномене очень мало, если вообще что-то знает.

Но это скоро изменится. В такие языки, как Java и Python, интегрируется всё больше и больше концепций ФП. А более современные языки, вроде Haskell, являются полностью функциональными.

Если описать функциональное программирование простыми словами, то это — создание функций для работы с неизменяемыми переменными. В противоположность этому, объектно-ориентированное программирование — это когда используется сравнительно постоянный набор функций, а программист, в основном, занят модификацией существующих переменных и созданием новых.

ФП, по своей природе, подходит для решения актуальных задач, вроде задач анализа данных и машинного обучения. Это не означает, что нужно попрощаться с объектно-ориентированным программированием и полностью перейти на функциональное. Современному программисту просто полезно знать основные принципы ФП, что даст ему возможность применить эти принципы там, где они могут сослужить ему хорошую службу.

Суть функционального программирования — это уничтожение побочных эффектов


Для того чтобы понять принципы функционального программирования, сначала надо разобраться в том, что такое «функция». Может, это покажется скучным, но, в итоге, это позволит увидеть то, что на первый взгляд незаметно. Поэтому давайте поговорим о функциях.

Функция, говоря упрощённо, это сущность, которая преобразует некие входные данные, передаваемые ей, в выходные данные, которые она возвращает в место вызова. Правда, на самом деле всё далеко не всегда выглядит так просто. Взгляните на следующую функцию, написанную на Python:

def square(x):
    return x*x

Эта функция крайне проста. Она принимает один аргумент, x, который, вероятно, имеет тип int, а, может быть, тип float или double, и выдаёт результат возведения этого x в квадрат.

А вот — ещё одна функция:

global_list = []
def append_to_list(x):
    global_list.append(x)

На первый взгляд кажется, что она принимает x какого-то типа и ничего не возвращает, так как в ней нет выражения return. Но не будем спешить с выводами!

Функция не сможет нормально работать в том случае, если заранее не будет объявлена переменная global_list. Результатом работы этой функции является модифицированный список, хранящийся в global_list. Даже хотя global_list не объявлен в качестве значения, которое подаётся на вход функции, данная переменная меняется после вызова функции.

append_to_list(1)
append_to_list(2)
global_list

После пары вызовов функции из предыдущего примера в global_list будет уже не пустой список, а список [1,2]. Это позволяет говорить о том, что список, в действительности, является значением, подаваемым на вход функции, хотя это и никак не зафиксировано при объявлении функции. Это может стать проблемой.

Нечестность при объявлении функций


Эти неявные входные или выходные значения имеют официальное наименование: побочные эффекты. Тут мы используем очень простые примеры, но в более сложных программах побочные эффекты способны приводить к возникновению реальных сложностей.

Подумайте о том, как бы вы тестировали функцию append_to_list. Недостаточно будет прочесть первую строку её объявления, и выяснить, что её надо тестировать, передавая ей некое значение x. Вместо этого нужно будет читать весь код функции, разбираться в том, что именно там происходит, объявлять переменную global_list, а потом уже тестировать функцию. То, что в нашем простом примере, как кажется, особых сложностей не вызывает, в программах, состоящих из тысяч строк кода, будет выглядеть уже совсем по-другому.

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

newlist = []
def append_to_list2(x, some_list):
    some_list.append(x)
append_to_list2(1,newlist)
append_to_list2(2,newlist)
newlist

Мы не особенно многое изменили в этом коде. В результате работы функции в newlist, как раньше в global_list, оказывается [1,2], да и всё остальное выглядит так же, как прежде.

Но мы, однако, внесли в этот код одно существенное изменение. Мы избавились от побочных эффектов. И это очень хорошо.

А именно, теперь, прочтя первую строку объявления функции, мы точно знаем о том, с какими входными данными она работает. В результате, если программа не будет вести себя так, как ожидается, можно легко протестировать каждую имеющуюся в ней функцию и найти ту, которая работает неправильно. Чистые функции легче поддерживать.

Функциональное программирование — это написание чистых функций


Функция, при объявлении которой чётко указано то, что она принимает, и то, что она возвращает — это функция без побочных эффектов. Функция без побочных эффектов — это чистая функция.

Вот очень простое определение функционального программирования. Это — написание программ, состоящих только из чистых функций. Чистые функции никогда не модифицирую переданные им данные, они лишь создают новые и возвращают их. (Отмечу, что я немного смошенничал в предыдущем примере. Он написан в духе функционального программирования, но в нём функция модифицирует глобальную переменную-список. Но здесь мы лишь разбираем базовые принципы ФП, поэтому я и поступил именно так. Если хотите, здесь вы можете найти более строгие примеры чистых функций.)

Далее, работая с чистыми функциями, можно ожидать того, что они, получая на вход одни и те же данные, всегда будут формировать одни и те же выходные данные. А функции, которые чистыми не являются, могут зависеть от каких-то глобальных переменных. В результате они, получая одно и то же на вход, могут выдавать разные результаты, зависящие от значения глобальных переменных. Этот факт способен значительно усложнить отладку и поддержку кода.

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

Чем не является функциональное программирование


▍Функции map и reduce


Циклы — это механизмы, не имеющие отношения к функциональному программированию. Взгляните на следующие Python-циклы:
integers = [1,2,3,4,5,6]
odd_ints = []
squared_odds = []
total = 0
for i in integers:
    if i%2 ==1
        odd_ints.append(i)
for i in odd_ints:
    squared_odds.append(i*i)
for i in squared_odds:
    total += i

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

А теперь — ещё один вариант этого кода:

from functools import reduce
integers = [1,2,3,4,5,6]
odd_ints = filter(lambda n: n % 2 == 1, integers)
squared_odds = map(lambda n: n * n, odd_ints)
total = reduce(lambda acc, n: acc + n, squared_odds)

Это — полностью функциональный код. Он короче. Он быстрее, так как тут не приходится перебирать множество элементов массива. И, если разобраться с функциями filter, map и reduce, окажется, что этот код понять не намного сложнее, чем тот, в котором применяются циклы.

Это не значит, что в любом функциональном коде используются map, reduce и прочие подобные функции. И это не означает, что для того чтобы с подобными функциями разобраться, нужно знать функциональное программирование. Дело лишь в том, что эти функции достаточно часто применяются тогда, когда избавляются от циклов.

▍Лямбда-функции


Когда говорят об истории функционального программирования, часто начинают с рассказа об изобретении лямбда-функций. Но, хотя лямбда-функции — это, без сомнения, краеугольный камень функционального программирования, они не являются главной причиной возникновения ФП.

Лямбда-функции — это инструменты, которые можно использовать для того чтобы писать программы в функциональном стиле. Но эти функции можно использовать и в объектно-ориентированном программировании.

▍Статическая типизация


Вышеприведённый пример не типизирован статически. Но он, тем не менее, представляет собой образец функционального кода.

Даже хотя статическая типизация добавляет дополнительный слой безопасности в код, она не является обязательным условием создания функционального кода. Она, правда, может быть приятным дополнением к функциональному стилю программирования.

Надо отметить, что на некоторых языках программировать в функциональном стиле легче, чем на других.

Некоторые языки «функциональнее» других


▍Perl


В Perl реализован такой подход к работе с побочными эффектами, который отличает его от большинства других языков. А именно, в нём имеется «волшебная переменная» $_, которая выводит побочные эффект на уровень одной из основных возможностей языка. У Perl есть свои достоинства, но я не стал бы пытаться заниматься функциональным программированием на этом языке.

▍Java


Желаю вам удачи в деле написания функционального кода на Java. Она вам не помешает. Во-первых, половину объёма кода будет занимать ключевое слово static. Во-вторых, большинство Java-программистов назовут ваш код недоразумением.

Это не значит, что Java — плохой язык. Но он не создан для решения тех задач, для решения которых отлично подходит функциональное программирование. Например — для управления базами данных или для разработки приложений из сферы машинного обучения.

▍Scala


Scala — интересный язык. Его цель — унификация функционального и объектно-ориентированного программирования. Если вам это кажется странным, то знайте, что вы не одиноки. Ведь функциональное программирование нацелено на полное устранение побочных эффектов. А объектно-ориентированное программирование направлено на ограничение побочных эффектов рамками объектов.

Учитывая это, можно сказать, что многие разработчики видят в Scala язык, который поможет им перейти от объектно-ориентированного к функциональному программированию. Использование Scala может упростить для них, в будущем, переход на полностью функциональный стиль программирования.

▍Python


В Python приветствуется функциональный стиль программирования. Понять это можно, если учесть тот факт, что у каждой функции, по умолчанию, есть, как минимум, один параметр — self. Это, во многом, в духе «Дзена Python»: «Явное лучше, чем неявное».

▍Clojure


Clojure, по словам создателя языка, является функциональным примерно на 80%. Все значения, по умолчанию, неизменяемы. А ведь именно это и нужно для написания функционального кода. Правда, обойти это можно, используя изменяемые контейнеры, в которые помещают неизменяемые значения. А если извлечь значение из контейнера — оно снова становится неизменяемым.

▍Haskell


Это — один из немногих полностью функциональных и статически типизированных языков. Хотя при его использовании в процессе разработки и может показаться, что на реализацию функциональных механизмов уходит слишком много времени, подобные усилия многократно окупятся во время отладки кода. Этот язык выучить не так просто, как другие, но его изучение — это, безусловно, стоящее вложение времени.

Итоги


Надо отметить, что сейчас — всё ещё самое начало эры больших данных. Большие данные идут, и не одни, а с другом — с функциональным программированием.

Функциональное программирование, если сравнить его с объектно-ориентированным программированием, всё ещё остаётся нишевым феноменом. Правда, если считать значимым явлением интеграцию принципов ФП в Python и в другие языки, то можно сделать вывод о том, что функциональное программирование набирает популярность.

И в этом есть смысл, так как функциональное программирование хорошо показывает себя в работе с базами данных, в параллельном программировании, в сфере машинного обучения. А в последнее десятилетие всё это находится на подъёме.

Хотя у объектно-ориентированного кода есть бесчисленное множество достоинств, не стоит сбрасывать со счетов и достоинства функционального кода. Если программист изучит некоторые базовые принципы ФП, то этого, в большинстве случаев, может быть достаточно для повышения его профессионального уровня. Такие знания, кроме того, помогут ему подготовиться к «функциональному будущему».

Как вы относитесь к функциональному программированию?

Let's block ads! (Why?)

Зачем Google инвестирует $450 млн в компанию-разработчика систем домашней безопасности ADT

В начале августа издание Bloomberg объявило о сделке – входящий в холдинг Alphabet поисковик Google купит 6,6% акций компании ADT за $450 млн. ADT занимается разработкой систем домашней безопасности. Зачем это Google? Разбираемся в нашей новой статье.

Что такое ADT


Компания ADT базируется в штате Флорида. Несмотря на то, что она не является очень хорошо известной – это крупнейший производитель инструментов для домашней безопасности в США. В ADT работает более 20 тысяч человек, продуктами фирмы пользуются более 6 млн клиентов.

Акции компании торгуются на нью-йоркской бирже NYSE. После объявления о сделке с Google, акции взлетели на 57%.

Зачем сделка нужна Google


В 2014 году Google купила производителей умных термостатов Nest за $3,2 млрд. За прошедшие годы это подразделение заняло лидирующие позиции на рынке производителей термостатов, пожарных сигнализаций и умных замков. В сфере домашней безопасности у Nest около 40% рынка, доля Amazon, которая производит системы Ring и голосового помощника Alexa, составляет 35%.

Google планирует использовать технологии ADT и мощности компании для улучшения и дистрибуции своих систем умного дома. Компания конкурирует на этом рынке с Amazon и Apple, но у нее нет ни сети офлайн-магазинов (Apple Store) ни своего онлайн-маркетплейса.

Партнерство с ADT позволит Google сделать шаг вперед на рынке. Раньше в системах домашней безопасности ADT могли использоваться голосовые ассистены любой компании, теперь же продуктам Google будет отдаваться приоритет. В рамках сделки компания станет вторым по размеру инвестором ADT.

Гендиректор ADT Джима ДеВрея (Jim DeVries) так прокомментировал будущее сотрудничество: «Компания будет интегрировать в свои продукты Alexa от Amazon, если об этом попросят клиенты, но в hardware-категориях, где представлены продукты Google, именно эта компания будет эксклюзивным партнером».

Также компании планируют отстраиваться от конкурентов с помощью дополнительных инвестиций в маркетинг при достижении определенных KPI. Так систему безопасности Ring от Amazon часто критикуют за слишком тесное сотрудничество с полицией – компаний предоставляет правоохранителям записи со своих камер. Руководитель ADT Джим ДеВрей говорил, что его компания не планирует заключать контракты с полицией и не будет предоставлять полицейским доступ к записям с камер.

В России акции Google и других американских компаний можно купить на Санкт-Петербургской бирже. Для этого не нужно открывать счет у иностранного брокера, достаточно будет российского счета. Открыть его можно онлайн.

Читайте обзоры, аналитику рынков и инвестидеи в Telegram-канале ITI Capital

Полезные ссылки по теме инвестиций и биржевой торговли:


Let's block ads! (Why?)

Склеиваем несколько фотографий в одну длинную с помощью машинного обучения

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

Этикетки заранее сегментированы и развернуты нейронной сетью, описанной в предыдущей статье.

Как вообще работает склеивание? Нужно взять две картинки с нахлестом, посчитать взаимный сдвиг и наложить одну на другую. Звучит довольно просто, но давайте рассмотрим каждый из шагов.

Чтобы посчитать взаимный сдвиг, нужно найти какие-то объекты, которые присутствуют на обоих изображениях и вычислить каким-то образом преобразование точек с одной картинки на другую. Этот сдвиг может быть представлен матрицей преобразования, где элементы матрицы кодируют сразу несколько трансформаций — масштабирование, перенос и вращение.
Есть отличная таблица в википедии, где показано, как и какие элементы влияют на трансформацию:
https://en.wikipedia.org/wiki/Transformation_matrix#/media/File:2D_affine_transformation_matrix.svg

Как видно на картинке ниже, общих объектов вполне хватает:

Но выбранными объектами есть проблема — их сложно детектировать алгоритмически. Вместо этого, принято искать более простые объекты — так называемые “уголки” (“corners”), они же дескрипторы (“descriptors”, “features”).
Есть отличная статья в документации OpenCV, почему именно уголки — если вкратце, то определить линию легко, но она дает только одну координату. Поэтому нужно детектировать еще и вторую (не параллельную) линию. Если они сходятся в точке, то это место и есть идеальное для поиска дескриптора, он же является уголком (хотя реальные дескрипторы не являются уголками в геометрическом смысле этого слова).
Одним из алгоритмов по поиску дескрипторов, является SIFT (Scale-Invariant Feature Transform). Несмотря на то, что его изобрели в 1999, он довольно популярен из-за простоты и надежности. Этот алгоритм был запатентован, но патент истёк этой весной (2020). Тем не менее, его не успели перенести в основную сборку OpenCV, так что нужно использовать специальный non-free билд.

Так давайте же найдем похожие уголки на обоих изображениях:

sift = cv2.xfeatures2d.SIFT_create()
features_left = sift.detectAndCompute(left_image, None)

features_right = sift.detectAndCompute(left_image, None)

Воспользуемся составителем дескрипторов Фланна (Flann matcher) — у него хорошая производительность даже, если количество дескрипторов велико.

KNN = 2
LOWE = 0.7
TREES = 5
CHECKS = 50

matcher = cv2.FlannBasedMatcher({'algorithm': 0, 'trees': TREES}, {'checks': CHECKS})
matches = matcher.knnMatch(left_descriptors, right_descriptors, k=KNN)

logging.debug("filtering matches with lowe test")

positive = []
for left_match, right_match in matches:
    if left_match.distance < LOWE * right_match.distance:
        positive.append(left_match)

Желтые линии показывают, как сопоставитель нашёл совпадения.

Как хорошо видно — правильных совпадений примерно только половина. Однако, если правильные совпадения всегда дают одно и то же преобразование, то неправильные показывают хаотично новое направление. Т.е. теоретически, их можно как-то отделить друг от друга:

Одним из алгоритмов, чтобы найти правильное преобразование, является RANSAC. Этот алгоритм отлично работает, если нужно отделить хорошие значения от шумов — как раз наш случай.
К счастью, в OpenCV уже есть функции, которые найдут матрицу преобразования по совпадениям, используя RANSAC, т.е. фактически, ничего писать не придется.
Воспользуемся функцией estimateAffinePartial2D которая ищет следующие преобразования: поворот, масштабирование и перенос (4 степени свободы).

H, _ = cv2.estimateAffinePartial2D(right_matches, left_matches, False)

Когда матрица преобразования найдена, мы можем трансформировать правое изображение для склейки.
Левый фрагмент:

Правый фрагмент:

Для начала давайте воспользуемся простейшим способом склейки фрагментов, когда каждый пиксель их пересечения вычисляется, как среднее. К сожалению, результат получается так себе — изображение заметно двоится, особенно возле линии склейки.

На анимации различие между двумя кадрами видны более наглядно:

Это не удивительно — фотографии были сделаны под разными углами, нейронная сеть также развернула их слегка по-разному, и в итоге получились небольшие расхождения.
Для бесшовной склейки, необходимо компенсировать нелинейные искажения. Искажение можно представить в виде векторного поля того же разрешения, что и исходное изображение, только вместо цвета, в каждом пикселе будет закодирован сдвиг. Такое векторное поле называется “оптический поток”.
Вообще, есть разные методики вычисления оптического потока — некоторые из них встроены прямо в OpenCV, а есть и специальные нейронные сети.
В нашем же случае, конкретную методику я опущу, но опубликую результат:

Но компенсацию нужно осуществлять пропорционально обоих фрагментов. Для этого разделим его на две матрицы:

Левый фрагмент будет компенсироваться слева направо по нарастающей, в то время, как правый — наоборот.

Теперь оба фрагмента накладываются один на другой практически идеально:

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

Эту проблему легко исправить, если вместо средних значений, накладывать их с градиентом:

С таким подходом, шва вообще не видно:

В принципе, есть еще и другие методики склейки, например, multiband blending, которые используют для склейки панорам, но они плохо работают с текстом — только компенсация оптического потока способно полностью убрать двоения на тексте.
Теперь склеиваем полное изображение:

Финальный варинат:

Дальнейшими улучшениями могут быть компенсация эффекта тени (правая сторона изображения), либо еще большая пост-обработка цвета и контрастности. Также видно, что слегка пострадала глобальная геометрия — линии справа чуть уползли вверх. Это проблему теоретически тоже можно исправить добавлением глобальной коррекцией масштабирования, но это тоже не совсем тривиальная задача.
Мы рассмотрели, как работает склейка, готовое решение доступно здесь в виде REST API, также рекомендую посмотреть следующие ссылки:

Let's block ads! (Why?)

Глава Viber рассказал, как протесты в Беларуси отразились на бизнесе компании

Гендиректор компании Rakuten Viber Джамел Агауа рассказал в интервью Forbes, что сейчас офис Viber в Беларуси закрыт ради безопасности сотрудников. Они все работают удаленно. Компания планирует сократить инвестирование в белорусскую экономику.
В минском офисе Viber работают 120 сотрудников. С начала лета из-за пандемии Covid-19 большая часть персонала работает удаленно. Также Viber имеет небольшой офис в Бресте. В планах компании было удвоение количества разработчиков в стране. Но сейчас они поменялись.

С начала протестных акций в Минске под разными предлогами было задержано двое сотрудников Viber, а также был арестован отец одного из сотрудников. Адвокаты компании помогали им выйти на свободу, так как для арестов не было причин. Сейчас один из задержанных отпущен, а второй по-прежнему числится арестованным, хотя и находится в больнице с серьезными травмами.

«Один просто находился рядом с местом, где арестовывали других, и его забрали с остальными. Другой был наблюдателем на избирательном участке. Он задал несколько вопросов руководству избирательного участка, а через 20 минут его арестовали», — рассказал Агауа.
Вдобавок к стране более недели были большие проблемы с доступом в интернет из-за блокировок. Агауа пояснил, что три четверти населения страны являются активными пользователями Viber. Компания зафиксировала в начале августа пиковое использование Viber несколько дней, пока не начались блокировки.
«Мы застали пиковое использование Viber за день, пока нас не заблокировали, когда интернет отключили. Около трех-четырех дней Viber то включался, то отключался из-за блокировки властями. Мы также работали над VPN, чтобы позволить людям пользоваться Viber, несмотря на блокировку,» — объяснил Агауа.
Теперь в компании ждут, когда прекратится насилие в стране. Только после этого руководство Viber начнет предпринимать определенные действия. Однако, если ситуация не улучшится, то компания начнет процесс сокращения инвестиций в экономику страны.

Агауа несколько раз в интервью уточнял, что Viber не занимается политикой, но против жестокости и страха.

С 9 августа мессенджер Viber был заблокирован в Беларуси.

11 августа 2020 года основатель Telegram Павел Дуров сообщил, что мессенджер активировал свои инструменты против цензуры в Беларуси на фоне протестов после президентских выборов. По его словам, это необходимо, чтобы сохранить доступ в Telegram для большинства пользователей.

13 августа в минских офисах «Яндекса» и Uber прошли обыски. Работа офисов была приостановлена. Несколько сотрудников “Яндекса” находились в это время на рабочих местах. Основания для проведения обысков, предъявленные сотрудниками правоохранительных органов в протоколах обысков, не были детализированы. В ходе обысков никакое оборудование или документы изъяты не были. По окончании обысков сотрудники не задерживались.

Let's block ads! (Why?)

Дуализм частица-волна: наглядно

«Если вам кажется, что вы понимаете квантовую теорию… то вы не понимаете квантовую теорию.» — Фейнман Р., лекции «Характер физических законов» (1964), гл. 6.

Это и подобные высказывания о непостижимости законов квантовой механики всегда раздражали меня. Корпускулярно-волновой дуализм, свойства квантовых частиц вести себя как волны и как частицы — неужели нельзя их понять наглядно, увидеть не как поведение математических решений, а воочию? В этом обзоре я представлю результаты, оспаривающие этот мистицизм.


Вывод соотношения де Бройля

Луи де Бройлю были известны соотношения $E = h\nu$ (формула Планка) и $E_0=m_0c^2$ (эквивалентность массы и энергии в специальной теории относительности) где $m_0$ – масса покоя, т.е. масса в собственной системе отсчёта.

Согласно теории относительности абсолютного времени нет, и у каждой точки пространства оно своё собственное – четвертая координата t. Собственное время, как рассуждал Луи де Бройль, это как личные часы. Они есть как у человека, так и у электрона. Что это значит?

Он предположил, что каждой частице свойственен внутренний периодический процесс (тик-так с частотой ), который служит мерой собственного времени [1]. Этот самый внутренний процесс с частотой в собственной системе отсчета позволяет связать две формулы энергии

$ E_0=m_0c^2=h\nu_0 $

Неподвижный наблюдатель воспринимает колебательный процесс $\nu_0$ частицы летящей со скоростью $v$ в точке $x$ как

$\psi=\exp(2\pi i\nu t)$

Переход в систему отсчёта частицы даёт в показателе экспоненты

$\underset{\nu}{\underbrace{\nu_0\sqrt{1-\frac{v^2}{c^2}}}}\cdot\underset{t}{\underbrace{\frac{-t_0+\frac{v}{c^2}x}{\sqrt{1-\frac{v^2}{c^2}}}}}=\frac{v}{c^2}x-\nu_0t_0 $

то есть бегущую волнуволну де Бройля, которая всегда синхронизирована по фазе с внутренним процессом $\exp(2\pi i\nu_0t_0)$

$ \psi=\exp(2\pi i(\frac{v}{c^2}x-\nu_0t_0)) $

Подставляя формулы для энергии, получаем

$\psi(x,t)=\exp(2\pi i(\frac{m_0c^2}{h}\frac{v}{c^2}\cdot x-\frac{E}{h}t_0))=\exp(2\pi i(\frac{m_0v}{h}x-\frac{E_0}{h}t_0))=\exp(\frac{i}{\hbar}(p\cdot x-E\cdot t)) $

В таком случае частице, летящей со скоростью $v$ соответствует длина волны

$ \lambda=\frac{h}{p} $

где $p=mv$ – импульс частицы, а $h$постоянная Планка.

Это была математика. Теперь найдем реальный объект, для которого собственные колебания синхронизированы с волной.


Частицы-волны? Силиконовые капли-волны!


Французский физик Ив Куде исследовал поведение прыгающей капли-«блинчика» силиконового масла на поверхности жидкости в вибрационной ванне. Слой жидкости (силиконового масла) в ванне был толщиной 4 мм. Под действием вибрации на поверхности появляется рябь (волны Фарадея), если вертикальное ускорение при вибрировании больше пороговой величины (4.5g в условиях эксперимента). Однако, в подпороговом режиме вибрации с частотой 50 Гц в ванне 40x40 мм дают иную картину стоячих волн с длиной =6.5 мм. Капля силиконового масла размером 1 мм, аккуратно помещенная на поверхность, прыгает по этим волнам не собираясь останавливаться.
image
Экспериментальная установка Ива Куде. Левая верхняя часть рисунка – фотографии движения капли по поверхности. Правая верхняя часть – встреча «блинчика» с дифракционной щелью. Внизу – схема установки. 1 – «блинчик», 2 – траектория его движения, волна, 3 – затухающий всплеск от удара «блинчика» о поверхность, 4 – подтопленная стенка-препятствие, из них сделаны дифракционные щели, 5 – вибростенд.

Силиконовая капля, ведомая волнами на поверхности ведёт себя как квантовая частица. Её прыжки — внутренний колебательный процесс синхронизированный с её «волной де Бройля» соответствующей траектории движения «блинчика» 2 на рисунке.
В местах, где глубина масла меньше (подтопленная стенка 4), стоячие волны затухают и поверхность не может подкидывать «блинчик». Эти участки моделируют препятствия для прыгающей капли (дифракционные щели) не разрушая её. Так был воспроизведен знаменитый двухщелевой эксперимент: собранная статистика поведения капли схожа с таковой у электрона [2].
image
Статистика отклонений силиконовой капли-блинчика по данным Y. Couder and E. Fort. Single-particle diffraction and interference at a macroscopic scale. Phy. Rev. Lett., 97(15):154101, 2006.

В недавнем посте Путь частицы или волна-пилот наносит ответный удар упоминалось, что более тщательные эксперименты развеяли подобные надежды, а именно, дать наглядную картину корпускулярно-волнового дуализма с помощью прыгающих капелек. Речь шла о работе Томаса Бора (да, внука того самого Нильса Бора, что придумал принцип дополнительности и мистифицировал квантовую механику). Грубо, суть его аргументов сводилась к тому, что дифракционная картина Ива Куде — иллюзия, распределение не фраунгоферовское, а скорее всего просто гауссово и эффекта нет.
image
По мнению Томаса Бора, случайный разброс (гаусс, рисунок справа) лучше описывает экспериментальные данные, чем дифракция (фраунгофер, слева). И вообще его дед Нильс Бор был во всем прав и непогрешим.

Конечно, прыгающие капли не точное подобие квантовых частиц, однако, они безусловно кандидаты на роль моделей квантовой механики. Ив Куде собрал систему автоколебательную. А про автоколебательные системы известно, что они обладают дискретностью состояний. Очень хорошо об автоколебаниях (картинки, объяснения, код) изложено в посте Автоколебания и резонанс. Детальные исследования системы Ива Куде показали, что у нее много разных режимов, в рассеянии капель есть отличия от картины дифракции электронов, но тем не менее, главное — они в самом деле ведут себя как частицы-волны.

Стоит отметить, что в отечественной науке обсуждались подобные идеи намного раньше, например, в книге томского ученого Б.Н. Родимова «Автоколебательная квантовая механика» [3]. Он тоже сконструировал частицу-волну. К сожалению, его идеи не были подхвачены.
image


Литература


  1. Л. де Бройль «Волны и кванты» 93 178–180 (1967)
  2. Robert Brady and Ross Anderson. Why bouncing droplets are a pretty good model of quantum mechanics. 2014.
  3. Б.Н. Родимов «Автоколебательная квантовая механика», Томск 1967.

Let's block ads! (Why?)

FCC открыла 6 ГГц диапазон для Wi-Fi — почему за это на нее подали в суд, и как развивается ситуация

Обсуждаем ситуацию и мнения ассоциаций, назвавших решение комиссии незаконным.


/ CC BY / John Schnobrich

Больше частот — лучше для пользователей


Причиной открытия 6-гигагерцового диапазона для работы домашних беспроводных сетей стало желание FCC высвободить перегруженные частоты 2,4 и 5 ГГц. Новый спектр предлагает семь дополнительных каналов, сокращает помехи и увеличивает скорость Wi-Fi почти до 10 Гбит/с.

Решение FCC поддержали в Wi-Fi Alliance. Организация даже разработала новый протокол — Wi-Fi 6E. В Apple и Facebook заявили, что он позволит им запустить проекты виртуальной реальности и стриминговые платформы с высоким качеством изображения. На этой неделе Google уже запросила разрешение на тестирование Wi-Fi на 6 ГГц — корпорация планирует улучшить качество широкополосного соединения для своих IoT-устройств.

Но есть и организации, назвавшие решение FCC крайне неудачным и даже незаконным.

Кто считает, что это плохая идея


Опасения высказали специалисты из Национальной организации управления спектром США. По их мнению, работа домашних сетей на частоте 6 ГГц создаст помехи для систем, которые уже его используют. В нескольких крупных американских городах он отведен для полицейских и пожарных служб. Существует вероятность, что с распространением нового стандарта в домашних сетях, спецслужбы будут вынуждены модифицировать свою ИТ-инфраструктуру.
О чем мы пишем на Хабре:

Ассоциация Utilities Technology Council (UTC), которая занимается развитием технологий в сфере коммуникаций, подала на Комиссию по связи в суд. Глава UTC заявляет, что FCC не имела права предоставлять 6-гигагерцовый спектр для массового использования без соответствующих методов предотвращения помех. Так, возникает риск создать проблемы с коммуникациями в областях, где на кону стоят человеческие жизни.


/ CC BY / Stephen Phillips

Еще одной организацией, подавшей на FCC в суд, стала Национальная ассоциация телерадиовещателей США (NAB). Её представители называют решение комиссии «незаконным», так как оно не учитывает интересы телевизионных и телекоммуникационных компаний. Загрузка этого канала может ухудшить качество предоставляемых телевизионщиками услуг.

Свои опасения по поводу 6-гигагерцовых сетей также высказали американские военные и владельцы погодных станций.

Реакция комиссии


Глава FCC Аджит Пай (Ajit Pai) говорит, что волноваться не о чем — специалисты технического отдела комиссии провели тесты и новый стандарт не мешает работе других систем и каналов связи. В то же время ИТ-компании, производящие оборудование для беспроводных сетей, должны будут внедрить механизмы предотвращения помех. Но в каком направлении продолжит развиваться ситуация станет понятно после первых судебных слушаний.
О работе интернет-провайдеров в нашем корпоративном блоге:

Let's block ads! (Why?)

Заметки Дата Сайентиста: персональный обзор языков запросов к данным


Рассказываю из личного опыта, что где и когда пригодилось. Обзорно и тезисно, чтобы понятно было, что и куда можно копать дальше — но тут у меня исключительно субъективный личный опыт, у вас, может быть, все совсем по-другому.

Почему важно знать и уметь обращаться с языками запросов? По своей сути в Data Science есть несколько важнейших этапов работы и самый первый и важнейший (без него уж точно ничего работать не будет!) — это получение или извлечение данных. Чаще всего данные в каком-то виде где-то сидят и их нужно оттуда «достать». 

Языки запросов как раз и позволяют эти самые данные извлечь! И сегодня я расскажу, о тех языках запросов, которые мне пригодились и расскажу-покажу, где и как именно — зачем оно нужно для изучения.

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

  • «Стандартные» языки запросов — то, что обычно понимают, когда говорят о языке запросов, как, например, реляционная алгебра или SQL.
  • Скриптовые языки запросов: например, питоновские штучки pandas, numpy или shell scripting.
  • Языки запросов к графам знаний и графовым базам данных.

Все написанное здесь — это просто персональный опыт, что пригодилось, с описанием ситуаций и «зачем оно было нужно» — каждый может примерить, насколько подобные ситуации могут встретиться вам и попробовать подготовиться к ним заранее, разобравшись с этими языками до того, как придется их в (срочном порядке) применять на проекте или вообще попасть на проект, где они нужны.

«Стандартные» языки запросов


Стандартные языки запросов именно в том плане, что обычно мы именно о них и думаем, когда говорим про запросы.

Реляционная алгебра


Зачем сегодня нужна реляционная алгебра? Для того чтобы иметь хорошее представление, почему языки запросов устроены определенным образом и осознанно их использовать нужно разобраться с ядром, лежащим в основе.

Что такое реляционная алгебра?

Формальное определение такое: реляционная алгебра --  замкнутая система операций над отношениями в реляционной модели данных. Если чуть более по-человечески, это система операций над таблицами, такая что результатом тоже всегда является таблица.

См. все реляционные операции в этой статье с Хабра — здесь же мы описываем, зачем нужно знать и где пригождается.

Зачем?

Начинаешь понимать, на что вообще складываются языки запросов и какие операции стоят за выражениями конкретных языков запросов — часто дает более глубокое понимание того, что и как работает в языках запросов.


Взято из этой статьи. Пример операции: join, который объединяет таблицы.

Материалы для изучения:

Хороший вводный курс от Стэнфорда. Вообще, материалов по реляционной алгебре и теории очень много — Сoursera, Udacity. Есть также огромное количество материалов онлайн, в том числе хороших академических курсов. Мой персональный совет: надо понимать реляционную алгебру очень хорошо — это основа основ.

SQL



Взято из этой статьи.

SQL — это, по сути, имплементация реляционной алгебры — с важной оговоркой, SQL — декларативен! То есть записывая запрос на языке реляционной алгебры, вы фактически говорите, как нужно считать — а вот с SQL вы задаете, что хотите извлечь, а дальше СУБД уже генерирует (эффективное) выражения на языке реляционной алгебры (их эквивалентность известна нам под теоремой Кодда).


Взято из этой статьи.

Зачем?

Реляционные СУБД: Oracle, Postgres, SQL Server, etc — по-прежнему фактически повсюду и невероятно велик шанс того, что вам придется с ними взаимодействовать, а это означает, что придется либо читать SQL (что очень вероятно), либо писать на нем (тоже не маловероятно).

Что читать и изучать

По тем же ссылкам выше (про реляционную алгебру), есть невероятное количество материала, например, этот.

Кстати, а что такое NoSQL?

«Стоит еще раз подчеркнуть, что термин «NoSQL» имеет абсолютно стихийное происхождение и не имеет общепризнанного определения или научного учреждения за спиной.» Соответствующая статья на Хабре.

По сути, люди поняли, что полная реляционная модель не нужна для решения многих задач, особенно для тех, где, например, принципиальна производительность и доминируют определенные простые запросы с агрегацией — там критично быстро считать метрики и писать их в базу, а большинство фич реляционной оказались не только не нужны, но и вредны — зачем нормализовывать что-то, если это будет портить самое важное для нас (для некоторой конкретной задачи) — производительность?

Также часто нужные гибкие схемы вместо фиксированных математических схем классической реляционной модели — и это невероятно упрощает разработку приложений, когда критично развернуть систему и начать работать быстро, обрабатывая результаты — или схема и типы хранимых данных не так уж и важны.

Например, мы создаем экспертную систему и хотим хранить информацию по определенному домену вместе с некоторой метаинформацией — мы можем и не знать всех полей и банально хранить JSON для каждой записи — это дает нам очень гибкую среду для расширения модели данных и быстрого итерирования — поэтому в таком случае NoSQL будет даже предпочтительнее и читаемее. Пример записи (из одного моего проекта, где NoSQL был прям там, где нужно).

{"en_wikipedia_url":"https://en.wikipedia.org/wiki/Johnny_Cash",
"ru_wikipedia_url":"https://ru.wikipedia.org/wiki/?curid=301643",
"ru_wiki_pagecount":149616,
"entity":[42775,"Джонни Кэш","ru"],
"en_wiki_pagecount":2338861}

Подробнее можно прочитать тут про NoSQL.

Что изучать?

Тут скорее нужно быть просто хорошо проанализировать свою задачу, какие у нее свойства и какие имеются NoSQL системы, который бы подходили под это описание — и уже заниматься изучением данной системы.

Скриптовые языки запросов


Сначала, кажется, причем тут вообще Python — это язык программирования, а не про запросы вовсе.
  • Pandas — это прям швейцарский нож Data Science, огромное количество трансформации данных, агрегации и тд происходит в нем.
  • Numpy — векторные вычисления, матрицы и линейная алгебра там.
  • Scipy — много математики в пакете этом, особенно статы.
  • Jupyter lab — много exploratory data analysis хорошо вписывается в ноутбуки — полезно уметь.
  • Requests — работа с сетью.
  • Pyspark — очень популярны среди инженеров данных, скорее всего, вам придется взаимодействовать с этой либо и спарком, просто в силу их популярности.
  • *Selenium — очень полезен для сбора данных сайтов и ресурсов, иногда просто по-другому данные никак не получить.

Мой главный совет: учите Python!

Pandas


Возьмем в качестве примера следующий код:
import pandas as pd
df = pd.read_csv(“data/dataset.csv”)
# Calculate and rename aggregations
all_together = (df[df[‘trip_type’] == “return”]\
    .groupby(['start_station_name','end_station_name'])\
                            .agg({'trip_duration_seconds': [np.size, np.mean, np.min, np.max]})\
                           .rename(columns={'size': 'num_trips', 
           'mean': 'avg_duration_seconds',    
           'amin': min_duration_seconds', 
           ‘amax': 'max_duration_seconds'}))

По сути, мы видим, что код вписывается в классический SQL паттерн.
SELECT start_station_name, end_station_name, count(trip_duration_seconds) as size, …..
FROM dataset
WHERE trip_type = ‘return’
GROUPBY start_station_name, end_station_name

Но важная часть — этот код является часть скрипта и пайплайна, фактически мы встраиваем запросы в Питоновский пайплайн. В данной ситуации язык запросов к нам приходит из библиотек, таких как Pandas или pySpark.

В целом в pySpark мы видим схожий тип трансформации данных через язык запросов в духе:

df.filter(df.trip_type = “return”)\
  .groupby(“day”)\
  .agg({duration: 'mean'})\
  .sort()

Где и что почитать

По самому питону вообще не проблема найти материалы для изучения. В сети огромное количество тьюториалов по pandas, pySpark и курсов по Spark (а также по самому DS). В целом тут материалы великолепно гуглятся и если бы мне нужно было выбрать один пакет, на котором стоит сфокусироваться — то это был бы pandas, конечно. По связке DS+Python материалов тоже очень много.

Shell как язык запросов


Немало проектов по обработке и анализу данных, с которыми мне приходилось работать — это, по сути, shell скрипты, которые вызывают код на питоне, на java и собственно сами shell команды. Поэтому в целом можно рассматривать пайплайны в баше/zsh/etc, как некоторый высокоуровневый запрос (можно туда, конечно, и циклы запихать, но это нетипично для DS кода на шелл языках), приведем простой пример — мне нужно было сделать маппинг QID викидаты и полной ссылки на русскую и английскую вики, для этого я написал простой запрос из команд в баше и для вывода написал простой скприт на питоне, которые я собрал вместе вот так:
pv “data/latest-all.json.gz” | 
unpigz -c  | 
jq --stream $JQ_QUERY | 
python3 scripts/post_process.py "output.csv"

где
JQ_QUERY = 'select((.[0][1] == "sitelinks" and (.[0][2]=="enwiki" or .[0][2] =="ruwiki") and .[0][3] =="title") or .[0][1] == "id")' 

Это был, по сути, весь пайплайн, который создавал нужный mapping, как мы видим все, работало в режиме потока:
  • pv filepath — дает прогресс бар на основе размера файла и передает его содержимое дальше
  • unpigz -c читал часть архива и отдавал jq
  • jq с ключом — stream сразу выдавал результат и передавал его постпроцессору (так же как и с самым первым примером) на питоне
  • внутри постпроцессор — это простая машина состояний, которая форматировала вывод 

Итого сложный пайплайн работающий в режиме потока на больших данных (0.5TB), без существенных ресурсов и сделан из простого пайплайна и пары тулзов.
Еще один важный совет: умейте хорошо и эффективно работать в терминале и писать на bash/zsh/etc.
Где пригодится? Да почти везде — материалов для изучения опять же ОЧЕНЬ много в сети. В частности, вот эта моя предыдущая статья.

R scripting


Опять же читатель может воскликнуть — ну это же целый язык программирования! И конечно же, будет прав. Однако, обычно мне приходилось сталкиваться с R всегда в таком контексте, что, по сути, это было очень похоже на язык запросов.

R — это среда статистических вычислений и язык статических вычислений и визуализации (согласно этому).


Взято отсюда. Кстати, рекомендую, неплохой материал.

Зачем дата саентисту знать R? По крайней мере, потому что есть огромный пласт людей не из IT, которые занимаются анализом данных на R. Мне встречалось в следующих местах:

  • Фармацевтический сектор.
  • Биологи.
  • Финансовый сектор.
  • Люди с чисто математическим образованием, занимающихся статами.
  • Специализированные статистические модели и модели машинного обучения (которые часто можно найти только в авторской версии в виде R пакета).

Почему это фактически язык запросов? В том виде, в котором он часто встречается — это фактически запрос на создание модели, включая чтение данных и фиксирование параметров запроса (модели), а также визуализация данных в таких пакетах как ggplot2 — это тоже форма написания запросов.

Пример запросов для визуализации

ggplot(data = beav, 
       aes(x = id, y = temp, 
           group = activ, color = activ)) +
  geom_line() + 
  geom_point() +
  scale_color_manual(values = c("red", "blue"))

В целом многие идеи из R перекочевали в пакеты python, такие как pandas, numpy или scipy, как датафреймы и векторизация данных — поэтому в целом очень многие вещи в R покажутся вам знакомыми и удобными.

Источников для изучения много, например, этот.

Графы знаний (Knowledge graph)


Тут у меня чуть необычный опыт, потому что мне таки довольно часто приходится работать с графами знаний и языки запросов к графам. Поэтому лишь кратко пройдемся по основам, так эта часть чуть более экзотическая.

В классических реляционных базах у нас фиксированная схема — здесь же схема гибкая, каждый предикат — это фактически «колонка» и даже больше.

Представьте, что вы бы моделировали человека и хотели описать ключевые вещи, для примера возьмем конкретного человека Дугласа Адамса, за основу возьмем вот это описание.


www.wikidata.org/wiki/Q42

Если бы мы использовали реляционную базу, нам бы пришлось создать огромную таблицу или таблицы с огромным количеством колонок, большая часть из которых бы была NULL или заполнена каким-то дефолтным False значением, например, вряд ли у многих из нас есть запись в национальной корейской библиотеке — конечно, мы могли бы выносить их в отдельные таблицы, но это бы в конечном итоге была бы попытка смоделировать гибкую логическую схему с предикатами, с помощью фиксированной реляционной.


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

Где вы вообще можете с таким столкнуться? Во-первых, работая с вики данными, да и с любыми графовыми базами данных или связными данными.

Далее следуют основные языки запросов, которые мне приходилось применять и с которыми приходилось работать.

SPARQL


Wiki:
SPARQL (рекурсивный акроним от англ. SPARQL Protocol and RDF Query Language) — язык запросов к данным, представленным по модели RDF, а также протокол для передачи этих запросов и ответов на них. SPARQL является рекомендацией консорциума W3C и одной из технологий семантической паутины.

А реально это язык запросов к логическим унарным и бинарным предикатам. Вы просто условно указывается, что является фиксированным в логическом выражении, а что нет (очень упрощенно).

Сама база RDF (Resource Description Framework), над которой выполняются SPARQL запросы — это тройка object, predicate, subject — и запрос выбирает нужные тройки по указанным ограничениям в духе: найти такой X, что p_55(X, q_33) верно — где, разумеется, p_55 — это какое-то отношение с айди 55, а q_55 — это объект с айди 33 (вот и весь сказ, опять же опуская всевозможные детали).

Пример представления данных:


Картинки и пример со странами вот отсюда.

Пример базового запроса

Фактически мы хотим найти значение переменной ?country, такой что для предиката
member_of, верно, что member_of(?country,q458), а q458 — это ID европейского союза.

Пример реального запроса SPARQL внутри движка python:

Как правило, мне приходилось читать SPARQL, а не писать — в такой ситуации, скорее всего, это будет полезным навыком понимать язык хотя бы на базовом уровне, чтобы понять, как именно извлекаются данные. 

Онлайн много материалов для изучения: например, вот этот и этот. Сам обычно гуглю конкретные конструкции и примеры и пока хватает.

Логические языки запросов


Подробнее по теме можно прочитать в моей статье тут. А здесь, мы лишь кратко разберем, почему логические языки хорошо подходят для написания запросов. По сути, RDF это просто набор вида логических утверждений вида p(X) и h(X,Y), а логический запрос имеет следующий вид:

output(X) :- country(X), member_of(X,“EU”).

Тут мы говорим, о создании нового предиката output/1 (/1 — значит унарный), при условии, что для X верно, что country(X) — т.е., Х — это страна и также member_of(X,“EU”).

То есть у нас и данные, и правила в таком случае представлены вообще одинаково, что позволяет очень легко и хорошо моделировать задачи.

Где встречались в индустрии: целый большой проект с компанией, которая пишет на таком языке запросы, а также на текущем проекте в ядре системы — казалось бы, вещь довольно экзотическая, однако иногда встречается.

Пример фрагмента кода на логическом языке, обрабатывающем wikidata:


Материалы: приведу тут парочку ссылок на современный логический язык программирования Answer Set Programming — рекомендую изучать именно его:

Let's block ads! (Why?)