Co może pójść nie tak w Data Science? Zbieranie danych

Co może pójść nie tak w Data Science? Zbieranie danych
Obecnie istnieje 100500 XNUMX kursów Data Science i od dawna wiadomo, że najwięcej pieniędzy w Data Science można zarobić na kursach Data Science (po co kopać, skoro można sprzedać łopaty?). Główną wadą tych kursów jest to, że nie mają one nic wspólnego z prawdziwą pracą: nikt nie dostarczy Ci czystych, przetworzonych danych w wymaganym formacie. A kiedy opuścisz kurs i zaczniesz rozwiązywać prawdziwy problem, wyłania się wiele niuansów.

Dlatego rozpoczynamy cykl notatek „Co może pójść nie tak w Data Science”, opartych na prawdziwych wydarzeniach, które przydarzyły się mnie, moim towarzyszom i współpracownikom. Przeanalizujemy typowe zadania Data Science na prawdziwych przykładach: jak to się faktycznie dzieje. Zacznijmy dzisiaj od zadania gromadzenia danych.

Pierwszą rzeczą, na którą napotykają ludzie, gdy zaczynają pracować z prawdziwymi danymi, jest zbieranie tych danych, które są dla nas najważniejsze. Kluczowe przesłanie tego artykułu:

Systematycznie nie doceniamy czasu, zasobów i wysiłku wymaganego do gromadzenia, czyszczenia i przygotowywania danych.

A co najważniejsze, omówimy, co zrobić, aby temu zapobiec.

Według różnych szacunków czyszczenie, transformacja, przetwarzanie danych, inżynieria cech itp. zajmują 80-90% czasu, a analiza 10-20%, podczas gdy prawie wszystkie materiały edukacyjne skupiają się wyłącznie na analizie.

Przyjrzyjmy się prostemu problemowi analitycznemu w trzech wersjach jako typowemu przykładowi i zobaczmy, jakie są „okoliczności obciążające”.

Jako przykład ponownie rozważymy podobne warianty zadania gromadzenia danych i porównywania społeczności dla:

  1. Dwa subreddity Reddita
  2. Dwie sekcje Habr
  3. Dwie grupy Odnoklassników

Podejście warunkowe w teorii

Otwórz stronę i przeczytaj przykłady, jeśli są jasne, poświęć kilka godzin na czytanie, kilka godzin na kod korzystając z przykładów i debugowanie. Dodaj kilka godzin na odbiór. Dorzuć kilka godzin do rezerwy (pomnóż przez dwa i dodaj N godzin).

Kluczowy punkt: Szacunki czasu opierają się na założeniach i domysłach dotyczących czasu trwania.

Analizę czasu należy rozpocząć od oszacowania następujących parametrów opisanego problemu warunkowego:

  • Jaki jest rozmiar danych i ile ich należy fizycznie zgromadzić (*patrz poniżej*).
  • Jaki jest czas odbioru jednej płyty i jak długo trzeba czekać, zanim będzie można odebrać drugą?
  • Rozważ napisanie kodu, który zapisuje stan i rozpoczyna restart, gdy (nie jeśli) wszystko się nie powiedzie.
  • Sprawdź, czy potrzebujemy autoryzacji i ustal czas uzyskania dostępu poprzez API.
  • Ustaw liczbę błędów jako funkcję złożoności danych - oceń pod kątem konkretnego zadania: strukturę, ile przekształceń, co i jak wyodrębnić.
  • Napraw błędy sieciowe i problemy związane z niestandardowym zachowaniem projektu.
  • Oceń, czy wymagane funkcje znajdują się w dokumentacji, a jeśli nie, to w jaki sposób i w jakim stopniu potrzebne jest obejście tego problemu.

Najważniejsze jest to, że aby oszacować czas - tak naprawdę trzeba poświęcić czas i wysiłek na "rozpoznanie w mocy" - tylko wtedy Twoje planowanie będzie odpowiednie. Dlatego niezależnie od tego, jak bardzo będziesz naciskany, aby powiedzieć „ile czasu zajmuje zebranie danych” - kup sobie trochę czasu na wstępną analizę i przekonuj, jak bardzo ten czas będzie się różnić w zależności od rzeczywistych parametrów problemu.

