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

Блог компании skillbox

Перевод Как проходить собеседование на дата-сайентиста в Amazon в 2021 году

04.02.2021 18:19:53 | Автор: admin
image

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

В: У пары есть двое детей, и пара знает, что один из детей мальчик. Какова вероятность того, что другой ребенок будет мальчиком?

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

В: Объясните, что такое p-значение.

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

Многословный ответ, по той причине, что значение p очень специфично по значению и часто понимается неправильно.

Более простое определение p-значения: Это вероятность того, что наблюдаемая статистика возникнет случайно, с учетом распределения выборки.

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

В: Есть 4 красных и 2 синих шара, какова вероятность того, что они будут одинаковыми в двух выборах?

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

  • Вероятность 2 красных = (4/6) * (3/6) = 1/3 или 33%
  • Вероятность 2 синих = (2/6) * (1/6) = 1/18 или 5,6%

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

Q: Опишите дерево, SVM и случайный лес. Расскажите об их преимуществах и недостатках.

Деревья решений: древовидная модель, используемая для моделирования решений на основе одного или нескольких условий.

Плюсы: легко реализовать, интуитивно понятно, обрабатывает пропущенные значения.
Минусы: высокая дисперсия, неточность

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

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

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

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

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

Нам нужно сделать некоторые предположения по этому вопросу, прежде чем мы сможем на него ответить. Предположим, что есть два возможных места для покупки определенного товара на Amazon, и вероятность найти его в месте A составляет 0,6, а B 0,8. Вероятность найти товар на Amazon можно объяснить так:

Мы можем переформулировать вышеизложенное как P (A) = 0,6 и P (B) = 0,8. Кроме того, давайте предположим, что это независимые события, а это означает, что вероятность одного события не зависит от другого. Затем мы можем использовать формулу

P (A или B) = P (A) + P (B) P (A и B)
P (A или B) = 0,6 + 0,8 (0,6 * 0,8)
P (A или B) = 0,92

В: Если есть 8 шариков равного веса и 1 шарик, который весит немного больше (всего 9 шариков), сколько взвешиваний необходимо, чтобы определить, какой шарик самый тяжелый?



Потребуются два взвешивания (см. Части A и B выше):

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

Q: Что такое переобучение?

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

Q: У нас есть две модели: одна с точностью 85%, другая 82%. Какой ты выберешь?

Если нам важна лишь точность модели, то ответ 85%. Но если бы об этом спросил интервьюер, вероятно, стоит узнать, в каком контексте задан вопрос, т.е. что модель пробует предсказать. Это даст нам лучшее представление о том, действительно ли метрикой оценки должна быть точность или другая метрика, такая как recall или оценка f1.

Q: Что такое наивный байесовский алгоритм?

Наивный байесовский классификатор популярный классификатор, используемый в Data Science. Идея, лежащая в основе этого, основана на теореме Байеса:

image

Говоря простым языком, это уравнение используется для ответа на следующий вопрос. Какова вероятность y (моей выходной переменной) при X (моих входных переменных)? И из-за наивного предположения, что переменные независимы для данного класса, вы можете сказать, что:

image

Кроме того, убрав знаменатель, мы можем сказать, что P (y | X) пропорционально правой части.

image

Поэтому цель найти класс с максимальной пропорциональной вероятностью.


Q: Как изменение основного членского взноса повлияет на рынок?

Я не уверен на 100% в ответе на этот вопрос, но постараюсь сделать все возможное!

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

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

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

Спасибо за внимание!

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

Надеюсь, все это поможет вам в подготовке к вашему путешествию в мир Data Science!

Комментарий к статье Вячеслава Архипова, специалиста в области Data Science AR-стартапа Banuba и консультанта по учебной программе онлайн-университета Skillbox.

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

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

Ну например:
1) Как можно получить случайную величину с заданным распределением, имея в наличие реализацию нормальной СВ?
2) Что такое корреляция случайных величин и какова ее геометрическая интерпретация?
3) Как можно бороться с переобучением?
4) В чем преимущество метода главных компонент по сравнению, например, с процессом Грама-Шмидта?
5) Как можно улучшить классификацию, имея набор слабых классификаторов?

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

Онлайн-митап сообщества разработчиков MSK VUE.JS

20.07.2020 14:14:41 | Автор: admin
image

23 июля приглашаем на онлайн-митап сообщества разработчиков MSK VUE.JS.

В программе митапа:

  • Разработка конструктора отчетов c Cube.js;
  • 5 действенных техник оптимизации vue-приложений;
  • Решение проблем REST API при помощи GraphQL.

Зарегистрироваться

О митапе


Разработчик Cube.js Леонид Яковлев расскажет, как сделать конструктор отчетов при помощи cube.js на бэкенде. Подробно поговорит, что такое query builder, какие у него преимущества и покажет пример простого queryBuilder

Руководитель AFFINAGE Игорь Яковлев поделится собственными техниками, инсайтами и лайфхаками, как разрабатывать по-настоящему быстрые vue-приложения.

Разработчик Московской биржи Юлия Кузнецова расскажет, как GraphQL помогает решать проблемы REST API архитектуры и покажет, как это сделать на примере Vue Apollo.

Об экспертах


Леонид Яковлев разработчик в команде Developer Relations and Community фреймворка Cube.js.

Игорь Яковлев руководитель аутсорспродакшена по фронтенду AFFINAGE.

Юлия Кузнецова старший разработчик Московской биржи.

О MSK VUE.JS


MSK VUE.JS сообщество разработчиков Vue.js, которое регулярно проводит митапы, чтобы делиться опытом, обсуждать перспективы и строить комьюнити.

По теме:


Подробнее..

Перевод 5 приемов и хитростей для работы с SSH и кое-что еще

24.11.2020 20:17:07 | Автор: admin
image

