Русский
Русский
English
Статистика
Реклама

Big data

Заметки Дата Сайентиста на что обратить внимание при выборе модели машинного обучения персональный топ-10

04.09.2020 14:06:16 | Автор: admin

Мы снова в эфире и продолжаем цикл заметок Дата Сайентиста и сегодня представляю мой абсолютно субъективный чек-лист по выбору модели машинного обучения.

Это топ-10 свойств задачи и просто пунктов (без порядка в них), с точки зрения которых я начинаю выбор модели и вообще моделирование задачи по анализу данных.

Совсем не обязательно, что у вас он будет таким же здесь все субъективно, но делюсь опытом из жизни.

А какая у нас вообще цель? Интерпретируемость и точность спектр



Источник

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

В чем, собственно, состоит бизнес задача?

Или исследовательская, если речь об академии, etc.

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

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

Но по сути нужно не просто прогнать Catboost / Xgboost / Random Forest и выбрать модельку, а понять, что хочет бизнес, какие у нас есть данные и как это будет применяться.

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

Тип самой задачи


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

  • Exploratory analysis чистая аналитика имеющихся данных и тыканье палочкой
  • Clustering собрать данные в группы по какой-тому общему признаку(ам)
  • Regression нужно вернуть целочисленный результат или там вероятность события
  • Classification нужно вернуть одну метку класса
  • Multi-label нужно вернуть одну или более меток класса для каждой записи

Примеры

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


И нужно построить модель, которая разметит эти самые данные:


Или как вариант никаких меток нет и нужно выделить группы:


Как например вот здесь:


Картинки отсюда.

А вот собственно пример иллюстрирует разницу между двумя понятиями: классификация, когда N > 2 классов multi class vs. multi label


Взято отсюда

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

Точность и как она определена


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

Поэтому вопрос об измерении качества работы первичен! Или представьте, что у вас присутствует существенный дисбаланс в данных, класс А = 10%, а class B = 90%, тогда классификатор, который просто возвращает B всегда умеет 90% точность! Скорее всего это не то, чтобы хотели увидеть, обучая модель.

Поэтому критично определить метрику оценки модели включая:

  • weight class как в примере выше, вес плохого кредита 5, а хорошего 1
  • cost matrix возможно перепутать low и medium risk это не беда, а вот low risk и high risk уже проблема
  • Должна ли метрика отражать баланс? как например ROC AUC
  • А мы вообще считаем вероятности или прям метки классов?
  • А может быть класс вообще один и у нас precision/recall и другие правила игры?

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

Model post analysis


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


Однако, что если нам нужно знать направление большие значения признака A увеличивают принадлежность классу Z или наоборот? Назовем их направленные feature importance их можно получить у некоторых моделей, например, линейных (через коэффициенты на нормированных данных)

Для ряда моделей, основанных на деревьях и бустинге например, подходит метод SHapley Additive exPlanations.

SHAP


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


Он позволяет оценить направление эффекта:


Причем для деревьев (и методах на них основанных) он точный. Подробнее об этом тут.

Noise level устойчивость, линейная зависимость, outlier detection и тд


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

Также признаки могут быть коллинеарны и присутствовать бессмысленные признаки разные модели по-разному на это реагируют. Приведем пример на классическом датасете German Credit Data (UCI) и трех простых (относительно) моделях обучения:

  • Ridge regression classifier: классическая регрессия с регуляризатором Тихонова
  • Decition trees
  • CatBoost от Яндекса

Ridge regression
# Create Ridge regression classifierridge_clf = RidgeClassifier(class_weight=class_weight, random_state=42)X_train, X_test, y_train, y_test = train_test_split(pd.get_dummies(X), y, test_size=0.33, random_state=42)# Train modelridge_model = ridge_clf.fit(X_train, y_train)y_pred = ridge_model.predict(X_test)print(classification_report(y_test,y_pred))print("weighted_accuracy:",weighted_accuracy(y_test,y_pred))



Decision Trees
# Create Ridge regression classifierdt_clf = DecisionTreeClassifier(class_weight=class_weight, random_state=42)X_train, X_test, y_train, y_test = train_test_split(pd.get_dummies(X), y, test_size=0.33, random_state=42)# Train modeldt_model = dt_clf.fit(X_train, y_train)y_pred = dt_model.predict(X_test)print(classification_report(y_test,y_pred))print("weighted_accuracy:", weighted_accuracy(y_test,y_pred))



CatBoost
# Create boosting classifiercatboost_clf = CatBoostClassifier(class_weights=class_weight, random_state=42, cat_features = X.select_dtypes(include=['category', object]).columns)X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.33, random_state=42)# Train modelcatboost_model = catboost_clf.fit(X_train, y_train, verbose=False)y_pred = catboost_model.predict(X_test)print(classification_report(y_test,y_pred))print("weighted_accuracy:",weighted_accuracy(y_test,y_pred))



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

Еще про DT а если чуть чуть поменять датасет? Feature importance может поменяться, так как decision trees вообще чувствительные методы, даже к перемешиванию данных.

Вывод: иногда проще лучше и эффективнее.

Масштабируемость


Действительно ли вам нужен Spark или нейросети с миллиардами параметров?

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

Спарк усложняет отладку, добавляет overhead и усложняет разработку не стоит его применять там, где не нужно. Классика.

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



И конечно же необходимо учитывать, что если у вас и правда крупные данные, то модель должна быть способной работать на них как обучаться по батчам, либо иметь какие-то механизмы распределенного обучения (и тд). А там же не слишком терять в скорости при увеличении объема данных. Например, мы знаем, что kernel methods требуют квадрата памяти для вычислений в dual space если вы ожидаете увеличение размера данных в 10 раз, то стоит дважды подумать, а умещаетесь ли вы в имеющиеся ресурсы.

Наличие готовых моделей


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

  • Данных не очень много, но они очень специфичны для нашей задачи например, медицинские тексты.
  • Тема в целом относительно популярна например, выделением тем текста много работ в NLP.
  • Ваш подход допускает в принципе до-обучение как например с некоторым типом нейросетей.


Pre-trained модели как GPT-2 и BERT могут существенно упростить решение вашей задачи и если уже натренированные модели существуют крайне рекомендую не проходит мимо и использовать этот шанс.

Feature interactions и линейные модели


Некоторые модели лучше работают, когда между признаками (features) нет сложных взаимодействий например весь класс линейных моделей Generalized Additive Models. Есть расширение этих моделей на случай взаимодействия двух признаков под название GA2M Generalized Additive Models with Pairwise Interactions.

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



Однако, если признаки активно взаимодействуют группами больше 2, то данные методы уже не показывают таких хороших результатов.

Package and model support




Многие крутые алгоритмы и модели из статей бывают оформлены в виде модуля или пакета для python, R и тд. Стоит реально дважды подумать, прежде чем использовать и в долгосрочной перспективе полагаться на такое решение (это я говорю, как человек написавший немало статей по ML с таким кодом). Вероятность того, что через год будет нулевая поддержка очень высок, ибо автору скорее всего сейчас необходимо заниматься другими проектами нет времени, и никаких incentives вкладываться в развитие модуля или репозитория.

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

Biases and Fairness


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

Условно, представьте упрощенную модель, которая просто считает цитирования статей и пусть историки друг друга цитируют активно среднее 100 цитат, а математики нет, у них среднее 20 и пишут вообще мало, тогда система распознает всех историков, как хороших ибо цитируемость высокая 100 > 60 (среднее), а математиков, как плохих потому что у них у всех цитируемость куда ниже среднего 20 < 60. Такая система вряд ли может показаться кому-то адекватной.

Классика сейчас предъявить логику принятия решения и тренировки моделей, которые борются с таким предвзятым подходом. Таким образом, для каждого решения у вас есть объяснение (условно) почему оно было принято и как вы собственно приложили усилия к тому, чтобы модель не сделала фигню (ELI5 GDPR).


Подробнее у гугла тут, или вот в статье тут.

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

Если какая-то тема заинтересовала больше остальных пишите в комментарии, будем идти в глубину. (DFS)!

Подробнее..

Заметки Дата Сайентиста с чем начать и нужно ли оно?

17.09.2020 14:13:09 | Автор: admin

TL;DR это пост для вопросов/ответов про Data Science и о том, как войти в профессию и развиваться в ней. В статьей я разберу основные принципы и FAQ и готов отвечать на ваши конкретные вопросы пишите в комментариях (или в личке), я постараюсь на все ответить в течение нескольких дней.
С появлением цикла заметок дата сатаниста пришло немало сообщений и комментариев с вопросами о том, как начать и куда копать и сегодня мы разберем основные скиллы и вопросы возникшие после публикаций.

Все указанное тут не претендует ни какую истину в последней инстанции и является субъективным мнением автора. Мы разберем основные вещи, которые кажутся самыми важными в процессе.

Зачем именно это нужно


Для того, чтобы цель была достижима лучше, чтобы она хоть как-то конкретно выглядела вы хотите стать DS или Research Scientist в Facebook/Apple/Amazon/Netflix/Google смотрите требования, языки и необходимые навыки прям конкретно под какую позицию. Какой процесс найма? Как проходить обычный день в такой роли? Как выглядит усредненный профиль человека, который там работает?

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

Будет или это еще актуально


К тому моменту, как вы дорастете до позиции.

Представьте, что до вашей позиции вам нужно получить PhD, поработать 2-3 года в индустрии и вообще остричься, медитируя в монастыре не будет ли с Data Science такой же ситуации как когда-то с экономистами и юристами? Не изменится ли все до неузнаваемости в той области, которой вы хотите заниматься.

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

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

К примеру автор и не планировал идти в дата сатанисты, а во время PhD пилил сторонние проекты, которые сильно перекликались по скиллам с DS и по окончанию аспирантуры естественным образом перешел в среду, увидев хорошую позицию.

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

Разбивка навыков


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

Программирование/Скриптинг


С какими языками обязательно надо познакомиться? Python? Java? Shell scripting? Lua? Sql? C++?

Что именно нужно уметь и зачем в плане программирования тут спектр позиций очень разнится.

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

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

Например, для питона люди уже даже составляют карту изучения языка.

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

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


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

Обычно, я задаюсь следующими вопросами:

  • Что именно я делаю в компании?
  • Зачем?
  • Кто и как это будет использовать?
  • Какие у меня есть опции?
  • В каких границах находятся параметры?

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

Математика


Тут вы думаю и сами все понимаете без знания базовой математики вы не более чем бебезьян с гранатой (простите с Random Forest) поэтому нужно понимать хотя бы базовые вещи. Если бы я составлял прям самый минимальный список, то туда бы вошли:

  • Линейная алгебра огромное количество ресурсов легко гуглится, ищите, что вам больше всего подходит;
  • Математический анализ (хотя бы в объеме первых двух семестров);
  • Теория вероятностей она повсюду в машинном обучении;
  • Комбинаторика она фактически комплементарна к теорверу;
  • Теория графов хотя бы БАЗОВО;
  • Алгоритмы хотя бы объеме первых двух семестров (см. рекомендации Кормена в его книжке);
  • Матлогика хотя бы базово.

Практический анализ и визуализация данных


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

Exploratory data analysis должен стать просто чем-то естественным, как и все прочие трансформации данных и умение накидать простой пайплайн из unix тузлов (см. предыдущие статьи) или написать читаемый и понятный ноутбук.

Отдельно упомяну визуализацию: лучше один раз увидеть, чем сто раз услышать.

Показать менеджеру график в сто раз проще и понятнее, чем набор цифр, поэтому matplotlib, seaborn и ggplot2 ваши друзья.

Софт скиллы


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

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

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

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

Вы можете аргументированно и безэмоционально донести свою позицию, сказать да/нет или поставить под сомнение/поддержать решение.

Обучение


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

  • Онлайн курсы: coursera, udacity, Edx, etc;
  • Новые школы: онлайн и офлайн SkillFactory, ШАД, MADE;
  • Классические школы: магистерские программы университетов и курсы повышения квалификации;
  • Проекты можно просто выбрать интересные вам задачи и пилить, выкладывая на github;
  • Стажировки тут сложно что-то подсказать, надо искать, что имеется и находить подходящий варианты.

А надо ли оно?


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

  • Должно быть интересно;
  • Приносить внутреннее удовольствие (= хотя бы не причинять страданий);
  • Быть вашим.

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

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

Быть вашим это то самое ощущение, что вы примерно этим и хотели заниматься. У меня есть небольшая история. Я с самого детства увлекался рок-музыкой (и металлом ЛОСОСЬ!) и как очень многие захотел научиться играть и вот это вот все. Выяснилось, что у меня нет слуха и голоса меня это совершенно не смущало (а надо сказать многих исполнителей это и прямо на сцене не смущает), и вот еще школьником у меня появилась гитара и стало понятно, что мне не очень нравится часами сидеть и играть на ней. Шло тяжко, мне все время казалось, что выходит какая-то фигня я совершенно не получал от этого удовольствия и только чувствовал себя паршиво, глупо и совершенно неспособным. Я буквально из под палки себя заставлял садиться за занятия и в целом это было не в коня корм.

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

И в какой-то момент я понял, что игра на гитаре это не мое и реально-то мне нравится слушать, а не играть. А глаза-то горели, когда я писал игры и код (слушая в этот момент всякие разновидности металла) и вот это-то мне тогда и нравилось, и этим мне стоило заниматься.

А еще есть вопросы?


Конечно же мы не смогли пройтись по всем темам и вопросам, так что пишите комменты и в личку я всегда рад вопросам.



Подробнее..

Как Data Science продает вам рекламу? Интервью с инженером Unity

20.09.2020 14:22:27 | Автор: admin
Неделю назад в наших соцсетях выступал Никита Александров Data Scientist в Unity Ads, где он улучшает алгоритмы конверсии. Никита сейчас живет в Финляндии, и кроме прочего он рассказал об IT-жизни в стране.

Делимся с вами расшифровкой и записью интервью



Меня зовут Никита Александров, я вырос в Татарстане и там же окончил школу, занимался олимпиадами по математике. После этого поступил на факультет компьютерных наук ВШЭ и там закончил бакалавриат. В начале 4 курса съездил на учебу по обмену, провел семестр в Финляндии. Мне там понравилось, я поступил в магистратуру университета Аалто, хотя не закончил ее полностью я закончил все курсы и начал писать диплом, но ушел работать в Unity, не получив степень. Сейчас я работаю в Unity data scientist-ом, отдел называется Operate Solutions (раньше он назывался Monetization); непосредственно моя команда занимается доставкой рекламы. То есть, внутриигровое рекламы той, которая выдается, когда вы играете в мобильную игру и нужно заработать дополнительную жизнь, например. Я работаю над улучшением конверсии рекламы то есть, делаю так, чтобы игрок с большей вероятностью прошел по рекламе.

Как ты переехал?


Сначала я приехал в Финляндию учиться на семестр по обмену, после этого вернулся в Россию и закончил диплом. Потом я поступил на магистратуру в университет Аалто по machine learning / data science. Так как я учился по обмену, мне даже не пришлось сдавать экзамен по английскому; поступил легко, я знал, на что поступаю. Живу здесь уже 3 года.

Финский необходим?


Он необходим, если вы собираетесь учиться здесь на бакалавра. Очень мало программ на английском языке для бакалавров, нужен финский или шведский это второй государственный язык, некоторые университеты обучают на шведском. Но в магистратуре и PhD большинство программ англоязычные. Если говорить про ежедневное общение и быт тут большинство людей говорит на английском языке, примерно 90%. Люди нормально живут целыми годами (мой коллега живет вообще 20 лет) без финского языка.

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

Отличается ли качество обучения от университетов РФ? Дают ли всю необходимую базу для устройства джуниором?


Качество отличается. Как мне кажется, в России пытаются сразу давать много всего: сразу дифференциальные уравнения, дискретная математика и многое другое. На самом деле, нужно брать дополнительные материалы, в качестве курсовой или дипломной работы, что-то новое постигать самостоятельно, ходить на какие-то курсы. Здесь же мне было легко в магистратуре; я знал многое из того, что проходилось. Опять же, в Финляндии бакалавр это еще не специалист, тут по-прежнему есть такое разделение. Вот если ты магистр, то можно устраиваться на работу. Я бы сказал, что в магистратуре в Финляндии важны социальные скиллы, важно участвовать, быть активным; есть исследовательские проекты. Если есть интересные для вас исследования, и вы хотите глубже копнуть, то можно получить контакты профессора, работать в этом направлении, развиваться.

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

Чем компания в Финляндии мотивирует сотрудников, какие плюшки?


Кроме очевидного (зарплаты), есть социальные плюшки. Например, количество декретного отпуска для родителей. Есть медицинские страховки, акции, опционы. Бывает необычное начисление отпускных дней. Ничего особенного, в основном.

У нас в офисе есть сауна, например.

Есть еще купоны какое-то количество денег на обеды, на общественный транспорт, на культурно-спортивные мероприятия (музеи, спорт).

Что посоветовать гуманитарию для входа в IT?


Повторять школьный курс и поступать в ВШЭ? Часто прогеры имею математическую базу/олимпиады

Я советую, конечно, подтянуть математику. Но не обязательно повторять школьный курс. Точнее, его надо повторять только в том случае, если не помните совсем ничего. Кроме того, надо определиться, в какое именно IT вы хотите пойти. Для фронтендера не обязательно знать математику: надо просто брать курсы по фронтенду и учиться. Моя подруга недавно решила записаться на курсы от компании Accenture, она сейчас учит Scala; она не гуманитарий, но опыта программирования у нее не было никакого. В зависимости от того, что вы хотите программировать и на чем, нужно разное количество математики. Конечно, для Machine Learning-специальности нужна математика, в том или ином ключе. Но, если вы хотите просто попробовать есть много разных туториалов, открытой информации, мест, где можно поиграть с нейросетью или построить самостоятельно, или скачать готовую, поменять параметры и посмотреть, как она меняется. Все зависит от того, как сильна мотивация.

Если не секрет зарплаты, опыт, на чем пишете?


Я пишу на Python это универсальный язык для machine learning и data science. Опыт был различный опыт; я был простым инженером в нескольких компаниях, был на стажировке несколько месяцев в Москве. Не было постоянной работы до Unity. Туда я пришел тоже как стажер, поработал стажером 9 месяцев, потом сделал перерыв, а теперь работаю уже год. Зарплата конкурентоспособная, выше медианной для региона. Начинающий специалист будет зарабатывать от 3500 EUR; в разных компаниях это разнится. В общем, 3.5-4 начинающая зарплата.

Какие книги и туториалы посоветуете?


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

Туториалы есть различные. Если вы хотите опробовать какой-то алгоритм берите название алгоритма, метода, классы методов, и вбивайте в поиск. Что зайдет первой ссылкой, то и смотрите.

Сколько остается чистыми?


После налогов надо брать налоги плюс 8% (которые как бы не налог, но налог) остается 2/3 зарплаты. Ставка динамическая чем больше зарабатываете, тем больше налог.

Какие компании обращаются за рекламой?


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

Какие проекты лучше делать для повышения скиллов?


Хороший вопрос. Если мы говорим о data science, нужно прокачать себя через онлайн-курс (например, в Стэнфорде есть) или онлайн-университет. Есть разнообразные платформы, за которые нужно платить например, Udacity. Там есть домашние задания, видео, менторство, но удовольствие это не из дешевых.

Чем уже ваши интересы (например, какой-нибудь reinforcement learning), тем сложнее найти проекты. Можно попробовать поучаствовать в Kegel-соревнованиях: заходите на kegel.com, там много различных соревнований по машинному обучению. Берете то, к чему уже приложен какой-то baseline; скачиваете и начинаете этим заниматься. То есть, много способов: можно заниматься самостоятельно, можно походить онлайн-курс бесплатный или платный, можно участвовать в соревнованиях. Если вы хотите искать работу в Facebook, Google и так далее, то нужно научиться решать алгоритмические задачи то есть, надо идти в LeetCode, набивать руку там для того, чтобы проходить собеседования.

Опишите краткий роадмап обучения Machine Learning?


Расскажу в идеале, не претендуя на универсальность. Вы сначала проходите математические курсы в универе, вам нужно знание и понимание линейной алгебры, теории вероятности и статистики. После этого вам кто-то рассказывает про ML; если вы живете в крупном городе, то в нем должны быть школы, предлагающие курсы по ML. Самая известная ШАД, Школа анализа данных Яндекса. Если вы в нее пройдете, и вы сможете проучиться два года, то вы получите всю базу ML. Вам нужно будет дальше оттачивать скилл в исследованиях и в работе.

Если и другие варианты: например, у Тинькова есть курсы по машинному обучению с возможностью трудоустроиться в Tinkoff после окончания. Если вам это удобно записывайтесь на эти курсы. Бывают разные пороги вхождения: например, в ШАД есть вступительные испытания.
Если вы не хотите идти на обычные курсы, можно начать с онлайн-курсов, которых более чем достаточно существует. Это зависит от вас; если у вас хороший английский хорошо, найти будет легко. Если нет, то, возможно, тоже что-то да есть. Те же лекции ШАДа есть в открытом доступе.
После получения теоретической базы можно идти вперед на стажировки, исследования и так далее.

Можно ли самому обучиться machine learning? Встречали ли вы такого программиста?


Я думаю, да. Только нужно иметь сильную мотивацию. Кто-то может сам выучить английский язык, например, а кому-то надо идти на курсы, и только так этот человек сможет выучиться. С ML все так же. Хотя я не знаю такого программиста, который бы научился всему сам, но, возможно, у меня просто мало знакомых; все мои друзья как раз обучались обычным способом. Я не берусь говорить, что 100% нужно обучаться так: главное ваше желание, ваше время. Конечно, если у вас не математической базы, придется потратить много времени, чтобы наработать ее.
Вдобавок к пониманию того, что значит быть data scientistом: я сам не занимаюсь data sci
ence как research. Наша компания это не лаборатория, где мы разрабатываем методы, закрываясь на полгода в лаборатории. Я непосредственно работаю с production, и мне нужны инженерные скиллы; мне нужно писать код, иметь инженерные навыки, чтобы понимать, что как работает. Люди часто опускают эти особенности, когда говорят про data science. Есть множество историй о том, как люди с PhD пишут нечитаемый ужасный неструктурированный код, у них возникают большие проблемы после того, как они решают пойти в индустрию. То есть, в совокупе с Machine Learning не нужно забывать про инженерные скиллы.

Data science это позиция, не говорящая о себе. Вы можете устроиться компанию, которая занимается data science, и вы станете писать SQL-запросы, или будет простая логистическая регрессия. В принципе, это тоже уже machine learning, но в каждой компании есть свое понимание того, что такое data science. Например, моя подруга в Facebook рассказала, что data science это когда люди просто запускаю статистические эксперименты: кликают на кнопочки, собирают результаты и потом предоставляют их. При этом я сам улучшаю методы конверсии и алгоритмы; в некоторых других компаниях эта специальность может называться machine learning engineer. В разных компаниях все может быть по-разному.

Какие библиотеки используете?


Мы используем Keras и TensorFlow. Можно и PyTorch это не принципиально, она позволяет делать все те же вещи но в какой-то момент было принято решение использовать именно их. При существующем продакшене трудно менять.

В Unity есть не только data scientistы, которые оптимизируют алгоритмы конверсии, но и GameTune это такая вещь, где вы улучшаете метрики в плане прибыли или retention с помощью различных туториалов. Допустим, кто-то поиграл в игру и сказал: мне непонятно, мне неинтересно забросил; кому-то слишком легко, наоборот он тоже забросил. Поэтому нужен GameTune это инициатива, которая адаптирует сложность игр по способностям геймера, или по истории игр, или по тому, как часто он что-то покупает внутри приложений.

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

Можно поговорить непосредственно про Unity Ads. Если вы решили написать игру, и решили опубликовать ее и заработать, то придется решить некоторые трудные задачи.

Я начну с примера: вот Apple анонсировал запуск iOS 14. В ней потенциальный геймер может зайти в приложение и сказать, что не хочет шарить свой Device-ID кому-либо. При этом он соглашается с тем, что качество рекламы ухудшится. Но в то же время это сложная задача для нас, потому что, если мы не сможем идентифицировать вас, то мы не сможем собирать определенные метрики, и просто будем иметь меньше информации о вас. Оптимизировать работу в условиях мира, который больше стремится к конфиденциальности, к защите данных, для data scientistа все труднее данных становится все меньше, как и доступных методов.

Помимо Unity, есть гиганты вроде Facebook и Google и, казалось бы, зачем нужен Unity Ads? Но нужно понимать, что в разных странах эти рекламные сети могут работать по-разному. Условно говоря, есть Tier 1-страны (Америка, Канада, Австралия); есть Tier 2-страны (Азия), есть Tier 2 (Индия, Бразилия). Рекламные сети могут работать в них по-разному. Также имеет значение используемый вид рекламы. Обычный ли вид, или реклама за вознаграждение (rewardable) когда, например, чтобы продолжить с того же места после game over, нужно просмотреть рекламу. Разные виды рекламы, разные люди. В каких-то странах одна рекламная сеть лучше работает, в каких-то другая. И еще, как дополнительное замечание я слышал, что интеграция AdMob, которая у Google, сложнее, чем Unity.

То есть, если вы создали игру в Unity, то вы автоматически интегрированы в Unity Ads. Разница в простоте интеграции. Что можно посоветовать: есть такая вещь, как медиация; в ней есть разные позиции: можно устанавливать позиции в waterfall (водопаде) для постановки рекламных placements. Можно сказать, например, так: хочу, чтобы по приоритету показывался сначала Facebook, потом Google, потом Unity. И, если Facebook и Google решат не показывать рекламу, то Unity покажет. Чем больше у вас рекламных сетей тем лучше. Это можно рассматривать как инвестирование, но вы инвестируете сразу в разное количество рекламных сетей.
Еще можно рассказать про то, что имеет значение для успеха рекламной кампании. На самом деле, здесь нет ничего особенного: нужно следить, чтобы реклама соответствовала контенту вашего приложения. Можно, например, поискать в Youtube app ads mafia и посмотреть, насколько реклама может не соответствовать контенту. Еще есть приложение Homescapes (или Gardenscapes?). Может иметь значение то, правильно ли настроена кампания: чтобы реклама на английском языке показывалась англоязычной аудитории, на русском русскоязычной. Очень часто бывают ошибки в этом: люди просто не разбираются, устанавливают наобум.
Вам нужно создавать различные прикольные видео, подумывать над форматом, думать, как часто обновлять их. В крупных компаниях этим занимаются специальные люди user acquisition managers. Если вы одиночный разработчик, то вам это не нужно, или нужно по достижению определенного роста.

Какие дальнейшие планы?


По-прежнему работать там, где я сейчас. Может быть, я получу финское гражданство это возможно после 5 лет проживания (если меньше 30 лет, нужно еще и отслужить, если человек не сделал этого в другой стране).

Почему переехали в Финляндию?


Да, это не слишком популярная страна для переезда IT-специалиста. Многие переезжают семьями, потому что здесь хорошие социальные плюшки детские сады, ясли, больше декретные отпуска для любого из родителей. Почему переехал я сам мне тут просто понравилось. Могло бы понравиться где угодно, наверно, но Финляндия довольно близкая по культурному менталитету; различия с Россией есть, конечно, но есть и сходство. Она маленькая, безопасная, и никогда не будет вовлечена в какие-то большие заварушки. Это не условная Америка, где может попасться президент, которого не любят, и начнется что-то из-за этого; и не Великобритания, которая вдруг захочет выходить из ЕС, и тоже будут проблемы. Тут всего 5 миллионов человек. Даже с эпидемией коронавируса Финляндия справилась достаточно достойно, по сравнению с другими странами.

Собираетесь возвращаться в Россию?


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

Про магистратуру в Финляндии


Ничего особенного. Если говорить про контент лекций это просто набор слайдов; есть теоретический материал, семинар с практикой, где оттачивается эта теория, потом экзамен по всем этим материалам (теория и задачи).

Особенность: из магистратуры не выгоняют. Если не сдали экзамен, то этот курс надо будет просто пройти в следующем семестре. Есть только ограничение на общее время обучения: на бакалавра не более 7 лет, на магистра 4 года. Можно спокойно закончить все за два года, кроме одного курса, и растянуть его на 2 года, или брать академы.

Работа в Москве и в Финляндии отличается сильно?


Я бы не сказал. Те же IT-компании, те же задачи. В культурно-бытовом плане удобно, работа недалеко, город маленький. Продуктовый магазин стоит в одной минуте от меня, зал в трех, работа двадцать пять, от двери до двери. Мне нравятся размеры; я раньше не жил в таких уютных городах, где все под рукой. Красивая природа, пляж рядом.

Но в плане работы, я думаю, все плюс-минус одинаково. Что касается рынка IT-труда Финляндии, касаемо machine learning некоторые замечают, что для специальностей, связанных с ML, требуют PhD или хотя бы магистров. Я считаю, что в обозримом будущем это изменится. Тут до сих пор есть предубеждение: если ты бакалавр, то ты не можешь быть сформированным специалистом, а вот если магистр у тебя есть специализация, и ты можешь работать. А если PhD, то уже все совершенно круто, и ты можешь делать IT-исследования. Хотя, как мне кажется, даже люди, которые закончили PhD, могут быть совершенно не интегрированы в индустрию, и могут не понимать, что индустрия это не только алгоритмы и методы, но и бизнес. Если вы не понимаете бизнес, то я не знаю, как вы сможете врастать компанию и понимать, как работает вся эта мета-система.

Поэтому идея переехать в магистратуру и сразу найти работу это довольно сложно; если вы переезжаете в Финляндию с бакалаврским дипломом вы ноунейм. Нужно иметь какой-нибудь опыт работы, чтобы сказать: я работал в Яндексе, в Mail, в Лаборатории Касперского и т.д.

Как прожить на 500 EUR в Финляндии?


Прожить можно. Если вы студент, нужно понимать, что у вас не будет стипендии; ЕС может предоставлять деньги, но только для тех, кто учится по обмену. Если вы поступаете в университет Финляндии, то нужно понимать, как вы будете жить. Есть несколько вариантов; если вы поступаете в магистратуру с PhD-треком (то есть, одновременно в магистратуру и на PhD), то с первого же года вы будете делать исследовательскую работу и получать за это деньги.
Небольшие, но студенту будет хватать. Второй вариант подработка; например, я был учебным ассистентом по определенному курсу и зарабатывал 400 EUR в месяц.

Кстати, в Финляндии хорошие студенческие бенефиты. Можно заселиться в общагу за 300 или 200 EUR за комнату, можно питаться в студенческих столовых с фиксированной ценой (все, что вы накладываете себе в тарелку 2.60 EUR). Некоторые стараются завтракать, обедать и ужинать в столовой за 2.60; если так делать, то можно прожить на 500 EUR. Но это самый минимум.

Куда можно поступить, если хочешь быть программистом?


Можно поступить на факультет компьютерных наук ВШЭ, МФТИ ФИВТ и ФУПМ, или ВМК МГУ, например. Можно что-то и в Петербурге найти. Но я не в курсе точной ситуации с обучением machine learning, попробуйте загуглить эту тему.

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

Естественно, жизнь в Финляндии не вполне сказочная переехал, и сразу все стало круто. Любой мигрант все равно встречается с культурным шоком. В разных странах разные люди, разный менталитет, разные законы. Например, здесь нужно самому заботиться о налогах заполнять самому налоговую карту; покупка машины, аренда жилья многое работает по-другому. Это достаточно трудно, если вы решите переехать. Народ здесь не сказать чтобы очень социальный, погода как в Санкт-Петербурге в ноябре-декабре может быть по 1-2 солнечных дня. Некоторые даже впадают в депрессию здесь; они приезжают с уверенностью, что они здесь очень нужны, но это оказывается не так, и нужно зарабатывать деньги, играя по чужим правилам. Это всегда риск. Всегда есть вероятность, что вам придется вернуться, потому что вы просто не приживетесь.

Какой совет дашь начинающим программистам?


Я советую попробовать как можно больше, понять, что вас действительно интересует. Старайтесь не зацикливаться в одной сфере: попробуйте Android-разработку, frontend/backend, Java, Javascript, ML, другие вещи. И, как я уже сказал, нужно быть активным, идти на контакт, интересоваться, что происходит; что делают друзья, коллеги, знакомые. Ходите на воркшопы, семинары, лекции, знакомьтесь с людьми. Чем больше у вас связей, тем проще понять, что интересного происходит.

Где еще используется Unity, кроме игр?


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

Если хотите задать вопрос не стесняйтесь находить меня во всех социальных сетях.



Что было ранее


  1. Илона Папава, Senior Software Engineer в Facebook как попасть на стажировку, получить оффер и все о работе в компании
  2. Борис Янгель, ML-инженер Яндекса как не пополнить ряды стремных специалистов, если ты Data Scientist
  3. Александр Калошин, СEO LastBackend как запустить стартап, выйти на рынок Китая и получить 15 млн инвестиций.
  4. Наталья Теплухина, Vue.js core team member, GoogleDevExpret как пройти собеседование в GitLab, попасть в команду разработчиков Vue и стать Staff-engineer.
  5. Ашот Оганесян, основатель и технический директор компании DeviceLock кто ворует и зарабатывает на ваших персональных данных.
  6. Сания Галимова, маркетолог RUVDS как жить и работать с психиатрическим диагнозом. Часть 1. Часть 2.
  7. Илья Кашлаков, руководитель фронтенд-отдела Яндекс.Денег как стать тимлидом фронтендеров и как жить после этого.
  8. Влада Рау, Senior Digital Analyst в McKinsey Digital Labs как попасть на стажировку в Google, уйти в консалтинг и переехать в Лондон.
  9. Ричард Левелорд Грей, создатель игр Duke Nukem 3D, SiN, Blood про личную жизнь, любимые игры и о Москве.
  10. Вячеслав Дреер, гейм-дизайнер и продюсер игр с 12-летним стажем про игры, их жизненный цикл и монетизацию
  11. Андрей, технический директор GameAcademy как видеоигры помогают прокачивать реальные навыки и найти работу мечты.
  12. Александр Высоцкий, ведущий PHP-разработчик Badoo как создаются Highload проекты на PHP в Badoo.
  13. Андрей Евсюков, заместитель CTO в Delivery Club про найм 50 синьоров за 43 дня и о том, как оптимизировать фреймворк найма
  14. Джон Ромеро, создатель игр Doom, Quake и Wolfenstein 3D байки о том, как создавался DOOM
  15. Паша Жовнер, создатель тамагочи для хакеров Flipper Zero о своем проекте и другой деятельности
  16. Татьяна Ландо, лингвист-аналитик в Google как научить Google-ассистента человеческому поведению
  17. Путь от джуна до исполнительного директора в Сбербанке. Интервью с Алексеем Левановым



