Çfarë mund të shkojë keq me Shkencën e Të Dhënave? Grumbullimi i të dhënave

Çfarë mund të shkojë keq me Shkencën e Të Dhënave? Grumbullimi i të dhënave
Sot të sotme, ekzistojnë 100500 kurse mbi Data Science dhe është e njohur se më shumë para në Data Science mund të fitohen nga kurset mbi Data Science (pse të qeshim, kur mund të shesim lopatat?). Minus i madh i këtyre kurseve është se ato nuk kanë asgjë të përbashkët me punën reale: askush nuk do t'ju japë të dhëna të pastra, të përpunuara në formatin e duhur. Dhe kur dilni nga kurset dhe filloni të zgjidhni një problem të vërtetë - shpesh dalin shumë nuanca.

Prandaj, ne fillojmë një seri shënimesh "Çfarë mund të shkojë keq me Data Science", të bazuara në ngjarje reale që ndodhen me mua, shokët dhe kolegët e mi. Do t'i shqyrtojmë shembuj konkretë të detyrave tipike të Data Science: si ndodh realisht kjo. Sot do të fillojmë me detyrën e mbledhjes së të dhënave.

Dhe e para në të cilën pengohen njerëzit, kur fillojnë të punojnë me të dhëna reale, është vetë mbledhja e këtyre të dhënave që na nevojiten. Mesazhi kryesor i këtij artikulli është:

Ne sistematikisht e underestimated kohën, resurset dhe përpjekjet për mbledhjen, përpunimin dhe përgatitjen e të dhënave.

Dhe mbi të gjitha, do të diskutojmë se çfarë të bëjmë që të mos e lejojmë këtë.

Sipas vlerësimeve të ndryshme, pastrimi, transformimi, përpunimi i të dhënave, inxhinieria e veçorive etj. zënë 80-90% të kohës, ndërsa analiza 10-20%, ndërsa pothuajse i gjithë materiali edukativ përqendrohet vetëm në analizë.

Le të shqyrtojmë një shembull tipik të një detyre analitike të thjeshtë në tri variante dhe të shohim se çfarë përbërësish mund të ndodhin.

Dhe si shembull përsëri, ne do të shqyrtojmë variacione të ngjashme të detyrës së mbledhjes së të dhënave dhe krahasimit të komuniteteve për:

  1. Dy subreddite në Reddit
  2. Dy seksione në Habr
  3. Dy grupe në Odnoklassniki

Qasje hipotetike në teori

Hapni faqen dhe lexoni shembujt, nëse kuptohet, dedikoni disa orë për lexim, disa orë për kodin sipas shembujve dhe për të debug-uar. Shtoni disa orë për mbledhjen. Shtoni disa orë për rezervë (dyfishoni dhe shtoni N orë).

Çelësi është: vlerësimi i kohës bazohet në supozime dhe spekulime për sa kohë do të zgjasë kjo.

Të fillosh analizën e kohës, është e nevojshme të vlerësosh këto parametra për detyrën hipotetike të përshkruar më sipër:

  • Cili është madhësia e të dhënave dhe sa duhet të mbledhësh fizikisht (*shih më poshtë*).
  • Cili është koha e grumbullimit të një regjistrimi dhe sa duhet të presim para se të mund të grumbullojmë të dytin.
  • Të përfshijmë kodin për ruajtjen e gjendjes dhe fillimin e rinisjes, kur (dhe jo nëse) gjithçka bie.
  • Të kuptojmë nëse na nevojitet autorizimi dhe të përfshijmë kohën për të marrë qasje përmes API.
  • Të përfshijmë numrin e gabimeve si një funksion i kompleksitetit të të dhënave — të vlerësojmë sipas detyrës specifike: struktura, sa transformime, çfarë dhe si do të ekzekutojmë.
  • Të përfshijmë gabimet e rrjetit dhe probleme me sjellje jo standarde të projektit.
  • Të vlerësojmë nëse funksionet e nevojshme janë në dokumentacion dhe nëse jo, si dhe sa duhet për një zgjidhje alternative.

E rëndësishme është se për të vlerësuar kohën — ju faktikisht duhet të investoni kohë dhe përpjekje për «eksplorim aktiv» — vetëm atëherë planifikimi juaj do të jetë adekuat. Prandaj, pavarësisht se sa do t'ju sugjerojnë të thoni «sa kohë nevojitet për të grumbulluar të dhënat» — sigurohuni të keni kohë për një analizë paraprake dhe argumentoni se sa do të ndryshojë koha në varësi të parametrave realë të detyrës.