В этой статье мы поговорим о полезных приемах и командах при работе с SSH. А именно:
  • Как использовать двухфакторную аутентификацию для SSH-подключений.
  • Безопасное использование проброса ключа (agent forwarding).
  • Завершение зависшей сессии.
  • Оставляем терминал открытым при выходе или разрыве связи.
  • Расшариваем удаленный терминал с другом (без Zoom!).


Многофакторная аутентификация


Для того, чтобы активировать ее, есть целых пять способов.

1. Обновляем OpenSSH и используем аппаратные токены. В феврале этого года в OpenSSH была добавлена поддержка токенов FIDO U2F (Universal Second Factor). Что сказать это отлично, но есть один нюанс.

Дело в том, что обновление добавляет новые типы ключей для поддержки токенов. Но использовать эту функцию можно лишь при обновлении клиента и сервера до версии 8.2 или более поздней. Текущую версию клиента можно проверить для этого есть команда ssh -V. Что касается удаленного сервера, то здесь стоит воспользоваться nc [servername] 22.

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

$ ssh-keygen -t ecdsa-sk -f ~/.ssh/id_ecdsa_sk.

Что она делает? Создает открытый и закрытый ключи, которые привязаны к U2F токену. Закрытый ключ на токене используется для расшифровки закрытого ключа, который хранится на диске.

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

$ ssh-keygen -t ecdsa-sk -O resident -f ~/.ssh/id_ecdsa_sk.

Ну а для того, чтобы перенести ключевой файл на новую машину, требуется вставить носитель и выполнить команду $ ssh-add -K. Помните токен нужно активировать при подключении.

2. Используем PIV+PKCS11 и Yubikey. В том случае, если нужно подключаться к машинам, где установлены более ранние версии SSH-сервера, есть еще одна возможность. Вот подробная инструкция U2F+SSH с PIV/PKCS11. Немного сложно, но оно стоит того.

3. Третий способ использование yubikey-agent. Вот сам SSH-агент для Yubikeys, его создал Filipo Valsorda.

4. Touch ID и sekey. Еще один способ заключается в использовании Sekey агента с открытым исходным кодом. Он сохраняет закрытые ключи в системе secure enclave для MacOS и дает возможность запускать функцию подписания посредством Touch ID.

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

Безопасный проброс ключа (agent forwarding)


Для чего используется проброс ключа? Для доступа удаленного хоста к локальному SSH-агенту пользователя. Дело в том, что когда SSH-клиент использует проброс ключа (чаще всего активируется ssh -A), то в ходе соединения присутствуют 2 канала. Первый это интерактивная сессия пользователя, второй канал проброса ключа.

Локальный SSH-агент создает IPC-сокет, который подключается через этот канал к удаленному хосту. Это достаточно опасно, поскольку у пользователя с правами root а удаленном хосте есть доступ к локальному SSH-агенту подключившегося пользователя. Таким образом, его можно использовать для доступа к ресурсам сети от имени этого пользователя. И если работать со стандартным SSH-агентом, о проблеме не узнать. Но вот с U2F-ключом или Sekey эту проблему можно убрать.

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

Выход из подвисшей SSH-сессии


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

1. Автоматически при разрыве сети. Для этого в файл SSH-конфигурации, .ssh/config, необходимо добавить:
ServerAliveInterval 5
ServerAliveCountMax 1


В этом случае ssh станет проверять соединение, отправляя echo-запросы на удаленный хост через определенные промежутки времени. Они задаются параметром ServerAliveInterval. Если без ответа остается больше, чем ServerAliveCountMax запросов, SSH закрывает соединение.

2. Разрыв сессии. ssh использует символ ~ в качестве управляющей последовательности по умолчанию. Команда ~ закрывает текущее соединение и возвращает в терминал.

Кроме того, команда ~? Выводит весь список команд, которые можно использовать в текущей сессии. Если у вас установлено несколько раскладок, то придется нажимать кнопку ~ дважды для отправки символа.

Оставляем терминал на удаленном хосте открытым


Есть два варианта для сохранения сессии во время переключения между сетями.

1. Использование Mosh или Eternal Terminal

Если нужно надежное и не закрывающееся соединение, даже во время переключения между сетями, то есть выход нужно использовать Mosh mobile shell. Mosh называют защищенную оболочку, которая использует SSH для инициализации сессии (handshake). После этого она переключается на собственный зашифрованный канал, который весьма стабилен. Он, например, может обрабатывать разные ситуации, включая разрывы связи, изменение IP-адреса устройства, большие лаги при передаче данных и все прочее. Все это благодаря UDP и протоколу синхронизации, который использует Mosh.

Для работы с ним нужно, прежде всего, установить его как на сервере, так и клиенте, открыв порты с 60000 по 61000 для входящего UDP трафика на вашем удаленном хосте. После этого нужно просто набрать mosh user@server для подключения.

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

2. Использование tmux. Для того, чтобы подключаться и отключаться при необходимости, сохраняя ту же сессию на удаленном хосте, стоит использовать мультиплексор терминала, который называется tmux. В том случае, если SSH-соединение отваливается, нужно снова подключиться и набрать tmux attach. После этого пользователь возвращается в сессию tmux.

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

Расшариваем удаленный терминал


Бывают ситуации, когда необходимо расшарить SSH-сессию например, во время решения сложных проблем с серверами. Лучший способ сделать это tmux. Для решения задачи нужно сделать вот что:
  • Убедиться в том, что tmux установлен на сервере в DMZ (или локации, к которой нужно подключиться).
  • Обоим пользователям требуется подключиться к серверу через SSH с одним и тем же аккаунтом.
  • Один из пользователей должен запустить tmux для создания tmux-сессии.
  • Второй пользователь выполняет команду tmux attach.
  • Все готово!

