Apa yang salah dengan Ilmu Data? Pengumpulan data

Apa yang salah dengan Ilmu Data? Pengumpulan data
Saat ini terdapat 100500 kursus Ilmu Data dan telah lama diketahui bahwa sebagian besar uang dalam Ilmu Data dapat diperoleh melalui kursus Ilmu Data (untuk apa menggali ketika Anda bisa menjual sekop?). Kerugian utama dari kursus ini adalah tidak ada hubungannya dengan pekerjaan nyata: tidak ada yang akan memberi Anda data bersih dan diproses dalam format yang diperlukan. Dan ketika Anda meninggalkan kursus dan mulai memecahkan masalah nyata, banyak perbedaan yang muncul.

Oleh karena itu, kami memulai serangkaian catatan “Apa yang salah dengan Ilmu Data”, berdasarkan peristiwa nyata yang terjadi pada saya, kawan, dan kolega. Kami akan menganalisis tugas-tugas Ilmu Data yang umum menggunakan contoh nyata: bagaimana hal ini sebenarnya terjadi. Mari kita mulai hari ini dengan tugas pengumpulan data.

Dan hal pertama yang membuat orang tersandung ketika mereka mulai bekerja dengan data nyata adalah mengumpulkan data yang paling relevan bagi kami. Pesan utama artikel ini:

Kami secara sistematis meremehkan waktu, sumber daya, dan upaya yang diperlukan untuk mengumpulkan, membersihkan, dan menyiapkan data.

Dan yang terpenting, kita akan membahas apa yang harus dilakukan untuk mencegah hal ini.

Menurut berbagai perkiraan, pembersihan, transformasi, pemrosesan data, rekayasa fitur, dll. memakan waktu 80-90%, dan analisis 10-20%, sementara hampir semua materi pendidikan berfokus secara eksklusif pada analisis.

Mari kita lihat masalah analitis sederhana dalam tiga versi sebagai contoh tipikal dan lihat apa yang dimaksud dengan “keadaan yang memberatkan”.

Dan sebagai contoh, sekali lagi, kami akan mempertimbangkan variasi serupa dalam tugas pengumpulan data dan membandingkan komunitas untuk:

  1. Dua subreddit Reddit
  2. Dua bagian Habr
  3. Dua kelompok Odnoklassniki

Pendekatan kondisional dalam teori

Buka situsnya dan baca contohnya, jika sudah jelas sisihkan beberapa jam untuk membaca, beberapa jam untuk kode menggunakan contoh dan debugging. Tambahkan beberapa jam untuk pengumpulan. Masukkan beberapa jam sebagai cadangan (kalikan dua dan tambahkan N jam).

Poin Penting: Perkiraan waktu didasarkan pada asumsi dan dugaan mengenai berapa lama waktu yang dibutuhkan.

Analisis waktu perlu dimulai dengan memperkirakan parameter berikut untuk masalah kondisional yang dijelaskan di atas:

  • Berapa ukuran datanya dan berapa banyak data yang perlu dikumpulkan secara fisik (*lihat di bawah*).
  • Berapa lama waktu pengumpulan untuk satu rekaman dan berapa lama Anda harus menunggu sebelum dapat mengumpulkan rekaman kedua?
  • Pertimbangkan untuk menulis kode yang menyimpan status dan memulai ulang ketika (bukan jika) semuanya gagal.
  • Cari tahu apakah kita memerlukan otorisasi dan atur waktu untuk mendapatkan akses melalui API.
  • Tetapkan jumlah kesalahan sebagai fungsi kompleksitas data - evaluasi untuk tugas tertentu: struktur, berapa banyak transformasi, apa dan bagaimana mengekstraknya.
  • Memperbaiki kesalahan jaringan dan masalah dengan perilaku proyek yang tidak standar.
  • Nilai apakah fungsi yang diperlukan ada dalam dokumentasi dan jika tidak, lalu bagaimana dan berapa banyak yang diperlukan untuk solusinya.