Подробнее..

Перевод Масштабируемая классификация данных для безопасности и конфиденциальности

23.09.2020 18:06:49 | Автор: admin


Классификация данных на основе контента это открытая задача. Традиционные системы предотвращения потери данных (DLP) решают эту проблему путем снятия отпечатков с соответствующих данных и мониторинга конечных точек для снятия отпечатков. Учитывая большое количество постоянно меняющихся ресурсов данных в Facebook, этот подход не только не масштабируется, но и неэффективен для определения того, где находятся данные. Эта статья посвящена сквозной системе, построенной для обнаружения чувствительных семантических типов в Facebook в масштабе и автоматического обеспечения хранения данных и контроля доступа.

Описанный здесь подход это наша первая сквозная система конфиденциальности, которая пытается решить эту проблему путем включения сигналов данных, машинного обучения и традиционных методов снятия отпечатков для отображения и классификации всех данных в Facebook. Описанная система эксплуатируется в производственной среде, достигая среднего балла F2 0,9+ по различным классам конфиденциальности при обработке большого количества ресурсов данных в десятках хранилищ. Представляем перевод публикации Facebook на ArXiv о масштабируемой классификации данных для обеспечения безопасности и конфиденциальности на основе машинного обучения.

Введение


Сегодня организации собирают и хранят большие объемы данных в различных форматах и местах [1], затем данные потребляются во многих местах, иногда копируются или кэшируются несколько раз, в результате чего ценная и конфиденциальная деловая информация рассеивается по многим корпоративным хранилищам данных. Когда от организации требуется выполнить определенные правовые или нормативные требования, например, соблюдать нормативные акты в ходе гражданского судопроизводства, возникает необходимость сбора данных о местоположении нужных данных. Когда в постановлении о конфиденциальности говорится, что организация должна маскировать все номера социального страхования (SSN) при передаче личной информации неавторизованным субъектам, естественным первым шагом является поиск всех SSN в хранилищах данных всей организации. При таких обстоятельствах классификации данных приобретает решающее значение [1]. Система классификации позволит организациям автоматически обеспечить соблюдение конфиденциальности и политики безопасности, такие как включение политики управления доступом, сохранение данных. Facebook представляет систему, построенную нами в Facebook, которая использует множество сигналов данных, масштабируемую системную архитектуру и машинное обучение для обнаружения чувствительных семантических типов данных.

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

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


Рисунок 1. Потоки онлайн и офлайн-прогнозирования

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

В этой статье описывается, как мы справлялись с проблемами выше, и представляется быстрая и масштабируемая система классификации, которая классифицирует элементы данных всех типов, форматов и источников на основе общего набора признаков. Мы расширили системную архитектуру и создали специальную модель машинного обучения для быстрой классификации офлайн и онлайн-данных. Эта статья организована следующим образом: в разделе 2 представляется общий дизайн системы. В разделе 3 обсуждаются части системы машинного обучения. В разделах 4 и 5 рассказывается о связанной работе, намечается будущее направление работы.

Архитектура


Чтобы справиться с проблемами устойчивых данных и данных онлайна в масштабе Facebook, система классификации имеет два отдельных потока, которые мы подробно обсудим.

Устойчивые данные


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

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

Каждое задание это скомпилированный двоичный файл, который выполняет выборку Бернулли по последним данным, доступным для каждого актива. Актив разбивается на отдельные столбцы, где результат классификации каждого столбца обрабатывается независимо. Кроме того, система сканирует любые насыщенные данные внутри столбцов. JSON, массивы, кодированные структуры, URL-адреса, сериализованные данные base 64 и многое другое всё это сканируется. Это может значительно увеличить время выполнения сканирования, так как одна таблица может содержать тысячи вложенных столбцов в большом двоичном объекте json.

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

Для чего нужны признаки?


Понятие признаков ключевой момент. Вместо признаков float и text мы можем передавать необработанные образцы строк, которые напрямую извлечены из каждого ресурса данных. Кроме того, модели машинного обучения могут обучаться напрямую на каждой выборке, а не на сотнях расчетов признаков, которые только пытаются приблизить выборку. Этому есть несколько причин:

  1. Конфиденциальность прежде всего: самое главное, понятие признаков позволяет нам хранить в памяти только те образцы, которые мы извлекаем. Это гарантирует, что мы храним образцы для единственной цели и никогда не логируем их нашими собственными усилиями. Это особенно важно для неустойчивых данных, поскольку сервис должен поддерживать некоторое состояние классификации, прежде чем предоставлять прогноз.
  2. Память: некоторые сэмплы могут иметь длину в тысячи символов. Хранение таких данных и передача их частям системы без необходимости потребляет много дополнительных байтов. Два фактора могут объединиться с течением времени, учитывая, что существует много ресурсов данных с тысячами столбцов.
  3. Агрегирование признаков: с помощью признаков через их набор четко представляются результаты каждого сканирования, что позволяет системе объединять результаты предыдущих сканирований одного и того же ресурса данных удобным способом. Это может быть полезно для агрегирования результатов сканирования одного ресурса данных в нескольких запусках.

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

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

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

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

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

Неустойчивые данные


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

Здесь API принимает два основных аргумента: ключ группировки и необработанные данные, которые должны быть спрогнозированы. Сервис выполняет то же извлечение объектов, что описано выше, и группирует объекты вместе для одного и того же ключа. Эти признаки также поддерживаются в сохраняемом кэше для восстановления после отказа. Каждому ключу группировки служба гарантирует, что перед вызовом сервиса прогнозирования она видела достаточно выборок в соответствии с процессом, описанным выше.

Оптимизация


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

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

Сигналы данных


Система классификации хороша настолько, насколько хороши сигналы от данных. Здесь мы рассмотрим все сигналы, используемые системой классификации.

  • На основе содержимого: конечно, первый и важнейший сигнал это содержимое. Выполняется выборка Бернулли по каждому активу данных, который мы сканируем и извлекаем признаки по содержанию данных. Многие признаки происходят из содержимого. Возможно любое количество плавающих объектов, которые представляют рассчеты того, сколько раз был замечен определенный тип образца. Например, у нас могут быть ротзнаки количества электронных писем, увиденных в выборке, или признаки того, сколько смайликов замечено в выборке. Эти расчеты признаков можно нормализовать и агрегировать по различным сканированиям.
  • Происхождения данных: важный сигнал, который может помочь, когда содержимое изменилось из родительской таблицы. Распространенный пример хэшированные данные. Когда данные в дочерней таблице хэшируются, они часто поступают из родительской таблицы, где остаются в открытом виде. Данные о происхождении помогают классифицировать определенные типы данных, когда они не читаются четко или преобразованы из таблицы вверх по потоку.
  • Аннотации: еще один высококачественный сигнал, помогающий в идентификации неструктурированных данных. Фактически аннотации и данные происхождения могут работать вместе для распространения атрибутов между различными активами данных. Аннотации помогают идентифицировать источник неструктурированных данных, в то время как данные о происхождении могут помочь отслеживать поток этих данных по всему хранилищу.
  • Инъекция данных это метод, когда намеренно вводятся специальные, нечитаемые символы в известные источники с известными типами данных. Затем, всякий раз, когда мы сканируем содержимое с одной и той же нечитаемой последовательностью символов, можно сделать вывод, что содержимое исходит из этого известного типа данных. Это еще один качественный сигнал данных, подобный аннотациям. За исключением того, что обнаружение на основе контента помогает обнаружить введенные данные.


Измерение метрик


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

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

Сбор достоверных данных


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

  • Конфигурации платформы логирования: определенные поля в таблицах улья заполняются данными, которые относятся к определенному типу. Использование и распространение этих данных служит надежным источником достоверных данных.
  • Ручная маркировка: разработчики, поддерживающие систему, а также внешние маркировщики обучены маркировать столбцы. Это обычно хорошо работает для всех типов данных в хранилище, и может быть основным источником достоверности для некоторых неструктурированных данных, таких как данные сообщений или пользовательский контент.
  • Столбцы из родительских таблиц могут помечаться или аннотироваться как содержащие определенные данные, и мы можем отслеживать эти данные в нижестоящих таблицах.
  • Выборка потоков выполнения: потоки выполнения в Facebook несут данные определенного типа. Используя наш сканер в качестве сервисной архитектуры, мы можем делать выборку потоков, имеющих известные типы данных, и отправлять их через систему. Система обещает не хранить эти данные.
  • Таблицы выборки: большие таблицы улья, которые, как известно, содержат весь корпус данных, также могут использоваться в качестве обучающих данных и передаваться через сканер как сервис. Это отлично подходит для таблиц с полным диапазоном типов данных, так что выборка столбца случайным образом эквивалентна выборке всего множества этого типа данных.
  • Синтетические данные: мы можем даже использовать библиотеки, которые генерируют данные на лету. Это хорошо работает для простых, общедоступных типов данных, таких как адрес или GPS.
  • Стюарды данных: программы конфиденциальности, как правило, используют стюардов данных для ручного закрепления политик за частями данных. Это служит высокоточным источником достоверности.

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

Непрерывная интеграция


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

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

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

Пока наборы данных сравнивают признаки RC и PROD, логируется множество вариаций движка классификации ML сервиса прогнозирования. Самая последняя построенная модель машинного обучения, текущая модель в производстве и любые экспериментальные модели. Тот же самый подход позволяет нам разрезать различные версии модели (агностик наших классификаторов правил) и сравнивать метрики в режиме реального времени. Так легко определить, когда эксперимент с ML готов к внедрению в производство.

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

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

Некоторые результаты


Маркируется более 100 различных типов данных с высокой точностью. Хорошо структурированные типы, такие как электронные письма и телефонные номера, классифицируются с оценкой f2 более 0,95. Свободные типы данных, такие как пользовательский контент и имя, также работают очень хорошо, с F2-баллами более 0,85.

Ежедневно классифицируется большое количество отдельных столбцов устойчивых и неустойчивых данных во всех хранилищах. Более 500 терабайт сканируются ежедневно в более чем 10 хранилищах данных. Охват большинства из этих хранилищ составляет более 98%.

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


Рис. 2. Диаграмма, описывающая непрерывный поток интеграции, чтобы понимать, как RC-объекты генерируются и отправляются в модель.


Рисунок 3. Высокоуровневая диаграмма компонента машинного обучения.

Компонент системы машинного обучения


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

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

Реализованная модель изучает векторные представления [3] над плотными и разреженными объектами отдельно. Затем они объединяются, чтобы сформировать вектор, который проходит через серию этапов пакетной нормализации [4] и нелинейности для получения конечного результата. Конечный результат число с плавающей точкой между [0-1] для каждой метки, указывающий вероятность того, что пример принадлежит данному типу чувствительности. Использование PyTorch для модели позволило нам двигаться быстрее, дав возможность разработчикам вне команды быстро вносить и тестировать изменения.

При проектировании архитектуры было важно моделировать разреженные (например, текстовые) и плотные (например, числовые) объекты отдельно из-за их внутреннего различия. Для окончательной архитектуры также было важно выполнить развертку параметров, чтобы найти оптимальное значение скорости обучения, размера пакета и других гиперпараметров. Выбор оптимизатора также был важным гиперпараметром. Мы обнаружили, что популярный оптимизатор Adamчасто приводит к переобучению, тогда как модель с SGD стабильнее. Были дополнительные нюансы, которые мы должны были включить непосредственно в модель. Например, статические правила, которые гарантировали, что модель делает детерминированный прогноз, когда признак имеет определенное значение. Эти статические правила определены нашими клиентами. Мы обнаружили, что включение их непосредственно в модель привело к созданию более самодостаточной и надежной архитектуры, в отличие от реализации этапа постобработки для обработки этих специальных граничных случаев. Также обратите внимание, что во время тренировки эти правила отключены, чтобы не мешать тренировочному процессу градиентного спуска.

Проблемы


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

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

Важность признака


Когда в модель вводится новый признак, мы хотим знать его общее влияние на модель. Мы также хотим убедиться, что прогнозы интерпретируемы человеком, чтобы можно было точно понять, какие признаки используются для каждого типа данных. Для этого мы разработали и ввели поклассовую важность признаков для модели PyTorch. Обратите внимание, что это отличается от общей важности признака, которая обычно поддерживается, потому что она не говорит нам, какие признаки важны для определенного класса. Мы измеряем важность объекта, вычисляя увеличение ошибки прогноза после перестановки объекта. Признак является важным, когда перестановка значений увеличивает ошибку модели, поскольку в этом случае модель полагалась на признак в прогнозировании. Признак неважен, когда перетасовка его значений оставляет ошибку модели неизменной, поскольку в этом случае модель игнорировала его [5].

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

Оценка


Важно определить единую метрику успеха. Мы выбрали F2 баланс между отзывом и точностью (смещение отзыва немного больше). Отзыв важнее для случая использования конфиденциальности, чем точность, потому что для команды крайне важно не пропустить никаких конфиденциальных данных (обеспечивая при этом разумную точность). Фактические данные оценки производительности F2 нашей модели выходят за рамки данной статьи. Тем не менее, при тщательной настройке мы можем достичь высокого (0,9+) балла F2 для наиболее важных чувствительных классов.

Связанная работа


Существует множество алгоритмов автоматической классификации неструктурированных документов с использованием различных методов, таких как сопоставление шаблонов, поиск сходства документов и различные методы машинного обучения (байесовские, деревья решений, k-ближайших соседей и многие другие) [6]. Любой из них может использоваться как часть классификации. Однако проблема в масштабируемости. Подход к классификации в этой статье смещен в сторону гибкости и производительности. Это позволяет нам поддерживать новые классы в будущем и поддерживать низкую задержку.

Существует также масса работ по снятию отпечатков с данных. Например, авторы в [7] описали решение, которое фокусируется на проблеме улавливания утечек конфиденциальных данных. Основное предположение заключается в возможности отпечатка с данных, чтобы сопоставить его с набором известных конфиденциальных данных. Авторы в [8] описывают аналогичную проблему утечки конфиденциальности, но их решение основано на конкретной архитектуре Android и классифицируется только в том случае, когда действия пользователя привели к отправке личной информации или если в базовом приложении утечка пользовательских данных. Ситуация здесь несколько отличается, поскольку пользовательские данные также могут быть сильно неструктурированными. Поэтому нам нужна более сложная техника, чем снятие отпечатков.

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

Заключение


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

Есть много направлений будущей работы. Она может включать обеспечение поддержки несхематизированных данных (файлов), классификацию не только типа данных, но и уровня чувствительности, а также использование самоконтролируемого обучения непосредственно во время обучения путем генерации точных синтетических примеров. Которые, в свою очередь помогут модели уменьшить потери на наибольшую величину. Будущая работа может также сосредоточиться на рабочем процессе расследования, где мы выходим за рамки обнаружения и предоставляем анализ первопричин различных нарушений конфиденциальности. Это поможет в таких случаях, как анализ чувствительности (т.е. является ли чувствительность конфиденциальности типа данных высокой (например, IP пользователя) или низкой (например, внутренний IP Facebook)).

Библиография
  1. David Ben-David, Tamar Domany, and Abigail Tarem. Enterprise data classification using semantic web technolo- gies. In Peter F. Patel-Schneider, Yue Pan, Pascal Hitzler, Peter Mika, Lei Zhang, Jeff Z. Pan, Ian Horrocks, and Birte Glimm, editors, The Semantic Web ISWC 2010, pages 6681, Berlin, Heidelberg, 2010. Springer Berlin Heidelberg.
  2. Subramanian Muralidhar, Wyatt Lloyd, Sabyasachi Roy, Cory Hill, Ernest Lin, Weiwen Liu, Satadru Pan, Shiva Shankar, Viswanath Sivakumar, Linpeng Tang, and Sanjeev Kumar. f4: Facebooks warm BLOB storage system. In 11th USENIX Symposium on Operating Systems Design and Implementation (OSDI 14), pages 383398, Broomfield, CO, October 2014. USENIX Association.
  3. Tomas Mikolov, Ilya Sutskever, Kai Chen, Greg S Corrado, and Jeff Dean. Distributed representations of words and phrases and their compositionality. In C. J. C. Burges, L. Bottou, M. Welling, Z. Ghahramani, and K. Q. Weinberger, editors, Advances in Neural Information Processing Systems 26, pages 31113119. Curran Associates, Inc., 2013.
  4. Sergey Ioffe and Christian Szegedy. Batch normalization: Accelerating deep network training by reducing internal covariate shift. In Francis Bach and David Blei, editors, Proceedings of the 32nd International Conference on Machine Learning, volume 37 of Proceedings of Machine Learning Research, pages 448456, Lille, France, 0709 Jul 2015. PMLR.
  5. Leo Breiman. Random forests. Mach. Learn., 45(1):532, October 2001.
  6. Thair Nu Phyu. Survey of classification techniques in data mining.
  7. X. Shu, D. Yao, and E. Bertino. Privacy-preserving detection of sensitive data exposure. IEEE Transactions on Information Forensics and Security, 10(5):10921103, 2015.
  8. Zhemin Yang, Min Yang, Yuan Zhang, Guofei Gu, Peng Ning, and Xiaoyang Wang. Appintent: Analyzing sensitive data transmission in android for privacy leakage detection. pages 10431054, 11 2013.
  9. Qizhe Xie, Zihang Dai, Eduard H. Hovy, Minh-Thang Luong, and Quoc V. Le. Unsupervised data augmentation.

image

Узнайте подробности, как получить востребованную профессию с нуля или Level Up по навыкам и зарплате, пройдя онлайн-курсы SkillFactory:



Подробнее..

Парсинг сайта Умного Голосования и новый API на сайте ЦИК

20.09.2020 20:22:28 | Автор: admin
image

13 сентября 2020 года в России прошёл единый день голосования. В некоторых регионах оппозицией была применена стратегия Умного Голосования, заключающаяся в том, что оппозиционно настроенные избиратели голосуют за единого кандидата, имеющего наивысшие шансы победить представителя от властей.

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

На сайте Умного Голосования нельзя получить список поддержанных кандидатов, указав, например, город и округ. Если кто-то захочет собрать данные по региону, ему предстоит монотонная работа по подбору адресов для каждого округа.

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

В итоге получилась вот такая сводная таблица. В данной статье я расскажу, как был получен приведённый набор данных, как собиралась информация с сайтов Умного Голосования и нового веб-сервиса ЦИК.

image


Сайт Умного Голосования



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

image


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

image


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

image


В данном случае мы видим выборы губернатора, для которых УмГ не указало кандидата от оппозиции. Связанно это с тем, что выборы губернаторов проходят в два тура и не имеет значения, за кого из оппозиционных кандидатов проголосуют избиратели.
Также мы видим сразу трёх кандидатов, за которых предлагают проголосовать на выборах в городской парламент. Связанно это с тем, что на выборах в Сочи многомандатные округа.
На всех остальных выборных кампаниях, задействованных УмГ в этом году, были только одномандатные округа.

Заглянем в код страницы и обнаружим, что все описанные данные, собраны в удобном JSON-формате. В элементе с id="__NEXT_DATA__", который используется для отрисовки страницы, есть информация об избирательном участке, о соответствующих выборных кампаниях и кандидатах:

Содержимое __NEXT_DATA__ элемента
{   "props":{      "pageProps":{         "id":"440384",         "settings":{            "id":1,            "share_photo":"/ganimed-media/share_photo/smartvote_sharepic_1200x628.jpg",            "video_on_main_page":"https://youtu.be/w8gapDGwWMY",            "fake_mode":false,            "title_share":"Объединяемся, чтобы победить Единую Россию",            "text_share":"Мы разные, но у нас одна политика  мы против монополии Единой России. Всё остальное  математика.",            "telegram_bot_link":"https://tlinks.run/smartvotebot",            "viber_bot_link":"viber://public?id=smartvote",            "facebook_bot_link":"https://facebook.com/umnoegolosovanie/",            "alice_link":null,            "vk_bot_link":null         },         "serverData":{            "commission":{               "id":440384,               "number":"4317",               "address":"354340, Краснодарский край, город Сочи, Адлерский район, улица Богдана Хмельницкого, 24",               "descr":"здание средней школы  49 им. Н.И. Кондратенко",               "lat":"43.425923",               "lon":"39.920152",               "region_id":26,               "region_intid":"135637827259064320000372513"            },            "campaigns":[               {                  "id":26,                  "code":"krasnodar-gub-2020",                  "title":"Выборы губернатора Краснодарского края",                  "is_regional":true,                  "ready_date":null,                  "district":{                     "id":458,                     "code":"oik-0",                     "name":"0",                     "leaflet":""                  },                  "candidates":[                     {                        "id":998,                        "name":"Кондратьева Вениамина Ивановича",                        "share_image":"/elections-api-media/share/26/998.png",                        "anticandidate":true,                        "self_nominated":false,                        "has_won":false,                        "has_second_round":false,                        "party":{                           "title":"Единая Россия",                           "antiparty":true                        }                     }                  ]               },               {                  "id":28,                  "code":"krasnodar-sochi-gorduma-2020",                  "title":"Выборы в городское собрание Сочи",                  "is_regional":false,                  "ready_date":null,                  "district":{                     "id":526,                     "code":"oik-2",                     "name":"2",                     "leaflet":"/elections-api-media/28/526-1334-1335-5385.pdf"                  },                  "candidates":[                     {                        "id":1334,                        "name":"Киров Сабир Рафаилович",                        "share_image":"/elections-api-media/share/28/1334.png",                        "anticandidate":false,                        "self_nominated":true,                        "has_won":false,                        "has_second_round":false,                        "party":null                     },                     {                        "id":1335,                        "name":"Мукаелян Марине Айковна",                        "share_image":"/elections-api-media/share/28/1335.png",                        "anticandidate":false,                        "self_nominated":true,                        "has_won":false,                        "has_second_round":false,                        "party":null                     },                     {                        "id":5385,                        "name":"Рябцев Виктор Александрович",                        "share_image":"/elections-api-media/share/28/5385.png",                        "anticandidate":false,                        "self_nominated":false,                        "has_won":false,                        "has_second_round":false,                        "party":{                           "title":"КПРФ",                           "antiparty":false                        }                     }                  ]               }            ]         },         "error":null,         "currentUrl":"https://votesmart.appspot.com/candidates/440384"      }   },   "page":"/candidates/[id]",   "query":{      "id":"440384"   },   "buildId":"U8hjaoxZw8TINu-DU_Ixw",   "runtimeConfig":{      "HOST":"https://votesmart.appspot.com"   },   "isFallback":false,   "customServer":true,   "gip":true}



Для избирательного участка указан номер (number) соответствующей УИК и её идентификатор в базе данных сайта УмГ. Id = 440834 соответствует номеру, который содержится в URL-адресе страницы (/candidates/440834).

Можем ли мы, зная номер УИК и регион, вычислить идентификатор комиссии на сайте УмГ? Я не смог найти очевидную зависимость, так как идентификаторы распределены достаточно хаотично:
Сочи, УИК 4512 -> id = 440834
Сочи, УИК 4513 -> id = 441403
Сочи, УИК 4514 -> id = 1781216

Каким образом собрать список отражений номеров УИК в id страниц? Перебирать и проверять всевозможные идентификаторы от 1 до 2000000 звучит крайне неэффективно, большинство из этих идентификаторов нерабочие.

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

Поиск участка по адресу
https://votesmart.appspot.com/api/v1/cik/addresses?query=ADDRESS

  • ADDRESS адрес, желательно в формате Субъект, город, улица, дом. Также желательно без сокращений ул., д., так как парсер на сервере плохо с ними справляется

Пример запроса:
https://votesmart.appspot.com/api/v1/cik/addresses?query=Смоленск ленина

Результат запроса
{   "suggestions":[      {         "value":"Смоленская область, город Смоленск, Промышленный район, Ленина улица",         "data":{            "fullname":"Смоленская область, город Смоленск, Промышленный район, Ленина улица",            "level":"7",            "region_id":69,            "commission_id":null,            "intid":"138474570115456000000347353",            "path":"135637827259064320000359815,135637827259064320000359819,135637827259064320000359820,138474570115456000000347353",            "snippet":"Смоленская область, город <em>Смоленск</em>, Промышленный район, <em>Ленина</em> улица",            "score":118.84238         }      },      {         "value":"Смоленская область, город Смоленск, Ленинский район, Ленина улица, 12А",         "data":{            "fullname":"Смоленская область, город Смоленск, Ленинский район, Ленина улица, 12А",            "level":"8",            "region_id":69,            "commission_id":1124357,            "intid":"135659820348349440000359937",            "path":"135637827259064320000359815,135637827259064320000359819,135637827259064320000359822,135659820348349440000359708,135659820348349440000359937",            "snippet":"Смоленская область, город <em>Смоленск</em>, Ленинский район, <em>Ленина</em> улица, 12А",            "score":115.14931         }      },...   ]}



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

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

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

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

Новый веб-сервиса ЦИК. Методы API


ГАС Выборы автоматизированная система, разработанная в 1995 году, предназначенная для подготовки и проведения выборов и референдумов в РФ.

Если вы когда-либо интересовались ходом выборной кампании, то наверняка сталкивались с данным сайтом, на котором публикуется основная информация из системы ГАС Выборы, в том числе ход подсчёта голосов, ещё до утверждения результатов выборов:

image

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

image


Как вы сами можете визуально оценить, капча конечно очень простая, и наверняка кто-то уже нашел способы её обходить. Я же, вместо того чтобы заняться машинным обучением, обратился к новому разделу на сайте ЦИК, о котором пока мало кто знает: Цифровые сервисы

image

Данный раздел появился как раз во время Голосования по поправкам и содержит в себе несколько веб-сервисов, которые через POST-запросы общаются с внутренним API для получения данных из системы ГАС Выборы. Пользователь Хабра уже обратил внимание на данный функционал. Рассмотрим же его подробнее.

Далее приведено описание основных запросов нового API, которые использовались в данном проекте:

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


Информация об УИК
http://cikrf.ru/iservices/voter-services/committee/subjcode/SUBJECT_CODE/num/COMMITTEE_NUM


Пример запроса:
http://cikrf.ru/iservices/voter-services/committee/subjcode/01/num/2

Результат запроса
{   "vrn":"4014001117979",   "name":"Участковая избирательная комиссия 2",   "subjCode":"01",   "numKsa":"01T001",   "vid":"5",   "address":{      "address":"385200, Республика Адыгея, городской округ Адыгейск, город Адыгейск, проспект имени В.И.Ленина, 16",      "descr":"здание МБОУ СОШ1",      "phone":"8-87772-9-23-72",      "lat":"44.882893",      "lon":"39.187187"   },   "votingAddress":{      "address":"385200, Республика Адыгея, городской округ Адыгейск, город Адыгейск, проспект имени В.И.Ленина, 16",      "descr":"здание МБОУ СОШ1",      "phone":"8-87772-9-23-72",      "lat":"44.882893",      "lon":"39.187187"   }}




Информация о выборных кампаниях на участке
http://cikrf.ru/iservices/voter-services/vibory/committee/COMMITTEE_VRN

  • COMMITTEE_VRN идентификатор УИК

Пример запроса:
http://cikrf.ru/iservices/voter-services/vibory/committee/4544028162533

Результат запроса
[   {      "vrn":"100100163596966",      "date":"2020-07-01",      "name":"Общероссийское голосование по вопросу одобрения изменений в Конституцию Российской Федерации",      "subjCode":"0",      "pronetvd":null,      "vidvibref":"0"   },   {      "vrn":"25420001876696",      "date":"2020-09-13",      "name":"Выборы депутатов Законодательного Собрания Новосибирской области седьмого созыва",      "subjCode":"54",      "pronetvd":"0",      "vidvibref":"2"   },   {      "vrn":"4544220183446",      "date":"2020-09-13",      "name":"Выборы депутатов Совета депутатов города Новосибирска седьмого созыва ",      "subjCode":"54",      "pronetvd":null,      "vidvibref":"2"   }]




Перечень округов выборной кампании
http://cikrf.ru/iservices/sgo-visual-rest/vibory/CAMPAIGN_VRN/tvd

  • CAMPAIGN_VRN идентификатор выборной кампании

Пример запроса:
http://cikrf.ru/iservices/sgo-visual-rest/vibory/457422069597/tvd

Результат запроса
{   "_embedded":{      "tvdDtoList":[         {            "vrn":457422069601,            "namtvd":"Муниципальная избирательная комиссия города Орла",            "namik":"Муниципальная избирательная комиссия города Орла",            "numtvd":"0",            "vidtvd":"ROOT",            "_links":{               "results":{                  "href":"http://cikrf.ru/iservices/sgo-visual-rest/vibory/457422069597/results/457422069601/proportion"               }            }         },         {            "vrn":457422069602,            "namik":"Окружная избирательная комиссия  1",            "numtvd":"1",            "vidtvd":"OIK",            "_links":{               "results":{                  "href":"http://cikrf.ru/iservices/sgo-visual-rest/vibory/457422069597/results/457422069602/major"               }            }         },         ...      ]   },   "_links":{      "self":{         "href":"http://cikrf.ru/iservices/sgo-visual-rest/vibory/457422069597/tvd"      }   }}


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

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



Список кандидатов, участвующих в выборной кампании
http://cikrf.ru/iservices/sgo-visual-rest/vibory/CAMPAIGN_VRN/candidates/?page=PAGE_NUM&numokr=NUMTVD

  • CAMPAIGN_VRN идентификатор выборной кампании
  • PAGE_NUM номер страницы списка
  • NUMTVD номер округа (необязательный параметр)

Пример запроса:
http://cikrf.ru/iservices/sgo-visual-rest/vibory/4674220125616/candidates/?page=1&numokr=11

Результат запроса
{   "_embedded":{      "candidateDtoList":[         ...         {            "index":50,            "vrn":4674020270868,            "fio":"Трофименко Владимир Карпович",            "datroj":"23.04.1964 00:00:00",            "vidvig":"выдвинут",            "registr":"зарегистрирован",            "vrnio":4674220132098,            "namio":"Региональное отделение Политической партии \"Российская партия пенсионеров за социальную справедливость\" в Смоленской области",            "numokr":11,            "tekstat2":"1",            "_links":{               "self":{                  "href":"http://cikrf.ru/iservices/sgo-visual-rest/vibory/4674220125616/candidates/4674020270868"               }            }         },         {            "index":56,            "vrn":4674020269642,            "fio":"Божедомов Евгений Эдуардович",            "datroj":"15.02.1986 00:00:00",            "vidvig":"выдвинут",            "registr":"отказ в регистрации",            "namio":"Самовыдвижение",            "numokr":11,            "tekstat2":"1",            "_links":{               "self":{                  "href":"http://cikrf.ru/iservices/sgo-visual-rest/vibory/4674220125616/candidates/4674020269642"               }            }         },         {            "index":105,            "vrn":4674020271181,            "fio":"Трифоненко Владислав Андреевич",            "datroj":"15.07.1994 00:00:00",            "vidvig":"выдвинут",            "registr":"зарегистрирован",            "vrnio":4674220134054,            "namio":"Смоленское городское отделение политической партии \"КОММУНИСТИЧЕСКАЯ ПАРТИЯ РОССИЙСКОЙ ФЕДЕРАЦИИ\"",            "numokr":11,            "tekstat2":"1",            "_links":{               "self":{                  "href":"http://cikrf.ru/iservices/sgo-visual-rest/vibory/4674220125616/candidates/4674020271181"               }            }         },         ...               ]   },   "_links":{      "self":{         "href":"http://cikrf.ru/iservices/sgo-visual-rest/vibory/4674220125616/candidates?page=1&numokr=11"      }   },   "page":{      "size":20,      "totalElements":9,      "totalPages":1,      "number":1   }}


Структура page содержит общее количество страниц, по ней можно определить когда вы достигните последней страницы (либо по пустому списку, вернувшемуся с сервера).



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

Выгрузка данных с сайта ЦИК


Прежде чем приступить к скачиванию нужных данных, нужно было составить список выборных кампаний, которые мы задействуем в проекте. Дело в том, что Умное Голосование проходило не везде, а именно на выборах:
в законодательные собрания регионов,
в городские советы региональных центров,
в городские советы крупных городов (с населением больше 200 тысяч человек)
(А также довыборы в Госдуму по 4 округам).
// Леонид Волков

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

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

vybory.izbirkom.ru/region/izbirkom?action=show&vrn=21120001136916&
region=11&prver=1&pronetvd=1


В итоге, список состоял из 43 выборных кампаний. Всего в Единый день голосования прошло более 9000 отдельных выборных кампаний в органы разного уровня.

Теперь, имея на руках список выборов и перечисленные ранее методы API, скачать данные не составило никакого труда. Написав скрипт на python, делая обычные запросы про помощи requests модуля, я сохранил данные о кандидатах и избирательных участках в исходном JSON-формате.

Главное, что стоит учесть при скачивании информации об избирательных участках: недостаточно перебирать всевозможные номера начиная с 1, до тех пор пока сервер не вернет пустое значение. Дело в том, что нумерация УИК в регионе может прерываться, и идти, например, в таком виде:
...1001 1016, 1101 1136, 1138 ...
либо:
0 700, 900 1002, 1004...
Чтобы определить максимальный номер УИК в регионе и не делать лишние запросы, я собирал данные следующим образом: пробовал выгрузить данные по первым 1000 номерам, а затем проверял если i+1,i+5,i+100,i+500,i+1000 номера соответствуют какому-либо УИКу (в случае чего продолжал скачивание).

Также, рекомендую сохранять номер УИК, по которому вы скачали данные об участке. Дело в том, что возвращаемые данные не содержат номер УИК, а только название в виде: Участковая Избирательная Комиссия 100. Процесс получения исходного номера УИК, с которым мне позже пришлось столкнуться, привёл к кратковременным багам и фрустрации. Как оказалось, нумерация в названии УИК в некоторых регионах имеет разный формат.