Если же нужна тонкая настройка мульти пользовательских сессий, стоит воспользоваться tmate. Это улучшенный форк tmux.

Советы от эксперта


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

Проброс TCP-портов


У ssh есть два полезных параметра: -L и -R.

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

После параметра -L указывается аргумент в следующем виде:

ssh -L XXX:server1:YYY login@server2

Здесь server2 удаленный сервер, на который мы заходим по ssh, login имя пользователя, под которым мы заходим на удаленный сервер, XXX номер порта, который надо организовать на локальном компьютере, server1 хост, на который надо пробросить соединение с этого порта, и наконец YYY порт, на который надо пробросить это соединение.

Рассмотрим два примера.

Пример 1.

  1. Мы находимся на сервере spb.company1.ru, и хотим протестировать веб-приложение, которое обращается к базе по адресу central-db.company1.ru
  2. Эта база доступна только с сервера moscow.company1.ru, на порту 9999
  3. Мы организуем проброс локального порта 55555 к базе данных через ssh-туннель следующим образом: ssh -L 55555:central-db.company1.ru:9999 login@moscow.company1.ru
  4. После этого разворачиваем на нашем локальном сервере веб-приложение, и в качестве базы указыаем не central-db.company1.ru:9999, а localhost:55555 это соединение будет проброшено на сервер moscow.company1.ru, и уже этот сервер выполнит соединение с базой данных на хосте central-db.company1.ru, порт 9999

Пример 2.

  1. Мы находимся на сервере spb.company1.ru, и хотим показать заказчику тестовый веб-сайт по адресу moscow.company1.ru, порт 5000.
  2. К этому сайту нет доступа из Интернета, есть только внутренний доступ с того же хоста, где он развернут, т. е. с moscow.company1.ru
  3. Мы организуем проброс локального порта 80 через ssh-туннель следующим образом ssh -L 80:localhost:5000 login@moscow.company1.ru
  4. Если теперь пользователь зайдет браузером по ссылке spb.company1.ru, то соединение будет проброшено через ssh-туннель к серверу moscow.company1.ru, и уже этот сервер выполнит установку соединения по адресу localhost:5000, т. е. к нашему тестовому веб-сайту.

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

После параметра -R указывается аргумент в следующем виде:

ssh -R XXX:server1:YYY login@server2

Здесь server2 удаленный сервер, на который мы заходим по ssh, login имя пользователя, под которым мы заходим на удаленный сервер, XXX номер порта, который надо организовать на удаленном сервере, server1 хост, на который надо пробросить соединение с удаленного сервера, и наконец YYY порт, на который надо пробросить это соединение.

Рассмотрим два примера.

Пример 1.

  • Мы находимся на сервере moscow.company1.ru, и с этого сервера доступна база данных на сервере central-db.company1.ru, на порту 9999.
  • Мы разворачиваем веб-приложение на сервере spb.company1.ru, и с этого сервера база данных недоступна.
  • Мы организуем проброс порта с сервера spb.company1.ru к базе данных следующим образом: ssh -R 55555:central-db.company1.ru:9999 login@spb.company1.ru
  • После этого мы разворачиваем на сервере spb.company1.ru наше веб-приложение, но в качестве базы указываем не central-db.company1.ru:9999, поскольку этот сервер нам недоступен, а localhost:55555 это соединение будет проброшено на нашу локальную машину через ssh-туннель, и далее локальная машина установит соединение на сервер central-db.company1.ru, порт 9999.

Пример 2.

  • Мы находимся на сервере moscow.company1.ru, и на нашем сервере развернут тестовый веб-сайт, на порту 5000.
  • Этот тестовый веб-сайт доступен только локально, соединения из Интернета к нему запрещены, но мы хотим продемонстрировать этот сайт заказчику, который может заходить веб-браузером на сервер spb.company1.ru
  • Мы организуем проброс порта с сервера spb.company1.ru следующим образом: ssh -R 80:localhost:5000 login@spb.company1.ru
  • Если теперь пользователь зайдет браузером по ссылке spb.company1.ru, то соединение будет проброшено через ssh-туннель на наш локальный сервер moscow.company1.ru, и уже с него будет установлено соединение на localhost:5000 то есть к нашему тестовому веб-сайту.

А какими хитростями можете поделиться вы?

По теме:

Подробнее..

Перевод Git, я хочу все отменить! Команды исправления допущенных ошибок

25.12.2020 14:07:02 | Автор: admin
image

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

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

Черт, я сделал что-то не то. Дайте мне волшебную машину времени!

git reflog
# you will see a list of every thing you've
# done in git, across all branches!
# each one has an index HEAD@{index}
# find the one before you broke everything
git reset HEAD@{index}
# magic time machine


image

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

Я сделал коммит, но сразу же заметил ошибку, ее нужно исправить!

# make your change
git add . # or add individual files
git commit --amend --no-edit
# now your last commit contains that change!
# WARNING: never amend public commits


Команда дает возможность поправить неприятные мелочи когда вы что-то закоммитили, а потом увидели проблему вроде отсутствующего пробела после знака "=". Да, есть возможность внести изменения новым коммитом, объединив два варианта при помощи rebase -i. Но это долгий путь.

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

Хочу изменить сообщение последнего коммита!

git commit --amend
# follow prompts to change the commit message


Это просто глупые требования к оформлению сообщений.

Я случайно закоммитил в мастер, хотя это должен был в новую ветку!

# create a new branch from the current state of master
git branch some-new-branch-name
# remove the last commit from the master branch
git reset HEAD~ --hard
git checkout some-new-branch-name
# your commit lives in this branch now :)


Если вы уже закоммитили в публичную ветку, команды не сработают. В этом случае поможет git reset HEAD@{укажите количество коммитов, на которое нужно вернуться} вместо HEAD~.

Ну вот, я ошибочно закоммитил не в ту ветку

