Điều gì có thể sai với Khoa học dữ liệu? Thu thập dữ liệu

Điều gì có thể sai với Khoa học dữ liệu? Thu thập dữ liệu
Ngày nay có 100500 khóa học Khoa học dữ liệu và từ lâu người ta đã biết rằng bạn có thể kiếm được nhiều tiền nhất trong Khoa học dữ liệu thông qua các khóa học Khoa học dữ liệu (tại sao phải đào khi bạn có thể bán xẻng?). Nhược điểm chính của các khóa học này là chúng không liên quan gì đến công việc thực tế: không ai cung cấp cho bạn dữ liệu đã được xử lý, sạch sẽ ở định dạng được yêu cầu. Và khi bạn rời khỏi khóa học và bắt đầu giải quyết một vấn đề thực sự, nhiều sắc thái sẽ xuất hiện.

Vì vậy, chúng tôi đang bắt đầu một loạt ghi chú “Điều gì có thể xảy ra với Khoa học dữ liệu”, dựa trên những sự kiện có thật đã xảy ra với tôi, các đồng chí và đồng nghiệp của tôi. Chúng tôi sẽ phân tích các nhiệm vụ Khoa học dữ liệu điển hình bằng cách sử dụng các ví dụ thực tế: điều này thực sự xảy ra như thế nào. Hãy bắt đầu ngay hôm nay với nhiệm vụ thu thập dữ liệu.

Và điều đầu tiên mọi người vấp phải khi bắt đầu làm việc với dữ liệu thực là thu thập dữ liệu phù hợp nhất với chúng ta. Thông điệp chính của bài viết này:

Chúng tôi đánh giá thấp một cách có hệ thống thời gian, nguồn lực và công sức cần thiết để thu thập, làm sạch và chuẩn bị dữ liệu.

Và quan trọng nhất, chúng ta sẽ thảo luận những việc cần làm để ngăn chặn điều này.

Theo nhiều ước tính khác nhau, việc dọn dẹp, chuyển đổi, xử lý dữ liệu, kỹ thuật tính năng, v.v. chiếm 80-90% thời gian và phân tích 10-20%, trong khi hầu hết tất cả tài liệu giáo dục đều tập trung hoàn toàn vào phân tích.

Hãy lấy một vấn đề phân tích đơn giản trong ba phiên bản làm ví dụ điển hình và xem “tình tiết tăng nặng” là gì.

Và để làm ví dụ, một lần nữa, chúng ta sẽ xem xét các biến thể tương tự của nhiệm vụ thu thập dữ liệu và so sánh các cộng đồng về:

  1. Hai subreddits Reddit
  2. Hai phần của Habr
  3. Hai nhóm Odnoklassniki

Cách tiếp cận có điều kiện về mặt lý thuyết

Mở trang web và đọc các ví dụ, nếu rõ ràng, hãy dành một vài giờ để đọc, một vài giờ cho mã sử dụng các ví dụ và gỡ lỗi. Thêm một vài giờ cho bộ sưu tập. Dành một vài giờ dự trữ (nhân hai và cộng thêm N giờ).

Điểm mấu chốt: Ước tính thời gian dựa trên các giả định và phỏng đoán về việc sẽ mất bao lâu.

Cần phải bắt đầu phân tích thời gian bằng cách ước tính các tham số sau cho bài toán có điều kiện được mô tả ở trên:

  • Kích thước của dữ liệu là bao nhiêu và cần thu thập bao nhiêu dữ liệu về mặt vật lý (*xem bên dưới*).
  • Thời gian thu thập một bản ghi là bao lâu và bạn phải đợi bao lâu trước khi có thể thu thập bản ghi thứ hai?
  • Hãy cân nhắc việc viết mã để lưu trạng thái và bắt đầu khởi động lại khi (không phải nếu) mọi thứ đều thất bại.
  • Tìm hiểu xem chúng tôi có cần ủy quyền hay không và đặt thời gian để có được quyền truy cập thông qua API.
  • Đặt số lượng lỗi dưới dạng hàm của độ phức tạp dữ liệu - đánh giá cho một tác vụ cụ thể: cấu trúc, số lượng phép biến đổi, nội dung và cách trích xuất.
  • Khắc phục các lỗi và sự cố mạng với hành vi dự án không chuẩn.
  • Đánh giá xem các chức năng cần thiết có trong tài liệu hay không và nếu không thì cần bao nhiêu và như thế nào để giải quyết.

Điều quan trọng nhất là để ước tính thời gian - bạn thực sự cần phải dành thời gian và công sức cho việc "trinh sát lực lượng" - chỉ khi đó kế hoạch của bạn mới đầy đủ. Do đó, cho dù bạn có bị buộc phải nói “mất bao lâu để thu thập dữ liệu” - hãy dành cho mình một chút thời gian để phân tích sơ bộ và tranh luận xem thời gian sẽ thay đổi bao nhiêu tùy thuộc vào các thông số thực của vấn đề.

