Pull to refresh

Поиск мотивации в скучных задачах

Level of difficultyEasy
Reading time7 min
Views2.2K

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

Меня вгоняет в чувство безнадежности задачи, которые не четко формализованы, или которые поставлены нечетко: «Сделай то, не знаю что».

Например, прилетела мне задача:

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

Вот всё что в кавычках — это неопределенные или слабо определенные параметры. Какое-то уравнение с огромным числом переменных, в котором даже «равенство» не определено.

Вы можете сказать «бывает, чё ныть». Садись, декомпозируй и решай.

И так-то оно так, но тут вступает в игру индивидуальный контекст. Он, конечно, на то и индивидуальный, но я попробую вас в него погрузить.

Мой контекст:

  • Неимоверное количество задач в бэклоге. Задачи есть всегда. За последние 5 лет не было момента, когда был бы пустой бэклог.

  • Непонятно как декомпозировать данную задачу. Это как будто ты пытаешься дрессировать теорию хаоса. Когда параметры как-будто независимы, но на деле всё взаимосвязано. Меняешь один параметр, меняются все остальные. Тут нужно решать задачу комплексно.

  • Я терпеть не могу рутинные задачи (вроде разметки), то есть где нужно делать, а не думать. Такие, знаете, где ты можешь включить два-три фильма на фоне и делать задачу. Моментально начинаю закипать. Мозг должен работать.

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

Пример из детства

Вы ребенок лет 12-ти. У вас выходной день от школы, и вы вышли гулять с друзьями — играть в футбол. Вышли играть в полдень. Сыграли матч — выиграли. Ещё один — проиграли, снова выиграли и снова проиграли. И вот отрыв уже в 3 очка, появляется азарт оторваться на 4 очка. Снова выигрыши и проигрыши, и снова азарт внутри вас всё кричит "Хочу разрыв в 5 очков". Снова выигрыши и проигрыши, и тут вроде появился шанс обыграть эту дурацкую команду соперников наконец с разрывом в 5 очков...

И именно в этот момент, вы слышите, как из окна вас зовет мать. Настойчиво. Очень настойчиво. Кричит уже не первый раз, так как вы наконец смогли услышать её. И что кричит? Конечно "Пора домой, уже поздно..."

Вы ей кричите, в возбуждении, мол, мам, игра горит, очень и очень нужно выиграть с разрывом в 5 очков. В ответ слышите «Ты и так весь день играешь. И так уже большой разрыв и вообще ты молодец. Но пора домой! Точка!»

Ну вот и как объяснить матери все свои чувства, весь тот азарт, который в вас полыхает?

Мой подход (как я подхожу к разрешению таких ситуаций)

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

Формализация моего подхода
Формализация моего подхода

Итак, начинается всё с верхнего правого блока. Чтобы применять подход, нужно осознать что произошел именно этот кейс. Что именно ЭТА задача заставляет прокрастинировать. А это не так просто:

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

  • Утром не хочется на неё тратить время, а вечером нет сил, чтобы погружаться в неё.

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

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

  • Дедлайн.

  • Опыт детекции этого цикла. Что ты находишь не причины, а отмазки, чтобы её не делать.

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

График функции эффективности применения подхода от дедлайна и мотивации Fae= f(D, M)
График функции эффективности применения подхода от дедлайна и мотивации Fae= f(D, M)

Вот у вас есть ещё определенное время до дедлайна, и вы пришли в блок «тяги». Зачем это делать? А как вы по другому поймете, какой процесс или ощущение нужно перекрыть?

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

Алгоритм поиска задач, решать которые вам в тягость
Алгоритм поиска задач, решать которые вам в тягость

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

Например, «тяга» — это написание документации. А «зажигалкой» может быть тестирование нового инструмента для рисования блок-схем. Я в свое время так и полюбил рисовать блок схемы для документации и презентаций, тестируя excalidraw.

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

Идея

Корреляция с задачей

Корреляция с зажигалками (максимизируем)

Насколько это решение — тяга (минимизируем)

Зажигалка 1

Зажигалка 2

Тяга 1

Тяга 2

Идея 1

9/10

5/10

9/10

1/10

1/10

Идея 2

6/10

8/10

8/10

6/10