# undo the last commit, but leave the changes available
git reset HEAD~ --soft
git stash
# move to the correct branch
git checkout name-of-the-correct-branch
git stash pop
git add . # or add individual files
git commit -m "your message here";
# now your changes are on the correct branch


Есть еще один способ, который использует большое количество разработчиков это cherry-pick.

git checkout name-of-the-correct-branch
# grab the last commit to master
git cherry-pick master
# delete it from master
git checkout master
git reset HEAD~ --hard


Мне нужно запустить diff, но ничего не получается

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

git diff --staged

В общем, это не баг, а фича, но она чертовски неочевидная \_()_/

Мне срочно нужно отменить коммит, который сделан 5 коммитов назад

# find the commit you need to undo
git log
# use the arrow keys to scroll up and down in history
# once you've found your commit, save the hash
git revert [saved hash]
# git will create a new commit that undoes that commit
# follow prompts to edit the commit message
# or just save and commit


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

Кроме того, откатить можно не только коммит, но и целый файл. Правда, это уже будут другие команды

Отменить изменения в файле

А вот и они, эти другие команды.

# find a hash for a commit before the file was changed
git log
# use the arrow keys to scroll up and down in history
# once you've found your commit, save the hash
git checkout [saved hash] -- path/to/file
# the old version of the file will be in your index
git commit -m "Wow, you don't have to copy-paste to undo"


Когда я впервые нашел эту возможность, это было КРУТО, КРУТО, К-Р-У-Т-О. Но если задуматься почему именно checkout лучший вариант для отмены изменений в файле? :shakes-fist-at-linus-torvalds:

Все, я сдаюсь

cd ..
sudo rm -r fucking-git-repo-dir
git clone https://some.github.url/fucking-git-repo-dir.git
cd fucking-git-repo-dir


Спасибо Eric V. За этот способ. И все жалобы по поводу использования sudo адресуйте ему.

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

# get the lastest state of origin
git fetch origin
git checkout master
git reset --hard origin/master
# delete untracked files and directories
git clean -d --force
# repeat checkout/reset/clean for each borked branch


Внимание! Эта статья не является исчерпывающим руководством. И да, есть и другие способы сделать то же самое, причем еще лучше. Но я пришел именно к этим вариантам методом проб и ошибок. Потом у меня появилась сумасшедшая идея поделиться находками. Берите это или уходите!

image

Комментарий эксперта

Даниил Пилипенко, директор центра подбора IT-специалистов SymbioWay и евангелист бэкенд-направления онлайн-университета Skillbox, дополнил перевод мнением о Git и его актуальности для разработчиков.

Git появился в 2005-ом году, и он далеко не сразу занял рынок. Помню, когда мы ещё в 2008-ом году в команде разработчиков внедряли SVN. И даже в 2012-ом одна близкая ко мне компания усиленно внедряла Mercurial. С годами для многих стало очевидным, что Git это лучшая система контроля версий, и её теперь используют практически все разработчики.

Если вы начинающий разработчик и собираетесь устраиваться на работу, обязательно изучите Git! Вы должны знать, что такое система контроля версий и зачем она нужна, что такое коммит, ветка, как клонировать репозиторий и отправлять сделанные изменения на сервер, как получать новые изменения с сервера, как делать merge, какие бывают виды reset. Поначалу эта тема вам может показаться непонятной и сложной, но вам нужно лишь привыкнуть пользоваться Git, и отвыкнуть вы уже не сможете.
Подробнее..

Перевод Регулярные выражения Python для новичков что это, зачем и для чего

14.04.2021 14:22:42 | Автор: admin
image

За последние несколько лет машинное обучение, data science и связанные с этими направлениями отрасли очень сильно шагнули вперед. Все больше компаний и просто разработчиков используют Python и JavaScript для работы с данными.

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

Кстати, свои советы по некоторым функциям добавил Алексей Некрасов лидер направления Python в МТС, программный директор направления Python в Skillbox. Чтобы было понятно, где перевод, а где комментарии, последние мы выделим цитатой.

Зачем нужны регулярные выражения?


Они помогают быстро решить самые разные задачи при работе с данными:
  • Определить нужный формат данных, включая телефонный номер или e-mail адрес.
  • Разбивать строки на подстроки.
  • Искать, извлекать и заменять символы.
  • Быстро выполнять нетривиальные операции.

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

Когда регулярные выражения не нужны? Когда есть аналогичная встроенная в Python функция, а таких немало.

А что там с регулярными выражениями в Python?


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

import re

Что касается самых востребованных методов, предоставляемых модулем, то вот они:

  • re.match()
  • re.search()
  • re.findall()
  • re.split()
  • re.sub()
  • re.compile()

Давайте рассмотрим каждый из них.

re.match(pattern, string)

Метод предназначен для поиска по заданному шаблону в начале строки. Так, если вызвать метод match() на строке AV Analytics AV с шаблоном AV, то его получится успешно завершить.

import reresult = re.match(r'AV', 'AV Analytics Vidhya AV')print(result) Результат:<_sre.SRE_Match object at 0x0000000009BE4370>

Здесь мы нашли искомую подстроку. Для вывода ее содержимого используется метод group(). При этом используется r перед строкой шаблона, чтобы показать, что это raw-строка в Python.

result = re.match(r'AV', 'AV Analytics Vidhya AV')print(result.group(0)) Результат:AV

Окей, теперь давайте попробуем найти Analythics в этой же строке. У нас ничего не получится, поскольку строка начинается на AV, метод возвращает none:

result = re.match(r'Analytics', 'AV Analytics Vidhya AV')print(result) Результат:None

Методы start() и end() используются для того, чтобы узнать начальную и конечную позицию найденной строки.

result = re.match(r'AV', 'AV Analytics Vidhya AV')print(result.start())print(result.end()) Результат:02