Hal yang paling penting adalah untuk memperkirakan waktu - Anda benar-benar perlu meluangkan waktu dan tenaga untuk "pengintaian yang berlaku" - hanya dengan demikian perencanaan Anda akan memadai. Oleh karena itu, tidak peduli seberapa besar Anda didorong untuk mengatakan "berapa lama waktu yang dibutuhkan untuk mengumpulkan data" - luangkan waktu untuk analisis awal dan perdebatkan seberapa besar waktu yang dibutuhkan akan bervariasi tergantung pada parameter masalah yang sebenarnya.

Dan sekarang kami akan menunjukkan contoh spesifik di mana parameter tersebut akan berubah.

Poin Utama: Perkiraan ini didasarkan pada analisis faktor-faktor utama yang mempengaruhi ruang lingkup dan kompleksitas pekerjaan.

Estimasi berbasis tebakan adalah pendekatan yang baik jika elemen fungsionalnya cukup kecil dan tidak banyak faktor yang dapat mempengaruhi desain masalah secara signifikan. Namun dalam kasus sejumlah masalah Ilmu Data, faktor-faktor tersebut menjadi sangat banyak dan pendekatan seperti itu menjadi tidak memadai.

Perbandingan komunitas Reddit

Mari kita mulai dengan kasus yang paling sederhana (ternyata nanti). Secara umum, sejujurnya, kita mempunyai kasus yang hampir ideal, mari kita periksa daftar kompleksitas kita:

  • Ada API yang rapi, jelas dan terdokumentasi.
  • Ini sangat sederhana dan yang terpenting, token diperoleh secara otomatis.
  • Ada pembungkus python - dengan banyak contoh.
  • Komunitas yang menganalisis dan mengumpulkan data di reddit (bahkan hingga video YouTube yang menjelaskan cara menggunakan python wrapper) Inilah contohnya.
  • Metode yang paling kita perlukan kemungkinan besar ada di API. Selain itu, kodenya terlihat ringkas dan bersih, di bawah ini adalah contoh fungsi yang mengumpulkan komentar pada sebuah postingan.

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

Diambil dari ini pilihan utilitas yang nyaman untuk membungkus.

Meskipun ini adalah kasus terbaik, ada baiknya mempertimbangkan sejumlah faktor penting dari kehidupan nyata:

  • Batasan API - kami terpaksa mengambil data secara batch (tidur di antara permintaan, dll.).
  • Waktu pengumpulan - untuk analisis dan perbandingan lengkap, Anda harus menyisihkan banyak waktu agar laba-laba dapat menelusuri subreddit.
  • Bot harus berjalan di server—Anda tidak bisa hanya menjalankannya di laptop, memasukkannya ke dalam ransel, dan menjalankan bisnis Anda. Jadi saya menjalankan semuanya di VPS. Dengan menggunakan kode promosi habrahabr10 Anda dapat menghemat 10% biaya lagi.
  • Tidak dapat diaksesnya beberapa data secara fisik (terlihat oleh administrator atau terlalu sulit untuk dikumpulkan) - hal ini harus diperhitungkan; pada prinsipnya, tidak semua data dapat dikumpulkan dalam waktu yang memadai.
  • Kesalahan jaringan: Jaringan itu menyusahkan.
  • Ini adalah data nyata yang nyata - tidak pernah murni.

Tentu saja nuansa tersebut perlu dimasukkan dalam pembangunan. Jam/hari tertentu bergantung pada pengalaman pengembangan atau pengalaman mengerjakan tugas serupa, namun kami melihat bahwa di sini tugas tersebut murni rekayasa dan tidak memerlukan gerakan tubuh tambahan untuk menyelesaikannya - semuanya dapat dinilai, dijadwalkan, dan dilakukan dengan sangat baik.

Perbandingan bagian Habr

Mari beralih ke kasus yang lebih menarik dan tidak sepele dalam membandingkan thread dan/atau bagian Habr.