Và bây giờ chúng tôi sẽ trình bày các ví dụ cụ thể trong đó các tham số đó sẽ thay đổi.

Điểm quan trọng: Ước tính này dựa trên phân tích các yếu tố chính ảnh hưởng đến phạm vi và mức độ phức tạp của công việc.

Ước lượng dựa trên phỏng đoán là một cách tiếp cận tốt khi các phần tử chức năng đủ nhỏ và không có nhiều yếu tố có thể ảnh hưởng đáng kể đến việc thiết kế bài toán. Nhưng trong trường hợp có một số vấn đề về Khoa học dữ liệu, các yếu tố như vậy trở nên vô cùng nhiều và cách tiếp cận như vậy trở nên không phù hợp.

So sánh các cộng đồng Reddit

Hãy bắt đầu với trường hợp đơn giản nhất (sau này sẽ rõ hơn). Nói chung, thành thật mà nói, chúng tôi có một trường hợp gần như lý tưởng, hãy kiểm tra danh sách kiểm tra độ phức tạp của chúng tôi:

  • Có một API gọn gàng, dễ hiểu và được ghi lại.
  • Việc này cực kỳ đơn giản và quan trọng nhất là mã thông báo sẽ được nhận tự động.
  • bánh bao trăn - với rất nhiều ví dụ.
  • Cộng đồng phân tích và thu thập dữ liệu trên reddit (thậm chí cả các video trên YouTube giải thích cách sử dụng trình bao bọc python) Ví dụ.
  • Các phương thức chúng tôi cần rất có thể đã tồn tại trong API. Hơn nữa, mã trông nhỏ gọn và rõ ràng, bên dưới là một ví dụ về chức năng thu thập nhận xét về một bài đăng.

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

Được lấy từ điều này một lựa chọn các tiện ích thuận tiện cho việc gói.

Mặc dù thực tế đây là trường hợp tốt nhất nhưng vẫn cần tính đến một số yếu tố quan trọng từ cuộc sống thực:

  • Giới hạn API - chúng tôi buộc phải lấy dữ liệu theo đợt (ngủ giữa các yêu cầu, v.v.).
  • Thời gian thu thập - để phân tích và so sánh đầy đủ, bạn sẽ phải dành thời gian đáng kể chỉ để con nhện đi qua subreddit.
  • Bot phải chạy trên máy chủ—bạn không thể chỉ chạy nó trên máy tính xách tay, đặt nó vào ba lô và tiếp tục công việc của mình. Vì vậy, tôi đã chạy mọi thứ trên VPS. Sử dụng mã khuyến mại habrahabr10, bạn có thể tiết kiệm thêm 10% chi phí.
  • Không thể truy cập vật lý của một số dữ liệu (quản trị viên hiển thị hoặc quá khó thu thập) - điều này phải được tính đến; về nguyên tắc, không phải tất cả dữ liệu đều có thể được thu thập trong thời gian thích hợp.
  • Lỗi mạng: Kết nối mạng là một vấn đề khó khăn.
  • Đây là dữ liệu thực tế - nó không bao giờ thuần túy.

Tất nhiên, cần phải đưa những sắc thái này vào quá trình phát triển. Số giờ/ngày cụ thể phụ thuộc vào kinh nghiệm phát triển hoặc kinh nghiệm làm các nhiệm vụ tương tự, tuy nhiên, chúng tôi thấy rằng ở đây nhiệm vụ này hoàn toàn mang tính kỹ thuật và không yêu cầu chuyển động cơ thể bổ sung để giải quyết - mọi thứ đều có thể được đánh giá, lên lịch và thực hiện rất tốt.

So sánh các phần Habr

Hãy chuyển sang một trường hợp thú vị hơn và không hề tầm thường khi so sánh các chủ đề và/hoặc các phần của Habr.