A teraz zademonstrujemy konkretne przykłady, w których takie parametry ulegną zmianie.

Kluczowy punkt: Wycena opiera się na analizie kluczowych czynników wpływających na zakres i złożoność prac.

Szacowanie oparte na domysłach jest dobrym podejściem, gdy elementy funkcjonalne są wystarczająco małe i nie ma wielu czynników, które mogą znacząco wpłynąć na projekt problemu. Jednak w przypadku szeregu problemów związanych z Data Science czynników takich jest niezwykle wiele i takie podejście staje się nieadekwatne.

Porównanie społeczności Reddit

Zacznijmy od najprostszego przypadku (jak się później okaże). Ogólnie mówiąc, mamy przypadek niemal idealny, sprawdźmy naszą listę kontrolną złożoności:

  • Istnieje schludne, przejrzyste i udokumentowane API.
  • Jest to niezwykle proste, a co najważniejsze, token uzyskiwany jest automatycznie.
  • Jest opakowanie Pythona - z dużą ilością przykładów.
  • Społeczność, która analizuje i zbiera dane na Reddicie (nawet do filmów na YouTube wyjaśniających, jak korzystać z opakowania Pythona) na przykład.
  • Metody, których potrzebujemy, najprawdopodobniej istnieją w interfejsie API. Co więcej, kod wygląda zwięźle i przejrzyście, poniżej znajduje się przykład funkcji zbierającej komentarze pod postem.

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()

Pochodzą z to wybór wygodnych narzędzi do pakowania.

Pomimo tego, że jest to najlepszy przypadek, nadal warto wziąć pod uwagę szereg ważnych czynników z prawdziwego życia:

  • Limity API - zmuszeni jesteśmy pobierać dane partiami (uśpienie pomiędzy żądaniami itp.).
  • Czas zbierania - na pełną analizę i porównanie będziesz musiał przeznaczyć znaczną ilość czasu na przejście pająka przez subreddit.
  • Bot musi działać na serwerze – nie można go po prostu uruchomić na laptopie, włożyć do plecaka i zająć się swoimi sprawami. Więc uruchomiłem wszystko na VPS. Korzystając z kodu promocyjnego habrahabr10, możesz zaoszczędzić kolejne 10% kosztów.
  • Fizyczna niedostępność niektórych danych (są widoczne dla administratorów lub są zbyt trudne do zebrania) – trzeba to wziąć pod uwagę, w zasadzie nie wszystkie dane można zebrać w odpowiednim czasie.
  • Błędy sieciowe: Praca w sieci jest uciążliwa.
  • To żywe, prawdziwe dane – nigdy nie są czyste.

Oczywiście konieczne jest uwzględnienie tych niuansów w opracowaniu. Konkretne godziny/dni zależą od doświadczenia programistycznego lub doświadczenia w pracy nad podobnymi zadaniami, jednak widzimy, że tutaj zadanie ma charakter czysto inżynieryjny i nie wymaga do rozwiązania dodatkowych ruchów ciała - wszystko można bardzo dobrze ocenić, zaplanować i wykonać.

Porównanie przekrojów Habr

Przejdźmy do ciekawszego i nietrywialnego przypadku porównywania wątków i/lub odcinków Habr.