Mari kita periksa daftar kompleksitas kita - di sini, untuk memahami setiap poin, Anda harus menggali sedikit ke dalam tugas itu sendiri dan bereksperimen.

  • Awalnya Anda mengira ada API, tapi ternyata tidak. Ya, ya, Habr memiliki API, tetapi tidak dapat diakses oleh pengguna (atau mungkin tidak berfungsi sama sekali).
  • Kemudian Anda baru saja mulai menguraikan html - "permintaan impor", apa yang salah?
  • Bagaimana cara menguraikannya? Pendekatan paling sederhana dan paling sering digunakan adalah dengan mengulangi ID, perhatikan bahwa ini bukan yang paling efisien dan harus menangani kasus yang berbeda - berikut adalah contoh kepadatan ID asli di antara semua ID yang ada.

    Apa yang salah dengan Ilmu Data? Pengumpulan data
    Diambil dari ini artikel.

  • Data mentah yang dibungkus dalam HTML di atas web sangat menyusahkan. Misalnya, Anda ingin mengumpulkan dan menyimpan peringkat sebuah artikel: Anda merobek skor dari html dan memutuskan untuk menyimpannya sebagai nomor untuk diproses lebih lanjut: 

    1) int(skor) menimbulkan kesalahan: karena di Habré ada tanda minus, seperti, misalnya, pada baris “–5” - ini adalah tanda hubung en, bukan tanda minus (tanpa diduga, bukan?), jadi di pada titik tertentu saya harus menghidupkan parser dengan perbaikan yang buruk.

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

    Mungkin tidak ada tanggal, plus minusnya sama sekali (seperti yang kita lihat di atas pada fungsi check_date, ini yang terjadi).

    2) Karakter khusus yang tidak dapat lolos - mereka akan datang, Anda harus bersiap.

    3) Strukturnya berubah tergantung pada jenis postingan.

    4) Postingan lama mungkin memiliki **struktur yang aneh**.

  • Pada dasarnya, penanganan kesalahan dan apa yang mungkin atau tidak terjadi harus ditangani dan Anda tidak dapat memprediksi dengan pasti apa yang akan salah dan bagaimana strukturnya dan apa yang akan jatuh di mana - Anda hanya perlu mencoba dan mempertimbangkannya. kesalahan yang dilontarkan parser.
  • Kemudian Anda menyadari bahwa Anda perlu mengurai dalam beberapa utas, jika tidak, penguraian dalam satu utas akan memakan waktu 30+ jam (ini murni waktu eksekusi parser utas tunggal yang sudah berfungsi, yang tidak aktif dan tidak termasuk dalam larangan apa pun). DI DALAM ini artikel, hal ini pada suatu saat mengarah pada skema serupa:

Apa yang salah dengan Ilmu Data? Pengumpulan data

Total daftar periksa berdasarkan kompleksitas:

  • Bekerja dengan jaringan dan penguraian html dengan iterasi dan pencarian berdasarkan ID.
  • Dokumen dengan struktur heterogen.
  • Ada banyak tempat di mana kode tersebut dapat dengan mudah jatuh.
  • Penting untuk menulis || kode.
  • Dokumentasi yang diperlukan, contoh kode, dan/atau komunitas tidak ada.

Perkiraan waktu untuk tugas ini akan 3-5 kali lebih lama dibandingkan mengumpulkan data dari Reddit.

Perbandingan grup Odnoklassniki

Mari kita beralih ke kasus yang paling menarik secara teknis. Bagi saya, ini menarik justru karena sekilas terlihat sepele, tetapi ternyata tidak seperti itu sama sekali - begitu Anda menyodoknya.