Все эти методы крайне полезны в ходе работы со строками.

re.search(pattern, string)

Этот метод похож на match(), но его отличие в том, что ищет он не только в начале строки. Так, search() возвращает объект, если мы пробуем найти Analythics.

result = re.search(r'Analytics', 'AV Analytics Vidhya AV')print(result.group(0)) Результат:Analytics

Что касается метода search (), то он ищет по всей строке, возвращая, впрочем, лишь первое найденное совпадение.

re.findall(pattern, string)

Здесь у нас возврат всех найденных совпадений. Так, у метода findall() нет никаких ограничений на поиск в начале или конце строки. Например, если искать AV в строке, то мы получим возврат всех вхождений AV. Для поиска рекомендуется использовать как раз этот метод, поскольку он умеет работать как re.search(), так и как re.match().

result = re.findall(r'AV', 'AV Analytics Vidhya AV')print(result) Результат:['AV', 'AV']

re.split(pattern, string, [maxsplit=0])

Этот метод разделяет строку по заданному шаблону.

result = re.split(r'y', 'Analytics')print(result) Результат:['Anal', 'tics']

В указанном примере слово Analythics разделено по букве y. Метод split() здесь принимает и аргумент maxsplit со значением по умолчанию, равным 0. Таким образом он разделяет строку столько раз, сколько это возможно. Правда, если указать этот аргумент, то разделение не может быть выполнено более указанного количества раз. Вот несколько примеров:

result = re.split(r'i', 'Analytics Vidhya')print(result) Результат:['Analyt', 'cs V', 'dhya'] # все возможные участки. result = re.split(r'i', 'Analytics Vidhya', maxsplit=1)print(result) Результат:['Analyt', 'cs Vidhya']

Здесь параметр maxsplit установлен равным 1, в результате чего строка разделена на две части вместо трех.

re.sub(pattern, repl, string)

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

result = re.sub(r'India', 'the World', 'AV is largest Analytics community of India')print(result) Результат:'AV is largest Analytics community of the World'

re.compile(pattern, repl, string)

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

pattern = re.compile('AV')result = pattern.findall('AV Analytics Vidhya AV')print(result)result2 = pattern.findall('AV is largest analytics community of India')print(result2) Результат:['AV', 'AV']['AV']

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

  • . Один любой символ, кроме новой строки \n.
  • ? 0 или 1 вхождение шаблона слева
  • + 1 и более вхождений шаблона слева
  • * 0 и более вхождений шаблона слева
  • \w Любая цифра или буква (\W все, кроме буквы или цифры)
  • \d Любая цифра [0-9] (\D все, кроме цифры)
  • \s Любой пробельный символ (\S любой непробельный символ)
  • \b Граница слова
  • [..] Один из символов в скобках ([^..] любой символ, кроме тех, что в скобках)
  • \ Экранирование специальных символов (\. означает точку или \+ знак плюс)
  • ^ и $ Начало и конец строки соответственно
  • {n,m} От n до m вхождений ({,m} от 0 до m)
  • a|b Соответствует a или b
  • () Группирует выражение и возвращает найденный текст
  • \t, \n, \r Символ табуляции, новой строки и возврата каретки соответственно

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

Несколько примеров использования регулярных выражений


Пример 1. Возвращение первого слова из строки

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

result = re.findall(r'.', 'AV is largest Analytics community of India')print(result) Результат:['A', 'V', ' ', 'i', 's', ' ', 'l', 'a', 'r', 'g', 'e', 's', 't', ' ', 'A', 'n', 'a', 'l', 'y', 't', 'i', 'c', 's', ' ', 'c', 'o', 'm', 'm', 'u', 'n', 'i', 't', 'y', ' ', 'o', 'f', ' ', 'I', 'n', 'd', 'i', 'a']


Теперь сделаем то же самое, но чтобы в конечный результат не попал пробел, используем \w вместо (.)

result = re.findall(r'\w', 'AV is largest Analytics community of India')print(result) Результат:['A', 'V', 'i', 's', 'l', 'a', 'r', 'g', 'e', 's', 't', 'A', 'n', 'a', 'l', 'y', 't', 'i', 'c', 's', 'c', 'o', 'm', 'm', 'u', 'n', 'i', 't', 'y', 'o', 'f', 'I', 'n', 'd', 'i', 'a']

Ну а теперь проделаем аналогичную операцию с каждым словом. Используем при этом * или +.

result = re.findall(r'\w*', 'AV is largest Analytics community of India')print(result) Результат:['AV', '', 'is', '', 'largest', '', 'Analytics', '', 'community', '', 'of', '', 'India', '']

Но и здесь в результате оказались пробелы. Причина * означает ноль или более символов. "+" поможет нам их убрать.

result = re.findall(r'\w+', 'AV is largest Analytics community of India')print(result)Результат:['AV', 'is', 'largest', 'Analytics', 'community', 'of', 'India']

Теперь давайте извлечем первое слово с использованием
^:

result = re.findall(r'^\w+', 'AV is largest Analytics community of India')print(result) Результат:['AV']

А вот если использовать $ вместо ^, то получаем последнее слово, а не первое:

result = re.findall(r'\w+$', 'AV is largest Analytics community of India')print(result) Результат:[India] 

Пример 2. Возвращаем два символа каждого слова

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

result = re.findall(r'\w\w', 'AV is largest Analytics community of India')print(result) Результат:['AV', 'is', 'la', 'rg', 'es', 'An', 'al', 'yt', 'ic', 'co', 'mm', 'un', 'it', 'of', 'In', 'di']


Теперь пробуем извлечь два последовательных символа с использованием символа границы слова (\b):

result = re.findall(r'\b\w.', 'AV is largest Analytics community of India')print(result) Результат:['AV', 'is', 'la', 'An', 'co', 'of', 'In']

