Mis võib andmeteadusega valesti minna? Andmete kogumine

Mis võib andmeteadusega valesti minna? Andmete kogumine
Praegu on andmeteaduse kursusi 100500 XNUMX ja on juba ammu teada, et andmeteaduses saab kõige rohkem raha teenida andmeteaduse kursuste kaudu (milleks kaevata, kui saab labidaid müüa?). Nende kursuste peamiseks puuduseks on see, et neil pole reaalse tööga mingit pistmist: keegi ei anna teile puhtaid, töödeldud andmeid vajalikus formaadis. Ja kui kursuselt lahkute ja reaalset probleemi lahendama asute, ilmneb palju nüansse.

Seetõttu alustame märkmete sarja “Mis võib andmeteadusega valesti minna”, mis põhineb minu, minu kaaslaste ja kolleegidega juhtunud tõsistel sündmustel. Analüüsime tüüpilisi andmeteaduse ülesandeid tõeliste näidete abil: kuidas see tegelikult juhtub. Alustame täna andmete kogumise ülesandega.

Ja esimene asi, mille peale inimesed pärisandmetega töötama asudes komistavad, on tegelikult meie jaoks kõige olulisemate andmete kogumine. Selle artikli põhisõnum:

Alahindame süstemaatiliselt andmete kogumiseks, puhastamiseks ja ettevalmistamiseks kuluvat aega, ressursse ja vaeva.

Ja mis kõige tähtsam, arutame, mida selle vältimiseks teha.

Erinevatel hinnangutel kulub puhastamisele, transformeerimisele, andmetöötlusele, funktsioonide inseneritööle jne 80-90% ajast ja analüüs 10-20%, samas kui peaaegu kogu õppematerjal keskendub eranditult analüüsile.

Vaatame tüüpilise näitena lihtsat analüütilist probleemi kolmes versioonis ja vaatame, mis on „raskendavad asjaolud”.

Ja näitena käsitleme taas andmete kogumise ja kogukondade võrdlemise ülesande sarnaseid variatsioone järgmistel juhtudel:

  1. Kaks Redditi alamrediti
  2. Kaks osa Habr
  3. Kaks Odnoklassniki rühma

Tingimuslik lähenemine teoorias

Avage sait ja lugege näiteid, kui see on selge, eraldage paar tundi lugemiseks, paar tundi koodi jaoks, kasutades näiteid ja silumist. Lisage kogumiseks paar tundi. Viska paar tundi varuks (korruta kahega ja lisa N tundi).

Põhipunkt: Ajahinnangud põhinevad oletustel ja oletustel selle kohta, kui kaua see aega võtab.

Ajaanalüüsi on vaja alustada ülalkirjeldatud tingimusliku probleemi järgmiste parameetrite hindamisega:

  • Mis on andmete suurus ja kui palju neist tuleb füüsiliselt koguda (*vt allpool*).
  • Mis on ühe plaadi kogumisaeg ja kui kaua pead ootama, enne kui saad teise koguda?
  • Kaaluge koodi kirjutamist, mis salvestab oleku ja alustab taaskäivitamist, kui (mitte kui) kõik ebaõnnestub.
  • Mõelge välja, kas vajame autoriseerimist, ja määrake API kaudu juurdepääsu saamiseks aeg.
  • Määrake vigade arv andmete keerukuse funktsioonina – hinnake konkreetse ülesande jaoks: struktuur, kui palju teisendusi, mida ja kuidas ekstraktida.
  • Parandage võrguvead ja projekti ebastandardse käitumisega seotud probleemid.
  • Hinnake, kas vajalikud funktsioonid on dokumentatsioonis ja kui ei, siis kuidas ja kui palju on vaja lahenduseks.