Mari kita mulai dengan daftar kesulitan kita dan perhatikan bahwa banyak di antaranya ternyata jauh lebih sulit daripada yang terlihat pada awalnya:

  • Ada API, tetapi hampir tidak ada fungsi yang diperlukan di dalamnya.
  • Untuk fungsi tertentu Anda perlu meminta akses melalui surat, artinya pemberian akses tidak terjadi secara instan.
  • Ini sangat terdokumentasi (pertama-tama, istilah Rusia dan Inggris tercampur di mana-mana, dan sama sekali tidak konsisten - terkadang Anda hanya perlu menebak apa yang mereka inginkan dari Anda di suatu tempat) dan, terlebih lagi, desainnya tidak cocok untuk memperoleh data, misalnya , fungsi yang kita perlukan.
  • Memerlukan sesi dalam dokumentasi, tetapi tidak benar-benar menggunakannya - dan tidak ada cara untuk memahami semua seluk-beluk mode API selain melihat-lihat dan berharap sesuatu akan berhasil.
  • Tidak ada contoh dan tidak ada komunitas; satu-satunya titik dukungan dalam mengumpulkan informasi adalah sebuah organisasi kecil pembungkus dengan Python (tanpa banyak contoh penggunaan).
  • Selenium tampaknya menjadi pilihan yang paling bisa diterapkan, karena banyak data yang diperlukan terkunci.
    1) Artinya, otorisasi dilakukan melalui pengguna fiktif (dan registrasi dengan tangan).

    2) Namun, dengan Selenium tidak ada jaminan untuk pekerjaan yang benar dan berulang (setidaknya dalam kasus ok.ru pastinya).

    3) Situs web Ok.ru mengandung kesalahan JavaScript dan terkadang berperilaku aneh dan tidak konsisten.

    4) Anda perlu melakukan penomoran halaman, memuat elemen, dll...

    5) Kesalahan API yang diberikan oleh pembungkus harus ditangani dengan canggung, misalnya, seperti ini (sepotong kode 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
    

    Kesalahan favorit saya adalah:

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

    6) Pada akhirnya, Selenium + API sepertinya pilihan paling rasional.

  • Penting untuk menyimpan status dan memulai ulang sistem, menangani banyak kesalahan, termasuk perilaku situs yang tidak konsisten - dan kesalahan ini cukup sulit untuk dibayangkan (kecuali jika Anda menulis parser secara profesional, tentu saja).

Perkiraan waktu bersyarat untuk tugas ini akan 3-5 kali lebih lama dibandingkan mengumpulkan data dari Habr. Terlepas dari kenyataan bahwa dalam kasus Habr kami menggunakan pendekatan frontal dengan penguraian HTML, dan dalam kasus OK kami dapat bekerja dengan API di tempat-tempat penting.

Temuan

Tidak peduli berapa banyak Anda diminta untuk memperkirakan tenggat waktu “di tempat” (kami berencana hari ini!) dari modul pipeline pemrosesan data yang sangat banyak, waktu eksekusi hampir tidak pernah mungkin untuk diperkirakan bahkan secara kualitatif tanpa menganalisis parameter tugas.

Pada catatan yang sedikit lebih filosofis, strategi estimasi tangkas bekerja dengan baik untuk tugas-tugas teknik, namun masalah yang lebih eksperimental dan, dalam arti tertentu, “kreatif” dan eksploratif, yaitu kurang dapat diprediksi, memiliki kesulitan, seperti dalam contoh topik serupa. yang telah kita bahas di sini.

Tentu saja, pengumpulan data hanyalah contoh utama - ini biasanya merupakan tugas yang sangat sederhana dan tidak rumit secara teknis, dan sering kali ada masalah dalam detailnya. Dan justru pada tugas inilah kami dapat menunjukkan seluruh kemungkinan opsi mengenai apa yang salah dan berapa lama waktu yang dibutuhkan untuk pekerjaan tersebut.

Jika Anda melihat karakteristik tugas tanpa eksperimen tambahan, maka Reddit dan OK terlihat serupa: ada API, pembungkus python, tetapi pada dasarnya perbedaannya sangat besar. Dilihat dari parameter ini, pars Habr terlihat lebih rumit daripada OK - namun dalam praktiknya justru sebaliknya, dan inilah yang dapat diketahui dengan melakukan eksperimen sederhana untuk menganalisis parameter masalahnya.

Menurut pengalaman saya, pendekatan yang paling efektif adalah dengan memperkirakan secara kasar waktu yang Anda perlukan untuk analisis pendahuluan itu sendiri dan eksperimen sederhana pertama, membaca dokumentasi - ini akan memungkinkan Anda memberikan perkiraan yang akurat untuk keseluruhan pekerjaan. Dalam kaitannya dengan metodologi tangkas yang populer, saya meminta Anda untuk membuat tiket untuk “memperkirakan parameter tugas”, yang atas dasar itu saya dapat memberikan penilaian tentang apa yang dapat dicapai dalam “sprint” dan memberikan perkiraan yang lebih akurat untuk setiap parameter tugas. tugas.

Oleh karena itu, argumen yang paling efektif tampaknya adalah argumen yang menunjukkan kepada spesialis “non-teknis” berapa banyak waktu dan sumber daya yang akan bervariasi tergantung pada parameter yang belum dinilai.

Apa yang salah dengan Ilmu Data? Pengumpulan data

Sumber: www.habr.com

Tambah komentar