Пример 3. Возвращение доменов из списка адресов электронной почты.

На первом этапе возвращаем все символы после @:

result = re.findall(r'@\w+', 'abc.test@gmail.com, xyz@test.in, test.first@analyticsvidhya.com, first.test@rest.biz')print(result) Результат:['@gmail', '@test', '@analyticsvidhya', '@rest']

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

result = re.findall(r'@\w+.\w+', 'abc.test@gmail.com, xyz@test.in, test.first@analyticsvidhya.com, first.test@rest.biz')print(result) Результат:['@gmail.com', '@test.in', '@analyticsvidhya.com', '@rest.biz']

Второй вариант решения той же проблемы извлечение лишь домена верхнего уровня с использованием "()":

result = re.findall(r'@\w+.(\w+)', 'abc.test@gmail.com, xyz@test.in, test.first@analyticsvidhya.com, first.test@rest.biz')print(result) Результат:['com', 'in', 'com', 'biz']

Пример 4. Получение даты из строки

Для этого необходимо использовать \d

result = re.findall(r'\d{2}-\d{2}-\d{4}', 'Amit 34-3456 12-05-2007, XYZ 56-4532 11-11-2011, ABC 67-8945 12-01-2009')print(result) Результат:['12-05-2007', '11-11-2011', '12-01-2009']

Для того, чтобы извлечь только год, помогают скобки:

result = re.findall(r'\d{2}-\d{2}-(\d{4})', 'Amit 34-3456 12-05-2007, XYZ 56-4532 11-11-2011, ABC 67-8945 12-01-2009')print(result) Результат:['2007', '2011', '2009']

Пример 5. Извлечение слов, начинающихся на гласную

На первом этапе нужно вернуть все слова:

result = re.findall(r'\w+', 'AV is largest Analytics community of India')print(result) Результат:['AV', 'is', 'largest', 'Analytics', 'community', 'of', 'India']

После этого лишь те, что начинаются на определенные буквы, с использованием "[]":
result = re.findall(r'[aeiouAEIOU]\w+', 'AV is largest Analytics community of India')print(result) Результат:['AV', 'is', 'argest', 'Analytics', 'ommunity', 'of', 'India']

В полученном примере есть два укороченные слова, это argest и ommunity. Для того, чтобы убрать их, нужно воспользоваться \b, что необходимо для обозначения границы слова:
result = re.findall(r'\b[aeiouAEIOU]\w+', 'AV is largest Analytics community of India')print(result) Результат:['AV', 'is', 'Analytics', 'of', 'India']


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

result = re.findall(r'\b[^aeiouAEIOU]\w+', 'AV is largest Analytics community of India')print(result) Результат:[' is', ' largest', ' Analytics', ' community', ' of', ' India']

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

result = re.findall(r'\b[^aeiouAEIOU ]\w+', 'AV is largest Analytics community of India')print(result) Результат:['largest', 'community']

Пример 6. Проверка формата телефонного номера

В нашем примере длина номера 10 знаков, начинается он с 8 или 9. Для проверки списка телефонных номеров используем:

li = ['9999999999', '999999-999', '99999x9999'] for val in li:    if re.match(r'[8-9]{1}[0-9]{9}', val) and len(val) == 10:            print('yes')    else:            print('no') Результат:yesnono

Пример 7. Разбиваем строку по нескольким разделителям

Здесь у нас несколько вариантов решения. Вот первое:

line = 'asdf fjdk;afed,fjek,asdf,foo' # String has multiple delimiters (";",","," ").result = re.split(r'[;,\s]', line)print(result) Результат:['asdf', 'fjdk', 'afed', 'fjek', 'asdf', 'foo']

Кроме того, можно использовать метод re.sub() для замены всех разделителей пробелами:

line = 'asdf fjdk;afed,fjek,asdf,foo'result = re.sub(r'[;,\s]', ' ', line)print(result) Результат:asdf fjdk afed fjek asdf foo

Пример 8. Извлекаем данные из html-файла

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

Пример файла









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

result=re.findall(r'<td>\w+</td>\s<td>(\w+)</td>\s<td>(\w+)</td>',str)print(result)Output:[('Noah', 'Emma'), ('Liam', 'Olivia'), ('Mason', 'Sophia'), ('Jacob', 'Isabella'), ('William', 'Ava'), ('Ethan', 'Mia'), ('Michael', 'Emily')]


Комментарий Алексея

При написании любых regex в коде придерживаться следующих правил:

  • Используйте re.compile для любых более менее сложных и длинных регулярных выражениях. А также избегайте многократного вызова re.compile на один и тот же regex.
  • Пишите подробные регулярные выражения используя дополнительный аргумент re.VERBOSE. При re.compile используйте флаг re.VERBOSE пишите regex в несколько строк с комментариями о том что происходит. Смотрите документацию по ссылкам тут и тут.

Пример:
компактный вид

pattern = '^M{0,3}(CM|CD|D?C{0,3})(XC|XL|L?X{0,3})(IX|IV|V?I{0,3})$'re.search(pattern, 'MDLV')


Подробный вид