Kõige tähtsam on see, et aja hindamiseks – tegelikult on vaja kulutada aega ja vaeva "luurele jõus" - ainult siis on teie planeerimine adekvaatne. Seetõttu olenemata sellest, kui palju teid sunnitakse ütlema "kui kaua võtab andmete kogumine aega" - ostke endale aega eelanalüüsiks ja arutlege, kui palju aeg varieerub sõltuvalt probleemi tegelikest parameetritest.

Ja nüüd näitame konkreetseid näiteid, kus sellised parameetrid muutuvad.

Võtmepunkt: hinnang põhineb töö ulatust ja keerukust mõjutavate võtmetegurite analüüsil.

Arvamuspõhine hindamine on hea lähenemine, kui funktsionaalsed elemendid on piisavalt väikesed ja pole palju tegureid, mis võivad probleemi kujundamist oluliselt mõjutada. Kuid mitme andmeteaduse probleemi puhul muutuvad sellised tegurid äärmiselt arvukaks ja selline lähenemine muutub ebapiisavaks.

Redditi kogukondade võrdlus

Alustame kõige lihtsamast juhtumist (nagu hiljem selgub). Üldiselt, kui täiesti aus olla, on meil peaaegu ideaalne juhtum, vaatame meie keerukuse kontrollnimekirja:

  • Seal on puhas, selge ja dokumenteeritud API.
  • See on äärmiselt lihtne ja mis kõige tähtsam, märgi saadakse automaatselt.
  • On python ümbris - paljude näidetega.
  • Kogukond, mis analüüsib ja kogub andmeid redditi kohta (isegi YouTube'i videote jaoks, mis selgitavad pythoni mähise kasutamist) Näiteks.
  • Meetodid, mida vajame, on tõenäoliselt API-s olemas. Lisaks näeb kood välja kompaktne ja puhas, allpool on näide funktsioonist, mis kogub postituse kohta kommentaare.

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

Võetud see valik mugavaid utiliite pakkimiseks.

Vaatamata sellele, et see on parim juhtum, tasub siiski arvestada mitmete oluliste teguritega tegelikust elust:

  • API piirangud – oleme sunnitud andmeid võtma pakettidena (päringute vaheline uni jne).
  • Kogumisaeg – täielikuks analüüsiks ja võrdlemiseks peate varuma märkimisväärset aega, et ämblik saaks subredditist läbi käia.
  • Bot peab töötama serveris – te ei saa seda lihtsalt oma sülearvutis käivitada, seljakotti panna ja oma äri ajama hakata. Nii et ma käivitasin kõike VPS-is. Kasutades sooduskoodi habrahabr10, saate säästa veel 10% kuludest.
  • Osade andmete füüsiline ligipääsmatus (need on administraatoritele nähtavad või liiga raskesti kogutavad) – sellega tuleb arvestada, põhimõtteliselt ei jõua kõiki andmeid piisava aja jooksul koguda.
  • Võrguvead: võrgu loomine on piin.
  • Need on elavad tõelised andmed – need pole kunagi puhtad.

Loomulikult on vaja need nüansid arendusse kaasata. Konkreetsed tunnid/päevad sõltuvad arenduskogemusest või sarnaste ülesannetega töötamise kogemusest, samas näeme, et siin on ülesanne puhtalt insenertehniline ega vaja lahendamiseks täiendavaid kehaliigutusi – kõike saab väga hästi hinnata, ajastada ja teha.

Habri lõikude võrdlus

Liigume edasi huvitavama ja mittetriviaalsema habri lõimede ja/või lõikude võrdlemise juhtumi juurde.

Kontrollime oma keerukuse kontrollnimekirja - siin peate iga punkti mõistmiseks pisut ülesande endasse süvenema ja katsetama.

  • Alguses arvate, et API on olemas, kuid seda pole. Jah, jah, Habril on API, kuid see pole kasutajatele lihtsalt juurdepääsetav (või võib-olla see ei tööta üldse).
  • Seejärel alustate lihtsalt html-i sõelumist - "imporditaotlused", mis võib valesti minna?
  • Kuidas ikkagi sõeluda? Lihtsaim ja sagedamini kasutatav lähenemine on ID-de itereerimine, pange tähele, et see ei ole kõige tõhusam ja peab käsitlema erinevaid juhtumeid – siin on näide tegelike ID-de tihedusest kõigi olemasolevate seas.

    Mis võib andmeteadusega valesti minna? Andmete kogumine
    Võetud see artiklid.

  • Veebi peal HTML-i mähitud töötlemata andmed on piin. Näiteks soovite koguda ja salvestada artikli hinnangu: rebisite skoori html-ist välja ja otsustasite selle edasiseks töötlemiseks numbrina salvestada: 

    1) int(score) annab vea: kuna Habré peal on miinus, nagu näiteks real “–5” - see on kriips, mitte miinusmärk (ootamatult, eks?), nii et mingi hetk pidin parseri sellise kohutava parandusega ellu äratama.

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

    Kuupäeva, plusse ja miinuseid ei pruugi üldse olla (nagu näeme ülal funktsioonis check_date, see juhtus).

    2) Põgenemata eritegelased - nad tulevad, peate olema valmis.

    3) Struktuur muutub sõltuvalt posti tüübist.

    4) Vanadel postitustel võib olla **veider ülesehitus**.

  • Sisuliselt tuleb tegeleda vigade käsitlemisega ja sellega, mis võib juhtuda või mitte juhtuda ja sa ei saa kindlalt ennustada, mis valesti läheb ja kuidas muidu struktuur võib olla ja mis kuhu kukub - tuleb lihtsalt proovida ja arvestada vead, mida parser viskab.
  • Siis saad aru, et tuleb sõeluda mitmes lõimes, vastasel juhul võtab ühes sõelumine aega 30+ tundi (see on puhtalt juba töötava ühelõimelise parseri täitmisaeg, mis magab ja ei kuulu mingite keeldude alla). IN see artikkel, viis see mingil hetkel sarnase skeemini:

Mis võib andmeteadusega valesti minna? Andmete kogumine

Kogu kontrollnimekiri keerukuse järgi:

  • Võrguga töötamine ja HTML-i sõelumine iteratsiooni ja ID-põhise otsinguga.
  • Heterogeense struktuuriga dokumendid.
  • Seal on palju kohti, kus kood võib kergesti kukkuda.
  • On vaja kirjutada || kood.
  • Puuduvad vajalikud dokumendid, koodinäited ja/või kogukond.

Selle ülesande hinnanguline aeg on 3–5 korda pikem kui Redditist andmete kogumiseks.

Odnoklassniki rühmade võrdlus

Liigume edasi kirjeldatud tehniliselt kõige huvitavama juhtumi juurde. Minu jaoks oli see huvitav just seetõttu, et esmapilgul tundub see üsna triviaalne, kuid see ei osutu sugugi nii - niipea, kui sellesse pulka torkate.

Alustame oma raskuste kontrollnimekirjaga ja pange tähele, et paljud neist osutuvad palju keerulisemaks, kui esmapilgul paistab:

  • API on olemas, kuid sellel puuduvad peaaegu täielikult vajalikud funktsioonid.
  • Teatud funktsioonidele peate taotlema juurdepääsu posti teel, see tähendab, et juurdepääsu andmine ei toimu hetkega.
  • See on kohutavalt dokumenteeritud (alustuseks on vene- ja ingliskeelsed terminid igal pool segamini ja täiesti ebajärjekindlalt - vahel tuleb lihtsalt arvata, mida nad kuskilt sinult tahavad) ja pealegi ei sobi kujundus näiteks andmete hankimiseks. , funktsioon, mida me vajame.
  • Nõuab dokumentatsioonis seanssi, kuid tegelikult ei kasuta seda – ja API-režiimide kõigist keerukustest ei saa muudmoodi aru, kui ainult ringi tuhnida ja loota, et midagi õnnestub.
  • Näiteid ja kogukonda pole, ainuke tugipunkt teabe kogumisel on väike ümbris Pythonis (ilma paljude kasutusnäideteta).
  • Seleen näib olevat kõige toimivam variant, kuna paljud vajalikud andmed on lukus.
    1) See tähendab, et autoriseerimine toimub fiktiivse kasutaja kaudu (ja käsitsi registreerimine).

    2) Seleeniga aga garantiid korrektseks ja korratavaks tööks pole (vähemalt ok.ru puhul kindlasti).

    3) Veebisait Ok.ru sisaldab JavaScripti vigu ning käitub mõnikord kummaliselt ja ebajärjekindlalt.

    4) Peate tegema lehekülgi, laadima elemente jne...

    5) API-vigu, mida ümbris annab, tuleb kohmakalt käsitleda, näiteks järgmiselt (eksperimentaalse koodi tükk):

    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
    

    Minu lemmikviga oli:

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

    6) Lõppkokkuvõttes tundub Selenium + API kõige ratsionaalsem variant.

  • Olek on vaja salvestada ja süsteem taaskäivitada, käsitleda paljusid vigu, sealhulgas saidi ebajärjekindlat käitumist - ja neid vigu on üsna raske ette kujutada (muidugi, kui te parsereid professionaalselt ei kirjuta).