Dhe tani do të demonstrojmë shembuj konkretë ku këto parametra do të ndryshojnë.

Pika kyçe: vlerësimi bazohet në analizën e faktorëve kryesorë që ndikojnë në volum dhe kompleksitetin e punës.

Një vlerësim i bazuar në supozime është një qasje e mirë kur elementet funksionale janë mjaft të vogla dhe nuk ka shumë faktorë që mund të ndikojnë ndjeshëm në strukturën e detyrës. Por në rastin e disa detyrave të Data Science, faktorët e tillë bëhen shumë të shumtë dhe një qasje e tillë bëhet e papërshtatshme.

Krahasimi i komuniteteve Reddit

Le të fillojmë me rastin më të thjeshtë (siç do të dalë më vonë). Në të vërtetë, nëse jemi të sinqertë, kemi një rast pothuajse të përsosur, le të verifikojmë kontrollin tonë të kompleksitetit:

  • Ka një API të pastër, të kuptueshëm dhe të dokumentuar.
  • Mund të krijohet me shumë lehtësi dhe automatikisht një token.
  • Ka python wrapper — me plot shembuj.
  • Një komunitet që merret me analizën dhe mbledhjen e të dhënave në Reddit (duke përfshirë video në YouTube që shpjegojnë se si të përdoret python wrapper) ja për shembull.
  • Metodat që na nevojiten, me siguri ekzistojnë në API. Më shumë se kaq, kodi duket i kompakt dhe i pastër, më poshtë është një shembull i funksionit që mbledh komentet për një postim.

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

Marre nga këtë selekcioni grupe të dobishme për utilitarë.

Megjithëse ky është rasti më i mirë, ka disa faktorë të rëndësishëm nga jeta reale që duhet të marrim parasysh:

  • Limitet e API-së – jemi të detyruar të marrim të dhënat në grupe (të presim midis kërkesave etj).
  • Koha e mbledhjes – për një analizë të plotë dhe krahasim, do të duhen një sasi e konsiderueshme kohe që thjesht spider të kalojë përmes subredd-it.
  • Boti duhet të funksionojë në server – nuk mund ta nisin thjesht në laptop, ta vendosni në çantë dhe të shkoni për punë. Prandaj e kam vendosur gjithçka në VPS. Me kodin promocional habrahabr10 mund të kurseni 10% të çmimit.
  • Paaftësia fizike për të aksesuar disa të dhëna (ato janë të dukshme vetëm për admina ose mblidhen shumë me vështirësi) – duhet marrë parasysh, jo të gjitha të dhënat mund të mblidhen në një kohë të arsyeshme.
  • Gabimet e punës së rrjetit: puna me rrjetin – është e vështirë.
  • Këto janë të dhëna të vërteta – ato nuk janë ndonjëherë të pastra.

Sigurisht, është e nevojshme të përfshihen nuancat e përmendura në zhvillim. Orët/ditat specifike varen nga përvoja e zhvillimit apo eksperienca në punë me detyra të ngjashme, megjithatë ne shohim se këtu detyra është krejtësisht inxhinierike dhe nuk kërkon lëvizje të tjera për zgjidhje — mund të vlerësohet, përshkruhet dhe realizohet shumë mirë.

Krahasimi i seksioneve të Habrit

Tani kalojmë në një rast më interesant dhe jo trivial për krahasimin e flukseve dhe/ose seksioneve të Habrit.