pattern = """    ^                   # beginning of string    M{0,3}              # thousands - 0 to 3 Ms    (CM|CD|D?C{0,3})    # hundreds - 900 (CM), 400 (CD), 0-300 (0 to 3 Cs),                        #            or 500-800 (D, followed by 0 to 3 Cs)    (XC|XL|L?X{0,3})    # tens - 90 (XC), 40 (XL), 0-30 (0 to 3 Xs),                        #        or 50-80 (L, followed by 0 to 3 Xs)    (IX|IV|V?I{0,3})    # ones - 9 (IX), 4 (IV), 0-3 (0 to 3 Is),                        #        or 5-8 (V, followed by 0 to 3 Is)    $                   # end of string    """re.search(pattern, 'M, re.VERBOSE)

Используйте named capture group для всех capture group, если их больше чем одна (?P...). (даже если одна capture, тоже лучше использовать).
regex101.com отличный сайт для дебага и проверки regex

При разработке регулярного выражения, нужно не забывать и про его сложность выполнения иначе можно наступить на те же грабли, что и относительно недавно наступила Cloudflare.
1 Noah Emma 2 Liam Olivia 3 Mason Sophia 4 Jacob Isabella 5 William Ava 6 Ethan Mia 7 Michael Emily
Подробнее..

Перевод Я спарсил больше 1000 топовых Github-профилей по машинному обучению и вот что я узнал

08.02.2021 12:21:23 | Автор: admin


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

Как я работал


Инструменты

Я использовал три инструмента для скрейпинга:
  • Beautiful Soup для извлечения URL всех репозиториев с тегом машинное обучение. Это Python библиотека, которая позволяет значительно упростить скрейпинг.
  • PyGithub позволяет извлекать информацию о пользователях. Это еще одна Python-библиотека для использования с Github API v3. Она дает возможность управлять различными Github-ресурсами (репозитории, профили пользователей, организации и т.п.) при помощи Python-скриптов.
  • Requests для извлечения информации о репозиториях и линков на профили контрибьюторов.

Методы

Я спарсил далеко не все, а лишь владельцев и 30 самых активных контрибьюторов 90 топовых репозиториев, которые оказались в результатах поиска.





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

new_profile.info()



Первые 13 параметров были получены отсюда.



Оставшиеся я взял из репозиториев пользователя:

  • total_stars общее количество звезд всех репозиториев
  • max_star максимальное количество звезд всех репозиториев
  • forks общее количество форков всех репозиториев
  • descriptions описания из всех репозиториев пользователя всех репо
  • contribution количество контрибуций за последний год




Визуализируем данные


Гистограммы

После очистки данных наступил черед самого интересного этапа: визуализации данных. Для этого я использовал Plotly.

import matplotlib.pyplot as pltimport numpy as npimport plotly.express as px # for plottingimport altair as alt # for plottingimport datapane as dp # for creating a report for your findings top_followers = new_profile.sort_values(by='followers', axis=0, ascending=False) fig = px.bar(top_followers,             x='user_name',             y='followers',             hover_data=['followers'],            )fig.show()

Вот что получилось.

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



Как видим, у llSourcell (Siraj Raval) больше всего фолловеров (36261). У второго по популярности количество фолловеров меньше в три раза (12682).

Мы можем пойти дальше и выяснить, что 1% профилей получил 41% всех фолловеров!

>>> top_n = int(len(top_followers) * 0.01)12>>> sum(top_followers.iloc[0: top_n,:].loc[:, 'followers'])/sum(top_followers.followers)0.41293075864408607

Далее визуализируем информацию по total_stars, max_star, forks при помощи логарифмической шкалы.

figs = [] # list to save all the plots and table features = ['followers',               'following',               'total_stars',               'max_star',               'forks',                'contribution']for col in features:    top_col = new_profile.sort_values(by=col, axis=0, ascending=False)        log_y = False     #change scale of y-axis of every feature to log except contribution    if col != 'contribution':        log_y = True            fig = px.bar(top_col,             x='user_name',             y=col,             hover_data=[col],             log_y = log_y            )        fig.update_layout({'plot_bgcolor': 'rgba(36, 83, 97, 0.06)'}) #change background coor        fig.show()        figs.append(dp.Plot(fig))

Получается вот так.

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

Корреляция

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

correlation = px.scatter_matrix(new_profile, dimensions=['forks', 'total_stars', 'followers',                                 'following', 'max_star','contribution'],                               title='Correlation between datapoints',                               width=800, height=800)correlation.show() corr = new_profile.corr() figs.append(dp.Plot(correlation))figs.append(dp.Table(corr))corr

Получается вот так и еще так.

Наиболее сильные положительные зависимости образуются между:
  • Максимальным количеством звезд и общим их количеством (0.939)
  • Количество форков и общим количеством звезд (0,929)
  • Количеством форков и количеством фолловеров (0,774)
  • Количеством фолловеров и общим количеством звезд (0,632)

Языки программирования


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

# Collect languages from all repos of al userslanguages = []for language in list(new_profile['languages']):    try:        languages += language    except:        languages += ['None']        # Count the frequency of each languagefrom collections import Counterocc = dict(Counter(languages)) # Remove languages below count of 10top_languages = [(language, frequency) for language, frequency in occ.items() if frequency > 10]top_languages = list(zip(*top_languages)) language_df = pd.DataFrame(data = {'languages': top_languages[0],                           'frequency': top_languages[1]}) language_df.sort_values(by='frequency', axis=0, inplace=True, ascending=False) language = px.bar(language_df, y='frequency', x='languages',      title='Frequency of languages') figs.append(dp.Plot(language)) language.show()

Соответственно, в топ-10 языков входят:

  • Python
  • JavaScript
  • HTML
  • Jupyter Notebook
  • Shell и т.п.

Местонахождение


Для того, чтобы понять, в каких частях света находятся владельцы профилей, нужно выполнить следующую задачу визуализировать местонахождение пользователей. Среди проанализированных профилей география указана для 31%. Для визуализации используем geopy.geocoders.Nominatim

from geopy.geocoders import Nominatimimport folium geolocator = Nominatim(user_agent='my_app') locations = list(new_profile['location']) # Extract lats and lonslats = []lons = []exceptions = [] for loc in locations:    try:        location = geolocator.geocode(loc)        lats.append(location.latitude)        lons.append(location.longitude)        print(location.address)    except:        print('exception', loc)        exceptions.append(loc)        print(len(exceptions)) # output: 17  # Remove the locations not found in maplocation_df = new_profile[~new_profile.location.isin(exceptions)] location_df['latitude'] = latslocation_df['longitude'] = lons

Ну а затем, для построения карты используем Plotlys scatter_geo

# Visualize with Plotly's scatter_geom = px.scatter_geo(location_df, lat='latitude', lon='longitude',                 color='total_stars', size='forks',                 hover_data=['user_name','followers'],                 title='Locations of Top Users')m.show() figs.append(dp.Plot(m))

По этой ссылке доступна оригинальная карта с зумом.

Описание репо и био пользователей


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

import stringimport nltkfrom nltk.corpus import stopwordsfrom nltk.tokenize import word_tokenizefrom nltk.stem import WordNetLemmatizerfrom nltk.tokenize import word_tokenizefrom wordcloud import WordCloud, STOPWORDSimport matplotlib.pyplot as plt nltk.download('stopwords')nltk.download('punkt')nltk.download('wordnet')       def process_text(features):  '''Function to process texts'''        features = [row for row in features if row != None]        text = ' '.join(features)                # lowercase    text = text.lower()     #remove punctuation    text = text.translate(str.maketrans('', '', string.punctuation))     #remove stopwords    stop_words = set(stopwords.words('english'))     #tokenize    tokens = word_tokenize(text)    new_text = [i for i in tokens if not i in stop_words]        new_text = ' '.join(new_text)        return new_text def make_wordcloud(new_text):  '''Function to make wordcloud'''        wordcloud = WordCloud(width = 800, height = 800,                background_color ='white',                min_font_size = 10).generate(new_text)         fig = plt.figure(figsize = (8, 8), facecolor = None)    plt.imshow(wordcloud)    plt.axis("off")    plt.tight_layout(pad = 0)     plt.show()        return fig    descriptions = []for desc in new_profile['descriptions']:    try:        descriptions += desc            except:        pass descriptions = process_text(descriptions) cloud = make_wordcloud(descriptions) figs.append(dp.Plot(cloud))



И то же самое для био

bios = []for bio in new_profile['bio']:    try:        bios.append(bio)            except:        pass      text = process_text(bios) cloud = make_wordcloud(text) figs.append(dp.Plot(cloud))



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

Выводы


Данные получены от пользователей и авторов 90 репозиториев с оптимальным соответствием ключу machine learning. Но гарантии того, что в список попали все ведущие владельцы профилей, эксперты по машинному обучению нет.

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

Ну и если нужно можете форкать код этой статьи и делать с ним что угодно, вот репо</a.

Комментарий к статье Вячеслава Архипова
, специалиста в области Data Science AR-стартапа Banuba и консультанта по учебной программе онлайн-университета Skillbox.

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

Хотелось бы обратить внимание на два факта:

1) несмотря на утверждение автора, что для визуализации показателей профиля используется логарифмическая шкала, на самом деле используются линейные шкалы. Это видно из приведенного листинга (из него следует, что логарифмическая шкала использовалась только для 'contribution'). Все графики выглядят, как построенные в линейной шкале.