Hãy kiểm tra danh sách kiểm tra độ phức tạp của chúng tôi - tại đây, để hiểu từng điểm, bạn sẽ phải tìm hiểu sâu hơn một chút về bản thân nhiệm vụ và thử nghiệm.

  • Lúc đầu bạn nghĩ có API nhưng thực ra không có. Có, vâng, Habr có API, nhưng người dùng không thể truy cập được (hoặc có thể nó không hoạt động).
  • Sau đó, bạn chỉ cần bắt đầu phân tích cú pháp html - “yêu cầu nhập”, điều gì có thể xảy ra?
  • Làm thế nào để phân tích cú pháp? Cách tiếp cận đơn giản và được sử dụng phổ biến nhất là lặp lại các ID, lưu ý rằng nó không hiệu quả nhất và sẽ phải xử lý các trường hợp khác nhau - đây là ví dụ về mật độ ID thực trong số tất cả các ID hiện có.

    Điều gì có thể sai với Khoa học dữ liệu? Thu thập dữ liệu
    Được lấy từ điều này bài viết.

  • Dữ liệu thô được gói trong HTML trên đầu trang web là một điều khó khăn. Ví dụ: bạn muốn thu thập và lưu xếp hạng của một bài viết: bạn xé điểm ra khỏi html và quyết định lưu nó dưới dạng số để xử lý thêm: 

    1) int(score) đưa ra lỗi: vì trên Habré có một dấu trừ, chẳng hạn như ở dòng “–5” - đây là dấu gạch ngang, không phải dấu trừ (thật bất ngờ, phải không?), vì vậy tại đôi khi tôi phải nâng trình phân tích cú pháp lên bằng một bản sửa lỗi khủng khiếp như vậy.

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

    Có thể không có ngày tháng, điểm cộng và điểm trừ nào cả (như chúng ta thấy ở trên trong hàm check_date, điều này đã xảy ra).

    2) Các ký tự đặc biệt không thoát - chúng sẽ đến, bạn cần chuẩn bị sẵn sàng.

    3) Cấu trúc thay đổi tùy theo loại bài viết.

    4) Các bài đăng cũ có thể có **cấu trúc kỳ lạ**.

  • Về cơ bản, việc xử lý lỗi và những gì có thể xảy ra hoặc không xảy ra sẽ phải được xử lý và bạn không thể dự đoán chắc chắn điều gì sẽ xảy ra và cấu trúc có thể như thế nào và điều gì sẽ rơi ra ở đâu - bạn sẽ chỉ phải thử và tính đến các lỗi mà trình phân tích cú pháp đưa ra.
  • Sau đó, bạn nhận ra rằng bạn cần phân tích cú pháp theo nhiều luồng, nếu không, việc phân tích cú pháp trong một luồng sẽ mất hơn 30 giờ (đây hoàn toàn là thời gian thực thi của một trình phân tích cú pháp một luồng đang hoạt động, ở chế độ ngủ và không bị cấm). TRONG điều này bài viết, điều này đôi khi dẫn đến một sơ đồ tương tự:

Điều gì có thể sai với Khoa học dữ liệu? Thu thập dữ liệu

Tổng danh sách kiểm tra theo độ phức tạp:

  • Làm việc với mạng và phân tích cú pháp html bằng phép lặp và tìm kiếm theo ID.
  • Tài liệu có cấu trúc không đồng nhất.
  • Có nhiều chỗ mã dễ rơi.
  • Cần phải viết || mã số.
  • Thiếu tài liệu cần thiết, ví dụ về mã và/hoặc cộng đồng.

Thời gian ước tính cho nhiệm vụ này sẽ cao gấp 3-5 lần so với việc thu thập dữ liệu từ Reddit.

So sánh các nhóm Odnoklassniki

Hãy chuyển sang trường hợp thú vị nhất về mặt kỹ thuật được mô tả. Đối với tôi, điều đó thật thú vị bởi vì thoạt nhìn, nó trông khá tầm thường, nhưng hóa ra lại không phải như vậy - ngay khi bạn chọc một cây gậy vào nó.

Hãy bắt đầu với danh sách kiểm tra độ khó của chúng tôi và lưu ý rằng nhiều trong số chúng sẽ trở nên khó hơn nhiều so với lúc đầu:

  • Có API nhưng gần như thiếu hoàn toàn các chức năng cần thiết.
  • Đối với một số chức năng nhất định, bạn cần yêu cầu quyền truy cập qua thư, nghĩa là việc cấp quyền truy cập không phải là ngay lập tức.
  • Nó được ghi lại một cách khủng khiếp (trước hết, các thuật ngữ tiếng Nga và tiếng Anh được trộn lẫn ở khắp mọi nơi và hoàn toàn không nhất quán - đôi khi bạn chỉ cần đoán xem họ muốn gì từ bạn ở đâu đó) và hơn nữa, thiết kế không phù hợp để lấy dữ liệu, chẳng hạn , chức năng chúng ta cần.
  • Yêu cầu một phiên trong tài liệu nhưng không thực sự sử dụng nó - và không có cách nào để hiểu tất cả sự phức tạp của các chế độ API ngoài việc tìm hiểu và hy vọng điều gì đó sẽ hoạt động.
  • Không có ví dụ và không có cộng đồng; điểm hỗ trợ duy nhất trong việc thu thập thông tin là một vỏ bánh bằng Python (không có nhiều ví dụ sử dụng).
  • Selenium có vẻ là lựa chọn khả thi nhất vì nhiều dữ liệu cần thiết đã bị khóa.
    1) Nghĩa là, việc ủy ​​quyền diễn ra thông qua một người dùng hư cấu (và đăng ký bằng tay).

    2) Tuy nhiên, với Selenium không có gì đảm bảo cho công việc chính xác và có thể lặp lại (ít nhất là trong trường hợp ok.ru).

    3) Trang web Ok.ru có lỗi JavaScript và đôi khi hoạt động kỳ lạ và không nhất quán.

    4) Bạn cần thực hiện phân trang, tải các phần tử, v.v...

    5) Các lỗi API mà trình bao bọc đưa ra sẽ phải được xử lý một cách lúng túng, chẳng hạn như thế này (một đoạn mã thử nghiệm):

    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
    

    Sai lầm yêu thích của tôi là:

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

    6) Cuối cùng, Selenium + API có vẻ là lựa chọn hợp lý nhất.

  • Cần phải lưu trạng thái và khởi động lại hệ thống, xử lý nhiều lỗi, bao gồm cả hành vi không nhất quán của trang web - và những lỗi này khá khó tưởng tượng (tất nhiên trừ khi bạn viết trình phân tích cú pháp một cách chuyên nghiệp).