Le të kontrollojmë listën tonë të vështirësive — këtu, për të kuptuar çdo pikë, do të duhet të eksplorojmë pak detyrën dhe të eksperimentojmë.

  • Fillimisht mendoni se ka një API, por në fakt nuk ka. Po, Habri ka një API, por ai është i papërballueshëm për përdoruesit (ndoshta as që funksionon në tërësi).
  • Pastaj thjesht filloni të parse html — «import requests», çfarë mund të shkojë keq?
  • Dhe si mund të parse? Qasja më e thjeshtë dhe më shpesh e përdorur është të iteroni përmes ID-ve, e cila nuk është më e efektshmja dhe do të duhet të trajtoni raste të ndryshme — për shembull, shpërndarja e ID-ve reale në mesin e të gjithë atyre ekzistuese.

    Çfarë mund të shkojë keq me Shkencën e Të Dhënave? Grumbullimi i të dhënave
    Marre nga këtë të artikullit.

  • Të dhënat e papërpunuara, të mbështjella në HTML mbi rrjet — janë një dhimbje. Për shembull, dëshiron të mbledhësh dhe ruash vlerësimin e një artikulli: e nxore score nga html dhe vendose ta ruash si një numër për përpunim të mëtejshëm: 

    1) int(score) shkakton një gabim: pasi në Habre minus, si për shembull në rreshtin "–5" — është një gjithpërfshirës i shkurtër, dhe jo një shenjë minus (papritmas, apo jo?), prandaj në një moment duhej të rrisja parserin me një fikës të tillë të tmerrshëm.

    provoni:
          score_txt = post.find(class_="score").text.replace(u"–","-").replace(u"+","+")
          score = int(score_txt)
          nëse kontrollo_datën(date):
            post_score += score
    

    Datat, pluset dhe minuset mund të mos jenë fare (siç e shohim më sipër në funksionin kontrollo_datën dhe ka ndodhur kjo).

    2) Karakteret speciale të paekranuara — ato do të vijnë, duhet të jesh gati.

    3) Struktura ndryshon në varësi të tipit të postimit.

    4) Postimet e vjetra mund të kenë **strukturë të çuditshme**.

  • Në thelb, përpunimi i gabimeve dhe çfarë mund të ndodhe apo jo, do të duhet të përpunohet dhe nuk mund të parashikohet me siguri se çfarë do të shkojë keq dhe si mund të jetë struktura dhe ku do të bjerë — thjesht do të duhet të provosh dhe të marrësh parasysh gabimet që hedh parseri.
  • Pastaj, kuptoni se duhet të bëni parser në disa procese, ndryshe e gjithë kjo do të zgjasë më shumë se 30 orë (ky është vetëm koha e ekzekutimit të një parseri në një proces, i cili fle dhe nuk bie nën ndonjë bllokim). Në këtë artikull, kjo çoi në një moment të tillë në një skemë të ngjashme:

Çfarë mund të shkojë keq me Shkencën e Të Dhënave? Grumbullimi i të dhënave

Pra, lista e kontrollit për vështirësinë:

  • Puna me rrjetin dhe parserin HTML me iterim dhe përjashtim sipas ID-ve.
  • Dokumente me strukturë të ndryshme.
  • Më shumë vende ku kodi mund të bjerë lehtësisht.
  • Është e nevojshme të shkruani || kod.
  • Mungon dokumentacioni i nevojshëm, shembujt e kodit dhe/ose komuniteti.

Vlerësimi i kushtëzuar i kohës për këtë detyrë do të jetë 3-5 herë më i lartë se sa mbledhja e të dhënave nga Reddit.

Krahasimi i grupeve në Odnoklassniki

Të kalojmë në rastin më teknik të interesant nga ato të përmendura. Për mua ishte i rëndësishëm pikërisht sepse fillimisht duket mjaft trivial, por në të vërtetë nuk është – sapo të klikoni në të me një tryezë.

Do të fillojmë me listën tonë të kontrollit për vështirësinë dhe do të theksojmë se shumë prej tyre do të jenë shumë më të ndërlikuara se sa duken në fillim:

  • Ka API, por funksionet e nevojshme janë pothuajse plotësisht të mungueshme.
  • Për disa funksione, duhet të kërkoni akses përmes postës, domethënë dhënia e aksesit nuk është e menjëhershme.
  • Ai është dokumentuar tmerrësisht (duke filluar që terminologjia ruse dhe angleze përzihen gjithandej, dhe kjo ndodh në mënyrë krejtësisht të papërshtatshme - herë pas here duhet thjesht të gjuajmë se çfarë kërkohet) dhe, për më tepër, nuk është i dizajnuar për të marrë të dhëna, për shembull, funksionin që na nevojitet.
  • Kërkon një sesion në dokumentacion, ndërsa në praktikë nuk e përdor atë - dhe nuk ka asnjë mënyrë për të kuptuar detajet e të gjithë modëve të API, përveç se të eksperimentohet dhe të shpresohet që diçka të funksionojë.
  • Nuk ka shembuj dhe komunitet, pika e vetme e mbështetjes në mbledhjen e informacionit është një wrapper në Python (pa shumë shembuj përdorimi).
  • Opsioni më funksional duket se është Selenium, pasi shumë nga të dhënat e nevojshme janë të mbyllura.
    1) Pra, ndodh autorizimi përmes një përdoruesi të rremë (dhe regjistrimi me dorë).

    2) Megjithatë, me Selenium nuk ka asnjë garanci për funksionimin e saktë dhe të përsëritur (të paktën në rastin e ok.ru, me siguri).

    3) Site-i Ok.ru ka gabime JavaScript dhe ndonjëherë sillet çuditshëm dhe në mënyrë të papërshtatshme.

    4) Duhet të merret me paginimin, ngarkimin e elementeve etj…

    5) Gabimet e API-së që jep të dhëna, do duhet të trajtohen në mënyrë të përshkruar, për shembull, kështu (një copë kod eksperimental):

    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
    

    Gabimi im më i preferuar ishte:

    OdnoklassnikiError("Gabim(kodi: 'Nuk ka', përshkrimi: 'gabim HTTP', metoda: 'discussions.getComments', parametrot: …)")

    6) Në përfundim, varianti Selenium + API duket si zgjidhja më logjike.

  • Duhet ruajtja e gjendjes dhe rinisja e sistemit, trajtimi i shumë gabimeve, përfshirë sjelljen e pasigurt të faqes — sidomos këto gabime janë të vështira për t'u imagjinuar (nëse nuk shkruani profesionalisht parsera, sigurisht).

