Kompromis pomiędzy czasem, jakością a zakresem w projektach ML

Dzisiaj przedstawię pewne podejście do projektów Machine Learning, które pozwoli Ci znacznie zwiększyć efektywność Twojej pracy.

Chodzi o uświadomienie sobie trzech czynników, z których składają się prace w każdym projekcie. Są to:

  1. Zakres projektu, tzn. co dokładnie będzie robił model, jakie przypadki będzie obsługiwał, jak skutecznie będzie działał, jakie będzie miał wymagania, ograniczenia itp.
  2. Jakość wykonanych prac, tzn. na ile eksperymenty są robione rzetelnie, jakie są standardy kodu (czystość, zrozumiałość, rozszerzalność), czy wykonywane jest code-review, czy pisane są testy, asercje, czy stosowane są narzędzia do trackowania wersji danych, eksperymentów itp. 
  3. Czas – czyli po prostu liczba godzin poświęconych na dane prace.

Zauważmy, że te czynniki są ze sobą ściśle związane: jeśli zwiększamy zakres projektu lub chcemy podnieść jakość wykonywanych prac, to rośnie czas potrzebny na jego wykonanie. Jeśli z kolei zmniejszamy zakres, to możemy w tym samym czasie zrobić projekt o wyższej jakości, lub skrócić czas wykonania. To zjawisko w pewien sposób możemy sobie zilustrować na trójkącie. Jeśli zbliżamy się do jednego z wierzchołków, to tym samym oddalamy się od dwóch pozostałych (przy czym „zbliżanie się” oznacza maksymalizowanie zakresu i jakości, a minimalizowanie czasu).

Kiedy uświadomimy sobie to zjawisko, możemy bardziej świadomie podejść do zaplanowania prac. Ważne będzie ustalenie priorytetów – czy odbiorca mojego modelu (PM, klient, szef) stawia nacisk na któryś z tych trzech czynników?

Z praktyki wiem, że niedoświadczony klient teoretycznie chce mieć wszystkie trzy czynniki, ale tak naprawdę najbardziej zwraca uwagę na czas, gdyż to on jest najbardziej mierzalny i wprost przekłada się na koszty projektu.

Miejmy to na uwadze – rzadko kiedy projekty są wykonywane z niemal nieograniczonymi zasobami czasu. Zazwyczaj terminy są dość ciasne i nie pozostaje nam nic innego, jak ograniczyć jakość lub zakres naszych działań.

Zachęcam tutaj, by z pewnego poziomu jakości nigdy nie rezygnować (np. code review, czy zasady pisania czystego kodu). Często może się wydawać, że nic się nie stanie, gdy zrobi się wyjątek, ale w praktyce niska jakość kodu dodaje wielokrotnie więcej pracy, gdy dany projekt jest potem rozwijany (a przecież to jest naszym celem – nie chcemy by nasze prace trafiały do kosza).

Dlatego jedynym sensownym rozwiązaniem jest zmniejszenie zakresu prac. Warto to rozumowanie przedstawiać naszym odbiorcom modelu.

Podam przykład z jednego z projektów z mojej poprzedniej firmy. Jednym z zadań było policzyć, ile zarabia algorytm dla danej kampanii reklamowej. Okazało się, że jest aż 10 różnych modeli rozliczeń kampanii i żeby policzyć zyski dla kampanii, trzeba było pobrać nowe dane, implementować różne podklasy itp. Nowa wycena czasowa to 2 tygodnie zamiast spodziewanych 2 godzin. Po dokładniejszym przyjrzeniu się, okazało się jednak, że 95% kampanii jest tylko w jednym prostym typie rozliczeniowym. A pozostałych 5% i tak nie chcemy optymalizować algorytmem.

Ta historia pokazuje, że ograniczając zakres prac w inteligentny sposób, tak na prawdę wcale nie musimy pogarszać docelowego rozwiązania.

Warto tutaj pamiętać o wszechobecnej zasadzie Pareto – w 20% czasu dostarczymy 80% efektów. Być może nie warto poświęcać dodatkowych 80% godzin na 20% efektów? 

2. Jak w praktyce ograniczać zakres

Podam teraz kilka punktów, przez które warto przejść, gdy planujesz pracę nad modelem ML, aby spróbować ograniczyć zakres prac.

  1. Obsługuj tylko podzbiór danych.

To chyba najczęstszy i najłatwiejszy przypadek. Zazwyczaj dane składają się ze zdecydowanej większości typowych przypadków i pewnej liczby outlierów. Rozmawiając z odbiorcą Twojego modelu, zapytaj, jakie przypadki są typowe, a jakie trudne (piszę o tym więcej w moim e-booku). Może model obsługujący 80-90% sytuacji będzie już wystarczający? Może warto taki model zbudować w pierwszej kolejności i spróbować go już wdrożyć?

  1. Uogólnij wartość do predykcji.

Drugą możliwością jest uogólnienie problemu. Jeśli np. model ma np. wskazywać precyzyjnie jakiś produkt, może wystarczy że zwróci grupę produktów? Może zamiast 100 kategorii można je pogrupować i utworzyć 5 podstawowych?

  1. Obsługuj tylko część cech.

Niejednokrotnie nasz zbiór danych może być bardzo zróżnicowany. Przykładowo, spotkałem się z danymi tabelarycznymi, w których część była liczbowa, część tekstowa (tekst należący do jednej z kategorii), a część to całkowicie luźny tekst (np. komentarze). Trenowanie modelu na wszystkich kolumnach wymaga znacznych prac, aby np. wykonać embeddingi luźnego tekstu. Być może w pierwszej wersji możesz uwzględnić tylko dane liczbowe, a model będzie sobie radził całkiem nieźle?

  1. Użyj najprostszych modeli.

Często złym pomysłem jest zaczynanie od najbardziej skomplikowanych architektur, typu głębokie sieci neuronowe. Na prostych zbiorach tabelarycznych, dobrze może działać zwykła regresja, bądź drzewa decyzyjne. Dlatego pomyśl, czy możesz użyć prostych modeli. Pisałem o tym więcej w artykule o modelach benchmarkowych.

  1. Wykorzystuj gotowe rozwiązania.

Mam tutaj na myśli przede wszystkim duże pretrenowane modele, np. do analizy obrazu lub języka. Może nie potrzebujesz wcale robić modelu od zera, tylko dotrenujesz istniejące modele? Może wystarczy dopisać tylko prostą heurystykę, która uzupełni działanie istniejących modeli?

  1. Skróć czas analizy danych.

Ten punkt może wydawać się kontrowersyjny, wszak każdy wie, że czyszczenie i analiza danych to 80-90% czasu pracy w ML-u (przypominam artykuł, w którym mówię, jak przeanalizować dowolne dane tabelaryczne w 2 minuty). Czasem jednak dane są tak skomplikowane, że wystarczy zidentyfikować kluczowe fragmenty, wyodrębnić metrykę do predycji i puścić już jakieś modele. W zależności od wyników, warto wówczas zagłębiać się bardziej w dane.

Podsumowanie

Zanim zaczniesz pracę nad projektem, pamiętaj o trzech czynnikach – czas, jakość i zakres projektu. Przedstaw je w razie potrzeby odbiorcy modelu. A jeśli potrzebujesz zmniejszyć zakres, przejdź przez listę 6 pomysłów, którą przedstawiłem.