- PVSM.RU - https://www.pvsm.ru -
Сегодня существует 100500 курсов по Data Science и давно известно, что больше всего денег в Data Science можно заработать именно курсами по Data Science (зачем копать, когда можно продавать лопаты?). Основной минус этих курсов в том, что они не имеют ничего общего с реальной работой: никто не даст вам чистые, обработанные данные в нужном формате. И когда вы выходите с курсов и начинаете решать настоящую задачу — всплывает много нюансов.
Поэтому мы начинаем серию заметок «Что может пойти не так с Data Science», основанных на реальных событиях случившихся со мной, моими товарищами и коллегами. Будем разбирать на реальных примерах типичные задачи по Data Science: как это на самом деле происходит. Начнем сегодня с задачи сбора данных.
И первое обо что спотыкаются люди, начав работать с реальными данными — это собственно сбор этих самых релевантных нам данных. Ключевой посыл этой статьи:
Мы систематически недооцениваем время, ресурсы и усилия на сбор, очистку и подготовку данных.
А главное, обсудим, что делать, чтобы этого не допустить.
По разным оценкам, очистка, трансформация, data processing, feature engineering и тд занимают 80-90% времени, а анализ 10-20%, в то время как практически весь учебный материал фокусируется исключительно на анализе.
Давайте разберем как типичный пример простую аналитическую задачу в трех вариантах и увидим, какими бывают «отягчающие обстоятельства».
И для примера опять же, мы рассмотрим подобные вариации задачи сбора данных и сравнения сообществ для:
Открыть сайт и почитать примеры, если понятно, заложить несколько часов на чтение, несколько часов на код по примерам и отладку. Добавить несколько часов на сбор. Накинуть несколько часов про запас (умножить на два и прибавить N часов).
Ключевой момент: временная оценка основана на предположениях и догадках о том, сколько это займет времени.
Начать анализ времени необходимо с оценки следующих параметров для условной задачи, описанной выше:
Самое важное, что для оценки времени — вам фактически необходимо потратить время и усилия для «разведки боем» — только тогда ваше планирование будет адекватным. Поэтому как бы вас не пушили сказать «а сколько времени нужно для сбора данных» — выбейте себе времени на предварительный анализ и аргументируйте тем насколько время будет варьироваться в зависимости от реальных параметров задачи.
И сейчас мы продемонстрируем конкретные примеры, где такие параметры и будут меняться.
Ключевой момент: оценка основана на анализе ключевых факторов, влияющих на объем и сложность работы.
Оценка, основанная на догадках — это хороший подход, когда функциональные элементы достаточно небольшие и не так много факторов, которые могут существенно повлиять на структуру задачи. Но в случае ряда задач Data Science таких факторов становится крайне много и подобный подход становится неадекватным.
Начнем с самого простого случая (как потом окажется). Вообще, если совсем честно, перед нами практически идеальный случай, проверим наш чеклист сложности:
def get_comments(submission_id):
reddit = Reddit(check_for_updates=False, user_agent=AGENT)
submission = reddit.submission(id=submission_id)
more_comments = submission.comments.replace_more()
if more_comments:
skipped_comments = sum(x.count for x in more_comments)
logger.debug('Skipped %d MoreComments (%d comments)',
len(more_comments), skipped_comments)
return submission.comments.list()
Взято из этой [3] подборки удобных утилит для обертки.
Несмотря на то что перед нами самый лучший случай здесь все же стоит учесть ряд важных факторов из реальной жизни:
Конечно, необходимо заложить в разработку указанные нюансы. Конкретные часы/дни зависят от опыта разработки или опыта работы над подобными задачами, тем не менее мы видим, что здесь задача исключительно инженерная и не требует дополнительных телодвижений для решения — можно все очень хорошо оценить, расписать и сделать.
Переходим к более интересному и нетривиальному случаю сравнению потоков и/или разделов Хабра.
Проверим наш чеклист сложности — здесь, чтобы понять каждый пункт уже придется немного потыкаться в саму задачу и поэкспериментировать.
Взято из этой [5] статьи.
1) int(score) кидает ошибку: так как на Хабре минус, как, например в строке "–5" — это короткое тире, а не знак минуса (неожиданно, да?), поэтому в какой-то момент пришлось поднимать парсер к жизни вот с таким ужасным фиксом.
try:
score_txt = post.find(class_="score").text.replace(u"–","-").replace(u"+","+")
score = int(score_txt)
if check_date(date):
post_score += score
Даты, плюсов и минусов может вообще не быть (как мы видим выше по функции check_date и такое было).
2) Неэкранированные спецсимволы — они придут, нужно быть готовым.
3) Структура меняется в зависимости от типа поста.
4) Старые посты могут иметь **странную структуру**.
Итого чеклист по сложности:
Условная оценка времени для данной задачи будет в 3-5 раз выше, чем для сбора данных с Реддита.
Перейдем к самому технически интересному случаю из описанных. Для меня он был интересен именно тем, что на первый взгляд, он выглядит достаточно тривиальным, но совсем таким не оказывается — как только вы ткнете в него палочкой.
Начнет с нашего чеклиста сложности и отметим, что многие из них окажутся куда сложнее, чем выглядят вначале:
2) Однако c Selenium никаких гарантий по корректной и повторяемой работе (по крайней в случае с ok.ru точно).
3) Сайт Ок.ру содержит ошибки JavaScript и иногда странно и непоследовательно себя ведет.
4) Нужно заниматься пагинацией, подгрузкой элементов и тд…
5) Ошибки API, которые отдает wrapper придется костыльно обрабатывать, например, вот так (кусочек экспериментального кода):
def get_comments(args, context, discussions):
pause = 1
if args.extract_comments:
all_comments = set()
#makes sense to keep track of already processed discussions
for discussion in tqdm(discussions):
try:
comments = get_comments_from_discussion_via_api(context, discussion)
except odnoklassniki.api.OdnoklassnikiError as e:
if "NOT_FOUND" in str(e):
comments = set()
else:
print(e)
bp()
pass
all_comments |= comments
time.sleep(pause)
return all_comments
Моя любимая ошибка была:
OdnoklassnikiError("Error(code: 'None', description: 'HTTP error', method: 'discussions.getComments', params: …)”)
6) В конечном итоге вариант Selenium + API выглядит наиболее рациональным вариантом.
Условная оценка времени для данной задачи будет в 3-5 раз выше, чем для сбора данных с Хабра. Несмотря на то что в случае с Хабром мы используем лобовой подход с парсом HTML, а в случае с ОК мы можем в критичных местах работать с API.
Как бы с вас не требовали оценку сроков «на месте» (у нас же сегодня планирование!) объемного модуля пайплана обработки данных, время выполнения практически никогда невозможно оценить даже качественно без анализа параметров задачи.
Если говорить чуть более философски, то стратегии оценки в agile неплохо подходят для инженерных задач, но с задачами более экспериментальными и, в некотором смысле, «творческими» и исследовательскими, т.е., менее предсказуемыми, возникают трудности, как в примерах подобных тем, что мы разобрали здесь.
Конечно, сбор данных является просто ярким иллюстративным примером — обычно это задача кажется невероятно простой и технически несложной, и именно в деталях здесь чаще всего и таится дьявол. И именно на этой задаче получается показать весь спектр возможных вариантов того, что может пойти не так и насколько именно может затянуться работа.
Если пробежаться краем глаза по характеристикам задачи без дополнительных экспериментов, то Reddit и ОК выглядят похоже: есть API, python wrapper, но по сути, разница огромна. Если судить по этим параметрам, то парс Хабра выглядит сложнее, чем ОК — а на практике это совсем наоборот и именно это можно выяснить, проведя простые эксперименты по анализу параметров задачи.
По моему опыту наиболее эффективным подходом является примерная оценка времени, которая вам потребуется на сам предварительный анализ и простые первые эксперименты, чтение документации — они-то и позволят вам дать точную оценку для всей работы. В терминах популярной методологии agile — я прошу завести мне тикет под “оценку параметров задачи”, на основе которого я могу дать оценку того, что возможно выполнить в рамках “спринта” и дать более точную оценку по каждой задаче.
Поэтому наиболее эффективным, кажется аргумент, который бы показал «нетехническому» специалисту, как сильно будет варьироваться время и ресурсы в зависимости от параметров, которые еще предстоит оценить.
Автор: paramonov_ruvds
Источник [10]
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/python/355102
Ссылки в тексте:
[1] python wrapper: https://github.com/praw-dev/praw
[2] вот например: https://www.programcreek.com/python/example/86599/praw.Reddit
[3] этой: https://github.com/timendum/reddit-utilities/blob/master/thread-export.py
[4] VPS: https://www.reg.ru/?rlink=reflink-717
[5] этой: https://habr.com/ru/post/218607/
[6] этой: https://habr.com/ru/post/276383/
[7] нужной нам функции: https://apiok.ru/dev/methods/rest/discussions/discussions.getComments
[8] wrapper: https://github.com/alternativshik/python-odnoklassniki
[9] Image: http://ruvds.com/ru-rub?utm_source=habr&utm_medium=article&utm_campaign=param&utm_content=datascience1#order
[10] Источник: https://habr.com/ru/post/510944/?utm_source=habrahabr&utm_medium=rss&utm_campaign=510944
Нажмите здесь для печати.