Vlerësimi i kushteve të kohës për këtë detyrë do të jetë 3-5 herë më i lartë se sa për mbledhjen e të dhënave nga Habra. Edhe pse në rastin e Habras ne përdorim një qasje frontale me parsing HTML, në rastin e OK ne mund të punojmë me API në vende kritike.

Përfundimet

Pavarësisht se si ju kërkohet të jepni një vlerësim të afateve "në vend" (ne kemi planifikim sot!), vëllimi i modulit të procesit të të dhënave të pipeline është praktikisht e pamundur të vlerësohet, madje edhe cilësisht, pa analizuar parametrat e detyrës.

Për të folur pak më filozofikisht, strategjitë e vlerësimit në agile përshtaten mirë për detyrat inxhinierike, por për detyrat më eksperimentale dhe, në njëfarë kuptimi, "kreative" dhe kërkimore, pra, më pak të parashikueshme, shfaqen vështirësi, si në shembujt e ngjashëm me ato që kemi shqyrtuar këtu.

Sigurisht, grumbullimi i të dhënave është një shembull ilustrues shumë i gjallë - zakonisht kjo detyrë duket jashtëzakonisht e thjeshtë dhe teknikisht e lehtë, dhe pikërisht në detaje shpesh qëndron djalli. Edhe në këtë detyrë është e mundur të tregohet e gjithë gama e mundësive për ato që mund të shkojnë keq dhe sa shumë mund të zgjatet puna.

Nëse shikojmë shkurtimisht karakteristikat e detyrës pa eksperimente të tjera, Reddit dhe OK duken të ngjashme: ka API, paketë python, por në thelb, ndryshimi është i madh. Nëse e gjykojmë nga këto parametra, parseri i Habrës duket më i komplikuar se OK - por në praktikë është krejtësisht e kundërta dhe pikërisht këtë mund ta zbulojmë duke kryer eksperimente të thjeshta për analizën e parametrave të detyrës.

Sipas تجربës time, qasja më efektive është një vlerësim i përafërt i kohës që do të nevojitet për analizën paraprake dhe eksperimentet e para të thjeshta, si dhe leximin e dokumentacionit – këto do t'ju lejojnë të jepni një vlerësim të saktë për punën e gjithëherë. Në terma të metodologjisë së njohur agile – kërkoj që të hapet një biletë për “vlerësimin e parametrave të detyrës”, në bazë të së cilës mund të jap një vlerësim për atë që mund të realizohet brenda “sprint-it” dhe të jap një vlerësim më të saktë për çdo detyrë.

Prandaj, argumenti më efektiv duket të jetë ai që do të tregonte një specialisti “jo teknik” se sa shumë do të ndryshojë koha dhe burimet në varësi të parametrave që ende duhet të vlerësohen.

Çfarë mund të shkojë keq me Shkencën e Të Dhënave? Grumbullimi i të dhënave

Burimi: habr.com

Bleni hostim të besueshëm për faqe me mbrojtje nga DDoS, serverë VPS VDS 🔥 Bleni hostim të besueshëm për faqe me mbrojtje nga DDoS, serverë VPS VDS | ProHoster