Selle ülesande tingimuslik ajaprognoos on 3–5 korda suurem kui Habrilt andmete kogumisel. Vaatamata sellele, et Habri puhul kasutame HTML-i parsimisega frontaalset lähenemist ja OK puhul saame API-ga kriitilistes kohtades töötada.

Järeldused

Ükskõik kui palju teilt nõutakse mahuka andmetöötluskonveieri mooduli "kohapeal" (plaanime täna!) tähtaegade hindamist, pole täitmisaega peaaegu kunagi võimalik isegi kvalitatiivselt hinnata ilma ülesande parameetreid analüüsimata.

Veidi filosoofilisemalt öeldes toimivad paindlikud hindamisstrateegiad hästi inseneriülesannete puhul, kuid probleemid, mis on rohkem eksperimentaalsed ja teatud mõttes "loovad" ja uurimuslikud, st vähem etteaimatavad, tekitavad raskusi, nagu sarnaste teemade näidetes. mida me siin arutanud oleme.

Loomulikult on andmete kogumine vaid musternäide – tavaliselt on see uskumatult lihtne ja tehniliselt lihtne ülesanne ning saatan peitub sageli detailides. Ja just selle ülesande puhul saame näidata kõiki võimalikke valikuid, mis võib valesti minna ja kui kaua töö täpselt aega võib võtta.

Kui heita pilk ülesande omadustele ilma täiendavate katseteta, näevad Reddit ja OK välja sarnased: API, python wrapper on olemas, kuid sisuliselt on erinevus tohutu. Nende parameetrite järgi otsustades tundub Habri pars keerulisem kui OK – kuid praktikas on see hoopis vastupidine ja just seda saab selgeks teha lihtsaid katseid ülesande parameetrite analüüsimiseks.

Minu kogemuse kohaselt on kõige tõhusam viis hinnata ligikaudselt aega, mis kulub eelanalüüsiks endaks ja lihtsateks esimesteks katseteks, lugedes dokumentatsiooni – see võimaldab anda täpse hinnangu kogu töö kohta. Populaarse agiilse metoodika osas palun koostada pilet “ülesande parameetrite hindamiseks”, mille alusel saan anda hinnangu, mida on võimalik “sprindi” raames korda saata ja iga kohta täpsema hinnangu anda. ülesanne.

Seetõttu tundub kõige tõhusam argument, mis näitaks "mittetehnilisele" spetsialistile, kui palju aega ja ressursse varieerub sõltuvalt parameetritest, mida tuleb veel hinnata.

Mis võib andmeteadusega valesti minna? Andmete kogumine

Allikas: www.habr.com

Lisa kommentaar