Привет! Меня зовут Mashkka Тихонова. Я - Senior Data Scientist, а еще я активно преподаю все, что связано с ML, DS и DL - помогаю людям начать свой путь в Data Science!За годы преподавания у меня накопилось много советов для тех, кто только-только начинает свой путь в DS. Этими советами я всегда делюсь со студентами, а теперь решила собрать их в одном посте, написанном по мотивам моей серии постов в tg . Советы эти совсем простые (уровня не заваливай горизонт на фото, когда фоткаешь пейзаж), но очень часто именно про такие базовые вещи на первых этапах забывают рассказать.В свое время я сама наступала на эти грабли, так как мне их никто не рассказал. Буду рада, если помогу вам этих ошибок избежать! Замечение: и не заваливайте горизонт без нужды на фото, пожалуйста, сделать его ровным - это всего пара секунд! Самый важный навык, который первым делом должен освоить любой DS - это гуглить!  Ищешь ответ на вопрос? - Гугли, а только потом спроси! Не работает код? - Гугли! Выбираешь алгоритм? - Гуглить! Нужен пример кода? - Гугли! Не знаешь, как правильно закодить? - Гугли! Нужны статьи по теме? - Гугли! и т. д. и т. п. Гугл, конечно, знает не все, но ооооочень многое. И прежде, чем бежать с вопросами к коллегам, знакомым, преподавателям - загуглите. Скорее всего вы найдете ответ. И помните не забывайте золотые правила Гуглежа:⬇ Гуглить только в Гугле, лучше на ванильном Google.com. Никакого поиска в Яндексе, Mail или Bing, если вы ищите что-то по Data Science. Не хочу обидеть другие поисковики, я сама люблю поиск Яндекса, но для целей Data Science - это Google и только он. Гуглить только на английском: не пытайтесь что-то искать на русском языке - это боль. Даже если не знаете английский, лучше перевести ваш запрос на английский и загуглить так.  Гуглить по ключевым словам: при формулировке запроса старайтесь выделить ключевые слова (на английском) и загуглить именно их. Вероятность найти то, что вы ищите, намного выше, чем когда вы формулируете предложение целиком. Если у вас в коде есть какая-то случайность (случайное разбиение на train и test, случайная инициализация и т. д.), то лучше эту случайность зафиксировать. Для этого у всех методов обычно есть специальные параметры  типа ransdom_state, seed, random_seed и т.п. Согласитесь, обидно: перезапустил ноутбук и скор упал или вообще все сломалось? Поэтому старайтесь, чтобы ваш код работал детерминировано и всегда выдавал один и тот же результат. Всем рассказываю страшилку про своего стажера. Он долго-долго обучал нейросеть, а когда я попросила его оценить качество и прогнать модель на тесте, он с ужасом понял, что забыл зафиксировать random_state при разбиении на train и test, а код с разбиением заглушил. Странная ситуация: есть модель, есть данные, а оценить ее нельзя - непонятно, какие данные использовались при обучении и на чем её тестировать. Пришлось переобучать. Итог: random_state = 42 наше все! Не надо бояться страшных логов ошибок. Часто в них содержится та самая информация, которая поможет понять, что не так в коде.  Единого "правила чтения" логов нет, у каждого здесь свой "авторский" подход. Я обычно вначале смотрю, на какой строчке все сломалось, а потом прокручиваю в самый конец - в последней строчке как правило содержится ключевая информация, что не так. Если этого оказалось недостаточно, то начинаю читать логи снизу вверх, постепенно раскручивая ошибку из недр Python вверх как спираль. А еще чаще гуглю (в Google! по правилу 1) самую последнюю строчку ошибки и в большинстве случаев на Stack Overflow нахожу ответ. Кстати, у sklearn очень хорошие подсказки в логах, которые зачастую напрямую говорят, что не так и как это исправить.  Например:На картинке sklearn прямо пишет о том, что в наших обучающих данных содержится всего один признак или пример надо попросту сделать train_X.reshape А дальше просто смотрим на размерность X_train и обнаруживаем, что да, в данных действительно всего один признак: Значит, по совету sklearn из логов надо написать так: Или пример чуть посложнее: При попытке зафитить GridSearch на ирисах Фишера (задача классификации на 3 класса), оценивая качество с помощью F1: sklearn подскажет нам, что необходимо указать тип агрегации, среди прочего выдав в логах вот такую подсказку: нам остается просто последовать его совету и поменять scoring = 'f1' на scoring = 'f1_micro': Как часто бывает, что код не работает и не понятно почему. Или еще хуже, работает неверно и в переменных оказывается записано что-то непонятное совсем с потолка. Например, такое нередко случается, если вы пытаетесь разом совместить всю предобработку данных вместе с обучением модели и запихиваете все это в одну ячейку кода, оборачивая в ColumnTransformer, Pipeline, и GridSearchCV. В этом случае дебаг вам в помощь! И если вы пока еще не освоили базовые логгеры и такую удобную штуку как VS Code (а я очень рекомендую вам это сделать и как можно скорее), то самое простое - это понаставить побольше принтов - print (можно прямо после каждой строчки кода), чтобы отследить что оказалось в каждой переменной на каждом шагу. Чаще всего это помогает найти ту самую строчку, где все пошло не так. А еще можно разбить одну ячейку с кодом на несколько (чем детальнее, тем лучше), выводя в конце каждой клетки значения переменных и проверяя их корректность.  Что касается ColumnTransformer и Pipeline, то на этапе первично написания кода, я обычно обхожусь без них, так как они очень усложняют дебаг. А оборачиваю в них все уже в конце, после первичной отладки кода. Но тут уже вкусовой вопрос. Замечание:  еще раз подчеркну, что специально сейчас не касаюсь сейчас всяких логгеров и прочих более продвинутых фишек откладки кода, а говорю про самый упрощенный дебаг на уровне принтов. Такой дебаг доступен всем, даже самым-самым начинающим DS, которые работают в GoogleColab. Если хотите начинать трушно, я только за! Никогда, никогда, никогда не обучайте модель на тесте! То, что модель ни в каком виде не должна видеть тест на этапе обучения вы должны запомнить как 2 X 2 = 4.* Показать (или дать подглядеть) модели тест - это все равно, что прорешать со школьником его вариант ЕГЭ в классе, а потом радоваться, что он получил высокий балл. Это, конечно, здорово, но к реальным знаниям, то есть качеству модели, этот результат на таком утекшем тесте отношения не будет иметь.*В примере 2 X 2 = 4 я предполагаю, что мы находимся в кольце целых чисел со стандартной операцией умножения. Но если с обучением модели и тестом все ясно, на то он и тест, то с обучением трансформаций типа StandardScaler или CountVectorizer и т. п. есть еще один нюанс. Метод fit_transform для них можно вызывать только от обучающих данных (то есть от train), а для теста всегда используем лишь transform: Строчка X_test_scaled = scaler.fit_trasnform(X_test) может полностью испортить ваш эксперимент, ведь обучение на тесте приведет к тому, что на обучающей и тестовых выборках данные будут отмасштабированы по-разному, а значения train и test не будут биться между собой. Пример: Допустим у нас есть набор данных x_train = [0, 10, 20], x_test = [0, 5, 10], к которому мы хотим применить минимаксное преобразование (это преобразование приводит данные в диапазон [0-1]).  Отталкиваясь от значений в x_train, получаем вот такое соответствие: 0 => 05 => 0.2510 => 0.520 => 1 В итоге получаем, что X_train_scaled = [0, 0.5, 1], X_test_scaled = [0, 0.25, 0.5]. Но стоит руке дрогнуть и случайно написать: X_test_scaled = scaler.fit_trasnform(X_test) и, о ужас, соответствие на тесте изменится и для теста мы получим вот такую вещь: 0 => 05 => 0.510 => 1 и в итоге получим X_train_scaled = [0, 0.5, 1], X_test_scaled = [0, 0.5, 1], что полностью собьет с толку вашу модель. Не самая частая, но очень неприятная ошибка: загрузил пакет или функцию, а потом нечаянно назвал переменную тем же именем. Как итог, тщетно пытаешься применить эту функцию, получая странный error, в котором непонятно ничего. Обычно выглядит это как-то так:  Как это связано с функцией/пакетом? НепАнЯтнА! А загулить такое по названию метода не получается никак... Тяжело... Помню, одна студентка парсила данные и импортировала BeautifulSoup - библиотеку для работы с html-документами по именем soup: Потом в совершенно другой ячейке написала: А потом долго недоумевала, почему при первом запуске все окей, но если перезапустить ячейку, то все ломается и что не так. А дело было в том, что после выполнения soup = soup(html, 'html.parser'), имя soup превращается в обычную переменную. Вот такие дела.... Заповедь эта немного шуточная и написана под вдохновением одного из подкастов Андрея Себранта, а ее название говорит само за себя, к нему и добавить-то нечего. Разве что прочитайте все ответы на вопрос и найдите тот, который действительно даёт правильный ответ! Как же приятно запустить код на выходные/поставить обучаться большую модель, а потом в понедельник обнаружить, что вычисления посчитались почти до конца, но в последний момент код упал. Например, на выходные перезапустили сервер, когда ваш прогресс был уже 99%! Или при парсинге огромного сайта после тысячной страницы вас забанили по API, а ваш код упал. Подобных случаев, увы, в практике любого DS-ника не избежать. Но от них можно хотя бы частично обезопасить себя, если делать промежуточные чекпоинты модели, сохранять раз в несколько итераций обработанные данные и логгировать прогресс. Тогда вам не придется перезапускать все с нуля, и вы сможете частично восстановить результат. Совет, казалось бы, очевидный, но почему-то очень часто многие забывают про него. Но помните, поленившись написать пару строк кода с сохранением, вы всегда рискуете потом об этом пожалеть! Регулярные выражения - очень мощный и удобной инструмент для работы с текстами. Они позволяют эффективно искать/заменять в текстах фрагменты, удовлетворяющие определенному шаблону. С помощью регулярок можно действительно решить кучу разных задач, связанных с поиском по тексту, но не стоит недооценивать их коварство. Ведь не зря говорят, когда некоторые люди сталкиваются с проблемой, думают «Я знаю, я решу её с помощью регулярных выражений.» Теперь у них две проблемы ©   У регулярок обожают вылезать крайние случаи, в которых они работают неправильно (спецсимволы, выражения, не удовлетворяющее шаблону в конце/начале строки и т. п.). А потом начинается бег по кругу: вы пытаетесь учесть крайний случай и регулярка начинает неправильно работать в другом месте и т. д. и т. п. Как итог, она разрастается до монструозных размеров, и вообще становится непонятно, когда она работает, а когда нет. Надеюсь, я вам не слишком напугала. Не стоит боятся регулярок, они действительно удобные, но с ними надо всегда быть аккуратными, вот и все! Если вы не знаете, как правильно, то Google, как вы знаете, знает все. Поэтому, в любой непонятной ситуации, по заповеди 1, мы гуглим. Но что делать, если у вас есть два варианта, оба правильные, но вы не знаете какой из них лучше взять? Встав перед таким выбором настоящий Data Scientist проведет эксперимент: попробует оба варианта и выберете тот, который окажется в данной ситуации лучше (например, на валидации). Студенты часто спрашивают: "Мария, вот у меня есть какой-то там датасет (который я лично никогда и в глаза не видела) и какая-то там задача (о которой я пока имею очень смутное представление только с их слов), как мне лучше всего заполнить пропуски в данных, медианой или средним? А какой метод снижения размерности выбрать?" На подобные вопросы я всегда отвечаю так: "Сравните и выберете то, что даст лучший результат! Только эксперимент даст вам ответ, что будет лучше в вашем конкретном случае!" Warning: только не переборщите с количеством вариантов, особенно при переборе гиперпараметров методом GridSearchCV. Помните, с ростом количества перебираемых фичей, количество вариантов возрастает мультипликативно, то есть в разы. Поэтому всегда прикидывайте, сколько вариантов у вас получится и сколько вы готовы ждать результат. Итого: в любой непонятной ситуации - гугли, а в любой неоднозначной - проводи эксперимент! Заключение: Буду рада, если эти советы помогут вам избежать самых типичных ошибок на пути начинающего Data Scientist. А возможно, если вы уже опытный DS-ник, они вас позабавят и вы с улыбкой вспомните, как сами через это прошли. А еще обязательно прочитайте мои вредные советы Айтишнику!   Также приглашаю всех посетить открытый урок для новичков в ML на тему «Первичный анализ данных с Pandas», который пройдет я проведу уже сегодня. На встрече обсудим, зачем нужен первичный анализ данных в машинном обучении, какие существуют инструменты для первичного анализа данных в Python, как визуализировать данные и какая преобработка данных нужна в ML. Запись на урок доступна по ссылке ниже. А для тех, кто не успеет зарегистрироваться, по этой же ссылке будет доступна запись урока. Зарегистрироваться на бесплатный урок    Data Scientist