Ước tính thời gian có điều kiện cho nhiệm vụ này sẽ cao hơn 3-5 lần so với việc thu thập dữ liệu từ Habr. Mặc dù thực tế là trong trường hợp của Habr, chúng tôi sử dụng cách tiếp cận trực tiếp với phân tích cú pháp HTML và trong trường hợp OK, chúng tôi có thể làm việc với API ở những vị trí quan trọng.

Những phát hiện

Cho dù bạn được yêu cầu ước tính thời hạn “tại chỗ” (chúng tôi đang lập kế hoạch ngay hôm nay!) của một mô-đun quy trình xử lý dữ liệu khổng lồ đến mức nào, thời gian thực hiện hầu như không bao giờ có thể ước tính ngay cả về mặt chất lượng nếu không phân tích các tham số nhiệm vụ.

Một lưu ý mang tính triết học hơn một chút, các chiến lược ước tính linh hoạt hoạt động tốt cho các nhiệm vụ kỹ thuật, nhưng các vấn đề mang tính thử nghiệm hơn và theo một nghĩa nào đó là “sáng tạo” và mang tính khám phá, tức là ít dự đoán hơn, sẽ gặp khó khăn, như trong các ví dụ về các chủ đề tương tự, mà chúng ta đã thảo luận ở đây.

Tất nhiên, thu thập dữ liệu chỉ là một ví dụ điển hình - nó thường là một nhiệm vụ cực kỳ đơn giản và không phức tạp về mặt kỹ thuật, và điều khó khăn thường nằm ở các chi tiết. Và chính trong nhiệm vụ này, chúng tôi có thể hiển thị toàn bộ các lựa chọn khả thi cho những gì có thể xảy ra và chính xác thời gian công việc có thể kéo dài.

Nếu nhìn qua đặc điểm của nhiệm vụ mà không có thử nghiệm bổ sung thì Reddit và OK trông giống nhau: có API, có trình bao bọc python, nhưng về bản chất, sự khác biệt là rất lớn. Đánh giá theo các tham số này, phân tích cú pháp của Habr có vẻ phức tạp hơn OK - nhưng trên thực tế thì hoàn toàn ngược lại, và đây chính xác là những gì có thể tìm ra bằng cách tiến hành các thí nghiệm đơn giản để phân tích các tham số của bài toán.

Theo kinh nghiệm của tôi, cách tiếp cận hiệu quả nhất là ước tính đại khái thời gian bạn cần cho bản phân tích sơ bộ và các thử nghiệm đơn giản đầu tiên, đọc tài liệu - những điều này sẽ cho phép bạn đưa ra ước tính chính xác cho toàn bộ công việc. Về phương pháp linh hoạt phổ biến, tôi yêu cầu bạn tạo một phiếu để “ước tính các thông số nhiệm vụ”, trên cơ sở đó tôi có thể đưa ra đánh giá về những gì có thể đạt được trong “chạy nước rút” và đưa ra ước tính chính xác hơn cho từng nhiệm vụ.

Do đó, lập luận hiệu quả nhất dường như là lập luận sẽ cho một chuyên gia “phi kỹ thuật” thấy được thời gian và nguồn lực sẽ thay đổi như thế nào tùy thuộc vào các thông số chưa được đánh giá.

Điều gì có thể sai với Khoa học dữ liệu? Thu thập dữ liệu

Nguồn: www.habr.com

Thêm một lời nhận xét