А вот само распределение показателя 'contribution' действительно похоже на распределение Парето, известное в применении к частотам встречаемости слов как распределение Ципфа. Графики других показателей мне не очень напоминают распределение Парето.

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

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

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

Онлайн-лекция Реактивные и нативные приложения на Java Spring и Quarkus

25.07.2020 14:22:36 | Автор: admin
image

28 июля приглашаем на онлайн-лекцию о разработке приложений на Java Spring, Quarkus, Vert.x и GraalVM с деплоем в MicroK8s.

В программе лекции: Сергей Кошкинов и Андрей Смирнов покажут процесс создания приложения на Java-фреймворке Quarkus с деплоем в MicroK8s. А также сравнят производительность и потребления памяти приложений на Spring WebFlux, Spring Boot, Quarkus, Quarkus+Vert.x и скомпилированными в native code с помощью GraalVM.

Зарегистрироваться



Об экспертах


Сергей Кошкинов разработчик в МегаФоне, Oracle Certified Professional Java Programmer.

Андрей Смирнов разработчик в МегаФоне. В прошлом преподавал программирование в ННГУ им. Н. И. Лобачевского.

По теме:

Подробнее..

Онлайн-лекция Какие навыки нужны разработчику для карьерного роста

27.09.2020 14:13:04 | Автор: admin


28 сентября приглашаем на онлайн-лекцию о развитии карьеры в IT.

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

Директор центра подбора IT-специалистов SymbioWay Даниил Пилипенко прочертит карьерный путь разработчика. Расскажет, что такое soft skills и почему их важно развивать. Поможет выяснить, что важнее для карьерного роста: трудоголизм или трудолюбие.

Регистрация


Об эксперте


Даниил Пилипенко директор центра подбора IT-специалистов SymbioWay.
Старший преподаватель Skillbox по Java и веб-верстке.

По теме:

Подробнее..

Категории

Последние комментарии

  • Имя: Макс
    24.08.2022 | 11:28
    Я разраб в IT компании, работаю на арбитражную команду. Мы работаем с приламы и сайтами, при работе замечаются постоянные баны и лаги. Пацаны посоветовали сервис по анализу исходного кода,https://app Подробнее..
  • Имя: 9055410337
    20.08.2022 | 17:41
    поможем пишите в телеграм Подробнее..
  • Имя: sabbat
    17.08.2022 | 20:42
    Охренеть.. это просто шикарная статья, феноменально круто. Большое спасибо за разбор! Надеюсь как-нибудь с тобой связаться для обсуждений чего-либо) Подробнее..
  • Имя: Мария
    09.08.2022 | 14:44
    Добрый день. Если обладаете такой информацией, то подскажите, пожалуйста, где можно найти много-много материала по Yggdrasil и его уязвимостях для написания диплома? Благодарю. Подробнее..
© 2006-2024, personeltest.ru