К примеру, в Удмуртии в названии УИК была следующая нумерация: 1/01, 1/02, 1/03, в Липецкой области: 01-01, 01-02, 01-03. В Оренбургской области я столкнулся с настоящей экзотикой: это был единственный регион, где ряд избирательных комиссий были названы в честь кого-то. Например Участковая избирательная комиссия 1696 имени Братьев Пустовитовых

Выгрузка данных с сайта Умного Голосования


Теперь, по каждому собранному адресу УИК мы собираемся скачать данные о голосовании с сайта УмГ. Перед этим стоит учесть несколько особенностей (о которых я узнал уже в процессе):

Во первых, надо учесть что адреса в базе данных ЦИК имеют различный формат, порой даже в отдельных областях регионов. Мне пришлось убирать сокращения д., г. и ул., так как сайт Умного Голосования совсем не справлялся с поиском адресов по таким запросам. Ещё рекомендую убирать почтовый индекс из адреса, а также, встречающийся иногда префикс Российская Федерация.

Во вторых, сайт УмГ имеет жёсткую защиту от DDoS атак, и даже если вы сделаете сотню запросов с интервалом в 0.3 секунды ваш IP получит бан. Можно было бы использовать набор из платных прокси, но лично я просто воспользовался бесплатными прокси и чередовал запросы со своего и стороннего IP. Чтоб уж точно не получить бан, между запросами был интервал примерно в 0.7 секунд. В итоге, скачивание всех данных заняло примерно сутки.

С использованием запросов из первой главы, алгоритм получился следующим:
  1. Форматируем адрес УИК
  2. Делаем запрос на список подходящих адресов
  3. Получаем список, содержащий идентификаторы страниц сайта
  4. Проверяем если уже скачали данные об участке по данному идентификатору
  5. Загружаем HTML-страницу сайта по данному идентификатором
  6. Извлекаем элемент __NEXT_DATA__ и сохраняем данные в JSON-формате


Парсинг страницы происходил при помощи библиотеки beautifulsoup4.

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

Это не беда, ведь для каждого округа, нам достаточно найти хоть одну соответствующую страницу на сайте.

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

Объединение данных с сайтов УмГ и ЦИК


На данном этапе, мы собираем удобную структуру данных, с информацией о каждом кандидате по округам: идентификатор кандидата, ФИО, партия, метка с информацией о том, подержан ли он УмГ.

Пример собранного набора данных о кандидатах
{    "33": [        {            "name": "Бекенева Любовь Александровна",            "vrn": 4444032121758,            "birthdate": "05.05.1958 00:00:00",            "party": "ЕР",            "smart_vote": 0        },        {            "name": "Крохичев Павел Александрович",            "vrn": 4444032122449,            "birthdate": "16.11.1977 00:00:00",            "party": "КПРФ",            "smart_vote": 0        },        {            "name": "Ростовцев Михаил Павлович",            "vrn": 4444032122782,            "birthdate": "27.02.1996 00:00:00",            "party": "ЛДПР",            "smart_vote": 0        },        {            "name": "Морозов Максим Сергеевич",            "vrn": 4444032123815,            "birthdate": "20.11.1991 00:00:00",            "party": "Яблоко",            "smart_vote": 1        },        {            "name": "Захарова Алина Сергеевна",            "vrn": 4444032124060,            "birthdate": "21.07.1996 00:00:00",            "party": "КПКР",            "smart_vote": 0        },        {            "name": "Афанасов Александр Николаевич",            "vrn": 4444032123597,            "birthdate": "21.05.1974 00:00:00",            "party": "СР",            "smart_vote": 0        }    ],    ...}



Алгоритм достаточно прямолинейный:
  1. По массиву данных с сайта УмГ создаем список поддержанных кандидатов для каждого округа
  2. По массиву данных с сайта ЦИК создаем отфильтрованный список допущенных кандидатов для каждого округа
  3. В каждом округе по ФИО вычисляем соответствие Кандидат-УмГКандидат-ЦИК

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

Во первых, есть шанс что в одном округе будут кандидаты с полностью совпадающими ФИО. Благо, среди 5000 кандидатов, такая ситуация была лишь в одном случае, причём ни один из кандидатов не был поддержан УмГ.

Во вторых, надо учесть, что в базе данных сайта ЦИКа могут быть ошибки. Самая частая ошибка: переносы строк и лишние пробелы в ФИО. Также, при сборе данных об итогах голосования попадалась ситуация, при которых буква ё в фамилии заменялась на е.

В третьих, надо учитывать актуальность данных. Данные на сайте ЦИКа и УмГ изменялись и обновлялись вплоть до субботы: каких-то кандидатов снимали/восстанавливали, в каких-то округах менялась поддержка УмГ.
Для валидации списков УмГ был написан простой скрипт, который делает по одному запросу на округ (ведь собранный нами набор данных теперь позволяет однозначно определить страницу, посвященную каждому округу) и проверяет соответствуют ли имена тем, что мы получали ранее.

Интересной задачей была идентификация партий по названию их отделений. Данный пункт можно было бы пропустить, но я решил заняться этим для унификации информации. Проблема заключается в том, что у кандидатов от одной партии может различаться её название в базе ЦИК. Например, в случае КПРФ встречалось более 40 вариантов:

Ивановское городское (местное) отделение Политической партии "Коммунистическая партия Российской Федерации"
Ямало-Ненецкое ОО ПП "КПРФ"
ЧОО ПП КПРФ
КАЛУЖСКОЕ РЕГИОНАЛЬНОЕ ОТДЕЛЕНИЕ политической партии "КОММУНИСТИЧЕСКАЯ ПАРТИЯ РОССИЙСКОЙ ФЕДЕРАЦИИ"
...


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

Выгрузка результатов выборов с сайта ЦИК


Собранного набора данных хватило для достижения первоначальной цели проекта мы составили списки кандидатов УМГ-2020 для каждого избирательного округа. Но если есть техническая возможность получить результаты выборов, почему бы не воспользоваться ею?


Результаты выборов в округе
http://cikrf.ru/iservices/sgo-visual-rest/vibory/CAMPAIGN_VRN/results/DISTRICT_VRN/major

  • CAMPAIGN_VRN идентификатор выборной кампании
  • DISTRICT_VRN идентификатор округа

Пример запроса:
http://cikrf.ru/iservices/sgo-visual-rest/vibory/457422069597/results/457422069602/major

Результат запроса
{   "report":{      "tvd":"",      "date_sign":"none",      "vrnvibref":"457422069597",      "line":[         {            "txt":"число избирателей на момент окончания голосования",            "kolza":"8488",            "index":"1"         },         {            "txt":"число бюллетеней, полученных участковой комиссией",            "kolza":"6700",            "index":"2"         },         ...         {            "txt":"число недействительных бюллетеней",            "kolza":"65",            "index":"9"         },         {            "txt":"число действительных бюллетеней",            "kolza":"1948",            "index":"10"         },         ...         {            "delimetr":"1"         },         {            "txt":"Авдеев Максим Юрьевич",            "numsved":"1",            "kolza":"112",            "index":"11",            "namio":"ПАРТИЯ ПЕНСИОНЕРОВ в Орловской области",            "perza":"5.56",            "numsvreestr":"4574030258379"         },         {            "txt":"Жуков Александр Александрович",            "numsved":"2",            "kolza":"186",            "index":"12",            "namio":"Орловское региональное отделение Партии СПРАВЕДЛИВАЯ РОССИЯ",            "perza":"9.24",            "numsvreestr":"4574030258723"         },         {            "txt":"Жуков Родион Вячеславович",            "numsved":"3",            "kolza":"54",            "index":"13",            "namio":"Самовыдвижение",            "perza":"2.68",            "numsvreestr":"4574030258555"         },         ...      ],      "data_gol":"13.09.2020 00:00:00",      "is_uik":"0",      "type":"423",      "version":"0",      "sgo_version":"5.6.0",      "isplann":"0",      "podpisano":"1",      "versions":{         "ver":{            "current":"true",            "content":"0"         }      },      "vibory":"Выборы депутатов Орловского городского Совета народных депутатов шестого созыва",      "repforms":"1",      "generation_time":"14.09.2020 07:59:21",      "nazv":"Результаты выборов по одномандатному (многомандатному) округу",      "datepodp":"14.09.2020 05:44:00"   }}


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



Когда в ГАС Выборы начали публиковать предварительные результаты, я столкнулся с небольшим разочарованием. Оказалось, что через API можно получить данные только по тем результатам, которые официально утвердили. С предварительными результатами всё ещё можно ознакомиться на старом сайте избиркома, но нельзя через новые веб-сервисы.

Спустя сутки были известны результаты по 50%, а к концу недели были подведены итоги почти всех выборов, некоторые регионы всё ещё отказывались утверждать результаты. На момент написания статьи, прошло уже 7 дней, а результаты выборов в Тамбове всё ещё не утверждены. К тому же, в некоторых округах происходит пересчёт голосов, из-за чего эти результаты также недоступны через API.

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

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

В результате, данные об итогах голосования я собрал в следующую структуру:

Пример результатов голосования в округе
{..."33": {        "candidate_total": {            "4444032121758": 880,            "4444032122449": 236,            "4444032122782": 143,            "4444032123597": 152,            "4444032123815": 149,            "4444032124060": 72        },        "is_final": 1,        "non_valid_votes": 132,        "registered_voters": 6928,        "valid_votes": 1632    },...}



Для каждого округа я сохранил суммарное число избирателей в списках (для подсчёта явки), число действительных и недействительных бюллетеней. В структуре содержится словарь: Идентификатор кандидата -> Набранное им число голосов.

Публикация итогов УмГ-2020


Во первых, собранные данные в JSON-формате я опубликовал на GitHub. Данные будут обновляться, пока результаты не утвердят во всех округах.

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

Вдаваться в подробности не буду, никаких сложностей (кроме изучения Google Sheets API) возникнуть не должно. Очень помогла данная статья, в которой подробно рассказано взаимодействие с Google Sheets API на Python.

image

В итоге получилась такая таблица, в которой собраны:



Послесловие


Идея данного мини-проекта возникла за 3 дня до дня голосования и лично я доволен тем, как успел изучить и реализовать всё в кратчайшие сроки (хотя код получился ужасным).

Я не собираюсь делать какие-либо выводы об итогах стратегии Умного Голосования, я лишь предоставил инструменты для любителей электоральной статистики. Уверен, среди вас найдутся таковые и скоро мы увидим замечательные исследования, с интересными графиками и диаграммами :)

Подробнее..

Можно ли воссоздать полную нейросеть мыши из тонких послойных разрезов мозга?

17.09.2020 10:15:44 | Автор: admin
image
Карликовая многозубка, самое маленькое млекопитающее по массе. Внутри маленький целостный сложный мозг, который уже принципиально можно картировать

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

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

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

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

Этот пост написан на основе материалов будущей книги нашего коллеги Сергея Маркова Охота на электроовец: большая книга искусственного интеллекта.

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

Бионика, или биомиметика, копировала принципы биосистем или брала их за основу. Как Леонардо да Винчи смотрел за полётом птиц и изобретал орнитоптер (к сожалению, подходящих материалов и источников энергии тогда не нашлось), так и мы в двадцатом веке копировали всё более сложные системы. RFID-чипы, медицинские адгезивы (клеи), гидрофобные структуры, наносенсоры всё это и многое другое создавалось по биопрототипам. Где-то само наличие прототипа в природе позволяло понять, что технология в принципе возможна. Если растения способны синтезировать сахара и крахмал из углекислого газа и воды, значит можно создать устройство, выполняющее ту же функцию.

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

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

Кстати, наши предки часто придерживались терминальной теории мышления, предполагая, что процессы проходят где-то удалённо (в душе) и транслируются в виде команд через какой-то орган. Аристотель с коллегами считал, что терминал души находится в сердце. Но опыты древних врачей были ограничены техническим уровнем цивилизации. Так продолжалось примерно до того, как Луиджи Гальвани в 1791 году обнаружил, что ток заставляет мышцы сокращаться. Эти опыты дали начало исследованиям в области биоэлектрических явлений. В какой-то момент Катон решил замерить потенциалы всего вокруг и начал открывать для своих измерений животных. Он обнаружил, что внешняя поверхность серого вещества была заряжена более положительно, чем глубокие структуры мозга. Он также отметил, что электрические токи головного мозга, по-видимому, имеют отношение к основной функции. Когда я показал обезьяне изюм, но не дал его, произошло небольшое уменьшение силы тока. Благодаря ему же родилась неинвазивная (то есть не связанная с проникновением через внешние барьеры организма) электроэнцефалография. В 1890 году физиолог Адольф Бек из Польши обнаружил низковольтные высокочастотные колебания электрических потенциалов, возникающие между двумя электродами, помещёнными в затылочную кору мозга кролика.

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

За два года до экспериментов Катона, в 1873 году, был открыт метод Гольджи (названный так в честь его автора итальянского физиолога Камилло Гольджи), позволяющий окрашивать отдельные нейроны (правда, слово нейрон не использовалось до 1891 года).

До открытия Гольджи в биологии была популярна концепция, предложенная немецким гистологом Йозефом фон Герлахом, который считал, что волокна, выходящие из различных клеточных тел, соединены в единую сеть, получившую название ретикулум. Популярность идей Герлаха была связана с тем, что, в отличие от сердца или печени, мозг и нервную систему не получалось разделить на отдельные структурные единицы: хотя нервные клетки были описаны в составе ткани многими исследователями того времени, связь между нервными клетками и связывающими их аксонами и дендритами была неясной. Главной причиной этого были недостатки микроскопии. Благодаря своему открытию, Гольджи увидел, что разветвлённые отростки одного клеточного тела не сливаются с другими. Он, однако, не стал отбрасывать концепцию Герлаха, предположив, что длинные тонкие отростки, вероятно, соединены в одну непрерывную сеть.

Это было похоже на то, что уже знали механики и электрики. Механистический подход торжествовал. Правда, всё ещё было решительно непонятно, как же это работает. Или хотя бы как может работать.

Четырнадцать лет спустя, в 1887 году, испанский нейроанатом Сантьяго Рамон-и-Кахаль доказал, что длинные тонкие отростки, выходящие из тел клеток, вовсе не связаны в единую сеть. Нервная система, как и все другие живые ткани, состояла из отдельных элементов. В 1906 году Рамон-и-Кахаль и Камилло Гольджи за труды по строению нервной системы получили Нобелевскую премию в области физиологии и медицины. Зарисовки Рамон-и-Кахаля, из которых до наших дней дошло около 3 000, и сегодня остаются одними из самых подробных описаний структурного разнообразия мозга и нервной системы.

image
Автор зарисовки Сантьяго Рамон-и-Кахаль (Santiago Ramon y Cajal)

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

image

Хотя ещё со времён Гальвани было известно, что нервы могут быть возбуждены электрически, однако стимулы, используемые для возбуждения нервов, было довольно трудно контролировать. Какой силы и продолжительности должен быть сигнал? И как связь между стимулом и возбудимостью может быть объяснена за счёт подлежащей биофизики? Этими вопросами задались на границе XIX и XX веков пионеры в области изучения нервной возбудимости Ян Хорвег (Jan Leendert Hoorweg, 18411919, иногда неточно передаётся как Гоорвег), Жорж Вейс (Jules Adolphe Georges Weiss, 18511931) и Луи Лапик (Louis Lapicque, 18661952). В своём первом исследовании 1907 года Лапик представляет модель нерва, которую он сравнивает с данными, полученными при стимуляции нерва лягушки. Эта модель, основанная на простой конденсаторной схеме, послужит основой для будущих моделей клеточной мембраны нейрона.

Просто, чтобы вы понимали сложности науки в те годы, стоит привести пару примеров. Стимулом, который использовал Лапик, был короткий электрический импульс, который подавался через два электрода, разработанных и изготовленных специально для этой цели. В идеале в экспериментах по стимуляции можно было бы использовать импульсы тока, но подходящие источники тока создать было непросто. Вместо этого Лапик использовал источник напряжения батарею. Регулировка напряжения осуществлялась при помощи делителя напряжения, представлявшего собой длинный провод с ползунком, похожий на современный потенциометр. Получить точные импульсы длительностью всего несколько миллисекунд тоже было непросто, изобретённый несколько ранее инструмент для этого был назван реотомом. Устройство состояло из пистолета с капсюльным замком, пуля которого сначала разрывала первую перемычку, создавая ток в стимулирующей цепи, затем разрывала на своём пути вторую перемычку, прерывая контакт.

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

В 1943 году увидела свет книга Лапика La machine nerveuse [Нервная машина], подводящая итог многолетних исследований учёного.

image
Издательство Paris: Maison parisienne Neurdein (ND. Phot.), s.d.

Нередко в рассуждениях о результатах работы Лапика для вычислительной нейробиологии можно столкнуться с утверждением о том, что Лапик является создателем и исследователем первой модели нейрона, носящей название интегрировать-и-сработать [integrate-and-fire]. В соответствии с этой моделью, алгоритм работы нейрона можно описать следующим образом: когда на вход нейрона подаётся ток, разность потенциалов (напряжение) на мембране возрастает со временем, пока не достигает некоторого порогового значения, при котором происходит скачкообразное изменение потенциала на выходе, напряжение сбрасывается до остаточного потенциала, после чего процесс может повторяться снова и снова. В действительности связь между возбуждением нерва и образованием нервного импульса во времена Лапика была ещё неясной, и учёный не выдвигает гипотез ни об этом, ни о том, как мембрана возвращается в исходное состояние после выдачи импульса.

Дальнейшее развитие идей Лапика в рамках вычислительной нейробиологии привело к появлению множества более точных и полных моделей биологического нейрона. В их числе модели интегрировать-и-сработать с утечками [leaky integrate-and-fire], интегрировать-и-сработать с утечками дробного порядка [fractional-order leaky integrate-and-fire], модель Гальвеса Лёкербаха [GalvesLocherbach model], экспоненциальный вариант модели интегрировать-и-сработать [exponential integrate-and-fire] и многие другие. Нобелевская премия 1963 года была выдана за исследования сэра Алана Ллойда Ходжкина (Sir Alan Lloyd Hodgkin, 19141998) и сэра Эндрю Филдинга Хаксли (Sir Andrew Fielding Huxley, 19172012, не путайте с писателем).

image
Источник

Долгопёрый прибрежный кальмар (Doryteuthis pealeii), как и другие кальмары, является чрезвычайно удобным для нейрофизиологов модельным организмом благодаря наличию у него гигантских аксонов. Гигантский аксон кальмаров это очень большой (обычно около 0,5 мм в диаметре, но иногда достигает 1,5 мм) аксон, который контролирует часть водореактивной системы кальмара, используемой им в основном для коротких, но очень быстрых перемещений в воде. Между щупальцами кальмара расположен сифон, через который вода может быстро выталкиваться за счёт сокращений мышц стенки тела животного. Это сокращение инициируется потенциалами действия в гигантском аксоне. Поскольку электрическое сопротивление обратно пропорционально площади поперечного сечения объекта, потенциалы действия распространяются быстрее в большем аксоне, чем в меньшем. Поэтому увеличение диаметра гигантского аксона поддерживалось в процессе эволюции, так как позволяло увеличить скорость мышечной реакции. Это стало настоящим подарком для Ходжкина и Хаксли, которых интересовал ионный механизм потенциалов действия ведь благодаря большому диаметру аксона, в его просвет можно было невозбранно установить зажимные электроды!

image
Источник

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

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

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

В 2014 году, через два года после запуска EyeWire, сотрудники лаборатории сделали первое открытие и рассказали о нём в журнале Nature. Учёным удалось выяснить, как именно млекопитающие распознают движение. Когда свет попадает на клетки фоторецепторов, они передают сигнал биполярным клеткам, затем амакриновым и, наконец, ганглионарным. Учёные проанализировали 80 звёздчатых амакриновых нейронов (29 из них помогли описать игроки EyeWire) и соединённые с ними биполярные клетки. Они заметили, что разные типы биполярных клеток по-разному соединяются с амакриновыми нейронами: биполярные клетки одного типа располагаются далеко от сомы (тела) звёздчатой клетки и передают сигнал быстро, клетки другого типа располагаются близко, но сигнал передают с задержкой.

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

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

2 апреля 2013 года началась программа BRAIN Initiative. Первым кирпичиком в фундаменте стала статья Пола Аливизатоса, в которой были изложены экспериментальные планы для более скромного проекта, в том числе рассмотрены методы, которые могут быть использованы для построения функционального коннектома, а также перечислены технологии, которые необходимо будет разработать в ходе проекта. От червей и мух планировалось перейти к более крупным биосистемам, в частности, карликовой многозубке. Это самое маленькое по массе тела из известных науке млекопитающих, а её мозг состоит из всего примерно миллиона нейронов. От землероек можно будет перейти к приматам, в том числе на последнем этапе к людям.

Первый коннектом живого существа, а именно нематоды C. elegans, был построен в далёком 1986 году группой исследователей во главе с биологом Сидни Бреннером (Sydney Brenner, 19272019) из Кембриджа. Бреннер и его коллеги аккуратно нарезали миллиметровых червей на тонкие ломтики и сфотографировали каждый срез с помощью плёночной камеры, установленной на электронном микроскопе, а затем по полученным снимкам вручную проследили все связи между нейронами. Однако у C. elegans всего 302 нейрона и около 7 600 синапсов. В 2016 году команда учёных из Университета Дэлхаузи в Канаде повторили подвиг своих коллег для личинки морского оболочника Ciona intestinalis, центральная нервная система которого, как выяснилось, состояла из 177 нейронов и 6 618 синаптических соединений. Однако надо заметить, что методы, используемые для построения коннектома, неэффективны для крупных нервных систем. Исследователи не задумывались всерьёз о том, чтобы приступить к осуществлению значительно более крупных проектов до 2004 года, когда физик Винфрид Денк и нейроанатом Хайнц Хорстманн предложили использовать автоматический микроскоп для разрезания и визуализации мозга, а также программное обеспечение для сбора и соединения результирующих изображений.

В 2019 году в журнале Nature появилась публикация доктора Скотта Эммонса с подробным отчётом о воссоздании коннектома нематоды Caenorhabditis elegans при помощи нового метода. Годом раньше группа учёных под руководством Чжихао Чжэна (Zhihao Zheng) из Принстонского университета завершила работу над сканированием мозга дрозофилы, состоящего из примерно 100 тысяч нейронов. Система, разработанная Чжэном и его коллегами, позволила пропустить через просвечивающий растровый электронный микроскоп более 7 000 тончайших срезов мозга мушки, толщина каждого из которых составляла порядка 40 нм, а суммарный размер полученных в результате изображений составил 40 триллионов пикселей.

В апреле 2019 года сотрудники Института головного мозга им. Аллена в Сиэтле отпраздновали преодоление последнего рубежа в проекте по картированию одного кубического миллиметра мозга мыши с его 100 000 нейронов и одним миллиардом связей между ними. Чтобы обработать образец размером с горчичное зёрнышко, микроскопы работали непрерывно в течение пяти месяцев, собрав более 100 миллионов изображений 25 000 срезов зрительной коры. Затем программному обеспечению, разработанному учёными института, потребовалось около трёх месяцев, чтобы объединить изображения в единый трёхмерный массив объёмом 2 петабайта. Все собранные более чем за 30 лет миссиями Landsat снимки нашей планеты занимают всего около 1,3 петабайта, что делает сканы мозга мыши практически целым миром в песчинке. Конечная цель наноразмерный коннектом человеческого мозга пока ещё далеко. Число нейронов в нём сопоставимо с количеством звёзд в Млечном Пути (порядка 1011). При использовании современной технологии обработки изображений потребуются десятки микроскопов, работающих круглосуточно на протяжении тысячи лет, чтобы собрать данные, необходимые для достижения конечной цели. Но достижения в области микроскопии, а также разработка более мощных компьютеров и алгоритмов для анализа изображений, продвинули область коннектомики вперёд столь быстро, что это удивляет и самих исследователей. Пять лет назад было слишком амбициозно думать о кубическом миллиметре, говорит Рэйд. Сегодня многие исследователи считают, что полное картирование мозга мыши, объём которого составляет около 500 кубических миллиметров, станет возможным в следующем десятилетии. Сегодня картирование человеческого мозга на синаптическом уровне может показаться невероятным. Но если прогресс будет идти вперёд теми же темпами, как в вычислительных мощностях, так и в научных методах, ещё одно тысячекратное увеличение возможностей уже не кажется нам немыслимым.

image

BRAIN Initiative не единственная масштабная программа в этой области. Созданием функциональной модели мозга крысы (с прицелом на мозг человека) заняты и учёные из проектов Blue Brain Project и Human Brain Project. Не стоит на месте и China Brain Project.

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

Подбор скважин-кандидатов для гидравлического разрыва пласта с использованием методов машинного обучения

11.09.2020 10:13:26 | Автор: admin
image

Сегодня мы расскажем, как разрабатывали систему поиска скважин-кандидатов для гидравлического разрыва пласта (ГРП) с использованием машинного обучения (далее ML) и что из этого вышло. Разберёмся, зачем делать гидравлический разрыв пласта, при чём здесь ML, и почему наш опыт может оказаться полезен не только нефтяникам.

Под катом подробная постановка задачи, описание наших IT решений, выбор метрик, создание ML конвейера, разработка архитектуры для выпуска модели в прод.

Зачем делать ГРП мы писали в наших предыдущих статьях тут и тут.

Зачем здесь машинное обучение? ГРП с одной стороны хоть и дешевле бурения, но всё равно мероприятие затратное, а с другой его не получится делать на каждой скважине не будет эффекта. Поиском подходящих мест занимается эксперт-геолог. Поскольку количество действующих велико (десятки тысяч) нередко варианты упускаются из виду, и Компания недополучает возможную прибыль. Значительно ускорить анализ информации позволяет использование машинного обучения. Однако создать ML модель это лишь полдела. Нужно заставить её работать в постоянном режиме, связать с сервисом данных, нарисовать красивый интерфейс и сделать так, чтобы пользователю было удобно зайти в приложение и решить свою проблему в два клика.

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

A. Автоматизировать обработку и анализ большого потока данных.
B. Уменьшить затраты и не упускать выгоду.
C. Сделать такую систему быстро и эффективно.

Из статьи вы узнаете, как мы реализовали подобную систему, какие инструменты использовали, а также какие шишки набили на тернистом пути внедрения ML в производство. Уверены, что наш опыт может быть интересен всем, кто хочет автоматизировать рутину вне зависимости от сферы деятельности.

Как происходит подбор скважин на ГРП традиционным способом

При подборе скважин-кандидатов на ГРП нефтяник опирается на свой большой опыт и смотрит на разные графики и таблицы, после чего прогнозирует, где сделать ГРП. Достоверно, однако, никто не знает, что творится на глубине нескольких тысяч метров, ведь взглянуть под землю так просто не получается (подробнее можно почитать в предыдущей статье). Анализ данных традиционными методами требует значительных трудозатрат, но, к сожалению, не даёт гарантии точного прогноза результатов ГРП (спойлер с ML тоже).

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

image
Текущий процесс подбора скважин-кандидатов

Основной минус подобного ручного подхода много рутины, объёмы растут, люди начинают тонуть в работе, отсутствует прозрачность в процессе и методах.

Постановка задачи

В 2019 году перед нашей командой по анализу данных встала задача создать автоматизированную систему по подбору скважин-кандидатов на ГРП. Для нас это звучало так смоделировать состояние всех скважин, предположив, что прямо сейчас на них необходимо произвести операцию ГРП, после чего отранжировать скважины по наибольшему приросту добычи нефти и выбрать Топ-N скважин, на которые поедет флот и проведёт мероприятия по увеличению нефтеотдачи.

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

В нашем случае дебит нефти представляет собой количество добытой нефти в метрах кубических за 1 месяц. Данный показатель рассчитывается на основе двух величин: дебита жидкости и обводнённости. Жидкостью нефтяники называют смесь нефти и воды именно эта смесь является продукцией скважин. А обводнённость это доля содержания воды в данной смеси. Для того чтобы рассчитать ожидаемый дебит нефти после ГРП, используются две модели регрессии: одна прогнозирует дебит жидкости после ГРП, другая прогнозирует обводнённость. С помощью значений, которые возвращают данные модели, рассчитываются прогнозы дебита нефти по формуле:

image

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

Что касается метрики Метрика должна идти от бизнеса и отражать интересы заказчика, говорят нам любые курсы по машинному обучению. По нашему мнению здесь кроется главный успех или неуспех проекта по машинному обучению. Группа датасайнтистов может сколь угодно долго улучшать качество модели, но если она никак не повышает бизнес-ценность для заказчика такая модель обречена. Ведь заказчику было важно получить точно кандидата с физичными прогнозами параметров работы скважины после ГРП.

Для задачи регрессии были выбраны следующие метрики:

image

Почему метрика не одна, спросите вы каждая отражает свою правду. Для месторождений, где средние дебиты высокие, МАЕ будет большим, а МАРЕ маленьким. Если взять месторождение с низкими средними дебитами, картина будет противоположной.

Для задачи классификации выбраны следующие метрики:

image
(вики),

Площадь под кривой ROCAUC (вики).

Ошибки, с которыми мы столкнулись

Ошибка 1 построить одну универсальную модель для всех месторождений.

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

image

Ошибка 2 отсутствие глубокого понимания данных.

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

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

Сперва мы выгружали много различных csv файлов для разных месторождений и разных показателей. В определённый момент файлов и моделей накопилось невыносимо много. Стало невозможно воспроизвести уже проведённые эксперименты, терялись файлы, возникала путаница.

1. ТЕХНИЧЕСКАЯ ЧАСТЬ

На сегодняшний день наша система автоподбора кандидатов выглядит следующим образом:

image

Каждый компонент представляет собой изолированный контейнер, который выполняет определённую функцию.

2.1 ETL = Загрузка данных

Всё начинается с данных. Особенно, если мы хотим построить модель машинного обучения. В качестве интеграционной системы мы выбрали Pentaho Data Integration.

image
Скриншот одной из трансформаций

Основные плюсы:

  • бесплатная система;
  • большой выбор компонент для подключения к различным источникам данных и трансформации потока данных;
  • наличие веб-интерфейса;
  • возможность управлять через REST API;
  • логирование.

Плюс ко всему перечисленному у нас был большой опыт разработки интеграций на данном продукте. Почему нужна интеграция данных в проектах ML? В процессе подготовки датасетов постоянно требуется реализовать сложные расчёты, привести данные к единому виду, по пути рассчитать новые признаки средние, изменения параметров во времени и т. д.

Для каждого факта ГРП выгружается более 400 параметров, описывающих работу скважины на момент проведения мероприятия, работу соседних скважин, а также информацию о проведённых ранее ГРП. Далее происходит преобразование и предобработка данных.

В качестве хранилища обработанных данных мы выбрали PostgreSQL. У него большой набор методов для работы с json. Так как мы храним итоговые датасеты в данном формате это стало решающим фактором.

Проект машинного обучения связан с постоянным изменением входных данных в силу добавления новых признаков, поэтому в качестве схемы базы данных используется Data Vault (ссылка на вики). Эта схема построения хранилищ позволяет быстро добавлять новые данные об объекте и не нарушать целостность таблиц и запросов.

2.2 Сервисы данных и моделей

После причёсывания и расчёта нужных показателей данные заливаются в БД. Здесь они хранятся и ждут, когда датасайнтист возьмёт их для создания ML модели. Для этого существует DataService сервис, написанный на Python и использующий gRPC протокол. Он позволяет получать датасеты и их метаданные (типы признаков, их описание, размер датасета и т. п.), загружать и выгружать прогнозы, управлять параметрами фильтрации и деления на train/test. Прогнозы в базе хранятся в формате json, что позволяет быстро получать данные и хранить не только значение прогноза, но и влияние каждого признака на этот конкретный прогноз.

image
Пример proto файла для сервиса данных.

Когда модель создана, её следует сохранить для этих целей используется ModelService, также написанный на Python с gRPC. Возможности этого сервиса не ограничиваются сохранением и загрузкой модели. Кроме того, он позволяет мониторить метрики, важность признаков, а также осуществляет связку модель + датасет, для последующего автоматического создания прогноза при появлении новых данных.

image
Примерно так выглядит структура нашего сервиса моделей.

2.3 ML модель

В определённый момент наша команда поняла, что автоматизация должна коснуться и создания ML моделей. Такая потребность была обусловлена необходимостью ускорения процесса создания прогнозов и проверки гипотез. И мы приняли решение разработать и внедрить в наш конвейер собственную библиотеку AutoML.

Изначально рассматривалась возможность использования готовых AutoML библиотек, однако существующие решения оказались недостаточно гибкими для нашей задачи и не обладали всем нужным функционалом сразу (по просьбам трудящихся можем написать отдельную статью о нашем AutoML). Отметим лишь, что разработанный нами фреймворк содержит классы, используемые для предобработки датасета, генерации и отбора признаков. В качестве моделей машинного обучения используется привычный набор алгоритмов, которые наиболее успешно применялись нами ранее: реализации градиентного бустинга из библиотек xgboost, catboost, случайный лес из Sklearn, полносвязная нейронная сеть на Pytorch и т. д. После обучения AutoML возвращает sklearn пайплайн, который включает в себя упомянутые классы, а также ML модель, которая показала наилучший результат на кросс-валидации по выбранной метрике.

Помимо модели формируется и отчёт о влиянии каких-либо признаков на конкретный прогноз. Такой отчёт позволяет геологам заглянуть под капот таинственного чёрного ящика. Таким образом, AutoML получает размеченный датасет с помощью DataService и после обучения формирует конечную модель. Далее мы можем получить окончательную оценку качества модели, загрузив тестовый датасет, сформировав прогнозы и рассчитав метрики качества. Завершающим этапом является выгрузка бинарного файла сформированной модели, её описания, метрик на ModelService, в то время как прогнозы и информация о влиянии признаков возвращаются на DataService.

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

2.4 Интерфейс

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

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

image
Интерфейс модуля в приложении.

image
Так выглядит карточка скважины в приложении.

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

image

В приложении наглядно показаны, какие признаки оказались наиболее важными для прогнозов модели.