Sprawdźmy naszą listę kontrolną złożoności - tutaj, aby zrozumieć każdy punkt, będziesz musiał trochę zagłębić się w samo zadanie i poeksperymentować.

  • Na początku myślisz, że istnieje API, ale tak nie jest. Tak, tak, Habr ma API, ale jest po prostu niedostępne dla użytkowników (a może w ogóle nie działa).
  • Potem po prostu zaczynasz analizować HTML – „żądania importu”, co może pójść nie tak?
  • Jak w ogóle analizować? Najprostszym i najczęściej stosowanym podejściem jest iteracja po identyfikatorach, należy pamiętać, że nie jest to najbardziej wydajne i będzie musiało obsługiwać różne przypadki - oto przykład gęstości rzeczywistych identyfikatorów wśród wszystkich istniejących.

    Co może pójść nie tak w Data Science? Zbieranie danych
    Pochodzą z to artykuły

  • Surowe dane zapakowane w HTML i umieszczone na wierzchu Internetu są uciążliwe. Na przykład, chcesz zebrać i zapisać ocenę artykułu: wyrwałeś wynik z kodu HTML i zdecydowałeś się zapisać go jako liczbę do dalszego przetwarzania: 

    1) int(score) wyrzuca błąd: skoro na Habré jest minus, jak na przykład w wierszu „–5” - to jest półpauza, a nie znak minus (nieoczekiwanie, prawda?), więc na w pewnym momencie musiałem ożywić parser za pomocą tak okropnej poprawki.

    try:
          score_txt = post.find(class_="score").text.replace(u"–","-").replace(u"+","+")
          score = int(score_txt)
          if check_date(date):
            post_score += score
    

    Może w ogóle nie być daty, plusów i minusów (jak widzimy powyżej w funkcji check_date, tak się stało).

    2) Nieuniknione znaki specjalne - przyjdą, musisz być przygotowany.

    3) Struktura zmienia się w zależności od rodzaju postu.

    4) Stare posty mogą mieć **dziwną strukturę**.

  • Zasadniczo trzeba będzie zająć się obsługą błędów oraz tym, co może się wydarzyć, a co nie, i nie można z całą pewnością przewidzieć, co pójdzie nie tak i jak inaczej może wyglądać struktura oraz co gdzie spadnie - będziesz musiał po prostu spróbować wziąć to pod uwagę błędy wyrzucane przez parser.
  • Wtedy zdajesz sobie sprawę, że musisz analizować w kilku wątkach, w przeciwnym razie analizowanie w jednym zajmie wtedy ponad 30 godzin (jest to wyłącznie czas wykonania już działającego jednowątkowego parsera, który śpi i nie podlega żadnym zakazom). W to artykuł, doprowadziło to w pewnym momencie do podobnego schematu:

Co może pójść nie tak w Data Science? Zbieranie danych

Całkowita lista kontrolna według złożoności:

  • Praca z siecią i parsowanie HTML z iteracją i wyszukiwaniem po ID.
  • Dokumenty o niejednorodnej strukturze.
  • Jest wiele miejsc, w których kod może łatwo spaść.
  • Trzeba napisać || kod.
  • Brakuje niezbędnej dokumentacji, przykładów kodu i/lub społeczności.

Szacowany czas wykonania tego zadania będzie 3-5 razy dłuższy niż zebranie danych z Reddita.

Porównanie grup Odnoklassniki

Przejdźmy do najciekawszego technicznie opisanego przypadku. Dla mnie było to ciekawe właśnie dlatego, że na pierwszy rzut oka wygląda dość banalnie, ale wcale tak nie jest – jak tylko wsunie się w to patykiem.