6/10

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

  1. Как сильно зажигает.

  2. Корреляция с задачей.

  3. Закрытие тяг.

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

Применение подхода к моей задаче

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

Мои «тяги»:

  • Скучно. Рутинная работа, вроде переразметки, уничтожает меня. Эту тягу нужно обязательно закрыть.

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

  • Долго. Хочется закрыть задачу максимально быстро.

Мои «зажигалки»:

  • Писать код. Редко получается кодить, скучаю по коддингу.

  • Новая технология или библиотека. Очень люблю пробовать новые технологии.

Ну и идеи, которые удалось придумать:

  1. Разметить ручками, прям прописать if 1.5 < tsne_1 < 3.5 and 0 < tsne_2 < 5, то это класс «аномалия» и т. д..

  2. Написать алгоритм для разметки. Например, как таргет мы просто берем 10 точек до аварии. Или на t-SNE измеряем дистанцию, и берем ближайшие 10 точек к аварии.

  3. Найти тулзу на просторах интернета, некий интерактивный редактор для разметки.

  4. Разработать графический интерактивный разметчик самому.

Идея

Корреляция с задачей

Корреляция с зажигалками (максимизируем)

Насколько это решение — тяга (минимизируем)

Писать код

Что-то новое

Скучно

Неопределенно

Долго

Разметка ручками

10

0

0

10

10

7

Авто алгоритм разметки

10

3

3

9

7

5

Поиск готового решения разметки

8

3

10

6

?

?

Написать визуальный разметчик

7

10

10

3

0

5

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

Я ставил «?» - где невозможно оценить. Чем больше вопросов для решения, тем сомнительнее его выбор.

Написание визуального разметчика

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

Пример интерактивности plotly
Пример интерактивности plotly

Запрос в поисковике «plotly callback», первая ссылка ведет на эту страницу. Для создания интерфейса и callbacks они используют dash библиотеку.

Если лень тыкать, фрагмент кода в спойлере
app = Dash(__name__)  # поднимает веб-сервер на Flask

app.layout = html.Div([
    dcc.Graph(id='graph-with-slider'),  # элемент для графика
    dcc.Slider(id='year-slider', ...)  # элемент управления
])

@callback(
    Output('graph-with-slider', 'figure'),  # обновить график
    Input('year-slider', 'value')  # стриггерить функцию после изменения
)
def update_figure(selected_year):
    fig = px.scatter(...)
    return fig

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

У меня пока нет инпута, но у меня есть график. В начале я хотел прям рисовать (о да, там можно даже рисовать). Но потом увидел замечательную функцию выделения (box select или lasso select). Поэтому следующий запрос в гугл был «dask plotly select event», который дал мне эту страницу. Событие «selectedData» триггерится, когда пользователь выделяет область на графике. Но что ещё потряснее, в колбэк передается «selected_data» - те фигуры, которые попали в выделенную область.

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

Скриншот интерфейса разработанной либы для загрузки данных
Скриншот интерфейса разработанной либы для загрузки данных

Файл загружается в *.csv формате, либо выбирается из списка ранее загруженных. Все загруженные файлы складываются в папку data/input (или какую вы в .env пропишете). Можно исключить столбцы, если они мешают вашей картинке (в моем случае, это столбец «date»). После выбора таргета начинается визуализация:

Скриншот из интерфейса разработанной либы для разметки датасета
Скриншот из интерфейса разработанной либы для разметки датасета

Визуализация производится путем разложения исходных (слегка предобработанных) данных на две компоненты. Пока добавил один метод, мне его хватило. Логика разметки следующая:

  1. Вводите новое значение таргета в поле «Input label value for selected».

  2. Выбираете на графике инструмент «Box select» или «Lasso select».

  3. Выделяете точки, для которых хотите изменить значения таргета.

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

Выглядит это вот так:

Демонстрация работы визуализатора для пере-разметки данных
Демонстрация работы визуализатора для пере-разметки данных

И напоследок оставлю ссылку на репо.

Как итог

Я закрыл задачу.

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

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

  • Писать документацию по ГОСТу (нашел нужные зажигалки).

  • Рисовать блок-диаграммы (нашел любимый визуализатор).

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

  • Решил задачу, про которую написана статья.

Tags:
Hubs:
+5
Comments1

Articles