Также пользователь может посмотреть на аналоги интересующей скважины. Поиск аналогов реализован на стороне клиента с помощью алгоритма K-d дерево.

image

Модуль выводит скважины, схожие по геологическим параметрам.

2. КАК М УЛУЧШАЛИ ML МОДЕЛЬ

image

Казалось бы, стоит запустить AutoML на имеющихся данных, и будет нам счастье. Но бывает так, что качество прогнозов, получаемых автоматическим способом, не идёт ни в какое сравнение с результатами датасайнтистов. Дело в том, что для улучшения моделей аналитики нередко выдвигают и проверяют различные гипотезы. Если идея позволяет улучшить точность прогнозирования на реальных данных, она реализуется и в AutoML. Таким образом, добавляя новые фичи, мы усовершенствовали автоматическое прогнозирование настолько, чтобы перейти к созданию моделей и прогнозов с минимальной включённостью аналитиков. Вот несколько гипотез, которые были проверены и внедрены в наш AutoML:

1. Изменение метода заполнения пропусков

В самых первых моделях мы заполняли почти все пропуски в признаках средним, кроме категориальных для них использовалась самое часто встречающееся значение. В дальнейшем, при совместной работе аналитиков и эксперта, в доменной области удалось подобрать наиболее подходящие значения для заполнения пропусков в 80% признаков. Также мы испробовали ещё несколько методов заполнения пропусков с использованием библиотек sklearn и missingpy. Наилучшие результаты дали заполнение константой и KNNImputer до 5% MAPE.

image
Результаты эксперимента по заполнению пропусков различными методами.

2. Генерация признаков

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

image
Проверка гипотез, выдвигаемых командой, помогает вводить новые признаки.

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

image
Процесс создания признака на основе выделения кластеров.

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

3. Отбор признаков

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

А теперь про полученные метрики...

На одном из месторождений мы получили следующие показатели качества моделей:

image

Стоит отметить, что результат выполнения ГРП также зависит от ряда внешних факторов, которые не прогнозируются. Поэтому о снижении МАРЕ до 0 говорить нельзя.

Заключение

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

Компания открыта для экспериментов, поэтому из списка были выбраны около 20 скважин, и на них провели операции гидроразрыва. Отклонение прогноза с фактическим значением запускного дебита нефти (МАРЕ) составило около 10%. И это очень неплохой результат!

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

Пишите вопросы и комментарии постараемся на них ответить.

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

Вебинар Контроль качества технологии и технологической дисциплины

21.09.2020 16:09:27 | Автор: admin
image

Рады объявить о серии вебинаров посвященных контролю качества технологии и технологической дисциплины. Приглашаем всех желающих присоединиться к обсуждению во вторник, 6 октября в 11:00 по московскому времени.

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

Данная серия вебинаров будет состоять из следующих блоков:


Вводная часть: IIoT для мониторинга
Как и чем Промышленный Интернет Вещей помогает технологам
Примеры реального использования IIoT-решения на отечественных предприятиях
Онлайн-подключение к действующему заводу
Q&A с лучшими в своем классе экспертами

Мероприятие ориентировано на руководителей предприятий, специалистов, отвечающих за подготовку производства, разработчиков УП, ИТ-директоров, директоров по цифровизации и развитию.

Вебинар для вас, если вы хотите:


Выпускать больше/качественнее благодаря современному подходу к подготовке производства
Увидеть места, где уместно пересмотреть и оптимизировать технологию
Сбалансировать выпуск за счет выравнивания производственных циклов
Узнать, как и где можно сократить время переналадок и смены инструмента
Получить автоматическую фотографию рабочего дня и актуализировать на ее основе нормы времени

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

Регистрация:

https://winnum.timepad.ru/event/1435934/
Подробнее..

Перевод Лучшие инструменты с открытым исходным кодом и библиотеки для Deep Learning ICLR 2020 Experiencebi

22.09.2020 10:23:41 | Автор: admin
Сложно найти на Хабре человека, который не слышал бы про нейронные сети. Регулярные новости о свежих достижениях нейронных сетей заставляют удивляться широкую публику, а также привлекают новых энтузиастов и исследователей. Привлеченный поток специалистов способствует не только еще большим успехам нейронных моделей, но и приводит к развитию инструментов для более удобного использования Deep Learning подходов. Помимо всем известных фреймворков Tensorflow и PyTorch активно развиваются и другие библиотеки, нередко более гибкие, но менее известные.

Эта статья является переводом одного из постов neptune.ai и освещает самые интересные инструменты для глубокого обучения, представленные на конференции по машинному обучения ICLR 2020.


Где создается и обсуждается передовое глубокое обучение?


Одним из главных мест обсуждения Deep Learning является ICLR ведущая конференция по глубокому обучению, которая состоялась 27-30 апреля 2020 года. Более 5500 участников и почти 700 презентаций и докладов это большой успех для полностью онлайн-мероприятия. Найти исчерпывающую информацию о конференции вы можете здесь, здесь или здесь.

Виртуальные социальные встречи были одной из изюминок ICLR 2020. Организаторы решили запустить проект под названием Open source tools and practices in state-of-the-art DL research. Тема была выбрана из-за того, что соответствующий инструментарий является неизбежной частью работы исследователя глубокого обучения. Достижения в этой области привели к распространению крупных экосистем (TensorFlow, PyTorch, MXNet), а также более мелких целевых инструментов, отвечающих за решение конкретных потребностей исследователей.

Цель упомянутого мероприятия заключалась во встрече с создателями и пользователями инструментов с открытым исходным кодом, а также в обмене опытом и впечатлениями среди сообщества Deep Learning. В общей сложности было собрано более 100 человек, включая основных вдохновителей и руководителей проектов, которым мы дали короткие промежутки времени для представления своей работы. Участники и организаторы были удивлены широким разнообразием и креативностью представленных инструментов и библиотек.

В этой статье собраны яркие проекты, представленные с виртуальной сцены.

Инструменты и библиотеки


Далее будут рассмотрены восемь инструментов, которые были продемонстрированы на ICLR с подробным обзором возможностей.

Каждый раздел представляет ответы на ряд пунктов в очень сжатой форме:

  1. Какую проблему решает инструмент / библиотека?
  2. Как запустить или создать минимальный пример использования?
  3. Внешние ресурсы для более глубокого погружения в библиотеку / инструмент.
  4. Профиль представителей проекта на случай, если будет желание к ним обратиться.

Вы можете перейти к конкретному разделу ниже или просто просмотреть их все один за другим. Наслаждайтесь чтением!

AmpliGraph


Тема: Модели эмбеддингов на основе Knowledge Graph.
Язык программирования: Python
Автор: Люка Костабелло
Twitter | LinkedIn | GitHub | Интернет сайт

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

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

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

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

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


Модели машинного обучения AmpliGraph генерируют графовые эмбеддинги, представления в векторном пространстве.

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

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

Automunge


Платформа подготовки табличных данных
Язык программирования: Python
Автор: Николас Тиг
Twitter | LinkedIn | GitHub | Интернет сайт

Automunge библиотека Python, помогающая в подготовке табличных данных для использование в машинном обучении. Посредством инструментария пакета возможны простые преобразования для feature engeenering-a с целью нормализации, кодировки и заполнения пропусков. Преобразования применяются к тренировочной подвыборке, а затем аналогичным образом применяются к данным из тестовой подвыборки. Преобразования могут выполняться в автоматическом режиме, назначаться из внутренней библиотеки или гибко настраиваться пользователем. Варианты заполнения включают заполнение на основе машинного обучения, в котором модели обучаются для каждого столбца данных прогнозировать недостающую информацию.

Проще говоря:

automunge (.) подготавливаются табличные данные для использования в машинном обучении,

postmunge (.) последовательно и с высокой эффективностью обрабатываются дополнительные данные.

Automunge доступен для установки посредством pip:


После установки достаточно импортировать библиотеку в Jupyter Notebook для инициализации:


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


Далее для последующей обработки данных из тестовой подвыборки, достаточно запустить команду, использующую словарь postprocess_dict, полученный вызовом automunge (.) выше:


С помощью параметров assigncat и assigninfill в вызове automunge (.) могут быть определены детали преобразований и типы данных для заполнения пропусков. Например, для набора данных со столбцами 'column1' и 'column2' можно назначить масштабирование на основе минимальных и максимальных значений ('mnmx') с ML-заполнением пропусков для column1 и one-hot encoding ('text') с заполнением пропусков на основе наиболее часто встречающегося значения для column2. Не указанные в явном виде данные из других столбцов будут обрабатываться автоматически.


Ресурсы и ссылки

Сайт | GitHub | Краткая презентация

DynaML


Машинное обучение для Scala
Язык программирования: Scala
Автор: Мандар Чандоркар
Twitter | LinkedIn | GitHub

DynaML это набор инструментов для исследований и машинного обучения на основе Scala. Он направлен на предоставление пользователю сквозной среды, которая может помочь в:

  • разработке / макетировании моделей,
  • работе с громоздкими и сложными pipelines,
  • визуализацией данных и результатов,
  • повторном использовании кода в виде скриптов и Notebook-ов.

DynaML использует сильные стороны языка и экосистемы Scala для создания среды, обеспечивающей производительность и гибкость. Он основан на таких превосходных проектах, как Ammonite scala, Tensorflow-Scala и библиотеке высокопроизводительных численных расчётов Breeze.

Ключевым компонентом DynaML является REPL / оболочка, которая имеет подсветку синтаксиса и продвинутую систему автозаполнения.

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

Среда поставляется с поддержкой 2D и 3D-визуализации, результаты могут быть отображены непосредственно из командной оболочки.

3D-диаграммы отображаются с помощью Java API jzy3d.

Модуль data pipes позволяет легко создавать pipelines обработки данных в пригодном для компоновки модульном виде. Создавайте функции, оборачивайте их с помощью конструктора DataPipe и составляйте блоки функций с помощью оператора >.

Обработка потоков данных выглядит интуитивно понятной, когда pipeline логически делится на этапы, а на каждом шаге выполняется одно единственное преобразование.

Также доступна экспериментальная функция интеграции c Jupyter notebook, каталог notebooks в репозитории содержит несколько примеров использования ядра DynaML-Scala Jupyter.

Notebook c линейной регрессией (linear-regression notebook) демонстрирует использование низкоуровневого API Tensorflow для вычисления коэффициентов линейной регрессионной модели.

Руководство пользователя содержит обширнуюсправочную информацию и документацию для освоения и получения максимальной отдачи от среды DynaML.

Ниже приводятся некоторые интересные приложения, которые подчеркивают сильные стороны DynaML:


Ресурсы и ссылки

GitHub | Руководство пользователя

Hydra


Configuration and parameters manager
Язык программирования: Python
Автор: Омры Ядан
Twitter | GitHub

Разработанная в Facebook AI, Hydra платформа Python, которая упрощает разработку исследовательских приложений, предоставляя возможность создавать и переопределять конфигурации с помощью конфигурационных файлов и командной строки. Платформа также обеспечивает поддержку автоматической развертки параметров, удаленное и параллельное выполнение посредством плагинов, автоматическое управление рабочим каталогом и динамическое предложение вариантов дополнения с помощью нажатия клавиши TAB.

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

Основной пример

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

config.yaml:


my_app.py:


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


Пример композиции:

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

Создать эту структуру директорий:


config.yaml:


defaults это специальная директива, указывающая Hydra использовать db / mysql.yaml при составлении объекта конфигурации.

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


Ознакомьтесь с туториалом, чтобы узнать больше.

Кроме того, в ближайшее время появятся новые интересные функции:

  • строго типизированные конфигурации (структурированные конфигурационные файлы),
  • оптимизация гиперпараметров с помощью плагинов Ax и Nevergrad,
  • запуск AWS с помощью плагина Ray launcher,
  • локальный параллельный запуск посредством плагина joblib и многое другое.

Larq


Бинаризованные нейронные сети
Язык программирования: Python
Автор: Лукас Гайгер
Twitter | LinkedIn | GitHub

Larq это экосистема пакетов Python с открытым исходным кодом для построения, обучения и развертывания бинаризованных нейронных сетей (BNN). BNN это модели глубокого обучения, в которых активации и веса кодируются не с использованием 32, 16 или 8 бит, а с использованием только 1 бита. Это может значительно ускорить время логического вывода и снизить энергопотребление, что делает BNN идеально подходящими для мобильных и периферийных устройств.

Экосистема Larq с открытым исходным кодом состоит из трех основных компонентов.

  1. Larq это мощная, но простая в использовании библиотека для построения и обучения крайне квантованных нейронных сетей. Она предлагает единообразные и простые API, которые расширяемы и обладают совместимостью с более крупной экосистемой TensorFlow Keras. Это позволяет сделать постепенное внедрение в текущую кодовую базу и обеспечивает быструю итерацию при разработке моделей. Хотя библиотека Larq в основном ориентирована на BNNs, она также может быть использована для обучения сетей с произвольными функциями активации и весами произвольной точности.
  2. Larq Zoo предоставляет базовые реализации BNNs, доступные наряду с предобученными весами. Целью Larq Zoo является стимулирование воспроизводимых исследований, а исследователям предоставляется возможность использовать последние достижения из литературы по BNN без затрат времени на попытки воспроизвести существующие работы.
  3. Larq Compute Engine это библиотека для логического вывода и развертывания BNNs. Она собрана поверх TensorFlow Lite и включает в себя конвертер на основе MLIR для преобразования моделей Larq в файлы FlatBuffer, совместимые с окружением TF Lite. В настоящее время он поддерживает мобильные платформы на базе ARM64, такие, как телефоны на Android и Raspberry Pi, и достигает самой высокой производительности в скорости логического вывода на устройствах с помощью ядер двоичной свертки, оптимизированных вручную, а также оптимизации на сетевом уровне для моделей BNN.

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

Ресурсы и ссылки

Сайт | GitHub larq / larq | GitHub larq / zoo | GitHub larq / compute-engine | Учебники | Блог | Twitter

McKernel


Ядерные методы в логарифмически линейное время
Язык программирования: C/C++
Автор: J. de Curt i Daz
Twitter | Интернет-сайт

Первая библиотека C++ с открытым исходным кодом, предоставляющая как аппроксимацию ядерных методов на основе случайных признаков, так и полноценный Deep Learning фреймворк.

McKernel предоставляет четыре различные возможностииспользования.

  1. Самодостаточный молниеносный код Адамара с открытым исходником. Для использования в таких областях, как компрессия, шифрование или квантовые вычисления.
  2. Чрезвычайно быстрые ядерные методы. Могут использоваться везде, где методы SVM (Метод Опорных Векторов: ru.wikipedia.org/wiki/%D0%9C%D0%B5%D1%82%D0%BE%D0%B4_%D0%BE%D0%BF%D0%BE%D1%80%D0%BD%D1%8B%D1%85_%D0%B2%D0%B5%D0%BA%D1%82%D0%BE%D1%80%D0%BE%D0%B2) превосходят Deep Learning. Например, в некоторых приложениях робототехники и ряде случаев использования машинного обучения в здравоохранении, а также в других областях, включают Federated Learning и выбор канала коммуникации.
  3. Интеграция методов Deep Learning и ядерных методов, позволяет развивать Deep Learning архитектуры в априорно антропоморфном / математическом направлении.
  4. Исследовательский фреймворк Deep Learning для решения ряда открытых вопросов в машинном обучении.

Уравнение, описывающее все вычисления, выглядит следующим образом:


Здесь авторы в качестве первопроходцев применяют формализм для объяснения с помощью случайных признаков как методов Deep Learning, так и ядерных методов. Теоретическая основа опирается на четырех гигантов: Гаусса, Винера, Фурье и Калмана. Фундамент для этого был заложен Рахими и Рехтом (NIPS 2007) и Le et al. (ICML 2013).

С прицелом на типичного пользователя

Основной аудиторией McKernel являются исследователи и практические специалисты в области робототехники, машинного обучения для здравоохранения, обработки сигналов и коммуникаций, которые нуждаются в эффективной и быстрой реализации на C++. В описанном случае большинство библиотек Deep Learning не удовлетворяют заданным условиям, поскольку они по большей части основаны на высокоуровневых реализациях на Python. Кроме того, аудиторией могут быть представители более широкого сообщества машинного обучения и Deep Learning, которые пребывают в поиске улучшения архитектуры нейронных сетей, используя ядерные методы.

Сверхпростой наглядный пример для запуска библиотеки без затрат времени выглядит следующим образом:


Что дальше?

Сквозное обучение, self-supervised learning, meta-learning, интеграция с эволюционными стратегиями, существенное сокращение пространства поиска с помощью NAS ,

Ресурсы и ссылки

GitHub | Полная презентация

SCCH Training Engine


Подпрограммы для автоматизации Deep Learning
Язык программирования: Python
Автор: Наталья Шепелева
Twitter | LinkedIn | Интернет-сайт

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

Целью SCCH Training Engine является унификация и автоматизация процедуры Deep Learning разработки для двух самых популярных фреймворков PyTorch и TensorFlow. Архитектура с одним входом позволяет минимизировать время разработки и защищает от программных ошибок.

Для кого?

Гибкая архитектура SCCH Training Engine обладает двумя уровнями взаимодействия с пользователем.

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

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


Что он может делать?

Текущие возможности:

  • работа с TensorFlow и PyTorch,
  • стандартизированный pipeline парсинга данных из различных форматов,
  • стандартизированный pipeline тренировки модели и валидации результатов,
  • поддержка задач классификации, сегментации и детекции,
  • поддержка кросс-валидации.

Возможности на стадии разработки:

  • поиск оптимальных гиперпараметров модели,
  • загрузка весов модели и тренировка от конкретной контрольной точки,
  • поддержка архитектуры GAN.

Как это работает?

Чтобы увидеть SCCH Training Engine во все красе, вам нужно сделать два шага.

  1. Просто скопируйте репозиторий и установите требующиеся пакеты с помощью команды: pip install requirements.txt.
  2. Запустите python main.py, чтобы увидеть учебный пример MNIST с процессом обработки и обучения на модели LeNet-5.

Всю информацию о том, как создать файл конфигурации и как использовать продвинутые возможности, можно найти на странице GitHub.

Стабильный релиз с основными функциями: был запланирован на конец мая 2020 г.

Ресурсы и ссылки

GitHub | Интернет-сайт

Tokenizers


Текстовые токенизаторы
Язык программирования: Rust с Python API
Автор: Энтони Муа
Twitter | LinkedIn | GitHub

huggingface/tokenizers обеспечивает доступ к самым современным токенизаторам, с акцентом на производительность и многоцелевое использование. Tokenizers позволяет обучать и использовать токенизаторы без усилий. Токенизаторы могут помочь вам независимо от того, являетесь ли вы ученым или практиков в области NLP.

Ключевые особенности

  • Чрезвычайная скорость: токенизация не должна быть узким местом в вашем pipeline, кроме того вам не нужно заниматься предварительной обработкой ваших данных. Благодаря нативной реализации на Rust, токенизация гигабайт текстов занимает всего несколько секунд.
  • Смещения / выравнивание: обеспечивает контроль смещения даже при обработке текста со сложной процедурой нормализации. Это позволяет легко извлекать текст для таких задач, как NER или question answering.
  • Предварительная обработка: заботится о любой предварительной обработке, необходимой перед подачей данных в вашу языковую модель (усечение, заполнение, добавление специальных токенов и т. д.).
  • Простота в обучении: Тренируйте любой токенизатор на новом корпусе. Например, обучение токенизатора для BERT на новом языке никогда не было таким простым.
  • Multi-languages: связка с несколькими языками. Прямо сейчас вы можете начать использовать его с Python, Node.js, или Rust. Работа в этом направлении продолжается!

Пример:


И скоро:

  • сериализация в единый файл и загрузка в одну строчку для любого токенизатора,
  • поддержка Unigram.

Hugging Face видят свою миссию в том, чтобы помогать в продвижении и демократизации NLP.

Ресурсы и ссылки

GitHub huggingface / трансформеры | GitHub huggingface / токенизаторы | Twitter

Заключение


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