Zacznijmy od naszej listy kontrolnej trudności i zwróćmy uwagę, że wiele z nich okaże się znacznie trudniejszych, niż się na pierwszy rzut oka wydaje:

  • Istnieje API, ale prawie całkowicie brakuje mu niezbędnych funkcji.
  • Do niektórych funkcji należy wnioskować o dostęp drogą pocztową, co oznacza, że ​​udzielenie dostępu nie następuje natychmiastowo.
  • Jest to strasznie udokumentowane (na początek terminy rosyjskie i angielskie są wszędzie pomieszane i zupełnie niekonsekwentne - czasem wystarczy się tylko domyślić, czego gdzieś od ciebie chcą), a w dodatku projekt nie nadaje się do pozyskiwania danych np. , funkcję, której potrzebujemy.
  • Wymaga sesji w dokumentacji, ale tak naprawdę z niej nie korzysta - i nie ma sposobu, aby zrozumieć wszystkie zawiłości trybów API poza przeglądaniem i nadzieją, że coś zadziała.
  • Nie ma przykładów i nie ma społeczności, jedynym punktem oparcia w zbieraniu informacji jest mały obwoluta w Pythonie (bez wielu przykładów użycia).
  • Selen wydaje się być najbardziej wykonalną opcją, ponieważ wiele niezbędnych danych jest zablokowanych.
    1) Oznacza to, że autoryzacja odbywa się za pośrednictwem fikcyjnego użytkownika (a rejestracja odbywa się ręcznie).

    2) Jednak w przypadku Selenium nie ma gwarancji prawidłowej i powtarzalnej pracy (przynajmniej w przypadku ok.ru na pewno).

    3) Strona Ok.ru zawiera błędy JavaScript i czasami zachowuje się dziwnie i niekonsekwentnie.

    4) Musisz wykonać paginację, załadować elementy itp.

    5) Błędy API podawane przez opakowanie będą musiały być obsługiwane w niezręczny sposób, na przykład w ten sposób (fragment kodu eksperymentalnego):

    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
    

    Moim ulubionym błędem było:

    OdnoklassnikiError("Error(code: 'None', description: 'HTTP error', method: 'discussions.getComments', params: …)”)

    6) Ostatecznie Selenium + API wygląda na najbardziej racjonalną opcję.

  • Konieczne jest zapisanie stanu i zrestartowanie systemu, obsłużenie wielu błędów, w tym niespójnego zachowania strony - a te błędy są dość trudne do wyobrażenia (chyba, że ​​piszesz oczywiście parsery profesjonalnie).

Warunkowy szacunkowy czas wykonania tego zadania będzie 3-5 razy większy niż w przypadku zbierania danych z Habr. Pomimo tego, że w przypadku Habr stosujemy podejście frontalne z parsowaniem HTML, a w przypadku OK możemy pracować z API w krytycznych miejscach.

odkrycia

Niezależnie od tego, jak bardzo trzeba oszacować terminy „na miejscu” (planujemy już dziś!) obszernego modułu potoku przetwarzania danych, prawie nigdy nie da się oszacować czasu realizacji, nawet jakościowo, bez analizy parametrów zadania.

W nieco bardziej filozoficznym ujęciu, zwinne strategie szacowania sprawdzają się dobrze w przypadku zadań inżynierskich, jednak problemy bardziej eksperymentalne i w pewnym sensie „kreatywne” i eksploracyjne, czyli mniej przewidywalne, mają trudności, jak w przykładach o podobnych tematach, które tutaj omawialiśmy.

Oczywiście zbieranie danych to tylko doskonały przykład – jest to zazwyczaj niezwykle proste i technicznie nieskomplikowane zadanie, a diabeł często tkwi w szczegółach. I to właśnie przy tym zadaniu możemy pokazać całą gamę możliwych opcji, co może pójść nie tak i dokładnie, ile czasu może zająć praca.

Jeśli spojrzysz na charakterystykę zadania bez dodatkowych eksperymentów, Reddit i OK wyglądają podobnie: istnieje API, opakowanie Pythona, ale w istocie różnica jest ogromna. Sądząc po tych parametrach, pars Habra wygląda na bardziej skomplikowane niż OK - jednak w praktyce jest zupełnie odwrotnie i właśnie tego można się dowiedzieć przeprowadzając proste eksperymenty w celu analizy parametrów problemu.

Z mojego doświadczenia wynika, że ​​najskuteczniejszym podejściem jest przybliżone oszacowanie czasu potrzebnego na samą wstępną analizę i proste pierwsze eksperymenty, zapoznanie się z dokumentacją - pozwolą one na dokładny kosztorys całej pracy. W ramach popularnej metodologii zwinnej proszę o utworzenie biletu do „oszacowania parametrów zadania”, na podstawie którego będę mógł ocenić, co da się osiągnąć w ramach „sprintu” i podać dokładniejszy szacunek dla każdego zadanie.

Dlatego najskuteczniejszym argumentem wydaje się ten, który pokaże „nietechnicznemu” specjalistowi, jak bardzo czas i zasoby będą się różnić w zależności od parametrów, które nie zostały jeszcze ocenione.

Co może pójść nie tak w Data Science? Zbieranie danych

Źródło: www.habr.com

Dodaj komentarz