Мы в компании CleverDATA стараемся следить за появлением новых инструментов и полезных библиотек, а также активно применяем свежие подходы в нашей работе, связанной с использованием Deep Learning и Машинного Обучения. Со своей стороны я хотел бы обратить внимание читателей на эти две библиотеки, не вошедшие в основную статью, но существенно помогающие в работе с нейронными сетями: Catalyst (https://github.com/catalyst-team/catalyst) и Albumentation (https://pypi.org/project/albumentations/).

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

Благодарю за внимание и надеюсь, что представленный набор библиотек окажется полезным в вашей работе!
Подробнее..

Экстракция данных из SAP HCM в non-SAP хранилища данных

23.09.2020 16:18:12 | Автор: admin
Как известно, компания SAP предлагает полный спектр программного обеспечения, как для ведения транзакционных данных, так и для обработки этих данных в системах анализа и отчетности. В частности платформа SAP Business Warehouse (SAP BW) представляет собой инструментарий для хранения и анализа данных, обладающий широкими техническими возможностями. При всех своих объективных преимуществах система SAP BW обладает одним значительным недостатком. Это высокая стоимость хранения и обработки данных, особенно заметная при использовании облачной SAP BW on Hana.

А что если в качестве хранилища начать использовать какой-нибудь non-SAP и желательно OpenSource продукт? Мы в Х5 Retail Group остановили свой выбор на GreenPlum. Это конечно решает вопрос стоимости, но при этом сразу появляются вопросы, которые при использовании SAP BW решались практически по умолчанию.



В частности, каким образом забирать данные из систем источников, которые в большинстве своем являются решениями SAP?

HR-метрики стал первым проектом, в котором необходимо было решить эту проблему. Нашей целью было создание хранилища HR-данных и построение аналитической отчетности по направлению работы с сотрудниками. При этом основным источником данных является транзакционная система SAP HCM, в которой ведутся все кадровые, организационные и зарплатные мероприятия.

Экстракция данных


В SAP BW для SAP-систем существуют стандартные экстракторы данных. Эти экстракторы могут автоматически собирать необходимые данные, отслеживать их целостность, определять дельты изменений. Вот, например, стандартный источник данных по атрибутам сотрудника 0EMPLOYEE_ATTR:



Результат экстракции данных из него по одному сотруднику:



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

Первой возникла идея о возможности их переиспользования. К сожалению, это оказалось неосуществимой задачей. Большая часть логики реализована на стороне SAP BW, и безболезненно отделить экстрактор на источнике от SAP BW не получилось.

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

Структура хранения данных в SAP HCM


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

Большинство данных в SAP HCM хранится в плоских SQL таблицах. На основании этих данных приложения SAP визуализируют пользователю оргструктуры, сотрудников и прочую HR информацию. Например, вот так в SAP HCM выглядит оргструктура:



Физически такое дерево хранится в двух таблицах в hrp1000 объекты и в hrp1001 связи между этими объектами.

Объекты Департамент 1 и Управление 1:



Связь между объектами:



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

Отображение руководителя в SAP:



Хранение в таблице БД:



Данные по сотрудникам хранятся в таблицах pa*. Например, данные о кадровых мероприятиях по сотруднику хранятся в таблице pa0000



Мы приняли решение, что GreenPlum будет забирать сырые данные, т.е. просто копировать их из SAP таблиц. И уже непосредственно в GreenPlum они будут обрабатываться и преобразовываться в физические объекты (например, Отдел или Сотрудник) и метрики (например, среднесписочная численность).

Было определено порядка 70 таблиц, данные из которых необходимо передавать в GreenPlum. После чего мы приступили к проработке способа передачи этих данных.

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

Конечно, в SAP HCM есть механизмы фиксация изменений данных. Например, для последующей передачи в системы получатели существуют указатели изменений(change pointer), которые фиксируют любые изменения и на основании которых формируются Idoc (объект для передачи во внешние системы).

Пример IDoc изменения инфотипа 0302 у сотрудника с табельным номером 1251445:



Или ведение логов изменений данных в таблице DBTABLOG.

Пример лога удаления записи с ключом QK53216375 из таблицы hrp1000:



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

Следующей серьезной проблемой были кластерные таблицы. Данные оценки времени и расчета зарплаты в RDBMS версии SAP HCM хранятся в виде набора логических таблиц по каждому сотруднику за каждый расчет. Эти логические таблицы в виде двоичных данных хранятся в таблице pcl2.

Кластер расчета заработной платы:



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

Оценивая варианты с формированием дельты изменения данных, решили так же рассмотреть вариант с полной выгрузкой. Вариант каждый день передавать гигабайты неизменных данных между системами не может выглядеть красиво. Однако он имеет и ряд преимуществ нет необходимости как реализации дельты на стороне источника, так и реализация встраивания этой дельты на стороне приемника. Соответственно, уменьшается стоимость и сроки реализации, и повышается надежность интеграции. При этом было определено, что практически все изменения в SAP HR происходят в горизонте трех месяцев до текущей даты. Таким образом, было принято решение остановиться на ежедневной полной выгрузке данных из SAP HR за N месяцев до текущей даты и на ежемесячной полной выгрузке. Параметр N зависит от конкретной таблицы
и колеблется от 1 до 15.

Для экстракции данных была предложена следующая схема:



Внешняя система формирует запрос и отправляет его в SAP HCM, там этот запрос проверяется на полноту данных и полномочия на доступ к таблицам. В случае успешной проверки, в SAP HCM отрабатывает программа, собирающая необходимые данные и передающая их в интеграционное решение Fuse. Fuse определяет необходимый топик в Kafka и передает данные туда. Далее данные из Kafka передаются в Stage Area GP.

Нас в данной цепочке интересует вопрос извлечения данных из SAP HCM. Остановимся на нем подробнее.

Схема взаимодействия SAP HCM-FUSE.



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

Данные запроса передаются в body в формате json.
Метод http: POST.
Пример запроса:



Сервис SAP выполняет контроль запроса на полноту, соответствие текущей структуре SAP, наличие разрешения доступа к запрошенной таблице.

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

Внешняя система в случае ошибки регистрирует ее в журнале. В случае успешного ответа передает id сессии и имя таблицы по которой был сделан запрос.

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

Фоновое задание SAP формирует курсор по заданным параметрам и пакет данных заданного размера. Размер пакета максимальное количество записей, которые процесс читает из БД. По умолчанию принимается равным 2000. Если в выборке БД больше записей, чем используемый размер пакета после передачи первого пакета формируется следующий блок с соответствующим offset и инкрементированным номером пакета. Номера инкрементируются на 1 и отправляются строго последовательно.

Далее SAP передает пакет на вход web-сервису внешней системы. А она система выполняет контроли входящего пакета. В системе должна быть зарегистрирована сессия с полученным id и она должна находиться в открытом статусе. Если номер пакета > 1 в системе должно быть зарегистрировано успешное получение предыдущего пакета (package_id-1).

В случае успешного контроля внешняя система парсит и сохраняет данные таблицы.

Дополнительно, если в пакете присутствует флаг final и сериализация прошла успешно, происходит уведомление модуля интеграции об успешном завершении обработки сессии и модуль обновляет статус сессии.

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

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

Для запроса данных на стороне SAP HСM был реализован интеграционный сервис. Сервис реализован на фреймворке ICF (SAP Internet Communication Framework help.sap.com/viewer/6da7259a6c4b1014b7d5e759cc76fd22/7.01.22/en-US/488d6e0ea6ed72d5e10000000a42189c.html). Он позволяет производить запрос данных из системы SAP HCM по определенным таблицам. При формировании запроса данных есть возможность задавать перечень конкретных полей и параметры фильтрации с целью получения необходимых данных. При этом реализация сервиса не предполагает какой-либо бизнес-логики. Алгоритмы расчёта дельты, параметров запроса, контроля целостности, и пр. также реализуются на стороне внешней системы.

Данный механизм позволяет собирать и передавать все необходимые данные за несколько часов. Такая скорость находится на грани приемлемой, поэтому это решение рассматривается нами как временное, позволившее закрыть потребность в инструменте экстракции на проекте.
В целевой картине для решения задачи экстракции данных прорабатываются варианты использования CDC систем типа Oracle Golden Gate или ETL инструментов типа SAP DS.
Подробнее..

Мы Опубликовали Современные STT Модели Сравнимые по Качеству с Google

17.09.2020 20:15:16 | Автор: admin


Мы наконец опубликовали наш набор высококачественных пре-тренированных моделей для распознавания речи (т.е. сравнимых по качеству с премиум-моделями Google) для следующих языков:


  • Английский;
  • Немецкий;
  • Испанский;

Вы можете найти наши модели в нашем репозитории вместе с примерами и метриками качества и скорости. Мы также постарались сделать начало работы с нашими моделями как можно более простым выложили примеры на Collab и чекпойнты для PyTorch, ONNX и TensorFlow. Модели также можно загружать через TorchHub.


PyTorch ONNX TensorFlow Качество Colab
Английский (en_v1) ссылка Открыть в Colab
Немецкий (de_v1) ссылка Открыть в Colab
Испанский (es_v1) ссылка Открыть в Colab

Почему это Важно


Распознавание речи традиционно имело высокие барьеры на вход по ряду причин:


  • Данные сложно собирать;
  • Разметка на сравнимую единицу данных стоит сильно дороже чем в компьютерном зрении;
  • Высокие требования по вычислительной мощности и устаревшие технологии;

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


  • Исследования в этой сфере обычно делаются на огромных вычислительных мощностях;
  • Пре-тренированные модели и готовые рецепты обычно имеют сильные проблемы с генерализацией, их тяжело использовать "как есть", много зависимостей от устаревших технологий;
  • До недавнего времени сообщество не имело доступа к простым в использовании, но качественным пре-тренированным моделям для распознавания речи;

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


  • Мы публикуем набор высококачественных пре-тренированных моделей для популярных языков;
  • Наши модели быстрые и могут работать на обычном железе;
  • Наши модели легко использовать;
  • Наши модели пре-тренированы на огромных и разнообразных речевых корпусах;
  • Мы строили наши модели так, чтобы они были устойчивы к разным доменам, насколько это возможно;

Сделать Просто Сложно


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


  • Скорость и компактность;
  • Генерализация между разными доменами. Должно существовать одно общее решение, которое незначительными усилиями настраивается на конкретные домены, а не наоборот;
  • Максимальная простота в использовании ("1 строка кода");

Дальнейшие Планы


Сейчас наименьший размер, до которого мы смогли ужать наши модели в районе 50 мегабайт.
В среднесрочной перспективе планка сжатия до 10-20 мегабайт без потери качества кажется нам выполнимой.
Также мы планируем добавлять другие популярные языки.


Ссылки


Подробнее..

Data Fest 2020 полностью в Online уже завтра

18.09.2020 14:13:41 | Автор: admin
Data Fest пройдет в этом году в онлайн формате 19 и 20 сентября 2020. Фестиваль организован сообществом Open Data Science и как обычно соберет исследователей, инженеров и разработчиков в области анализа данных, искусственного интеллекта и машинного обучения.

Регистрация. Ну а дальше к деталям.



События этого года влияют не только на людей и экономику, но и на организацию мероприятий. Поэтому Data Fest в этот раз превращается в 2х дневный глобальный бесплатный фест, проходящий в формате онлайн-конференции. Присоединиться однозначно стоит, у вас будет уникальная возможность пообщаться с командами Мегафона, McKinsey, Huawei, Yandex, с топовыми организаторами из ODS.ai и другими специалистами в области технологий со всего мира, не вставая с дивана.

В 2019 году мы собирались на площадках в таких городах как: Минск, Одесса, Новосибирск и даже, на минуточку, в Дубае. За прошлый год мы разослали тысячи инвайтов на наши мероприятия, но вот Data Fest 2020 впервые соберет нас в онлайн.

Программа и треки


Data Fest 2020 глобальное онлайн мероприятие, состоящее из 5 тематических блоков. Для участников будут доступны десятки выступлений, некоторые из которых будут проходить параллельно. Дополнительно более трети всего контента феста будет доступно на английском языке. Так что встретимся в эти выходные, чтобы обсудить горячие темы:

  • Бизнеса важные темы со стороны бизнеса.
  • Индустрии применение DS/ML в индустрии.
  • Инженерии технические секции о прикладных методах и о том, как это работает.
  • Науки научные секции по актуальным и горячим темам.
  • Сообщества жизнь сообщества и специалистов.

P.s. Все доклады по темам сформированы в треки, которые в свою очередь состоят из видео-докладов, практических заданий и статей. Важно, что все треки навсегда попадут в историю ODS.ai, сформировав базу знаний для следующих поколений дата-саентистов.

А вот посмотреть, как проходили Data Festы в прошлом и вдохновиться на будущий, можно здесь.



Основные активности


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

  • Livestream конференция на youtube: спикеры секций, беседы с Алексеем Натекиным, основателем ODS.ai, включения из разных городов, разбавленные умиротворяющими лесными пейзажами (с ламами и оленями (и это не шутка));
  • Networking в Spatial Chat: максимально приближенный к офлайн конференции формат. В комнате можно вести несколько бесед параллельно, присоединяясь к той, которая наиболее интересна (или куда возьмут).

Вроде все по-старому. А теперь разберемся с доступом.
Смотреть прямую трансляцию феста может любой желающий, достаточно просто подключиться 19 и 20 сентября к эфиру по ссылке, которая будет доступна на сайте. А вот чтобы попасть в networking комнаты, нужна регистрация (да-да, она обязательна). Комнаты будут сгруппированы по существующим трекам, их порядка 35.



Ну а если вы еще сомневаетесь, нужно ли участвовать в Data Fest 2020, то вот вам пара весомых причин:


  • Оценить новый формат: пожалуй, такого масштабного онлайн ивента в области Data Science еще не было.
  • Послушать спикеров: среди них заявлены Алексей Натёкин основатель сообщества ODS.ai, организатор Data Fest, Валерий Бабушкин руководитель управления развития данных в компании X5 Retail Group, Михаил Рожков основатель онлайн-курсов по управлению экспериментами и проектированию машинного обучения, Асхат Уразбаев управляющий партнер в ScrumTrek, Павел Плесков digital nomad, data scientist в стартапе Praxis Pioneering, Eghbal Rahimikia доктор философии Alliance Manchester Business School, University of Manchester, Ser-Huang Poon профессор University of Manchester, Alliance Manchester Business School и это далеко не все.
  • Узнать новое по темам ML, Big Data, Quantum Computing, Computer Vision, Индустрия Антифрода/Антиспама, математическую оптимизацию задач ML, ML Repa, и многого другого. Полный список треков на сайте.
  • Пообщаться с DS командами Мегафона, McKinsey, Huawei, Yandex
  • Нетворкать, прокачивать soft skills и послушать, как строится карьера в Data Science.



Но что остается неизменно Data Fest, это по-прежнему глобальный мировой ивент. И это не просто слова. Присоединяйтесь!

Подробнее..

Возможности ClickHouse для продвинутых разработчиков. Алексей Миловидов (2018г)

15.09.2020 10:12:59 | Автор: admin
![](http://personeltest.ru/aways/habrastorage.org/webt/pu/fq/64/pufq64pgen2y7nx3el0l8-znwxa.jpeg)

В докладе планируется рассмотреть малоизвестные или недостаточно хорошо освещённые в документации возможности ClickHouse: инкрементальная агрегация и манипуляции с состояниями агрегатных функций, межкластерное копирование, выполнение запросов без использования сервера и т.п. Будут приведены примеры из практики разработки сервисов Яндекса: как выжать из системы максимум возможного.

Всем привет! Меня зовут Алексей! Я делаю ClickHouse. И сегодня я хочу вам рассказать про некоторые возможности, которые я сам считаю интересными, но про которые не все знают.





![](http://personeltest.ru/aways/habrastorage.org/webt/wf/zp/ze/wfzpzexig0isbnlqra24kx6t87e.jpeg)

Например, сэмплирование. И, соответственно, ключ сэмплирования. Это возможность выполнения приближенных запросов. Знает пара человек. Уже хорошо.

Рассмотрим типичную задачу для ClickHouse, именно ту задачу, для которой он предназначался изначально. Есть у вас какой-то clickstream. Например, рекламная сеть, система веб-аналитики. И, допустим, есть у вас Яндекс.Метрика.

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

![](http://personeltest.ru/aways/habrastorage.org/webt/1i/gc/pq/1igcpqx18d5zo0ep7rj_zfg2bhc.jpeg)

И вы хотите генерировать отчеты для разных клиентов. И среди клиентов есть некоторые маленькие, например, маленькие сайты типа pupkin.narod.ru; есть средние и есть действительно крупные такие, как yandex.ru. И вы хотите для таких крупных клиентов получать отчеты мгновенно. Что значит мгновенно? Хотя бы за секунду.

И для этого есть отличное решение. Можно выполнять запросы не целиком, а по некоторому сэмплу. Для этого нужно просто объявить в вашей таблице MergeTree, ключ сэмплирования.

![](http://personeltest.ru/aways/habrastorage.org/webt/vr/qk/_w/vrqk_wcxhktimd--gbffzxpwsys.jpeg)

И вот, как это делается. CREATE TABLE. Дальше ORDER BY первичный ключ. Кстати, структура точно такая же, как в Яндекс.Метрике для таблиц просмотров событий. Номер счетчика, т. е. идентификатор сайта, потом дата идет, а потом некий Hash от идентификатора пользователя. Дальше партиционирование. И в самом низу ключ сэмплирования. И в качестве ключа сэмплирования hash от идентификатора пользователя.

![](http://personeltest.ru/aways/habrastorage.org/webt/j7/vc/pr/j7vcprd2vs33rger_r8w-8vascu.jpeg)

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

Выполнился за 4,5 секунды и скорость приличная, т. е. 3,5 гигабайта в секунду. И это на одном сервере. Но 4,5 секунды ждать не хочется.

![](http://personeltest.ru/aways/habrastorage.org/webt/hi/0t/jr/hi0tjrif0-lbos8qgew1ew2aa_0.jpeg)

Давайте добавим простую секцию в запросе сэмпл 1/10. Прямо после from пишем такой синтаксис. Теперь тот же самый запрос выполняется за 0,6 секунды. Если посмотреть скорость в гигабайтах в секунду, то стало почему-то меньше, всего лишь 2,5 гигабайта в секунду. Но нас это не волнует, главное не скорость, а то, чтобы запрос выполнялся за маленькое время. А с какой скоростью в байтах он читает, обрабатывает это уже его дело. Правда, количество уникальных посетителей получилось в 10 раз меньше. И его еще надо умножить, чтобы получить приблизительный результат.

![](http://personeltest.ru/aways/habrastorage.org/webt/si/lv/db/silvdbdioopkwhikvfrsksppaje.jpeg)

Что нужно, чтобы все это работало?

Во-первых, ключ сэмплирования должен входить в первичный ключ. Это как в нашем примере. Последний компонент первичного ключа, после него ничего другое не имеет смысла.
Он должен быть равномерно распределенным в своем типе данных. Типичная ошибка, если мы в качестве ключа сэмплирования возьмем unix timestamp.
Если нарисовать график количества событий в зависимости от timestamp, то там будет вот такая штука (рисует волну, размахивая рукой в воздухе). Все, кто работал админом, DevOps, видели такой график. Это график активности по времени суток. Так нельзя, потому что неравномерно.
Надо что-нибудь захэшировать. Если захэшировать идентификатор пользователя, то все будет прекрасно.
Ключ сэмплирования должен быть легким как для чтения из таблицы, так и для вычисления.
Тоже плохой пример, когда берем url, хэшируем его и этот hash используем в качестве ключа сэмплирования. Это очень плохо, потому что, если просто выполняется запрос, то все нормально. А теперь добавляется сэмпл и запрос может работать дольше, потому что вам нужно будет этот url из таблицы прочитать. А потом еще и хэшировать какой-то сложной hash-функцией.
Возьмите в качестве ключа сэмплирования что-нибудь маленькое.
Вот это более распространенная ошибка. Надо, чтобы ключ сэмплирования не находился после мелко-гранулированной части первичного ключа.
Например, в первичном ключе у вас есть время с точностью до секунды. Допустим, у вас логи и это естественно. А потом вы еще добавляете какой-то hash. И это будет работать плохо, потому что ключ сэмплирования позволяет именно с диска читать мало данных. И почему это работает? Потому что данные на диске упорядочены по первичному ключу. И если есть какие-то диапазоны префикса первичного ключа, то из них можно читать меньшие поддиапазоны ключа сэмплирования. А если там эти диапазоны маленькие для каждой секунды, то из них уже нет возможности эффективно какой-нибудь кусочек прочитать, придется читать все.
В нашем примере из Яндекс.Метрики первичный ключ это счетчик, дата и только затем ключ сэмплирования. И для больших счетчиков есть много данных за каждую дату. И из этих данных можно выбрать меньше данных достаточно эффективно.

![](http://personeltest.ru/aways/habrastorage.org/webt/ho/b2/qw/hob2qwa8luxvjjiagurciarnwqc.jpeg)

Посмотрим, какие есть свойства, на которые можно полагаться:

Во-первых, сэмплирование работает детерминировано, потому что у нас там не рандом, у нас нормальная hash-функция, т. е. выполняется запрос один раз, выполняется запрос другой раз и результаты одинаковые, отчеты прыгать не будет.
И он работает консистентно для разных таблиц. Есть у вас таблица с просмотрами страниц, есть таблица с сессиями. В них объявляете один и тот же ключ сэмплирования. И вы можете эти данные джойнить. Т. е. выбирается подмножество 1/10 всех возможных hashes от посетителей и это подмножество будет одинаковым.
И он реально позволяет читать меньше данных с диска, если все сделать правильно.

![](http://personeltest.ru/aways/habrastorage.org/webt/vy/sk/-f/vysk-fuvtp8oapj1eznau8alnvq.jpeg)

А в качестве бонуса применять его можно разными способами:

Самый частый это выбираем 1/10 всевозможных данных.
Другой способ мы можем написать сэмпл какое-то большое число, например, 1 000 000. И в этом случае подмножество выберется динамически. Относительный коэффициент подберется динамически, чтобы выбрать не менее, чем 1 000 000, но и не сильно больше. Правда, в этом случае будут трудности с тем, чтобы узнать, какой же относительный коэффициент сэмплирования выбрался, какая это доля данных. Т. е. это 1 000 000 строк из 10 000 000 или из 1 000 000 000? И для этого есть никому не известная возможность это виртуальный столбец _sample_factor. И теперь вы можете написать: x умножить на _sample_factor, получится все, что нужно.
Еще одна интересная возможность это SAMPLE OFFSET. Это очень просто. Вы выбрали 1/10 данных, а теперь вы можете сказать: Дайте мне, пожалуйста, вторую 1/10 данных. И для этого просто напишите: SAMPLE 1/10 OFFSET 1/10. И так можно все эти данные перебрать.
И еще один бонус. Если у вас в таблице есть ключ сэмплирования, то вы можете теперь распараллелить запрос не только по шардам, но и по репликам каждого шарда. На разных репликах будет выбираться разный сэмпл данных так, чтобы покрыть все множество. И, соответственно, запрос будет выполняться быстрее. Или не будет? Будет, если ключ сэмплирования выбран так, что его легко читать, вычислять и это само сэмплирование, добавленное в запрос, не потребует существенного overhead.

![](http://personeltest.ru/aways/habrastorage.org/webt/lr/ms/7x/lrms7xwzzepfnseq0wroozfa69a.jpeg)

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

Но к каждой агрегатной функции можно еще справа приписать такой комбинатор. Дописывается прямо в имя. Например, If. Мы вместо суммы, пишем: sumIf. И теперь это у нас агрегатная функция принимает не один аргумент, а сразу два. Первый аргумент это то, что мы суммируем, а второй это условие, которое возвращает какое-нибудь число типа UInt8. И там, где не нули, мы это будем суммировать. А там, где нули, все будем пропускать.

![](http://personeltest.ru/aways/habrastorage.org/webt/hk/hl/o4/hkhlo4iys2lsy4ayd3t_mysrraa.jpeg)

Для чего это нужно? Типичное применение это сравнение разных сегментов. Мы это используем для сравнения сегментов в Яндекс.Метрике.

В данном запросе мы за один проход считаем количество уникальных посетителей для Яндекса и количество уникальных посетителей для Google. Очень удобно.

![](http://personeltest.ru/aways/habrastorage.org/webt/dp/l3/yn/dpl3ynpppht1429pv_velrujsh0.jpeg)

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

Рассмотрим пример. Есть у нас два массива разных. И мы сначала считаем количество разных массивов, потом количество разных элементов в объединении этих массивов.

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

Потом groupUniqArray. Функция собирает все уникальные значения в массив.

И еще мы к этим функциям можем приписать комбинатор Array и получится что-то такое, что сначала выглядит несколько необычно и даже неудобно, но тем не менее к этому можно привыкнуть.

Итак, что такое groupArrayArray? Это значит взять массивы, взять все элементы этих массивов, а потом собрать их в один массив. Получится один массив из всех элементов.

А groupUniqArrayArray это тоже самое, только для разных элементов.

![](http://personeltest.ru/aways/habrastorage.org/webt/1x/u3/rd/1xu3rdmjhh8oha4jgh3xmpjkohk.jpeg)

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

![](http://personeltest.ru/aways/habrastorage.org/webt/v4/xc/-w/v4xc-wwdxjjlv_n12p14b3yt59m.jpeg)

Комбинаторы агрегатных функций можно комбинировать друг с другом. Т. е. взяли агрегатную функцию sum, приписали к ней Array, а потом можно еще If приписать, а можно, наоборот. Т. е. sumArrayIf и SumIfArray.

В чем разница? В одном случае у нас будет два аргумента массива. Мы возьмем элементы этих массивов соответствующие, а массивы должны быть одинаковых длин. И один элемент это то, что суммировать, а другое это условие: надо ли суммировать этот элемент или не надо. Это у нас будет sumIfArray. Т. е. комбинатор Array применяется к функции sumIf и превращает оба аргумента в массивы.

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

![](http://personeltest.ru/aways/habrastorage.org/webt/no/_d/oq/no_doq92fks0cqhy3lcbuk7d3ju.jpeg)

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

![](http://personeltest.ru/aways/habrastorage.org/webt/ss/mo/ix/ssmoixgahzyuuqyy7i5ywamazyq.jpeg)

Агрегатную функцию можно вычислять не только до конца. Есть у вас агрегатная функция, например, сумма. Вычислили, получили сумму. Все просто.

Если есть агрегатная функция среднее, то вычислили и получили среднее, но в процессе вычисления мы будем накапливать некоторые состояния и это будет два числа. Это будет сумма и количество. А потом мы делим одно на другое.

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

Какое нужно состояние, чтобы посчитать count distinct? Hash table. Вчера был замечательный доклад про hashтаблицы и как раз на эту тему.

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

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

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

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

Давайте посмотрим, что получится.

![](http://personeltest.ru/aways/habrastorage.org/webt/jt/vw/jn/jtvwjnxcpmy4bqrmi9fz9sbumvy.jpeg)

Состояния вычислений агрегатных функций

Сначала вычислим среднее и uniq из двух чисел. Ничего интересного.

![](http://personeltest.ru/aways/habrastorage.org/webt/_z/ns/4o/_zns4o1uxlc8fhh3uoau32f26ei.jpeg)

А теперь вычислим состояние. Приписали комбинатор State. И он нам вернул какую-то вещь, которой пользоваться невозможно. Какие-то бинарные данные. Половина байт не выводится в терминал, потому что терминал кодировки UTF-8. А эти бинарные данные, естественно, не UTF-8.

![](http://personeltest.ru/aways/habrastorage.org/webt/2u/6g/d4/2u6gd4yhugkcepgmqm0l30rw7ly.jpeg)

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

![](http://personeltest.ru/aways/habrastorage.org/webt/6r/gl/da/6rgldach7ajiv8v8shqby6vrrn4.jpeg)

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

![](http://personeltest.ru/aways/habrastorage.org/webt/94/gt/ca/94gtcaif2xoz10rrmgp-sj1m40s.jpeg)

Типичный сценарий использования это инкрементальная агрегация данных.

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

Но все не так просто. Иногда агрегировать данные все-таки полезно, ведь их становится меньше, и запрос работает быстрее.

И мы поддерживаем этот сценарий работы. Достаточно создать таблицу типа AggregatingMergeTree. Это такая таблица, в которой данные будет доагрегироваться в фоне. Вы в ней определили некоторые столбцы с промежуточными состояниями агрегатных функций. Когда вы записываете в эту таблицу, у вас какие-то куски на диске. И эти куски в фоне мержатся. И для одного значения первичного ключа все эти состояния агрегатных функций будут объединены в одно более толстое состояние, т. е. вы можете инкрементально в около реальном времени добавлять данные, обновлять ваши статистики, count distinct, квантили.

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

![](http://personeltest.ru/aways/habrastorage.org/webt/xi/xj/zw/xixjzwwa_xszudzo15ijowh_-ue.jpeg)

Но есть некоторые ограничения. И что мы могли бы сделать лучше?

Сейчас эти состояния агрегатных функций это бинарные данные, которые не версионируются. И мы попали в ловушку, потому что мы не можем их поменять. Я уже рассказал про эту возможность, вы будете ее использовать. И было бы очень плохо, если вы обновили бы ClickHouse-сервер, и она сломалась бы. Поэтому нам придется добавить туда версионирование как можно скорее.
И надо определять больше случаев, когда состояния, казалось бы, разных агрегатных функций, на самом деле это одно и то же. Состояние агрегатной функции sum и sumIf это одно и то же, но сейчас они не совместимы.
Тут написано, что должна быть возможность создавать состояние агрегатной функции с помощью обычной функции*. Сейчас это тоже можно, если функция, например, arrayReduce. Берем массив, указываем, какая нам агрегатная функция нужна, и она передает все эти данные в агрегатную функцию, все элементы массива. И мы получаем значение агрегатной функции. А если в качестве агрегатной функции указать агрегатную функцию с комбинатором State, то мы получим состояние.

\* по состоянию на 2020 год, добавлена функция initializeAggregation.

![](http://personeltest.ru/aways/habrastorage.org/webt/cz/i_/lp/czi_lpqphxksyeajzf-4dassc84.jpeg)

Еще одна интересная возможность ClickHouse это настраиваемый режим консистентности.

По умолчанию, ClickHouse реализует репликацию асинхронную, т. е. сделали INSERT, получили подтверждение, когда данные записаны на одну реплику. И данные будут реплицированы в фоне. Успешный ответ от INSERT вовсе не означает, что данные на нескольких репликах. И вовсе не означает, что данные реплицированы.

Репликация conflict-free без конфликтов по причине того, что у нас нет update. Есть INSERT. Прекрасно коммутируются друг с другом, конфликтов друг с другом быть не может.

И за счет этого она работает mulit-master. Пишите на любую реплику. Если реплика недоступна, то вы можете тот же самый блок данных повторить на другой реплику. Даже если он на самом деле был записан, есть идемпотентность, т. е. будут дедуплицированы. И таким образом вы можете добиться надежной записи с exactly-once семантикой.

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

![](http://personeltest.ru/aways/habrastorage.org/webt/5q/xp/co/5qxpcojar9q_gii4at78m3npxik.jpeg)

И специально для таких случаев у нас есть магическая настройка. Теперь можно включить строгую консистентность, а точнее линеаризуемость INSERT.

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

Первая настройка это включить кворумную запись для INSERT. Минимальное количество реплик, на которые данные должны быть записаны перед тем, как клиент получит успешное подтверждение записи. Ставите insert_quorum = 2. И будет записано на две реплики.

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

А со стороны SELECT есть такая настройка, как select_sequential_consistency. Может быть, ее имя даже не совсем точное. Надо было ее назвать select_linearizability, но переименовывать уже поздно.

В этом случае, если вы отправите SELECT, то будет сделан запрос в метаданные в ZooKeeper. И SELECT будет разрешен только на репликах, которые консистентные, т. е. содержат все раннее подтвержденные INSERT, записанные с кворумом.

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

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

![](http://personeltest.ru/aways/habrastorage.org/webt/ae/nu/ez/aenuezuzio5way2okjrw_ehqy9u.jpeg)

Теперь рассмотрим еще одну интересную возможность. Это агрегация во внешней памяти.

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

Рассмотрим простой запрос. Считаем разные поисковые фразы. И для каждой поисковой фразы количество просмотров страниц и количество разных посетителей. Попробуем это посчитать.

![](http://personeltest.ru/aways/habrastorage.org/webt/qx/7y/9d/qx7y9d3l2z5x8z9_qzw1l6fo8wc.png)

Вот он считает. Красивый progress-bar, мне он очень нравится. И ClickHouse-клиент это тоже замечательная штука, я его очень люблю. К сожалению, он ничего не посчитал, потому что не хватило оперативной памяти. Он пишет, что для обработки этого запроса не хватило 9,31 гигабайта оперативной памяти, но это 10 млрд байт.

И первый вопрос, который стоит задать: Почему именно 10 млрд байт?. Это по умолчанию такое ограничение. Вы можете его увеличить спокойно.

![](http://personeltest.ru/aways/habrastorage.org/webt/er/wh/jh/erwhjhzminuj37msfdohirzui3c.png)

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

Если у вас есть какой-то сервер, то там наверняка больше 10 гигабайтов оперативки. И, допустим, вы с этим сервером сейчас работаете один. Например, вы сидите ночью в выходные и вам очень надо посчитать какую-то аналитику.

![](http://personeltest.ru/aways/habrastorage.org/webt/zz/s5/g4/zzs5g4mae2l4x3j551dhl-ojps0.jpeg)

Почему бы просто не сказать: Давайте я увеличу max_memory_usage для себя?

![](http://personeltest.ru/aways/habrastorage.org/webt/o3/jr/8d/o3jr8dyl5ietrcgffprxg9igu90.png)

Я использую всю память на этом сервере, на всех остальных пользователей можно не обращать внимание. Вроде все нормально. Но это не тот способ, который можно использовать на production все время.

![](http://personeltest.ru/aways/habrastorage.org/webt/ry/hg/3m/ryhg3mu8-zcmgopf_jjkzj2st5g.jpeg)

Правильный способ это включить GROUP BY во внешней памяти. Что это значит? Это значит, что накапливаются какие-то данные в оперативке. Когда их становится много, мы их сбрасываем на диск. Потом снова накапливаются, снова сбрасываем на диск. Снова накапливаются, сбрасываем. А потом возьмем это все и будем мержить. Причем мержить будем с использованием маленького количества оперативки. Т. е. будем какие-то маленькие кусочки брать из каждого куска. И будем вот так мержить, и отдавать результат клиенту.

Есть две настройки, которые для этого предназначены:

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

Обычно распределенная обработка запроса устроена так. Мы с каждого сервера весь временный dataset скачиваем по сети на сервер-инициатор запроса. Все объединяем и для этого нужна оперативка. А тут он будет скачивать эти datasets по каким-то кусочкам, по buckets. И будет объединять их в потоковом режиме.

![](http://personeltest.ru/aways/habrastorage.org/webt/-a/xi/ly/-axily37jlv6ubrcxag7rrbpkka.png)

Давайте проверим. Выставляем max_memory_usage в 10 гигабайт. Сбрасывать будем 8 гигабайт (max_bytes_before_external_group_by = 8 000 000 000, distributed_aggregation_memory_efficient = 1). И у нас progress-bar завис на какой-то момент. А потом дальше продолжил идти. Что это значит? Это значит, что именно в этот момент времени данные сбрасывались на диск. И как ни странно, запрос обработался даже не сильно дольше, чем запрос без этих настроек.

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

И еще данные при этом жмутся, т. е. данные сбрасываются в сжатом виде. И вполне возможно, что у вас 10 гигабайтов оперативки использовалось для GROUP BY, а потом вы сжали, и получился всего 1 гигабайт.

На практике это приводит к тому, что запрос работает не более, чем в несколько раз медленнее, а в этом случае даже в полтора раза.

![](http://personeltest.ru/aways/habrastorage.org/webt/tw/g5/-i/twg5-ibhhvfpf777nrg8jlzzapq.jpeg)

Давайте перейдем к следующей возможности. Это работа с географическими координатами.

Честно сказать, что ClickHouse это не какая-то geospatial-система, но наши пользователи очень хотят складывать туда всякие координаты.

У нас в компании есть сервис Метрика мобильных приложений. Она собирает логи. И, естественно, там есть координаты.

А что мы хотим делать с этими координатами? Конечно, мы хотим показывать рекламу. Например, вы прошли мимо какого-то магазина, но ничего не купили. А мы покажем вам объявление, что зря ничего не купили, вернитесь назад.

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

Вот пример функции pointInPolygon. Первый аргумент это кортеж: lat, lon, а дальше идет массив координат полигона. Этот массив должен быть константным*. Вы какую-то область этим полигоном зачеркиваете.

\* по состоянию на 2020 год, поддерживаются и неконстантные полигоны тоже.

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

Есть еще парочка функций, вместо которых я рекомендую использовать pointInPolygon, но они есть. Это pointInElliplses, которая позволяет задать несколько ellipses на координатах. Как не странно, ни на земле, ни на сфере, а просто на плоскости. И будьте осторожны, если у вас пользователи на Чукотке. Там есть этот разрыв координат. И просто вернет 0 или 1, если пользователь попал в эти ellipses.

И другая функция это greatCircleDistance. Это расстояние на сфере*. Две точки. И считаем, сколько на сфере будет.

\* по состоянию на 2020 год, присутствует также функция geoDistance, которая считает расстояние на WGS-84 эллипсоиде.

![](http://personeltest.ru/aways/habrastorage.org/webt/ya/ku/zd/yakuzdw7njj4gjycronkahy7byu.jpeg)

events.yandex.ru/lib/talks/5330

Еще одна экспериментальная интересная вещь это интеграция ClickHouse с моделями машинного обучения. Это не значит машинное обучение внутри ClickHouse. Это значит, что это машиннообученные модели, которые вы обучили где-то заранее. И теперь вы можете их загрузить в ClickHouse. Они будут доступны для выполнения.

Объявляются эти модели машинного обучения в некотором конфигурационном файле. Конфигурационные файлы можно обновлять налету без перезагрузки сервера. Объявляете имя, некоторые данные. И теперь они доступны в виде одной функции в виде modelEvaluate.

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

Например, вам нужно предсказать CTR или предсказать вероятность покупки. Про эту тему я подробно рассказывать не буду. Если интересует, то вот замечательная ссылка: events.yandex.ru/lib/talks/5330. Там есть доклад про эту возможность и как ей пользоваться.

Сейчас у нас единственный метод машинного обучения доступен. Это CatBoost. Почему именно CatBoost? Потому что он лучше.

![](http://personeltest.ru/aways/habrastorage.org/webt/0l/fk/rs/0lfkrscyjmfqhiyn2vjuehytm5c.jpeg)

Что мы могли бы сделать, чтобы улучшить эту возможность?

Часто нужно применять какие-то простые модели, но применять их много. Например, для каждого сайта какую-нибудь маленькую модель, и чтобы она быстро выполнялась. Для этого можно добавлять самые простые методы регрессии типа логистической регрессии*. И это должно соответствовать нашим принципам, что работать это должно быстро и тормозить не должно. Если какой-то сложный градиентный бустинг, то это работать будет быстро, но может быть будет тормозить. Нам этого не надо.
Представьте, как было бы удобно, если можно было бы обучить модель в ClickHouse с агрегатной функции. Я показывал пример о промежуточном состоянии функции. А представьте, что у вас будет агрегатная функция создать модель логистической регрессии. Вы передаете туда данные, получаете состояние, записываете в таблицу. И теперь можете взять и из этой таблицы поджоиниться, и применить это состояние в виде обычной модели. Это не то, что доступно в ClickHouse. Это мои фантазии. Но было бы круто.
И, конечно, важно онлайн-обучение, т. е. чтобы модель сама адаптировалась к постоянно поступающим данным.

\* эти методы уже добавлены в ClickHouse.

![](http://personeltest.ru/aways/habrastorage.org/webt/xk/bf/uu/xkbfuu4wy4l5nkwkm_d2g1b5msy.jpeg)

Следующая возможность тоже интересная. Это обработка данных с помощью ClickHouse без ClickHouse-сервера.

Есть у вас какая-то машина. Вы не хотите на нее ставить ClickHouse. Но у вас на ней есть какие-то логи. И вы админ.

Что вы обычно делаете? У вас обычно есть куча средств от grep, sed, awk или даже perl. И, например, вы где-то увидели, как круто в ClickHouse обрабатывать данные, можно написать запрос и не надо грепить и седить. Было бы очень заманчиво обрабатывать эти файлы с помощью ClickHouse без какой-либо загрузки, без преобразования. И такая возможность есть. Это утилита [clickhouse-local](http://personeltest.ru/aways/clickhouse.tech/docs/ru/operations/utilities/clickhouse-local/).

Вы указываете некоторые параметры. Самое важное это передать структуру, т. е. имена и типы столбцов. Это важно, потому что ClickHouse все-таки типизируемая система.

Указываете формат, в котором ваши данные лежат. Например, очень удобно, если у вас логи в JSON, то вы указываете формат JSONEachRow. Указываете запрос и прямо в stdin передаете ваши данные. И, пожалуйста, ваши данные обработаны. Конечно, это будет не так быстро, как если вы сначала все-таки загрузите данные в ClickHouse. Потому что эти данные надо будет распарсить и все, что нужно, с ними сделать. Но работать будет быстрее, чем awk, perl, sed. В некоторых случаях даже будет быстрее, чем grep, т. е. зависит от параметров.

Но если вам данные нужно обработать не один раз, а хотя бы два запроса выполнить, то, пожалуйста, не нужно мелочиться поставьте себе ClickHouse-сервер. Много ресурсов не отнимет. И будет удобно работать.

![](http://personeltest.ru/aways/habrastorage.org/webt/tw/k1/io/twk1ioozjoqqvch1kfhcadkhs98.jpeg)

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

![](http://personeltest.ru/aways/habrastorage.org/webt/-g/ps/ts/-gpstsxuqecwzfe9oasvvs9hzaw.jpeg)

Что сейчас эту возможность ограничивает? Что надо сделать, чтобы стало удобнее?

Мы сейчас весьма строги к форматам Date и DateTime. Date у нас, например, в формате `ISO 8601`, а в DateTime не поддерживается, чтобы можно было указать плюс-минус смещение или суффикс, или дробные секунды. И, естественно, было бы очень удобно, чтобы такая возможность была*.

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

\* а уже всё есть, смотрите настройку `date_time_input_format`.

Еще очень удобно было бы, если мы добавили бы такие форматы, которые более свойственны для Hadoop инфраструктуры. Чтобы вы могли запустить ClickHouse-local в качестве MapReduce jobs прямо в Hadoop.

Было бы очень хорошо, если бы мы добавили Parquet. И сейчас эта возможность появилась в виде pull request. Наверное, скоро помержим*.

\* ура, помержили теперь возможность есть!

Еще интересный вариант, если бы добавили такой формат данных, который я про себя называю trash SQL. Представьте, что вы могли бы данные разделить каким-нибудь regexpом на столбцы, а потом подать на вход clickhouse-local. Конечно, это можно сначала сделать с помощью Awk, но иногда было бы удобно, чтобы такая возможность была прямо внутри ClickHouse*.

\* и это тоже добавили смотрите формат `Regexp`.

![](http://personeltest.ru/aways/habrastorage.org/webt/pp/7x/sz/pp7xsz7eosu7kpt4b4wtp5-6hmu.jpeg)

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

В чем суть? Конфигурация кластера в ClickHouse довольно жесткая. Т. е. вы должны указать, сколько у вас шардов, сколько реплик на каждом шарде. И все прекрасно будет работать, пока вам не надо будет это перешардировать.

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

Но проблема в том, что это работает в один поток. Будет передавать данные через один сервер по сети. И если у вас данных достаточно, вы запустите, но оно поработает, например, недельку, а потом сетевая ошибка и вам придется смотреть, какие данные скопировались, какие данные не скопировались. Или разделять это как-то вручную по партициям. Это неудобно.

И поэтому у нас есть специальный инструмент, который называется ClickHouse-copier. Это такая программа, которую вы можете в любом количестве экземпляров запускать на любых серверах. Она автоматически будет выбирать себе задачи и координироваться через Zookeeper. А задачи это партиции одной таблицы на одном шарде того кластера, который вам нужно будет создать путем копирования.

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

Если какая-то партиция частично скопирована на другой сервер, то попытка скопировать будет повторяться. Какие-то частично скопированные данные удаляются и копируются заново.

![](http://personeltest.ru/aways/habrastorage.org/webt/qs/rp/fh/qsrpfhg3xsjuyt-s3-cywsl3o_u.jpeg)

И самое главное эта возможность проверена в production.

Мы недавно завершили операцию межкластерного копирования в Яндекс.Метрике. У нас был один кластер на 538 серверов. И мы взяли другой кластер на 240 серверов. Меньше, потому что серверы более современные и туда больше помещается. Мы изменили в наших таблицах все.

Поменяли схему шардирования. Было шардирование по сайтам, сделали шардирование по пользователям. Изменили алгоритм сжатия. На старом кластере было lz4, на новом кластере zstd и запустили это все. И оно начало копировать. И у нас были проблемы, потом еще были проблемы и еще были проблемы. Мы дорабатывали ClickHouse-copier. Потому что это серьезная задача и с первого раза, конечно, ничего не работает. И где-то через месяц все скопировалось.

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

Все, спасибо!

![](http://personeltest.ru/aways/habrastorage.org/webt/iy/7j/no/iy7jnoq_3bmfytpnco6y4p-w3pm.jpeg)

Вопросы

*Спасибо за доклад! Вопрос по поводу копира. Интересная возможность. Он в real time поддерживает дописывание данных, которые прилетели на старый кластер?*

Нет. Копирует партиции, которые не изменяются.

*Т. е., соответственно, когда вы копировали, вы уже читали с дистрибьютора между старым и новым кластером? Или читали только с нового кластера? Как это происходило?*

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

*Т. е. как раз тестировать ClickHouse?*

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

*Здравствуйте! Раз вы уже смотрите на Avro, на Parquet, на замену MapReduce и machine learning, то есть какие-то наработки для того, чтобы запускать ClickHouse как какие-то jobs под управлением YARN, под управлением Mesos? Т. е. чтобы запускались так же, как Spark, шедулилось на кластер, запускалось рядом с данными, где лежат уже на конкретных нодах с хорошей date locality и вот это все было рядышком, все быстро обрабатывалось?*

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

*Понятно. Т. е. внутри Яндекса такие наработки по поводу применения на YT и запуск под конкретный ресурс-менеджер на кластере уже есть? Т. е. то, что уже не конкретно на каждой ноде установлен ClickHouse, а это уже как tool для обработки CSV уже распространяется в виде job?*

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

\* уже в продакшене.

*Спасибо за доклад! ClickHouse-local существует только в виде бинарника или есть еще какие-то модули для каких-нибудь языков или его куда-нибудь встраивать можно, например?*

Встраивать нельзя, только как standalone-приложение. Единственный бонус он встроен прямо в ClickHouse. Т. е. есть общий бинарник ClickHouse, там и сервер, и клиент, и local, и все, что угодно.

*Спасибо! И второй вопрос есть. groupUniqArrayArray он не order делает, он их в рандомном порядке берет?*

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

*Привет! Спасибо за доклад! У меня была практическая проблема с ClickHouse. Она немножко надуманная. Данные до этого лежали в Vertica. Люди там пытались писать запрос, но это все ужасно тормозило. Что я сделал? Я их выгрузил в CSV. Из CSV загрузил в ClickHouse. В ClickHouse заджойнил уже в другую таблицу, в которой все было в денормализованном виде. Но уже по ней запросы шли быстро. Проблемы была только в том, что если ты хочешь это все заджойнить, то тебе нужно очень много памяти, чтобы весь запрос в память влез. Я ничего лучшего не придумал, кроме, как еще памяти докинуть на этот момент. Но можно ли это как-то было решить другим путем?*

Есть ли возможность в ClickHouse выполнить JOIN так, чтобы необязательно правая таблица или результат правого подзапроса помещался в оперативку? Пока нет*. Пока в ClickHouse реализован hash JOIN, т. е. правый результат, правая часть должна помещаться в эту hash-таблицу в оперативке. Но у нас есть план это изменить. Эти планы довольно серьезные. Правда, их серьезность в том числе связана еще и с тем, что это будет не так-то просто сделать. Для этого придется серьезно менять конвейер выполнения запросов, чтобы реализовать merge JOIN, чтобы он работал нормально, и в том числе в распределенном случае.

\* уже да, смотрите настройку `join_algorithm`. И конвейер, кстати, тоже переписали.

*Спасибо! Если или, когда появятся апдейты, то будет ли еще master-master репликация, если да, то, как? Если нет, то что надо делать, чтобы она работала?*

По этому вопросу можно сказать ура, потому что сейчас апдейты находятся в pull request. Мы их планируем домержить в мастер на этой неделе. Я сейчас здесь стою, а другие люди в офисе мержат. Master-master репликация продолжит работать. Во-первых, все операции в ClickHouse линеаризуются с помощью ZooKeeper. Там есть полный порядок этих операций. Если вы будете выполнять апдейты конкурентно на разных репликах, то, соответственно, в каком-то порядке они дойдут и в каком-то порядке выполнятся.

*Здравствуйте! Спасибо за доклад! Поможет ли ClickHouse-copier решить задачу, когда необходимо вывести из шарда реплику и на новую реплику этого шарда скопировать данные, например, для проведения работ?*

Для этой задачи ClickHouse-copier не нужен, потому что это очень простая задача и типичная operation-вещь. Вы просто создаете новую реплику. У вас, допустим, было две реплики, вы создаете новую. И теперь три реплики. Старую теперь можно удалять. Или одна реплика была, вы создаете новую. И она наливает сама данные. Самое главное, если у вас сервис с репликой с концами исчез куда-то, т. е. его больше нет, то надо удалить метаданные этой исчезнувшей реплики из ZooKeeper. Там есть особенность накапливаются логи репликации и поэтому будут проблемы*.

\* уже исправлено, теперь не накапливаются.
Подробнее..

Анализируем причинно-следственные связи метрик ВКонтакте

11.09.2020 14:12:59 | Автор: admin
Всем привет, меня зовут Анвер, я работаю в команде Core ML ВКонтакте. Одна из наших задач создавать и улучшать алгоритмы ранжирования для ленты новостей. В этой статье расскажу о том, как можно применять для этого причинно-следственный анализ чтобы в результате сделать сервис интереснее для пользователей. Поговорим про преимущества такого подхода по сравнению с корреляционным анализом, и я предложу модификации существующих алгоритмов.




Что такое короткие и долгие метрики?


Модели ранжирования пытаются оценить вероятность того, что пользователь повзаимодействует с новостью (постом): задержит на ней внимание, поставит отметку Нравится, напишет комментарий. Затем модель распределяет записи по убыванию этой вероятности. Поэтому, улучшая ранжирование, мы можем получить рост CTR (click-through rate) пользовательских действий: лайков, комментов и других. Эти метрики очень чувствительны к изменениям модели ранжирования. Я буду называть их короткими.

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

Оптимизировать долгие метрики непосредственно через алгоритмы ранжирования нетривиальная задача. С короткими метриками это делать намного проще: CTR лайков, например, напрямую связан с тем, насколько хорошо мы оцениваем их вероятность. Но если мы знаем причинно-следственные (или каузальные) связи между короткими и долгими метриками, то можем сфокусироваться на оптимизации лишь тех коротких метрик, которые должны предсказуемо влиять на долгие. Я попытался извлечь такие каузальные связи и написал об этом в своей работе, которую выполнил в качестве диплома на бакалавриате ИТМО (КТ). Исследование мы проводили в лаборатории Машинное обучение ИТМО совместно с ВКонтакте.

Ссылки на код, датасет и песочницу


Весь код вы можете найти здесь: AnverK.

Чтобы проанализировать связи между метриками, мы использовали датасет, включающий результаты более чем 6000 реальных A/B-тестов, которые в разное время проводила команда ВКонтакте. Датасет тоже доступен в репозитории.

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

Боремся с ложными корреляциями


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


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

Даже на таком простом примере становится очевидно, что простой анализ корреляций приведёт к множеству неверных выводов. Восстановить причинно-следственные связи из данных позволяет causal inference (методы вывода связей). Чтобы применить их в задаче, мы выбрали наиболее подходящие алгоритмы causal inference, реализовали для них python-интерфейсы, а также добавили модификации известных алгоритмов, которые лучше работают в наших условиях.

Классические алгоритмы вывода связей


Мы рассматривали несколько методов вывода связей (causal inference): PC (Peter and Clark), FCI (Fast Causal Inference) и FCI+ (похож на FCI с теоретической точки зрения, но намного быстрее). Почитать о них подробно можно в этих источниках:

  • Causality (J. Pearl, 2009),
  • Causation, Prediction and Search (P. Spirtes et al., 2000),
  • Learning Sparse Causal Models is not NP-hard (T. Claassen et al., 2013).

Но важно понимать: первый метод (PC) предполагает, что мы наблюдаем все величины, влияющие на две метрики или более, такая гипотеза называется Causal Sufficiency. Другие два алгоритма учитывают, что могут существовать ненаблюдаемые факторы, которые влияют на отслеживаемые метрики. То есть во втором случае каузальное представление считается более естественным и допускает наличие ненаблюдаемых факторов $U_1, \dots U_k$:



Все реализации этих алгоритмов представлены в библиотеке pcalg. Она прекрасная и гибкая, но с одним недостатком написана на R (при разработке самых вычислительно тяжёлых функций используется пакет RCPP). Поэтому для перечисленных выше методов я написал обёртки в классе CausalGraphBuilder, добавив примеры его использования.

Опишу контракты функции вывода связей, то есть интерфейс и результат, который можно получить на выходе. Можно передать функцию тестирования на условную независимость. Это такой тест, который возвращает $p_{value}$ при нулевой гипотезе, что величины $X$ и $Y$ условно независимы при известном множестве величин $Z$. По умолчанию используется тест, основанный на частной корреляции. Я выбрал функцию с этим тестом, потому что она используется по умолчанию в pcalg и реализована на RCPP это делает её быстрой на практике. Также можно передать $p_{value}$, начиная с которого вершины будут считаться зависимыми. Для алгоритмов PC и FCI также можно задать количество CPU-ядер, если не нужно писать лог работы библиотеки. Для FCI+ такой опции нет, но я рекомендую использовать именно этот алгоритм он выигрывает по скорости. Ещё нюанс: FCI+ на данный момент не поддерживает предложенный алгоритм ориентации рёбер дело в ограничениях библиотеки pcalg.

По итогам работы всех алгоритмов строится PAG (partial ancestral graph) в виде списка рёбер. При алгоритме PC его стоит интерпретировать как каузальный граф в классическом понимании (или байесовскую сеть): ребро, ориентированное из $A$ в $B$, означает влияние $A$ на $B$. Если ребро ненаправленное или двунаправленное, то мы не можем однозначно его ориентировать, а значит:

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

Результатом работы FCI-алгоритмов будет тоже PAG, но в нём появится новый тип рёбер с о на конце. Это означает, что стрелка там может как быть, так и отсутствовать. При этом важнейшее отличие FCI-алгоритмов от PC в том, что двунаправленное (с двумя стрелками) ребро даёт понять, что связываемые им вершины следствия некой ненаблюдаемой вершины. Соответственно, двойное ребро в PC-алгоритме теперь выглядит как ребро с двумя о на концах. Иллюстрация для такого случая есть в песочнице с синтетическими примерами.

Модифицируем алгоритм ориентации рёбер


У классических методов есть один существенный недостаток. Они допускают, что могут быть неизвестные факторы, но при этом опираются на ещё одно слишком серьёзное предположение. Его суть в том, что функция тестирования на условную независимость должна быть идеальной. Иначе алгоритм за себя не отвечает и не гарантирует ни корректность, ни полноту графа (то, что больше рёбер сориентировать нельзя, не нарушая корректность). Много ли вы знаете идеальных тестов на условную независимость при конечной выборке? Я нет.

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

Сравниваем модели 1: оценка правдоподобия графа


Одну из серьёзных трудностей при выводе каузальных связей представляет, как ни странно, сравнение и оценка моделей. Как так вышло? Дело в том, что обычно истинное каузальное представление реальных данных неизвестно. И тем более мы не можем знать его с точки зрения распределения настолько точно, чтобы генерировать из него реальные данные. То есть неизвестен ground truth для большинства наборов данных. Поэтому возникает дилемма: использовать (полу-) синтетические данные с известным ground truth или пытаться обходиться без ground truth, но тестировать на реальных данных. В своей работе я попробовал реализовать два подхода к тестированию.

Первый из них оценка правдоподобия графа:



Здесь $PA_G(X)$ множество родителей вершины $X$, $I(X, Y)$ совместная информация величин $X$ и $Y$, а $H(X)$ энтропия величины $X$. На самом деле второе слагаемое не зависит от структуры графа, поэтому считают, как правило, только первое. Но можно заметить, что правдоподобие не убывает от добавления новых рёбер это необходимо учитывать при сравнении.

Важно понимать, что такая оценка работает только для сравнения байесовских сетей (выхода алгоритма PC), потому что в настоящих PAG (выход алгоритмов FCI, FCI+) у двойных рёбер совсем иная семантика.

Поэтому я сравнил ориентацию рёбер моим алгоритмом и классическим PC:



Модифицированная ориентация рёбер позволила значительно увеличить правдоподобие по сравнению с классическим алгоритмом. Но теперь важно сравнить количество рёбер:



Их стало даже меньше это ожидаемо. Так что даже с меньшим числом рёбер удаётся восстанавливать более правдоподобную структуру графа! Здесь вы можете возразить, что правдоподобие не убывает с увеличением количества рёбер. Дело в том, что полученный граф в общем случае это не подграф графа, полученного классическим PC-алгоритмом. Двойные рёбра могут появиться вместо одиночных, а одиночные изменить направление. Так что никакого рукомашества!

Сравниваем модели 2: используем подход из классификации


Перейдём ко второму способу сравнения. Будем строить PC-алгоритмом каузальный граф и выбирать из него случайный ациклический граф. После этого сгенерируем данные в каждой вершине как линейную комбинацию значений в родительских вершинах с коэффициентами $\pm[0,2, 0,8]$ с добавлением гауссова шума. Идею для такой генерации я взял из статьи Towards Robust and Versatile Causal Discovery for Business Applications (Borboudakis et al., 2016). Вершины, которые не имеют родителей, генерировались из нормального распределения с параметрами, как в наборе данных для соответствующей вершины.

Когда данные получены, применяем к ним алгоритмы, которые хотим оценить. При этом у нас уже есть истинный каузальный граф. Осталось только понять, как сравнивать полученные графы с истинным. В Robust reconstruction of causal graphical models based on conditional 2-point and 3-point information (Affeldt et al., 2015) предложили использовать терминологию классификации. Будем считать, что проведённое ребро это Positive-класс, а непроведённое Negative. Тогда True Positive ($TP$) это когда мы провели то же ребро, что и в истинном каузальном графе, а False Positive ($FP$) если провели ребро, которого в истинном каузальном графе нет. Оценивать эти величины будем с точки зрения скелета.

Чтобы учитывать направления, введём $TP_{misorient}$ для рёбер, которые выведены верно, но с неправильно выбранным направлением. После этого будем считать так:

  • $TP' = TP - TP_{misorient}$
  • $FP' = FP + TP_{misorient}$

Затем можно считать $F_1$-меру как для скелета, так и с учётом ориентации (очевидно, в этом случае она будет не выше такой меры для скелета). Однако в случае PC-алгоритма двойное ребро добавляет к $TP_{misorient}$ только $0.5$, а не $1$, потому что одно из реальных рёбер всё-таки выведено (без Causal Sufficiency это было бы неверно).

Наконец, сравним алгоритмы:



Первые два графика это сравнение скелетов PC-алгоритма: классического и с новой ориентацией рёбер. Они нужны, чтобы показывать верхнюю границу $F_1$-меры. Вторые два сравнение этих алгоритмов с учётом ориентации. Как видим, выигрыша нет.

Сравниваем модели 3: выключаем Causal Sufficiency


Теперь закроем некоторые переменные в истинном графе и в синтетических данных после генерации. Так мы выключим Causal Sufficiency. Но сравнивать результаты надо будет уже не с истинным графом, а с полученным следующим образом:

  • рёбра от родителей скрытой вершины будем проводить к её детям,
  • всех детей скрытой вершины соединим двойным ребром.

Сравнивать уже будем алгоритмы FCI+ (с модифицированной ориентацией рёбер и с классической):



И теперь, когда Causal Sufficiency не выполняется, результат новой ориентации становится значительно лучше.

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



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

Вывод


Сформулирую кратко, о чём мы поговорили в этой статье:

  1. Как задача вывода каузальных связей может возникнуть в крупной IT-компании.
  2. Что такое ложные корреляции и как они могут мешать Feature Selection.
  3. Какие алгоритмы вывода связей существуют и используются наиболее часто.
  4. Какие трудности могут возникать при выводе каузальных графов.
  5. Что такое сравнение каузальных графов и как с этим бороться.


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

Преступления на почве расизма в США статистический анализ

15.09.2020 04:20:57 | Автор: admin
После моей недавней статьи (части 1, 2, 3) о криминале и полицейской стрельбе в США и их связи с расовой принадлежностью я решил продолжить эту тему и в таком же ключе проанализировать другие открытые данные благо, таких еще достаточно благодаря программе криминальной отчетности ФБР.

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

Дисклеймер
Позвольте мне быть ленивым и отправить вас, уважаемые читатели, посмотреть дисклеймер в начале моей первой статьи о криминале в США :) Все, что там написано, подходит и для этого исследования.


Исходные данные


В качестве исходных данных я скачал датасет с сайта Crime Data Explorer, поддерживаемого ФБР в рамках программы криминальной отчетности США (об этом сайте я уже писал в предыдущей статье). Скачать по прямой ссылке можно здесь (4.4 МБ). Скачанный архив содержит собственно сами данные в формате CSV, а также текстовое описание. Данные я никак не трансформировал, поэтому если вы захотите повторить анализ самостоятельно, вы должны получить те же результаты.

Также я использовал данные по численности населения США с разбивкой по расовой принадлежности, полученные из официальных данных Бюро переписи населения и дополненные модельными данными за период с 1991 по 2009 г. Скачать можно здесь (Яндекс.Диск). Для анализа географического распределения удельных показателей мне понадобилась и численность населения по штатам, полученные из того же источника (скачать здесь). Эти же данные я использовал в своей предыдущей статье.

Что такое преступления на почве нетерпимости и как они регистрируются?


С сайта ФБР:
The FBIs UCR Program defines hate crime as a committed criminal offense which is motivated, in whole or in part, by the offenders bias(es) against a race, religion, disability, sexual orientation, ethnicity, gender, or gender identity.

Перевод:
Программа криминальной отчетности ФБР определяет преступление на почве нетерпимости как совершенное преступление, мотивированное (частично или полностью) предвзятостью правонарушителя против расы, религии, физического ограничения, сексульной ориентации, принадлежности к этнической группе, пола или половой самоидентификации.

В справке, сопровождающей исходный датасет по преступлениям, также указано следующее (курсив сохранен):
Because motivation is subjective, it is sometimes difficult to know with certainty whether a crime resulted from the offenders bias. Moreover, the presence of bias alone does not necessarily mean that a crime can be considered a hate crime. Only when a law enforcement investigation reveals sufficient evidence to lead a reasonable and prudent person to conclude that the offenders actions were motivated, in whole or in part, by his or her bias, should an agency report an incident as a hate crime.

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

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

Структура базы данных


База содержит данные по преступлениям на почве нетерпимости с 1991 по 2018 г. На момент написания статьи последняя запись датируется 31 декабря 2018 г., всего 201403 записи. Каждая запись один случай преступления. Таким образом, получаем в среднем 7193 преступлений в год.

Список полей базы данных в исходном CSV формате
  1. INCIDENT_ID: ID события (преступления)
  2. DATA_YEAR: год, в который совершено преступление
  3. ORI: ID агентства (службы правопорядка), предоставившего данные
  4. PUB_AGENCY_NAME: публичное название агентства / службы (обычно совпадает с городом)
  5. PUB_AGENCY_UNIT: название подразделения службы (например, округ)
  6. AGENCY_TYPE_NAME: тип службы (муниципальная / окружная)
  7. STATE_ABBR: сокращенное наименование штата
  8. STATE_NAME: полное название штата
  9. DIVISION_NAME: название региона (куда входят несколько штатов)
  10. REGION_NAME: название макрорегиона (куда входят несколько регионов)
  11. POPULATION_GROUP_CODE: код места совершения преступления по численности населения
  12. POPULATION_GROUP_DESC: описание места совершения преступления по численности населения (например город с населением от 0,5 до 1 млн.)
  13. INCIDENT_DATE: дата совершения преступления
  14. ADULT_VICTIM_COUNT: количество совершеннолетних пострадавших
  15. JUVENILE_VICTIM_COUNT: количество несовершеннолетних пострадавших
  16. TOTAL_OFFENDER_COUNT: общее количество преступников
  17. ADULT_OFFENDER_COUNT: количество совершеннолетних преступников
  18. JUVENILE_OFFENDER_COUNT: количество несовершеннолетних преступников
  19. OFFENDER_RACE: раса/-ы преступника/-ов
  20. OFFENDER_ETHNICITY: этническая группа преступника/-ов (латиноамериканская / не латиноамериканская / смешанная / неизвестная)
  21. VICTIM_COUNT: общее количество пострадавших (физических и юридических лиц)
  22. OFFENSE_NAME: вид совершенного преступления
  23. TOTAL_INDIVIDUAL_VICTIMS: общее количество пострадавших (физических лиц)
  24. LOCATION_NAME: место преступления (например, квартира, шоссе, школа и т.д.)
  25. BIAS_DESC: вид нетерпимости (мотив преступления)
  26. VICTIM_TYPES: категория/-и пострадавших (физические лица / власти / частная компания и т.п.)
  27. MULTIPLE_OFFENSE: маркер множественного преступления (т.е. если совершено не одно, а несколько видов преступлений)
  28. MULTIPLE_BIAS: маркер множественного мотива (не один, а несколько видов нетерпимости)



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

Виды преступлений


В базу попадают 13 основных видов преступлений:

  • преступления против личности: убийство, изнасилование, нападение, тяжкое нападение, личная угроза и торговля людьми (сексуальное рабство и рабский труд)
  • преступления против собственности: грабеж, незаконное проникновение, хищение, угон, поджог и порча имущества / вандализм

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

Все 48 категорий преступлений (названия в оригинале)
Aggravated Assault
All Other Larceny
Animal Cruelty
Arson
Assisting or Promoting Prostitution
Betting/Wagering
Bribery
Burglary/Breaking & Entering
Counterfeiting/Forgery
Credit Card/Automated Teller Machine Fraud
Destruction/Damage/Vandalism of Property
Drug Equipment Violations
Drug/Narcotic Violations
Embezzlement
Extortion/Blackmail
False Pretenses/Swindle/Confidence Game
Fondling
Hacking/Computer Invasion
Human Trafficking, Commercial Sex Acts
Identity Theft
Impersonation
Incest
Intimidation
Kidnapping/Abduction
Motor Vehicle Theft
Murder and Nonnegligent Manslaughter
Negligent Manslaughter
Not Specified
Pocket-picking
Pornography/Obscene Material
Prostitution
Purchasing Prostitution
Purse-snatching
Rape
Robbery
Sexual Assault With An Object
Shoplifting
Simple Assault
Sodomy
Statutory Rape
Stolen Property Offenses
Theft From Building
Theft From Coin-Operated Machine or Device
Theft From Motor Vehicle
Theft of Motor Vehicle Parts or Accessories
Weapon Law Violations
Welfare Fraud
Wire Fraud


Виды нетерпимости / мотивы преступлений


В соответствии с определением выше, в базу заносятся следующие виды нетерпимости:
  1. против расовой принадлежности (против белых, против черных, против азиатов, против евреев и т.д.)
  2. против этнической принадлежности (против латиноамериканцев)
  3. против конфессии или религиозного мировоззрения (против христиан, против атеистов, против мусульман, против Свидетелей Иеговы и т.д.)
  4. против сексуальной ориентации или пола (против мужских и женских гомосексуалов, против мужчин, против женщин, против трансгендеров и т.д.)
  5. против физических ограничений (ненависть к инвалидам)


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

Категории пострадавших


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

Итак, вооружившись Python с pandas или еще парочкой библиотек (см. раздел Инструменты в моей предыдущей статье), а также не забыв пропустить кофе, чай, пиво или чайный гриб (кому что нравится) надвигаем маску на лицо, одеваем хирургические перчатки, поправляем операционную лампу и

Препарируем данные


image

Как и в предыдущей статье, весь анализ я выполняю в Jupyter Lab / Notebook на Python 3.8. Здесь я не буду приводить и комментировать сам код его вы можете скачать по этой ссылке (в архиве листинг и файл в формате Jupyter Notebook). Сосредоточимся больше на получаемых результатах. Все графики кликабельны.

Обзор данных и топ-листы


После загрузки данных из CSV (только нужных для исследования столбцов) получаем такой датафрейм:

YEAR STATE_NAME OFFENDER_RACE OFFENSE_NAME BIAS_DESC VICTIM_TYPES
0 1991 Arkansas White Intimidation Anti-Black or African American Individual
1 1991 Arkansas Black or African American Simple Assault Anti-White Individual
2 1991 Arkansas Black or African American Aggravated Assault Anti-Black or African American Individual
3 1991 Arkansas Black or African American Aggravated Assault;Destruction/Damage/Vandalis... Anti-White Individual
4 1991 Arkansas Black or African American Aggravated Assault Anti-White Individual
... ... ... ... ... ... ...
201398 2018 West Virginia NaN Burglary/Breaking & Entering Anti-Black or African American Individual
201399 2018 West Virginia White Simple Assault Anti-Black or African American Individual
201400 2018 West Virginia NaN Intimidation Anti-Asian Individual
201401 2018 West Virginia White Intimidation Anti-White Law Enforcement Officer
201402 2018 West Virginia NaN Burglary/Breaking & Entering;Destruction/Damag... Anti-Other Religion Religious Organization

201403 rows 6 columns



Более 200 тысяч строк и чуть больше 8 МБ памяти. Давайте для начала посмотрим на топ-10 совершаемых преступлений, видов нетерпимости (мотивов), рас преступников и категорий жертв:

Кликабельно

Кликабельно

Итак, что мы здесь наблюдаем:
  • Самый распространенный вид преступления порча имущества / вандализм, за ним с небольшим отставанием личная угроза (intimidation). Каждый из этих видов преступления занимает почти треть всех случаев. Далее идут нападения, а грабеж и другие преступления уже гораздо менее распространены.
  • Среди видов нетерпимости с большим отрывом лидирует нетерпимость к чернокожим (больше трети всех случаев), затем в порядке убывания, но примерно на одном уровне: нетерпимость к евреям, нетерпимость к белым, нетерпимость к геям. Остальные виды нетерпимости статистически на порядок реже лидера.
  • 70% всех преступлений совершаются белыми, порядка 23% черными, остальные в пределах погрешности.
  • Преступления против личности составляют 80% всех случаев.


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


OFFENSE_COUNT TOP_OFFENSE TOP_OFFENSE_SHARE TOP_BIAS TOP_BIAS_SHARE TOP_VICTIM TOP_VICTIM_SHARE
OFFENDER_RACE
White 79514 Intimidation 36.796036 Anti-Black or African American 46.877279 Individual 92.730840
Black or African American 25956 Simple Assault 36.292187 Anti-White 46.594236 Individual 94.760364
Multiple 4047 Simple Assault 36.545589 Anti-Black or African American 29.033852 Individual 91.153941
Asian 1453 Simple Assault 31.865107 Anti-Black or African American 30.075705 Individual 93.048864
American Indian or Alaska Native 1095 Simple Assault 40.182648 Anti-White 31.415525 Individual 93.059361
Native Hawaiian or Other Pacific Islander 35 Simple Assault 45.714286 Anti-Other Religion 22.857143 Individual 77.142857


В этой таблице:

  • OFFENSE_COUNT общее количество преступлений, совершенных представителями данной расы
  • TOP_OFFENSE самый частый вид преступления для представителей данной расы
  • TOP_BIAS самый частый вид нетерпимости (мотива преступления) для представителей данной расы
  • TOP_VICTIM самая частая категория потерпевших для представителей данной расы

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

Здесь можно увидеть, что для черных и белых основным мотивом является расовая нетерпимость по отношению к представителям противоположной расы (47% преступлений для обеих рас). При этом белые преступники, в основном, занимаются угрозами и запугиванием (37% преступлений), а черные нападениями без отягчающих обстоятельств (36% преступлений). (Удивительно, какое совпадение по процентным долям обнаруживают эти две расы!) Кстати говоря, только для белых преступников основной вид преступлений не связан с физическим ущербом (угрозы); представители других рас чаще совершают нападения.

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

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

Кликабельно

Как и следовало предположить, преступления белых и черных на графике доминируют над остальными расами, по которым даже не видно изменений из-за разницы в масштабе. Пик со стороны белых здесь приходится на 1995 2002 гг., а со стороны черных начало 1990-х. С 2002 г. количество преступлений, совершенных белыми на почве нетерпимости, довольно уверенно спадало, снизившись в 2 раза по сравнению с пиковым 2001-м; однако после 2016 г. вновь начало круто расти. Нетерпимость среди черных плавно спадала с 1995 по 2004 г., однако затем так же плавно начала расти, выйдя в 2018 г. на уровень 1995 г.

Здесь интересно отметить, что при Бараке Обаме (который, как мы знаем, принадлежит к афроамериканской расе), то есть с 2009 по 2017 гг., количество преступлений среди белых очень резко снизилось, но в это же самое время количество преступлений среди черных обнаружило стабильный рост. Ранее при Буше (2001 2009 гг.) после пика преступлений среди белых в первый год его президентства количество преступлений, совершаемых представителями обеих рас, вышло на полку и практически не менялось. А вот при Клинтоне (1993 2001 гг.) преступления среди белых росли быстро, почти год от года, в то время как преступления среди черных, наоборот, плавно снизились.

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

Первая фильтрация: по видам преступлений и потерпевших


В соответствии с исследованием, представленным в моей предыдущей статье, произведем аналогичную фильтрацию данных для анализа:

  1. среди категорий потерпевших оставим только физических лиц (исключим преступления против организаций, властей и всего общества);
  2. среди видов преступлений оставим только убийства, нападения (тяжкие и обычные), грабежи и изнасилования как наиболее злодейские.

Посмотрим, что получилось:


YEAR STATE_NAME OFFENDER_RACE OFFENSE_NAME BIAS_DESC COUNT
0 1991 Arizona Black or African American Assault Anti-Gay (Male) 1
1 1991 Arizona Black or African American Assault Anti-White 4
2 1991 Arizona White Assault Anti-Black or African American 10
3 1991 Arkansas Black or African American Assault Anti-Black or African American 1
4 1991 Arkansas Black or African American Assault Anti-White 4
... ... ... ... ... ... ...
16428 2018 Wisconsin White Assault Anti-Hispanic or Latino 1
16429 2018 Wisconsin White Assault Anti-Hispanic or Latino;Anti-White 1
16430 2018 Wisconsin White Assault Anti-Physical Disability 1
16431 2018 Wisconsin White Assault Anti-Sikh 1
16432 2018 Wisconsin White Assault Anti-White 1

16433 rows 6 columns



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

В качестве промежуточного шага посмотрим на распределение преступлений по расе преступников:

Кликабельно

и по видам нетерпимости:

Кликабельно

Итак, белые и черные преступники составляют вместе 93% всех случаев (преступлений среди белых в два раза больше, но мы же знаем, что белых и самих в 5 раз больше). Поэтому совершенно не удивляет и то, что почти та же пропорция и по видам нетерпимости: 33% преступлений мотивировано нетерпимостью к черным, 18% нетерпимостью к белым. Здесь попутно интересно отметить, что преступления на почве нетерпимости к белым количественно примерно равны преступлениям на почве нетерпимости к гомосексуалам это третий по величине мотив.

Вторая фильтрация: по расе преступников и мотиву преступлений


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


YEAR STATE_NAME OFFENDER_RACE OFFENSE_NAME BIAS_DESC COUNT
0 1991 Arizona Black Assault Anti-White 4
1 1991 Arizona White Assault Anti-Black 10
2 1991 Arkansas Black Assault Anti-Black 1
3 1991 Arkansas Black Assault Anti-White 4
4 1991 Arkansas Black Murder Anti-White 1
... ... ... ... ... ... ...
3870 2018 West Virginia White Assault Anti-White 2
3871 2018 Wisconsin Black Assault Anti-Black 1
3872 2018 Wisconsin Black Assault Anti-White 4
3873 2018 Wisconsin White Assault Anti-Black 6
3874 2018 Wisconsin White Assault Anti-White 2

3875 rows 6 columns



Пора включить в анализ удельные показатели (на количество населения по каждой расовой группе). Для этого подгрузим данные по численности населения из файла us_pop_1991-2018.csv.

Посмотрим, как в целом распределено население США по расам (среднегодовые показатели за 1991 2018 гг.):

Кликабельно

Белых получается в 5.8 раз больше, чем черных. Все остальные расы составляют 11% населения.

Далее добавляем в наш датасет данные по численности и вычисляем удельное количество преступлений на 1 млн. представителей каждой расы.

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

Кликабельно

Отдельно для убийств и изнасилований (т.к. их на общих графиках не видно):

Кликабельно

Что же мы здесь видим? А видим вот что:

  • Из анализируемых видов преступлений с большим отрывом лидируют нападения (в 25 раз больше, чем грабеж, в 250 раз чем убийство и изнасилование).
  • Нападений, совершенных белыми, в два раза больше, но в удельном отношении черные совершают нападения почти в 3 раза чаще.
  • Грабежей, совершенных черными, в 1.5 раза больше в абсолютных цифрах и в 10 раз больше в удельных.
  • Суммарно белые совершили несколько больше убийств, чем черные, и примерно столько же изнасилований. В удельном же выражении черные насилуют в 6 раз чаще и убивают в 3.6 раз чаще, чем белые. Между убийством и изнасилованием белые предпочитают убийство, а черные изнасилование.


Преступления на почве расизма по годам


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

Кликабельно

Кликабельно

Нетрудно по этим графикам сделать очевидные выводы:

  • В среднем белые совершают в год немного больше преступлений на почве расизма, но в 4-5 раз реже в удельном выражении (другими словами, вероятность совершения расистского преступления афроамериканцем в 4-5 раз выше, чем белым).
  • Тем не менее, с 1990-х годов удельный показатель расистских преступлений среди черных постепенно падает, снизившись в полтора раза за четверть века.
  • При переходе от абсолютных показателей к удельным скачки преступлений белых значительно сгладились, что говорит о прямой корреляции между количеством преступлений, совершаемых белыми, с численностью белокожего населения. Однако для черных это не так: сильные скачки остались и на удельном графике, что говорит о плохой связи расизма среди черных с приростом чернокожего населения. Проще говоря, расизм среди белых относительно стабилен (почти константен) начиная с 1993 года, а расизм среди черных, скорее всего, подвержен влиянию внешних факторов, таких как общественно-политические и внутренние события в стране.


Взглянем и на обобщенные (среднегодовые) показатели:

Кликабельно

Лишний раз убеждаемся в сделанных наблюдениях: в среднем белые совершают на 15-16% больше преступлений на почве расизма, но при этом из-за разницы в численности белых и черных, как мы знаем, почти в 6 раз, черные в столько же раз чаще совершают такие преступления.

Только ли белые против черных, черные против белых?


Давайте к нашим обобщенным показателям добавим параметр нетерпимости, т.е. мотива преступлений. Как вы помните, в результате фильтрации мы оставили только два мотива: нетерпимость к белой расе и нетерпимость к чернокожей расе. Как они распределены между белыми и черными преступниками? 100% полярно, конечно же? А вот и нет!

Кликабельно

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

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

География преступлений


Наконец, посмотрим на распределение преступности на почве расизма по штатам США. Для вычисления удельных показателей нам, как обычно, надо будет загрузить численность по штатам и расам из файла us_pop_states_race_2010-2019.csv.

Среднегодовые показатели численности белых и черных по штатам:

Кликабельно

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

Но везде ли одинакова доля чернокожего населения пресловутые 13%? Посмотрим:

Кликабельно

Итак, черных больше половины всего Округа Колумбия (где находится славный город Пентагон Вашингтон), около трети в хлопковых южных штатах Миссисипи, Луизиане, Джорджии, Алабаме, Южной Каролине и в одном северном (Мэриленде, где Округ Колумбия, где славный город...); в остальных меньше четверти. Это, как говорится, просто для справки.

А что с преступлениями? Смотрим на среднегодовые показатели в абсолютных и удельных выражениях:

Кликабельно

Кликабельно

Видно, что по абсолютному количеству преступлений лидирует самый населенный штат Калифорния. Но далее Флориду и Техас потеснили Мичиган, Иллинойс и Мэриленд экономически более развитые северные штаты. А на удельном графике выбились вперед наименее населенные штаты Монтана, Вермонт, Айдахо, Северная и Южная Дакота, Аляска (все тоже на севере страны). При этом видно, что пропорция преступлений между белыми и черными не одинакова по штатам, несмотря на доминирование черных по удельным показателям (например, в белую сторону выделяется Округ Колумбия и Гавайи).

Отобразим на карте (для большей наглядности заменим среднегодовые показатели накопленной суммой).

Сначала в абсолютном выражении:

Кликабельно

Здесь выделяется северо-восток страны (особенно Мичиган) плюс Калифорния и Вашингтон на тихоокеанском побережье. И в удельном выражении:

Кликабельно

Здесь заметно преобладание севера с наименее населенными штатами: Округ Колумбия, обе Дакоты и все тот же Вашингтон, а также по паре штатов с восточной и западной стороны. При этом южные штаты не обнаруживают значительной преступности среди населения.

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

Вместо выводов


Как там у Булгакова? Факты самая упрямая в мире вещь. Если нам что-то твердят со всех сторон, совсем необязательно это является правдой это может оказаться полуправдой или же ложью. Но имея в руках факты в виде N-ного количества наборов данных, вы можете сами подтвердить или опровергнуть те или иные рассуждения. Можно строить гипотезы и подтверждать / опровергать их статистическими методами, а можно просто без всяких гипотез рассмотреть данные и найти в них некие закономерности, которые уже в свою очередь помогут либо сделать выводы, либо предложить гипотезы, которые далее можно так же препарировать. Вам решать верить всему на слово или проверять.

Конечно, этот маленький анализ далеко не полный. Он выполнен поверхностно, ведь я только рассмотрел базовые показатели, не применяя даже четверти доступного аппарата математической статистики. Конечно, и о качестве исходных данных можно спорить. Всем ли регистрируемым данным можно верить? Все ли преступления регистрируются? Кто и как определяет мотивы нетерпимости? Но как по мне, я лучше буду анализировать официальные открытые данные as-is, чем довольствоваться заявлениями вроде в крови господина N нашли отравляющее вещество X или страна W уже на протяжении десятков лет систематически нарушает права человека.

PS. В комментариях к моему предыдущему исследованию меня много раз просили разделить чисто белых и латиносов, так как культуры все-таки имеют различия. Я бы и не против, но, к сожалению, это невозможно сделать ни в том, ни в этом случае по причине скудности сведений об этом этническом признаке в исходных данных. Так, например, в данных, которые мы разбираем в этой статье, из 79514 преступлений, совершенных белыми, только 6999 имеют пометку об этнической принадлежности, причем только 489 помечены как Hispanic or Latino (это 0,6%). Конечно, такие данные нельзя использовать для анализа.
Подробнее..

Перевод Временные сверточные сети революция в мире временных рядов

19.09.2020 18:15:27 | Автор: admin
Перевод статьи подготовлен в преддверии старта курса Deep Learning. Basic.



В этой статье мы поговорим о последних инновационных решениях на основе TCN. Для начала на примере детектора движения рассмотрим архитектуру временных сверточных сетей (Temporal Convolutional Network) и их преимущества перед традиционными подходами, такими как сверточные нейронные сети (CNN) и рекуррентные нейронные сети (RNN). Затем поговорим о последних примерах применения TCN, включая улучшение прогнозирования трафика, локализатор и детектор звука и вероятностное прогнозирование.

Краткий обзор TCN


В фундаментальной работе Леа и др. (2016) было впервые предложено использовать временные сверточные сети для сегментации действий на основе видео. Обычно процесс разбивается на два этапа: во-первых, вычисление низкоуровневых признаков с использованием (чаще всего) CNN, которая кодирует пространственно-временную информацию, и во-вторых, ввод низкоуровневых признаков в классификатор, который получает высокоуровневую временную информацию с помощью (чаще всего) RNN. Главным недостатком такого подхода является потребность в двух отдельных моделях. TCN предлагает унифицированный подход, чтобы покрыть оба уровня информации по принципу иерархии.

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



Шумиха вокруг TCN дошла даже до журнала Nature, где недавно появилась публикация работы Яна и др. (2020) об использовании TCN в задачах прогнозирования погоды. В своей работе авторы провели эксперимент по сравнению TCN и LSTM. Одним из результатов стал вывод о том, что TCN хорошо справляется с задачами прогнозирования временных рядов.



В следующих разделах представлены реализация и расширение классической TCN.

Улучшение прогнозирования трафика


Сервисы райдшеринга и онлайн-навигации могут улучшить прогнозирование трафика и изменить пребывание на дорогах к лучшему. Уменьшение количества пробок, уменьшение загрязнения окружающей среды, безопасное и быстрое вождение вот всего несколько целей, которых можно достичь за счет улучшения прогнозирования дорожного движения. Поскольку эта проблема основывается на данных в реальном времени, необходимо использовать накопленные данные о трафике. По этой причине Дай и др. (2020) недавно представили гибридную пространственно-временную графовую сверточную сеть (Hybrid Spatio-Temporal Graph Convolutional Network, H-STGCN). Основная идея заключается в том, чтобы использовать преимущества отношения кусочно-линейной скользящей плотности потока и преобразовывать предстоящий объем трафика в его эквивалент времени движения. Одним из наиболее интересных подходов, которые они использовали в своей работе, является свертка графа для получения временной зависимости. Составная матрица смежности отражает врожденные характеристики аппроксимации трафика (чтобы узнать больше, читайте статью Ли 2017 года). В следующей архитектуре представлены четыре модуля для описания всего процесса прогнозирования.



Локализация и обнаружение звуковых событий


Область локализации и обнаружения звуковых событий (SELF) продолжает расти. В автономной навигации понимание среды играет большую роль. Гирджис и др. (2020) недавно предложили новую архитектуру звуковых событий SELF-TCN. Группа исследователей утверждает, что их фреймворк превосходит современные решения в этой области, сокращая время обучения. В их SELDnet (архитектура представлена ниже) многоканальная аудиозапись, дискретизированная на частоте 44,1 кГц, извлекает, применяя кратковременное преобразование Фурье, фазу и величину спектра и выделяет их в виде отдельных входных признаков. Затем соединяются сверточные блоки и рекуррентные блоки (двунаправленные GRU), а затем идет полностью соединенный блок. На выходе из SELDnet можно получить обнаружение звуковых событий и направление, откуда пришел звук.



И для того, чтобы превзойти существующее решение, авторы представили SELD-TCN:



Поскольку расширенные свертки позволяют сети обрабатывать различные входные данные, может потребоваться более глубокая сеть (на которую будут влиять нестабильные градиенты во время обратного распространения ошибки). Авторы исследования эту проблему смогли решить, адаптировав архитектуру WaveNet (Дарио и др., 2017). Они показали, что рекуррентные слои не требуются для задач SELD, и при этом смогли определить время начала и окончания активных звуковых событий.

Вероятностное прогнозирование


Новый фреймворк, разработанный Ченом и др. (2020) может быть применен для оценки плотности вероятности. Прогнозирование временных рядов улучшает многие сценарии принятия бизнес-решений (например, управление ресурсами). Вероятностное прогнозирование позволяет извлекать информацию из исторических данных и минимизировать неопределенность будущих событий. Когда задача прогнозирования состоит в том, чтобы предсказать миллионы связанных временных рядов (как в розничном бизнесе), требуются непомерно большие трудовые и вычислительные ресурсы для оценки параметров. Чтобы разрешить эти трудности, авторы предложили систему оценки плотности и прогнозирования на основе CNN. Их структура может выучить скрытую корреляцию между рядами. Научная новизна в их работе заключается в предложенной ими глубокой TCN, представленной в их архитектуре:



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

Заключение


В этой статье мы рассмотрели последние работы, связанные с временными сверточными сетями, которые превосходят по тем или иным характеристикам классические подходы CNN и RNN в решении задач временных рядов.

Источники


  • Lea, Colin, et al. Temporal convolutional networks: A unified approach to action segmentation. European Conference on Computer Vision. Springer, Cham, 2016.
  • Lea, Colin, et al. Temporal convolutional networks for action segmentation and detection. proceedings of the IEEE Conference on Computer Vision and Pattern Recognition. 2017.
  • Yan, Jining, et al. temporal convolutional networks for the Advance prediction of enSo. Scientific Reports 10.1 (2020): 115.
  • Li, Yaguang, et al. Diffusion convolutional recurrent neural network: Data-driven traffic forecasting. arXiv preprint arXiv:1707.01926 (2017).
  • Rethage, Dario, Jordi Pons, and Xavier Serra. A wavenet for speech denoising. 2018 IEEE International Conference on Acoustics, Speech and Signal Processing (ICASSP). IEEE, 2018.
  • Chen, Yitian, et al. Probabilistic forecasting with temporal convolutional neural network. Neurocomputing (2020).
  • Guirguis, Karim, et al. SELD-TCN: Sound Event Localization & Detection via Temporal Convolutional Networks. arXiv preprint arXiv:2003.01609 (2020).




Читать ещё:


Подробнее..

Сколько зарабатывает Аналитик данных обзор зарплат и вакансий в России и за рубежом в 2020

25.09.2020 20:20:19 | Автор: admin

Привет, Хабр! 28 сентября, Skillfactory запускает новый поток курса Data Analyst, поэтому мы решили сделать широкий обзор рынка вакансий, которые предлагают сегодня компании.

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

Мы проанализировали 450 вакансий на должность аналитика данных в России и за рубежом и собрали результаты в этой статье.

Кто такой аналитик данных и что он должен знать


Прежде чем анализировать вакансии, разберемся, что делает Data Analyst в компании. В IT-сфере есть три направления специальностей по работе с данными: Data Analyst, Data Engineer и Data Scientist.

Data Analyst собирает информацию, обрабатывает ее и интерпретирует ее на человеческий язык. По сути, он переводит статистику и big data в понятные и наглядные выводы, которые можно использовать для развития конкретного проекта или бизнеса в целом.

Результат работы аналитика данных это основа для принятия любых бизнес-решений.

Data Engineer работает больше не с самими данными, а с их инфраструктурой: базами данных, хранилищами и системами обработки. Инженер данных определяет, как анализировать данные, чтобы они были полезными для проекта. Если обобщить, то Data Engineer налаживает конвейер обработки данных.

Data Scientist занимается стратегической работой с информацией. Именно он создает системы прогнозирования, моделирования и динамического анализа, внедряет алгоритмы автоматизации и обучения.

Главная сложность в том, что границы между этими тремя специальностями довольно размыты. Большинство компаний не видят разницы, поэтому часто в вакансиях Data Analyst встречаются требования, которые больше подходят специалистам Data Engineer или Data Scientist.

В основном это обусловлено спецификой рынка. Если в IT-компаниях знают, что Data Analyst, Data Engineer и Data Scientist это в идеале три разных специалиста или даже три разных подразделения, то в продуктовых компаниях и производствах часто об этом даже не задумываются.

Что требуют работодатели от аналитика данных


Мы проанализировали свыше 450 вакансий на позицию аналитика данных, открытых в августе-сентябре 2020 года.

Во многих случаях требования к специалистам очень отличаются. Как мы писали выше, границы между Data Analyst, Data Engineer и Data Scientist стерты, поэтому часто бывает, что в заголовке вакансии пишут Аналитик данных, а фактически вакансия полностью соответствует Инженеру данных.

Но мы смогли выделить набор хард и софт скилов, которые работодатели указывают в большинстве вакансий на должность аналитика данных.

Хард скилы


Python с библиотеками для анализа данных Pandas и NumPy. Это мастхэв, его знание хотя бы на базовом уровне требуют 83% компаний в отрасли. Знание R, JavaScript и других ЯП требуют нужны всего лишь 17% работодателям.

Интересно, что в 2013 году по результатам опроса Data Analyst и Data Scientist язык R в аналитике данных был куда популярнее его использовали 61% специалистов.

SQL практически во всех вакансиях требуется знание SQL и навыки работы с реляционными базами данных. Чаще всего требуют умение писать запросы и оптимизировать их.

Навыки работы с NoSQL системами управления базами данных вроде MongoDB, CouchDB или Apache Cassandra работодатели требуют довольно редко примерно в 9% вакансий.

Power BI, Qlik, Tableau. Большинство компаний не требует знаний какой-нибудь конкретной программы визуализации данных. Обычно они указывают одну из трех на выбор или пишут системы визуализации данных без указания конкретной.

В целом специалисты могут сами выбирать, что именно им удобнее использовать. Принципиальной позиции у абсолютного большинства работодателей нет.

Опыт работы с Agile, Scrum, Kanban. Почти в половине вакансий работодатели указывают, что дополнительным плюсом будет умение соискателя работать с гибкими методологиями создания продуктов.

То есть, важно не только то, что делает аналитик данных в рамках своей специальности, но и то, как он это делает.

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

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

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

Многие компании отдельно выделяют высокий уровень математической подготовки. Но здесь нужно понимать, что Data Analyst, в отличие от Data Scientist, использует довольно ограниченные математические инструменты, поэтому не нужно быть гением математики. Большинство задач аналитика данных вписываются в рамки базовых знаний статистики, теории вероятностей, математического анализа и линейной алгебры.

Высшее образование в области математики пригодится, но при должном усердии все необходимые функции можно изучить и самому. Но для Data Scientist глубокое знание математики уже считается критичным. Если вы планируете расти из Data Analyst в Data Scientist, то математику нужно будет подтянуть.

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

Софт скиллы


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

  • Критическое мышление
  • Аналитический склад ума
  • Умение правильно излагать и доносить информацию
  • Ответственность и внимание к деталям
  • Бизнес-мышление
  • Готовность принимать решения и брать ответственность за результат
  • Многозадачность
  • Чувство юмора

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

На самом деле, все немного иначе. Аналитик данных действительно много времени проводит над анализом, но ему также важно уметь донести выводы руководителям компании или отдела. Навыки выступления перед публикой и грамотного подбора аргументации очень пригодятся. Ведь от того, насколько правильно ЛПРы поймут результаты аналитики, будут зависеть их дальнейшие действия в развитии компании или конкретного проекта.

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

Обязательный английский часто приятно отражается на зарплате. Вакансии, которые предлагают работу на международных проектах, гарантируют денежную компенсацию в 1,3-2 раза больше, чем русскоязычные.

Зарплата и другие плюшки для аналитика данных


Теперь перейдем к самому интересному к зарплате. Мы проанализировали открытые вакансии на сайтах HH.ru и Хабр Карьера.

Больше всего вакансий для аналитиков данных по состоянию на 12.09.2020 открыто в Москве (241) и в Санкт-Петербурге (74). Для сравнения, во всей остальной России актуально всего 99 вакансий на эту должность.

Интересно, что только 20% компаний указывают уровень заработной платы в самом объявлении. Остальные 80% предпочитают обсуждать денежное вознаграждение в личной беседе с соискателем.

Разброс зарплат довольно большой. Зависит он не только от опыта соискателя, но и от географии. К примеру, аналитик-стажер в Перми получает 25 000 рублей, а Data Analyst в московском офисе международной компании зарабатывает 200 000 рублей.

В Москве средняя зарплата аналитика данных составляет 134 000 рублей. На нее вполне может рассчитывать хороший специалист с опытом от 2 лет.

Стажеры и Junior-спецы получают от 60 000 рублей. Есть небольшое количество вакансий, которые предлагают ниже этой суммы (8%), но они в основном предлагают работу не на полный день либо с ограниченной загрузкой в неделю.



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

Руководители отделов аналитики и Senior-спецы могут рассчитывать на зарплату от 170 000 рублей. Есть даже вакансии, которые предлагают больше 250 000 рублей в месяц. Да, для них требуется опыт больше 5 лет в аналитике и большой пул компетенций, но такие вакансии есть. Так что вполне ясно, куда можно расти.

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

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

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

Аналитики данных востребованы в любом крупном и среднем бизнесе, особенно в тех проектах, которые относятся к диджитал и IT. Финтех-банки, диджитал-агентства, продуктовые компании, которые налаживают онлайн-систему продаж, консалтинговые проекты.

Среди вакансий есть представители бизнеса практически всех сфер: от медицины до тяжелой промышленности. Так что профессия очень востребованная.

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

Зарплата у такого специалиста тоже не топовая. В среднем, аналитик за пределами Москвы и Питера получает 54 000 рублей. Дополнительных плюшек в половине случаев часто нет вообще, а в остальном они ограничиваются бесплатным кипяточком на кофепойнте печеньками и кофе, спортзалом и обучающими курсами.

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

Мы также провели сравнительный анализ вакансий из Украины и Беларуси.

Средняя зарплата аналитика данных в Украине порядка 20 000 гривен (53 000 рублей). В столице есть вакансии с оплатой в 2-2,5 раза выше, но их выставляют преимущественно международные компании с филиалами в Киеве.

Абсолютно та же ситуация и в Беларуси. Средние размер заработной платы аналитика данных составляет 2800 белорусских рублей (81 000 рублей), Но разброс зарплат очень большой. В Гомеле, к примеру, аналитик с опытом от года получает в среднем 1100 белорусских рублей (31 000 российских рублей), а в Минске специалист может зарабатывать вплоть до 10 000 (287 000 российских рублей).

Откуда прийти в профессию и куда расти аналитику данных


Есть мнение, что попасть в касту аналитиков можно только с исключительными знаниями математики. Но это не так.

В аналитику обычно уходят Junior- и Middle-разработчики на Python. Если вдобавок есть базовые знания SQL вообще отлично. В таком случае разобраться со всеми особенностями работы будет намного проще.

Также можно начать карьеру непосредственно с аналитика. Выбирайте один из десятков доступных курсов и вперед. Высшую математику знать необязательно. Для Data Analyst уровня Junior и Middle нужно только знание инструментов работы с данными. А в большинстве случаев хватит и школьных знаний математики.

Возможностей роста для специалиста аналитики данных тоже хватает. Три самых очевидных: Data Mining Specialist, Data Engineer, Data Scientist. Первый работает непосредственно с поиском данных для аналитики, второй разрабатывает инфраструктуры данных, а третий прогнозированием и стратегией.

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

Специально для материала, мы попросили дать комментарий о необходимых навыках для роста в BI-аналитике,Александра Царёва, основателя компании SmartDataLab, лидера образовательного курса BI SkillFactory и Сергея Земскова руководителя направления Power BI/DWH SmartDataLab и преподавателя Bootcamp SkillFactory.

В обзоре указаны мастхэв компетенции, но если вы хотите и дальше расти как Аналитик данных, вам понадобится быть в курсе ETL и изучить:
Так называемый золотой треугольник Microsoft: SSRS, SSIS, SSAS;
Иметь представление о других промышленных ETL, например, KNIME;
Литературу по архитектуре данных, например, книгу Билла Инмона Методология Кимбалла;
Также нужно хотя бы в первом приближении понимать, что такое Informatica, GreenPlum, Pentaho, чем они друг от друга отличаются и как работают.
Быть в курсе, что такое SAP Web Analytics и другие новые BI решения от SAP, хотя сейчас отмечается переход с этих решений на Power BI (который, по исследованию проведенному в июле-августе телеграм каналом вакансий и фриланса в BI/DWH BI HeadHunter, в топе по запросу от работодателей).

Это солидный пласт знаний, но он сделает вас уберспецом.

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

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

В вакансиях на сайтах работы часто смешивают понятия. Даже встречаются предложения вроде Бизнес/системный аналитик. Не надо так. Это два разных направления.

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

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

Совсем недавно мы запустили первый в России Онлайн-буткемп по Data Analytics, включающий в себя 5 недель обучения, 5 проектов в портфолио, оплачиваемая стажировка для лучшего выпускника. Это суперинтенсивный формат для самых целеустремленных: учиться нужно фултайм. Зато в итоге выход на работу уже через 13 месяца.

image

Узнайте подробности, как получить востребованную профессию с нуля или Level Up по навыкам и зарплате, пройдя онлайн-курсы SkillFactory:



Подробнее..

Leatherman для разработчика в Big Data

06.09.2020 22:19:56 | Автор: admin
Экосистема Big Data, а для определенности Hadoop, достаточно большая, и включает в себя множество продуктов. Какие-то применяются чаще, какие-то реже. Но один из них в нашей команде мы выбрали для себя в качестве универсального инструмента на все случаи жизни на нем пишутся как одноразовые скрипты, так и постоянно работающие приложения (в первую очередь отчеты).

Этот инструмент Spark Shell. Обычно такую штуку называют швейцарский нож, но лично я предпочитаю мультитулы Leatherman.


Фактически, Spark Shell это Scala REPL, то есть обычная для scala интерактивная среда прототипирования и отладки, плюс Apache Spark. Тут можно вводить код с клавиатуры, при этом законченные предложения сразу вычисляются. А если при запуске указать параметр -i <scala-скрипт>, то сразу будет прочитан (и интерпретирован) этот файл <scala-скрипт>, написанный на scala. Можно загрузить код из файла и в интерактивном режиме, для этого есть команды, начинающеся с символа :. При этом написанный вами код может пользоваться средствами спарка для работы с большими данными, то есть например, выполнять SQL запросы к Hive, или читать/писать данные в HDFS, или работать с чем-то типа HBase, например.

Spark Shell часть дистрибутива Apache Spark. Про то, как установить Spark на машине разработчика, во-первых уже есть много описаний, а во-вторых, возможно много вариантов. Поэтому эту часть опустим, и начнем сразу с запуска.
spark-shell [-i <scala-скрипт>]


Посмотрим, что там за версия:

...Spark context Web UI available at http://192.168.1.12:4040scala> scala.util.Properties.versionStringres1: String = version 2.11.8


А версия самого спарк?
scala> spark.versionres0: String = 2.2.0


Вы можете вводить построчно код на scala, или вставлять целые многострочные куски (для этого есть например команда :paste):
2+2res0: Int = 4


Соответственно, мы ввели выражение, оно вычислилось, и мы получили ответ, который называется res0, и имеет тип Int. Дальше мы можем его использовать в следующих выражениях. Или же можно было сразу завести переменную/константу, названную так, как мы хотим:

val four= 2+2four: Int = 4


Наконец, можно воспользоваться командой :load <файл>, чтобы загрузить код из подготовленного файла.

Как обычно, справка доступна по команде :help
scala> :helpAll commands can be abbreviated, e.g., :he instead of :help.:edit <id>|<line>        edit history:help [command]          print this summary or command-specific help:history [num]           show the history (optional num is commands to show):h? <string>             search the history:imports [name name ...] show import history, identifying sources of names:implicits [-v]          show the implicits in scope:javap <path|class>      disassemble a file or class name:line <id>|<line>        place line(s) at the end of history:load <path>             interpret lines in a file:paste [-raw] [path]     enter paste mode or paste a file:power                   enable power user mode:quit                    exit the interpreter:replay [options]        reset the repl and replay all previous commands:require <path>          add a jar to the classpath:reset [options]         reset the repl to its initial state, forgetting all session entries:save <path>             save replayable session to a file:sh <command line>       run a shell command (result is implicitly => List[String]):settings <options>      update compiler options, if possible; see reset:silent                  disable/enable automatic printing of results:type [-v] <expr>        display the type of an expression without evaluating it:kind [-v] <expr>        display the kind of expression's type:warnings                show the suppressed warnings from the most recent line which had any


Доступ к средствам Spark


Ну хорошо, на Scala мы посмотрели, а где Spark? Оказывается, сразу при запуске для нас определены две переменные, spark и sc:

Spark context available as 'sc' (master = local[*], app id = local-1576608607085).
Spark session available as 'spark'.

То есть, это спарк контекст, и сессия. Они используются для выполнения специфичных для Spark функций.

Для начала word count


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

scala> var hFile = sc.textFile("file:///d:/tmp/inp")scala> val wc = hFile.flatMap(line => line.split(" ")).map(word => (word, 1)).reduceByKey(_ + _)scala> val cnt= wc.countcnt: Long = 3scala> val arr= wc.collectarr: Array[(String, Int)] = Array((bbb,1), (ccc,1), (aaa,1))scala> val ds= wc.toDSds: org.apache.spark.sql.Dataset[(String, Int)] = [_1: string, _2: int]scala> ds.show+---+---+| _1| _2|+---+---+|bbb|  1||ccc|  1||aaa|  1|+---+---+scala> val sch= ds.schemasch: org.apache.spark.sql.types.StructType = StructType(StructField(_1,StringType,true), StructField(_2,IntegerType,false))scala> val fldn= ds.schema.fieldNamesfldn: Array[String] = Array(_1, _2)


В итоге, в несколько строк мы: прочитали текстовый файл с локального диска, разбили его на слова (по пробелам), преобразовали каждое слово в кортеж (слово, 1), и выполнили подсчет числа слов операцией reduceByKey (в данном случае ключом является само слово).

Затем мы полученный RDD посчитали, получили его в массив, преобразовали в Dataset, и посмотрели на этот самый Dataset с разных сторон, включая схему.

Можно было сразу построить Dataset, используя новый API и spark:
scala> var ds= spark.read.text("file:///d:/tmp/inp")


Казалось бы, что тут особенного? Ну, для начала это довольно удобно. Скала, по крайней мере до определенного предела, язык лаконичный и простой. А во-вторых, что более важно, вы можете точно так же, не меняя ничего в коде (ну, или почти ничего) запустить этот скрипт для подсчета слов в 1 или в 100 терабайтах текста. Разумеется, для этого потребуется железо, потому что выполнить такое можно только на множестве машин, распределив между ними нагрузку.

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

Чем вы еще можете спарку помочь?

И чего, не подумав, делать не следует


В сети достаточно много описаний работы с данными в Spark, как через RDD API, так и с более новым Dataset API. Вряд ли тут можно дополнить чем-то существенным, но некоторые замечания все-же хотелось бы озвучить.

Чуть ли не самый частый пример, который вы можете в сети увидеть это подсчет числа строк в датасете. И я его тоже выше показал. Ну то есть:

val ds= spark.read.text("путь к файлу")... обработка, например фильтрацияprintln ds.count... делаем что-то еще с ds


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

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


Можно посмотреть на все это, запросив план датасета (логический или физический). В нем вы увидите доступ к таблицам Hive или папкам, разного рода UNION, проекции (выборка подмножества колонок), фильтрацию и т.п.

Spark (как в общем-то и Hadoop) работает с данными в разных форматах. Например, с данными в формате Parquet, которые хранятся в HDFS, то есть в распределенной системе, на разных узлах кластера. То есть, это данные, которые в общем случае не содержат в себе статистик, указывающих, что тут, допустим, датасет из 100 млн записей. Схема обычно есть а вот статистик зачастую нет.

Когда вы читаете датасет, выполняя spark.read..., вы на самом деле еще не считываете сами данные, хранящиеся в указанном файле (или папке, или таблице Hive), которые разбросаны по неизвестному числу узлов кластера, и размер которых мы еще не знаем. А в общем случае и не можем узнать, потому что многие из форматов, с которыми Spark (и Hadoop) умеет работать, не содержат метаданных, говорящих нам о числе строк данных. Чтобы узнать число нужно прочесть сами данные, и подсчитать.

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

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

Если же дальше, узнав это число, вы захотите что-то еще с датасетом проделать, его, вполне возможно, придется вычислить повторно (потому что промежуточные результаты сами по себе не сохраняются).

С другой стороны, если сделать например вот так:
val ds= spark.read.text("путь к файлу")println ds.toRDD.isEmpty


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

Почти такая же ситуация с операцией show над датасетом. Да, это чрезвычайно удобно, что вы можете посмотреть промежуточные результаты, просто выполнив ds.show, но надо понимать, что если ваш датасет, допустим, был получен изначально как-то так:

val ds= spark.read.jdbc("параметры доступа к реляционной базе")ds.show...прочие операции над тем же датасетом.


то выполнение .show приведет к выполнению SQL-запроса к базе данных, а прочие операции далее к выполнению еще одного такого же запроса. В какой-то степени проблему может снять кеширование (ds.cache), или сохранение датасета (ds.persist), но оба способа не гарантируют вас от повторного вычисления. Почему? Да все потому же чтобы кешировать или сохранить датасет для повторного использования, нужно где-то иметь место, куда его сохранять. Для датасета большого у вас может просто этого места не быть, и в любом случае это сохранение это тоже работа.

В тоже время, иногда может быть выгодно просто прочитать датасет из источника, сохранить его в HDFS в некотором хорошо оптимизированном формате (типа паркета), а потом прочитать снова. В чем тут причина?

Одна из причин в том, что источник данных может иметь намного меньшую производительность, чем ваш кластер Hadoop. Если источник что-то вроде базы данных Oracle, то одно ядро для этой базы стоит как одно ядро Hadoop + стоимость лицензии Oracle. Поэтому зачастую бывает выгоднее наращивать ядра в кластере, чем покупать новые лицензии для СУБД. Соответственно, повторное чтение данных из HDFS и базы примерно одинаково эффективно, при условии что у вас одинаковое число ядер и/или дисковых шпинделей но обычно это условие не выполняется, кроме того, чтение из HDFS параллелится обычно намного лучше, за счет того что данные распределены по узлам, и реплицированы то есть, один блок доступен более чем на одном узле.

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

Заметим так же, что колоночно ориентированные форматы хранения, такие как паркет, очень эффективны при выборке подмножества колонок. Так что прочитать из них лишь одну колонку сильно дешевле, чем прочитать все. И вы можете выбирать, в каком формате (строчно или колоночно ориентированном) вам сохранить данные для каждой отдельной таблицы, в зависимости от типа операций над ней.

Менее стандартные применения


Посмотрим, как в Spark Shell можно работать например с Hive MetaStore.

Базы данных Hive, кто они, и где они?


Для начала, получим свой экземпляр ExternalCatalog:

scala> val cat= spark.sharedState.externalCatalogcat: org.apache.spark.sql.catalyst.catalog.ExternalCatalog = org.apache.spark.sql.hive.HiveExternalCatalog@4a4979bf


В нашей команде прижился идентификатор cat для этой переменной, поэтому мы между собой зовем его котик. Это API для доступа к метаданным Hive о базах, таблицах, партициях и т.п.

Посмотрим, что за базы у нас есть в Hive:
scala> cat.listDatabasesres0: Seq[String] = Buffer(default)


А вот нет у нас никаких баз кроме default, у нас и Hive-то не имеется, мы на локальном ноуте все это делаем

Но в тоже время, мы видим, что список баз это Seq[String], т.е. возвращается нам коллекция названий.

Дальше мы можем сделать что-то вот такое:
scala> val db= cat.getDatabase("default")db: org.apache.spark.sql.catalyst.catalog.CatalogDatabase = CatalogDatabase(default,Default Hive database,file:./spark-warehouse,Map())val loc= db.locationUriloca: java.net.URI = file:.../spark-warehouse


База данных под названием default существует всегда, по умолчанию она пустая.

Что мы можем сказать про базу? Не так уж и много это достаточно простая конструкция для Hive. У нее есть имя (default), описание (Default Hive database), location (т.е. расположение файлов таблиц по умолчанию), и свойства (набор key-value пар). Ну и еще в ней хранятся таблицы. У Hive двухуровневая структура, т.е. база->таблица, поэтому термин база (database) используется наравне и термином схема (schema), и означает одно и тоже. Далее я постараюсь применять термин база, так как у термина схема есть и другое значение, и оно нам понадобится ниже.

А теперь все тоже самое, но одновременно:
scala> cat.listDatabases.map{db=>(db, cat.getDatabase(db).locationUri)}


Что мы тут проделали? Мы получили список баз данных Hive, потом сами базы, и для каждой из них location, т.е. расположение базы в файловой системе. И вернули мы Seq[(String, java.net.URI)], то есть последовательность кортежей, где _1 это имя базы, а _2 это location.

Посмотрим на таблицы


Таблица штука немного интереснее. Кроме все тех же имени и описания, у таблицы также есть название базы, куда она входит. Естественно, у таблицы есть колонки, которые составляют ее схему данных. Колонки это упорядоченный набор из имени, типа данных, и описания. Кроме обычных атомарных типов данных (числовых, строковых, бинарных, дата или timestamp), обычных для реляционных баз, в Hive есть и типы составные, а именно структуры (struct), которые эквивалентны таблице (т.е. вложенные таблицы), массивы (array), и словари (map), содержащие пары ключ->значение.

Так же, как у базы, у таблицы есть location т.е. URI, указывающий на файлы данных. URI, в случае HDFS (а это обычно так и бывает), может указывать как на текущий кластер, так и на другой, т.е. в другой экземпляр файловой системы HDFS. location это папка, а не файл, а файлы с данными уже лежат в ней. Также как и у базы, у таблицы есть свойства (тоже набор key-value пар), куда приложение может, например, складывать собранную статистику.

В отличие от типовой реляционной СУБД, для Hive у таблицы обязателен формат хранения данных. Абстрактного формата по умолчанию не бывает. Набор форматов расширяемый, фактически формат хранения базы это набор из нескольких Java классов, которые умеют с ним работать. Например, набор классов, умеющих работать с CSV. А еще их параметры (для CSV это разделители, наличие кавычек или апострофов, метасимвол для кодирования разделителей и ограничителей внутри данных колонки). Можно указать эти классы явно (когда мы работаем с API то всегда так), а можно просто сообщить Hive, что таблица хранится в формате Parquet, например, или в виде текста (несколько стандартных форматов).

Общая схема преобразования данных при чтении и записи такова:
Файлы в HDFS >
Hadoop InputFileFormat >
<key, value> >
Deserializer >
объект Row
объект Row >
Serializer >
<key, value> >
OutputFileFormat >
файлы в HDFS

Тут важно помнить, что от key/value Hive использует только value. А так называемый интерфейс SerDe, или его конкретная реализация, отвечает за то, чтобы преобразовать это значение в набор колонок таблицы.

По сравнению с обычными реляционными СУБД Hive не умеет делать (или не делает) некоторые вещи самостоятельно. Например, не поддерживает ключи, и не создает индексы для них, не сортирует данные, и еще многое другое. Все это делает приложение, а Hive мы сообщаем, что данные таблицы будут например отсортированы или партиционированы определенным образом.

Побегаем по HDFS



API для доступа к файловой системе в Hadoop (как HDFS, так и локальной) представляет собой по большей части класс FileSystem:
import org.apache.hadoop.fs.FileSystemval fs= FileSystem.get(sc.hadoopConfiguration)


Мы получили экземпляр FileSystem, построенный на основе конфигурации Hadoop, взятой из Spark. Это будет файловая система HDFS того кластера, на котором мы сейчас работаем.

Ну а дальше начинается довольно обычная возня с методами FileSystem и вспомогательных классов типа Path:

import org.apache.hadoop.fs.{Path,FileStatus}fs.exists(new Path(path))val status= fs.getFileStatus(new Path(path))val files = fs.listStatus(new Path(path))val cs= fs.getContentSummary(new Path(path))


Ну то есть, проверить существование файла по пути, получить его статус (где, например, написаны даты модификации, или признак того, что это папка), посмотреть список файлов в папке (на самом деле статусов), или скажем summary (где есть занимаемое место, число файлов и папок внутри, и т.д.). Ну в общем обычный такой API, не похожий на Java IO, но вполне рабочий.

Если мы хотим работать с содержимым файла, то можно получить входной или выходной поток, обычный java.io.Stream:

val is = new BufferedInputStream(fs.open(new Path(path)))Source.fromInputStream(is).getLines().foreach(mapper)


Таким образом мы читаем из файла в HDFS все строки, и применяем к каждой функцию mapper. Аналогично для записи: fs.create(p:Path): OutputStream.

Методов у FIleSystem много, поэтому за полной справкой отошлю к документации.

Совсем короткие выводы


Итак, у нас есть инструмент, в котором можно интерактивно попрограммировать на скале, воспользоваться средствами спарка для анализа данных (насколько больших зависит от имеющихся у нас ресурсов, и от того, как долго мы согласны подождать результата), а также посмотреть на разные аспекты Hadoop, Hive (на самом деле почти всех продуктов экосистемы, так как в конечном счете это scala, и мы можем пользоваться любыми API, доступными для Java приложений.

Все это делает Spark Shell очень удобным инструментом для создания приложений самого разнообразного назначения, таких как отчеты, средства мониторинга, ну и ETL немножко. В первую очередь, конечно же, Spark Shell, как и другие похожие скриптовые языки, подходит на роль клея, на котором мы можем собрать приложение из готовых компонентов. Как именно собирать, и как должны выглядеть компоненты в случае Spark это уже другая история.
Подробнее..
Категории: Big data , Spark scala bigdata hadoop

Перевод - recovery mode Инструменты обработки OLAP-запросов для Big Data

14.09.2020 22:10:58 | Автор: admin


Введение


Эта статья является компиляцией другой статьи. В ней я намерен сконцентрироваться на инструментах для работы с Big data, ориентированных на анализ данных.

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

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

  • Хранилище данных против Озера
  • Hadoop против Автономного хранилища
  • OLAP против OLTP
  • Движок запросов против OLAP механизмов


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


Инструменты для обработки данных


Большинство упомянутых инструментов могут подключаться к серверу метаданных, например Hive, и выполнять запросы, создавать представления и т.п. Это часто используется для создания дополнительных (улучшенных) уровней отчетности.

Spark SQL предоставляет способ беспрепятственно смешивать запросы SQL с программами Spark, поэтому вы можете смешивать API DataFrame с SQL. Он имеет интеграцию с Hive и стандартное подключение через JDBC или ODBC, так что вы можете подключить Tableau, Looker или любой инструмент бизнес-аналитики к своим данным через Spark.



Apache Flink также предоставляет SQL API. Поддержка SQL в Flink основана на Apache Calcite, который реализует стандарт SQL. Он также интегрируется с Hive через HiveCatalog. Например, пользователи могут хранить свои таблицы Kafka или ElasticSearch в Hive Metastore с помощью HiveCatalog и повторно использовать их позже в запросах SQL.

Kafka тоже предоставляет возможности SQL. В целом большинство инструментов обработки данных предоставляют SQL интерфейсы.

Инструменты выполнения запросов


Этот тип инструментов ориентирован на унифицированный запрос к различным источникам данных в разных форматах. Идея состоит в том, чтобы направлять запросы к вашему озеру данных с помощью SQL, как если бы это была обычная реляционная база данных, хотя у нее есть некоторые ограничения. Некоторые из этих инструментов могут также выполнять запросы к NoSQL базам и многое другое. Эти инструменты предоставляют интерфейс JDBC для внешних инструментов, таких как Tableau или Looker, для безопасного подключения к вашему озеру данных. Инструменты запросов самый медленный вариант, но обеспечивают максимальную гибкость.

Apache Pig: один из первых инструментов наряду с Hive. Имеет собственный язык, отличный от SQL. Отличительным свойством программ созданных Pig является то, что их структура поддается существенному распараллеливанию, что, в свою очередь, позволяет им обрабатывать очень большие наборы данных. Это работает не в пользу более новых движков на базе SQL.

Presto: платформа от Facebook с открытым исходным кодом. Это распределенный механизм SQL-запросов для выполнения интерактивных аналитических запросов к источникам данных любого размера. Presto позволяет запрашивать данные там, где они находятся, включая Hive, Cassandra, реляционные базы данных и файловые системы. Она может выполнять запросы к большим наборам данных за секунды. Presto не зависит от Hadoop, но интегрируется с большинством его инструментов, особенно с Hive, для выполнения SQL-запросов.

Apache Drill: предоставляет механизм SQL запросов без схем для Hadoop, NoSQL и даже облачного хранилища. Он не зависит от Hadoop, но имеет множество интеграций с инструментами экосистемы, такими как Hive. Один запрос может объединять данные из нескольких хранилищ, выполняя оптимизацию, специфичную для каждого из них. Это очень хорошо, т.к. позволяет аналитикам обрабатывать любые данные как таблицу, даже если фактически они читают файл. Drill полностью поддерживает стандартный SQL. Бизнес-пользователи, аналитики и специалисты по обработке данных могут использовать стандартные инструменты бизнес-аналитики, такие как Tableau, Qlik и Excel, для взаимодействия с нереляционными хранилищами данных, используя драйверы Drill JDBC и ODBC. Кроме того, разработчики могут использовать простой REST API Drill в своих пользовательских приложениях для создания красивых визуализаций.

OLTP базы данных


Хотя Hadoop оптимизирован для OLAP, все же бывают ситуации, когда вы хотите выполнять запросы OLTP для интерактивного приложения.

HBase имеет очень ограниченные свойства ACID по дизайну, поскольку он был построен для масштабирования и не предоставляет возможностей ACID из коробки, но его можно использовать для некоторых сценариев OLTP.

Apache Phoenix построен на основе HBase и обеспечивает способ выполнения запросов OTLP в экосистеме Hadoop. Apache Phoenix полностью интегрирован с другими продуктами Hadoop, такими как Spark, Hive, Pig, Flume и Map Reduce. Он также может хранить метаданные, поддерживает создание таблиц и добавочные изменения с управлением версиями при помощи команд DDL. Это работает довольно быстро, быстрее, чем при использовании Drill или другого
механизма запросов.

Вы можете использовать любую крупномасштабную базу данных за пределами экосистемы Hadoop, такую как Cassandra, YugaByteDB, ScyllaDB для OTLP.

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

Распределенное индексирование


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

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

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

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

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

OLAP базы данных


Тут мы рассмотрим базы данных, которые также могут предоставлять хранилище метаданных для схем запросов. Если сравнивать эти инструменты с системами выполнения запросов, эти инструменты также предоставляют хранилище данных и могут применяться для конкретных схем хранения данных (звездообразная схема). Эти инструменты используют синтаксис SQL. Spark, либо другие платформы могут с ними взаимодействовать.

Apache Hive: мы уже обсуждали Hive, как центральный репозиторий схем для Spark и других инструментов, чтобы они могли использовать SQL, но Hive также может хранить данные, так что вы можете использовать его в качестве хранилища. Он может получить доступ к HDFS или HBase. При запросе Hive он использует Apache Tez, Apache Spark или MapReduce, будучи намного быстрее Tez или Spark. Он также имеет процедурный язык под названием HPL-SQL. Hive это чрезвычайно популярное хранилище мета-данных для Spark SQL.

Apache Impala: это собственная аналитическая база данных для Hadoop, которую вы можете использовать для хранения данных и эффективных запросов к ним. Она может подключаться к Hive для получения метаданных с помощью Hcatalog. Impala обеспечивает низкую задержку и высокий уровень параллелизма для запросов бизнес-аналитики и аналитики в Hadoop (что не предоставляется пакетными платформами, такими как Apache Hive). Impala также масштабируется линейно, даже в многопользовательских средах, что является лучшей альтернативой для запросов, чем Hive. Impala интегрирована с собственной системой безопасности Hadoop и Kerberos для аутентификации, поэтому вы можете безопасно управлять доступом к данным. Она использует HBase и HDFS для хранения данных.



Apache Tajo: это еще одно хранилище данных для Hadoop. Tajo разработан для выполнения специальных запросов с малыми задержкой и масштабируемостью, онлайн-агрегирования и ETL для больших наборов данных, хранящихся в HDFS и других источниках данных. Он поддерживает интеграцию с Hive Metastore для доступа к общим схемам. Он также имеет множество оптимизаций запросов, он масштабируемый, отказоустойчивый и предоставляет интерфейс JDBC.

Apache Kylin: это новое распределенное хранилище аналитических данных. Kylin чрезвычайно быстр, поэтому его можно использовать для дополнения некоторых других баз данных, таких как Hive, для случаев использования, где важна производительность, таких как панели мониторинга или интерактивные отчеты. Это, вероятно, лучшее хранилище данных OLAP, но его сложно использовать. Другая проблема заключается в том, что из-за большой растягиваемости требуется больше места для хранения. Идея состоит в том, что если механизмы запросов или Hive недостаточно быстры, вы можете создать Куб в Kylin, который представляет собой многомерную таблицу, оптимизированную для OLAP, с предварительно вычисленными
значениями, которые вы можете запрашивать из панелей мониторинга или интерактивных отчетов. Он может создавать кубики прямо из Spark и даже почти в реальном времени из Kafka.



Инструменты OLAP


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

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

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

Apache Druid: это самый известный движок OLAP в реальном времени. Он ориентирован на данные временных рядов, но может использоваться для любых данных. Он использует свой собственный столбчатый формат, который может сильно сжимать данные, и он имеет множество встроенных оптимизаций, таких как инвертированные индексы, кодирование текста, автоматическое сворачивание данных и многое другое. Данные загружаются в реальном времени с использованием Tranquility или Kafka, которые имеют очень низкую задержку, хранятся в памяти в формате строки, оптимизированном для записи, но как только они поступают, они становятся доступными для запроса, как и предыдущие загруженные данные. Фоновая процесс отвечает за асинхронное перемещение данных в систему глубокого хранения, такую как HDFS. Когда данные перемещаются в глубокое хранилище, они разделяются на более мелкие фрагменты, сегрегированные по времени, называемые сегментами, которые хорошо оптимизированы для запросов с низкой задержкой. У такого сегмента есть отметка времени для нескольких измерений, которые вы можете использовать для фильтрации и агрегирования, и метрики, которые представляют собой предварительно вычисленные состояния. При пакетном приеме данные сохраняются непосредственно в сегменты. Apache Druid поддерживает проглатывание по принципу push и pull, имеет интеграцию с Hive, Spark и даже NiFi. Он может использовать хранилище метаданных Hive и поддерживает запросы Hive SQL, которые затем преобразуются в запросы JSON, используемые Druid. Интеграция Hive поддерживает JDBC, поэтому вы можете подключить любой инструмент бизнес-аналитики. Он также имеет собственное хранилище метаданных, обычно для этого используется MySQL. Он может принимать огромные объемы данных и очень хорошо масштабируется. Основная проблема в том, что в нем много компонентов, и им сложно управлять и развертывать.



Apache Pinot: это более новая альтернатива Druid с открытым исходным кодом от LinkedIn. По сравнению с Druid, он предлагает меньшую задержку благодаря индексу Startree, который выполняет частичное предварительное вычисление, поэтому его можно использовать для приложений, ориентированных на пользователя (он использовался для получения лент LinkedIn). Он использует отсортированный индекс вместо инвертированного, который работает быстрее. Он имеет расширяемую архитектуру плагинов, а также имеет множество интеграций, но не поддерживает Hive. Он также объединяет пакетную обработку и режим реального времени, обеспечивает быструю загрузку, интеллектуальный индекс и сохраняет данные в сегментах. Его легче и быстрее развернуть по сравнению с Druid, но на данный момент он выглядит немного недозрелым.

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

Прочитайте эту статью, которая сравнивает 3 движка детально.

Начните с малого, изучив свои данные, прежде чем принимать решение. Эти новые механизмы очень мощные, но их сложно использовать. Если вы можете ждать по несколько часов, используйте пакетную обработку и базу данных, такую как Hive или Tajo; затем используйте Kylin, чтобы ускорить запросы OLAP и сделать их более интерактивными. Если этого недостаточно и вам нужно еще меньше задержки и данные в реальном времени, подумайте о механизмах OLAP. Druid больше подходит для анализа в реальном времени. Кайлин больше ориентирован на дела OLAP. Druid имеет хорошую интеграцию с Kafka в качестве потоковой передачи в реальном времени. Kylin получает данные из Hive или Kafka партиями, хотя планируется прием в реальном времени.

Наконец, Greenplum еще один механизм OLAP, больше ориентированный на искусственный интеллект.

Визуализация данных


Для визуализации есть несколько коммерческих инструментов, таких как Qlik, Looker или Tableau.

Если вы предпочитаете Open Source, посмотрите в сторону SuperSet. Это замечательный инструмент, который поддерживает все упомянутые нами инструменты, имеет отличный редактор и действительно быстрый, он использует SQLAlchemy, что обеспечивает поддержку многих баз данных.

Другие интересные инструменты: Metabase или Falcon.

Заключение


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

Обратите особое внимание на новые инструменты, такие как Druid или Pinot, которые обеспечивают простой способ анализа огромных объемов данных с очень низкой задержкой, сокращая разрыв между OLTP и OLAP с точки зрения производительности. У вас может возникнуть соблазн подумать об обработке, предварительном вычислении агрегатов и т.п., но подумайте об этих инструментах, если вы хотите упростить свою работу.
Подробнее..

Применение low-code в аналитических платформах

24.09.2020 18:11:15 | Автор: admin
Уважаемые читатели, доброго дня!

Задача построения программных платформ для накопления и проведения аналитики над данными рано или поздно возникает у любой компании, в основе бизнеса которой заложена интеллектуально нагруженная модель оказания услуг или создания технически сложно изготавливаемых продуктов. Построение аналитических платформ сложная и трудозатратная задача. Однако любую задачу можно упростить. В этой статье я хочу поделиться опытом применения low-code-инструментов, помогающих в создании аналитических решений. Данный опыт был приобретён при реализации ряда проектов направления Big Data Solutions компании Неофлекс. Направление Big Data Solutions компании Неофлекс с 2005 года занимается вопросами построения хранилищ и озёр данных, решает задачи оптимизации скорости обработки информации и работает над методологией управления качеством данных.



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

Однако в каком случае задачи аналитики данных могут перерасти в задачи класса Rocket Science? Пожалуй, в тот момент, когда речь идёт о действительно больших данных.
Чтобы упростить задачу Rocket Science, можно есть слона по частям.



Чем большая дискретность и автономность будет у ваших приложений/сервисов/микросервисов, тем проще вам, вашим коллегам и всему бизнесу будет переваривать слона.

К этому постулату пришли практически все наши клиенты, перестроив ландшафт, основываясь на инженерных практиках DevOps-команд.

Но даже при раздельной, слоновьей диете мы имеем неплохие шансы на перенасыщение IT-ландшафта. В этот момент стоит остановиться, выдохнуть и посмотреть в сторону low-code engineering platform.

Многих разработчиков пугает перспектива появления тупика в карьере при уходе от непосредственного написания кода в сторону перетаскивания стрелочек в UI-интерфейсах low-code систем. Но появление станков не привело к исчезновению инженеров, а вывело их работу на новый уровень!

Давайте разбираться почему.

Анализ данных таких сфер, как: логистика, телеком-индустрия, медиаисследования, финансовый сектора бизнеса, всегда сопряжён со следующими вопросами:

  • Скорость проведения автоматизированного анализа;
  • Возможность проведения экспериментов без воздействия на основной поток производства данных;
  • Достоверность подготовленных данных;
  • Отслеживание изменений и версионирование;
  • Data proveance, Data lineage, CDC;
  • Быстрота доставки новых фич на продукционное окружение;
  • И пресловутое: стоимость разработки и поддержки.

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

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

Давайте проведём аналогию с низкоуровневыми и высокоуровневыми языками программирования. Переход от низкоуровневых языков в сторону высокоуровневых это переход от написания прямых директив на языке железа в сторону директив на языке людей. То есть добавление некоторого слоя абстракции. В таком случае переход на low-code-платформы с высокоуровневых языков программирования это переход от директив на языке людей в сторону директив на языке бизнеса. Если найдутся разработчики, которых этот факт опечалит, тогда опечалены они, возможно, ещё с того момента, как на свет появился Java Script, в котором используются функции сортировки массива. И эти функции, разумеется, имеют под капотом программную имплементацию другими средствами того же самого высокоуровнего программирования.

Следовательно, low-code это всего лишь появление ещё одного уровня абстракции.

Прикладной опыт использования low-code


Тема low-code достаточно широка, но сейчас я хотел бы рассказать о прикладном применении малокодовых концепций на примере одного из наших проектов.

Подразделение Big Data Solutions компании Неофлекс в большей степени специализируется на финансовом секторе бизнеса, cтроя хранилища и озёра данных и автоматизируя различную отчётность. В данной нише применение low-code давно стало стандартом. Среди прочих low-code-инструментов можно упомянуть средства для организации ETL-процессов: Informatica Power Center, IBM Datastage, Pentaho Data Integration. Или же Oracle Apex, выступающий средой быстрой разработки интерфейсов доступа и редактирования данных. Однако применение малокодовых средств разработки не всегда сопряжено с построением узконаправленных приложений на коммерческом стеке технологий с явно выраженной зависимостью от вендора.

С помощью low-code-платформ можно также организовывать оркестрацию потоков данных, создать data-science-площадки или, например, модули проверки качества данных.

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



Медиаисследования технологически нагруженная сфера бизнеса. Распознавание видеоряда, сбор данных с устройств, анализирующих просмотр, измерение активности на веб-ресурсах всё это подразумевает наличие у компании большого IT-штата и колоссального опыта в построении аналитических решений. Но экспоненциальный рост количества информации, числа и разнообразия ее источников заставляет постоянно прогрессировать IT-индустрию данных. Самым простым решением масштабирования уже функционирующей аналитической платформы Mediascope могло стать увеличение штата IT. Но гораздо более эффективное решение это ускорение процесса разработки. Одним из шагов, ведущих в эту сторону, может являться применение low-code-платформ.

На момент старта проекта у компании уже имелось функционирующее продуктовое решение. Однако реализация решения на MSSQL не могла в полной мере соответствовать ожиданиям по масштабированию функционала с сохранением приемлемой стоимости доработки.

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

В качестве фундамента для построения новой платформы данных, основанной на low-code-вычислениях, был выбран стек технологий Hadoop. Стандартом хранения данных стал HDFS с использованием файлов формата parquet. Для доступа к данным, находящимся в платформе, использован Hive, в котором все доступные витрины представлены в виде внешних таблиц. Загрузка данных в хранилище реализовывалась с помощь Kafka и Apache NiFi.

Lowe-code-инструмент в данной концепции был применён для оптимизации самой трудозатратной задачи в построении аналитической платформы задачи расчёта данных.



Основным механизмом для маппирования данных был выбран low-code-инструмент Datagram. Neoflex Datagram это средство для разработки трансформаций и потоков данных.
Применяя данный инструмент, можно обойтись без написания кода на Scala вручную. Scala-код генерируется автоматически с использованием подхода Model Driven Architecture.

Очевидный плюс такого подхода ускорение процесса разработки. Однако помимо скорости есть ещё и следующие достоинства:

  • Просмотр содержимого и структуры источников/приемников;
  • Отслеживание происхождения объектов потока данных до отдельных полей (lineage);
  • Частичное выполнение преобразований с просмотром промежуточных результатов;
  • Просмотр исходного кода и его корректировка перед выполнением;
  • Автоматическая валидация трансформаций;
  • Автоматическая загрузка данных 1 в 1.

Порог вхождения в low-code-решения для генерации трансформаций достаточно невысок: разработчику необходимо знать SQL и иметь опыт работы с ETL-инструментами. При этом стоит оговориться, что code-driven-генераторы трансформаций это не ETL-инструменты в широком понимании этого слова. Low-code-инструменты могут не иметь собственного окружения для выполнения кода. То есть сгенерированный код будет выполняться на том окружении, которое имелось на кластере ещё до инсталляции low-code-решения. И это, пожалуй, ещё один плюс в карму low-code. Так как в параллель с low-code-командой может работать классическая команда, реализующая функционал, например, на чистом Scala-коде. Втягивание доработок обеих команд в продуктив будет простым и бесшовным.

Пожалуй, стоит ещё отметить, что помимо low-code есть ещё и no-code решения. И по своей сути это разные вещи. Low-code в большей степени позволяет разработчику вмешиваться в генерируемый код. В случае с Datagram возможен просмотр и редактирование генерируемого кода Scala, no-code такой возможности может не предоставлять. Эта разница весьма существенна не только в плане гибкости решения, но и в плане комфорта и мотивации в работе дата-инженеров.

Архитектура решения


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



Источники данных в нашем случае весьма разнородны и многообразны:

  • Пиплметры (ТВ-метры) программно-аппаратные устройства, считывающие пользовательское поведение у респондентов телевизионной панели кто, когда и какой телеканал смотрел в домохозяйстве, которое участвует в исследовании. Поставляемая информация это поток интервалов смотрения эфира с привязкой к медиапакету и медиапродукту. Данные на этапе загрузки в Data Lake могут быть обогащены демографическими атрибутами, привязкой к геострате, таймзоне и другими сведениями, необходимыми для проведения анализа телепросмотра того или иного медиа продукта. Произведённые измерения могут быть использованы для анализа или планирования рекламных компаний, оценки активности и предпочтений аудитории, составления эфирной сетки;
  • Данные могут поступать из систем мониторинга потокового телевещания и замера просмотра контента видеоресурсов в интернете;
  • Измерительные инструменты в web-среде, среди которых как site-centric, так и user-centric счётчики. Поставщиком данных для Data Lake может служить надстройка браузера research bar и мобильное приложение со встроенным VPN.
  • Данные также могут поступать с площадок, консолидирующих результаты заполнения онлайн-анкет и итоги проведения телефонных интервью в опросных исследованиях компании;
  • Дополнительное обогащение озера данных может происходить за счёт загрузки сведений из логов компаний-партнёров.

Имплементация as is загрузки из систем-источников в первичный staging сырых данных может быть организована различными способами. В случае использования для этих целей low-code возможна автоматическая генерация сценариев загрузки на основе метаданных. При этом нет необходимости спускаться на уровень разработки source to target мэппингов. Для реализации автоматической загрузки нам необходимо установить соединение с источником, после чего определить в интерфейсе загрузки перечень сущностей, подлежащих загрузке. Создание структуры каталогов в HDFS произойдёт автоматически и будет соответствовать структуре хранения данных в системе-источнике.

Однако в контексте данного проекта эту возможность low-code-платформы мы решили не использовать в силу того, что компания Mediascope уже самостоятельно начала работу по изготовлению аналогичного сервиса на связке Nifi + Kafka.

Стоит сразу обозначить, что данные инструменты являются не взаимозаменяющими, а скорее дополняющими друг друга. Nifi и Kafka способны работать как в прямой (Nifi -> Kafka), так и в обратной (Kafka -> Nifi) связке. Для платформы медиаисследований использовался первый вариант связки.



В нашем случае найфаю требовалось обрабатывать различные типы данных из систем-источников и пересылать их брокеру Kafka. При этом направление сообщений в определённый топик Kafka производилось посредством применения Nifi-процессоров PublishKafka. Оркестрация и обслуживание этих pipeline`ов производится в визуальном интерфейсе. Инструмент Nifi и использование связки Nifi + Kafka также можно назвать low-code-подходом к разработке, обладающим низким порогом вхождения в технологии Big Data и ускоряющим процесс разработки приложений.

Следующим этапом в реализации проекта являлось приведение к формату единого семантического слоя детальных данных. В случае наличия у сущности исторических атрибутов расчёт производится в контексте рассматриваемой партиции. Если же сущность не является исторической, то опционально возможен либо пересчёт всего содержимого объекта, либо вовсе отказ от пересчёта этого объекта (вследствие отсутствия изменений). На данном этапе происходит генерация ключей для всех сущностей. Ключи сохраняются в соответствующие мастер-объектам справочники Hbase, содержащие соответствие между ключами в аналитической платформе и ключами из систем-источников. Консолидация атомарных сущностей сопровождается обогащением результатами предварительного расчёта аналитических данных. Framework`ом для расчёта данных являлся Spark. Описанный функционал приведения данных к единой семантике был реализован также на основе маппингов low-code-инструмента Datagram.

В целевой архитектуре требовалось обеспечить наличие SQL-доступа к данным для бизнес-пользователей. Для данной опции был использован Hive. Регистрация объектов в Hive производится автоматически при включении опции Registr Hive Table в low-code-инструменте.



Управление потоком расчёта


Datagram имеет интерфейс для построения дизайна потоков workflow. Запуск маппингов может осуществляться с использованием планировщика Oozie. В интерфейсе разработчика потоков возможно создание схем параллельного, последовательного или зависящего от заданных условий исполнения преобразований данных. Имеется поддержка shell scripts и java-программ. Также возможно использование сервера Apache Livy. Apache Livy используется для запуска приложений непосредственно из среды разработки.

В случае, если у компании уже есть собственный оркестратор процессов, возможно использование REST API для встраивания маппингов в уже имеющийся поток. Например, у нас имелся достаточно успешный опыт встраивания маппингов на Scala в оркестраторы, написанные на PLSQL и Kotlin. REST API малокодового инструмента подразумевает наличие таких операций, как генерация исполняемого года на основе дизайна маппинга, вызов маппинга, вызов последовательности маппингов и, разумеется, передача в URL параметров для запуска маппингов.

Наравне с Oozie возможно организовать поток расчёта средствами Airflow. Пожалуй, не буду долго останавливаться на сравнении Oozie и Airflow, а просто скажу, что в контексте работ по проекту медиаисследований выбор пал в сторону Airflow. Главными аргументами на этот раз оказались более активное сообщество, развивающее продукт, и более развитый интерфейс + API.



Airflow также хорош потому, что для описания процессов расчёта в нём используется многими любимый Python. Да и вообще, платформ управления рабочими процессами с открытым исходным кодом не так уж и много. Запуск и мониторинг выполнения процессов (в том числе с диаграммой Ганта) лишь добавляют очков в карму Airflow.

Форматом конфигурационного файла для запуска маппингов low-code-решения стал spark-submit. Произошло это по двум причинам. Во-первых, spark-submit позволяет напрямую запустить jar-файл из консоли. Во-вторых, он может содержать всю необходимую информацию для конфигурирования рабочего потока (что облегчает написание скриптов, формирующих Dag).
Наиболее часто встречающимся элементом рабочего потока Airflow в нашем случае стал SparkSubmitOperator.

SparkSubmitOperator позволяет запускать jar`ники упакованные маппинги Datagram с предварительно сформированными для них входными параметрами.

Следует упомянуть, что каждая задача Airflow выполняется в отдельном потоке и ничего не знает о других задачах. В связи с чем взаимодействие между задачами осуществляется с помощью управляющих операторов, таких как DummyOperator или BranchPythonOperator.

В совокупности использования low-code-решения Datagram в связке с универсализацией конфигурационных файлов (формирующих Dag) привело к существенному ускорению и упрощению процесса разработки потоков загрузки данных.

Расчёт витрин


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



Отдельным шагом подготовки витрин является валидация данных. Алгоритм валидации сопряжён с применением ряда математических science-моделей. Однако использование low-code-платформы позволяет разбить сложный алгоритм на ряд отдельных визуально считываемых маппингов. Каждый из маппингов выполняет узкую задачу. Вследствие чего возможен промежуточный дебаг, логирование и визуализация этапов подготовки данных.

Алгоритм валидации было решено дискретизировать на следующие подэтапы:

  • Построение регрессий зависимостей смотрения телесети в регионе со смотрением всех сетей в регионе за 60 дней.
  • Расчёт стьюдентизированных остатков (отклонения фактических значений от предсказанных регрессионной моделью) для всех точек регрессии и для расчетного дня.
  • Выборка аномальных пар регион-телесеть, где стьюдентизированный остаток расчетного дня превышает норму (заданную настройкой операции).
  • Пересчёт поправленного стьюдентизированного остатка по аномальным парам регион-телесеть для каждого респондента, смотревшего сеть в регионе с определением вклада данного респондента (величина изменения стьюдентизированного остатка) при исключении смотрения данного респондента из выборки.
  • Поиск кандидатов, исключение которых приводит стьюдентизированный остаток расчетного дня в норму;

Приведённый выше пример является подтверждением гипотезы о том, что у дата-инженера и так слишком много чего должно быть в голове И, если это действительно инженер, а не кодер, то страх профессиональной деградации при использовании low-code-инструментов у него должен окончательно отступить.

Что ещё может low-code?


Область применения low-code инструмента для пакетной и потоковой обработки данных без необходимости написания кода на Scala вручную не заканчивается.

Применение low-code в разработке datalake`ов для нас стало уже некоторым стандартом. Наверное, можно сказать, что решения на стеке Hadoop повторяют путь развития классических DWH, основанных на РСУБД. Малокодовые инструменты на стеке Hadoop могут решать, как задачи обработки данных, так и задачи построения конечных BI-интерфейсов. Причём нужно заметить, что под BI может пониматься не только репрезентация данных, но и их редактирование силами бизнес-пользователей. Данный функционал нами часто применяется при построении аналитических платформ для финансового сектора.



Среди прочего, с помощью low-code и, в частности, Datagram возможно решить задачу отслеживания происхождения объектов потока данных с атомарностью до отдельных полей (lineage). Для этого в low-code-инструменте имплементировано сопряжение с Apache Atlas и Cloudera Navigator. По сути, разработчику необходимо зарегистрировать набор объектов в словарях Atlas и ссылаться на зарегистрированные объекты при построении маппингов. Механизм отслеживания происхождения данных или анализ зависимостей объектов экономит большое количество времени при необходимости внесения доработок в алгоритмы расчёта. Например, при построении финансовой отчётности эта фишка позволяет комфортнее пережить период изменений законодательства. Ведь, чем качественнее мы осознаём межформенную зависимость в разрезе объектов детального слоя, тем меньше мы столкнёмся с внезапными дефектами и сократим количество реворков.



Data Quality & Low-code


Ещё одной задачей, реализованной low-code-инструментом на проекте компании Mediascope, стала задача класса Data Quality. Особенностью реализации конвейера проверки данных для проекта исследовательской компании было отсутствие влияния на работоспособность и скорость работы основного потока расчёта данных. Для возможности оркестрирования независимыми потоками проверки данных применялся уже знакомый Apache Airflow. По мере готовности каждого шага производства данных параллельно происходил запуск обособленной части DQ-конвейера.

Хорошей практикой считается наблюдение за качеством данных с момента их зарождения в аналитической платформе. Имея информацию о метаданных, мы можем уже с момента попадания информации в первичный слой проверять соблюдение базовых условий not null, constraints, foreign keys. Этот функционал реализован на основе автоматически генерируемых мэппингов семейства data quality в Datagram. Кодогенерация в данном случае также основывается на метаданных модели. На проекте компании Mediascope сопряжение происходило с метаданными продукта Enterprise Architect.

Благодаря сопряжению low-code-инструмента и Enterprise Architect автоматически были сгенерированы следующие проверки:

  • Проверка присутствия значений null в полях с модификатором not null;
  • Проверка присутствия дублей первичного ключа;
  • Проверка внешнего ключа сущности;
  • Проверка уникальности строки по набору полей.

Для более сложных проверок доступности и достоверности данных был создан мэппинг с Scala Expression, принимающий на вход внешний Spark SQL-код проверки, подготовленной силами аналитиков в Zeppelin.



Разумеется, к автогенерации проверок необходимо приходить постепенно. В рамках описываемого проекта этому предшествовали следующие шаги:
  • DQ, реализованные в блокнотах Zeppelin;
  • DQ, встроенные в мэппинг;
  • DQ в виде отдельных массивных мэппингов, содержащих целый набор проверок под отдельную сущность;
  • Универсальные параметризованные DQ-мэппинги, принимающие на вход информацию о метаданных и бизнес-проверках.

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

  • Все проверки метаданных генерируются автоматически при изменении модели в EA;
  • Проверки доступности данных (определение наличия каких-либо данных на момент времени) могут быть сгенерированы на основе справочника, хранящего ожидаемый тайминг появления очередной порции данных в разрезе объектов;
  • Бизнес-проверки достоверности данных создаются силами аналитиков в notebook`ах Zeppelin. Откуда направляются прямиком в настроечные таблицы модуля DQ на продукционном окружении.

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

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

Вместо заключения


Преимущество применения low-code очевидно. Разработчикам не нужно разрабатывать приложение с нуля. А освобождённый от дополнительных задач программист даёт результат быстрее. Скорость, в свою очередь, высвобождает дополнительный ресурс времени на разрешение вопросов оптимизации. Следовательно, в данном случае можно рассчитывать на наличие более качественного и быстрого решения.

Разумеется, low-code не панацея, и волшебство само по себе не случится:

  • Малокодовая индустрия проходит стадию крепчания, и пока в ней нет однородных индустриальных стандартов;
  • Многие low-code-решения не бесплатны, и их приобретение должно быть осознанным шагом, сделать который следует при полной уверенности финансовой выгоды от их использования;
  • Многие малокодовые решения не всегда хорошо дружат с GIT / SVN. Либо неудобны в использовании в случае сокрытия генерируемого кода;
  • При расширении архитектуры может потребоваться доработка малокодового решения что, в свою очередь, провоцирует эффект привязанности и зависимости от поставщика low-code-решения.
  • Должный уровень обеспечения безопасности возможен, но весьма трудозатратен и сложен в реализации движков low-code-систем. Малокодовые платформы должны выбираться не только по принципу поиска выгоды от их использования. При выборе стоит задаться вопросами наличия функционала управлением доступа и делегированием/эскалацией идентификационных данных на уровень всего IT-ландшафта организации.



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

Если один разработчик на low-code-платформе будет выполнять свою работу быстрее, чем два разработчика без low-code, то это даёт компании фору во всех отношениях. Порог вхождения в low-code-решения более низкий, чем в традиционные технологии, и это положительным образом сказывается на вопросе кадрового дефицита. При использовании малокодовых инструментов возможно ускорение взаимодействия между функциональными командами и более быстрое принятие решений о корректности выбранного пути data-science-исследований. Низкоуровневые платформы могут выступить причиной цифровой трансформации организации, поскольку производимые решения могут быть доступны к пониманию нетехническим специалистам (в частности, бизнес-пользователям).

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

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

Категории

Последние комментарии

© 2006-2020, personeltest.ru