Qu'est-ce qui peut mal se passer avec la science des données ? Collecte de données

Qu'est-ce qui peut mal se passer avec la science des données ? Collecte de données
Il existe aujourd’hui 100500 XNUMX cours de Data Science et on sait depuis longtemps que c’est grâce aux cours de Data Science que l’on peut gagner le plus d’argent en Data Science (pourquoi creuser quand on peut vendre des pelles ?). Le principal inconvénient de ces cours est qu'ils n'ont rien à voir avec un travail réel : personne ne vous fournira des données claires et traitées dans le format requis. Et lorsqu’on quitte le cours et qu’on commence à résoudre un vrai problème, de nombreuses nuances apparaissent.

C'est pourquoi nous commençons une série de notes « Qu'est-ce qui peut mal tourner avec la science des données », basées sur des événements réels qui me sont arrivés, ainsi qu'à mes camarades et collègues. Nous analyserons les tâches typiques de la Data Science à l'aide d'exemples réels : comment cela se produit réellement. Commençons aujourd'hui par la tâche de collecte de données.

Et la première chose sur laquelle les gens trébuchent lorsqu’ils commencent à travailler avec des données réelles est de collecter les données qui nous intéressent le plus. Le message clé de cet article :

Nous sous-estimons systématiquement le temps, les ressources et les efforts nécessaires pour collecter, nettoyer et préparer les données.

Et surtout, nous discuterons de ce qu'il faut faire pour éviter cela.

Selon diverses estimations, le nettoyage, la transformation, le traitement des données, l'ingénierie des fonctionnalités, etc. prennent 80 à 90 % du temps, et l'analyse 10 à 20 %, alors que presque tout le matériel pédagogique se concentre exclusivement sur l'analyse.

Examinons un problème analytique simple en trois versions comme exemple typique et voyons ce que sont les « circonstances aggravantes ».

Et à titre d'exemple, encore une fois, nous considérerons des variantes similaires de la tâche de collecte de données et de comparaison des communautés pour :

  1. Deux sous-reddits Reddit
  2. Deux sections de Habr
  3. Deux groupes d'Odnoklassniki

Approche conditionnelle en théorie

Ouvrez le site et lisez les exemples, si c'est clair, prévoyez quelques heures pour la lecture, quelques heures pour le code utilisant les exemples et le débogage. Ajoutez quelques heures pour la collecte. Mettez quelques heures en réserve (multipliez par deux et ajoutez N heures).

Point clé : les estimations de temps sont basées sur des hypothèses et des conjectures sur le temps que cela prendra.

Il est nécessaire de commencer l’analyse temporelle en estimant les paramètres suivants pour le problème conditionnel décrit ci-dessus :

  • Quelle est la taille des données et quelle quantité doit être physiquement collectée (*voir ci-dessous*).
  • Quel est le délai de collecte pour un enregistrement et combien de temps devez-vous attendre avant de pouvoir récupérer le second ?
  • Pensez à écrire du code qui enregistre l'état et démarre un redémarrage lorsque (pas si) tout échoue.
  • Déterminez si nous avons besoin d'une autorisation et définissez l'heure d'obtention de l'accès via l'API.
  • Définissez le nombre d'erreurs en fonction de la complexité des données - évaluez pour une tâche spécifique : la structure, le nombre de transformations, quoi et comment extraire.
  • Corrigez les erreurs réseau et les problèmes liés au comportement non standard du projet.
  • Évaluez si les fonctions requises figurent dans la documentation et, dans le cas contraire, comment et quelle quantité est nécessaire pour une solution de contournement.

Le plus important est que pour estimer le temps - vous devez en fait consacrer du temps et des efforts à la "reconnaissance en force" - ce n'est qu'alors que votre planification sera adéquate. Par conséquent, peu importe à quel point vous êtes poussé à dire « combien de temps faut-il pour collecter des données » - gagnez du temps pour une analyse préliminaire et argumentez dans quelle mesure le temps variera en fonction des paramètres réels du problème.

Et maintenant, nous allons montrer des exemples spécifiques dans lesquels ces paramètres changeront.

Point clé : L'estimation est basée sur une analyse des facteurs clés influençant la portée et la complexité des travaux.

L’estimation basée sur des suppositions est une bonne approche lorsque les éléments fonctionnels sont suffisamment petits et qu’il n’existe pas beaucoup de facteurs pouvant influencer de manière significative la conception du problème. Mais dans le cas d’un certain nombre de problèmes de Data Science, ces facteurs deviennent extrêmement nombreux et une telle approche devient inadéquate.

Comparaison des communautés Reddit

Commençons par le cas le plus simple (comme il s'avérera plus tard). En général, pour être tout à fait honnête, nous avons un cas presque idéal, vérifions notre liste de contrôle de complexité :

  • Il existe une API soignée, claire et documentée.
  • C’est extrêmement simple et surtout, un token s’obtient automatiquement.
  • Il est enveloppe de python - avec de nombreux exemples.
  • Une communauté qui analyse et collecte des données sur Reddit (même sur des vidéos YouTube expliquant comment utiliser le wrapper Python) par exemple.
  • Les méthodes dont nous avons besoin existent très probablement dans l'API. De plus, le code semble compact et propre ; vous trouverez ci-dessous un exemple de fonction qui collecte des commentaires sur une publication.

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

Extrait de cette une sélection d'utilitaires pratiques pour l'emballage.

Même s'il s'agit du meilleur des cas, il convient néanmoins de prendre en compte un certain nombre de facteurs importants issus de la vie réelle :

  • Limites de l'API - nous sommes obligés de prendre des données par lots (veille entre les requêtes, etc.).
  • Temps de collecte - pour une analyse et une comparaison complètes, vous devrez prévoir un temps important juste pour que l'araignée parcoure le subreddit.
  • Le bot doit fonctionner sur un serveur : vous ne pouvez pas simplement l’exécuter sur votre ordinateur portable, le mettre dans votre sac à dos et vaquer à vos occupations. J'ai donc tout exécuté sur un VPS. En utilisant le code promotionnel habrahabr10, vous pouvez économiser 10 % supplémentaires sur le coût.
  • L'inaccessibilité physique de certaines données (elles sont visibles pour les administrateurs ou sont trop difficiles à collecter) - il faut en tenir compte ; en principe, toutes les données ne peuvent pas être collectées dans un délai suffisant.
  • Erreurs de réseau : la mise en réseau est pénible.
  • Il s’agit de données réelles et vivantes – elles ne sont jamais pures.

Bien entendu, il est nécessaire d’inclure ces nuances dans le développement. Les heures/jours spécifiques dépendent de l'expérience en développement ou de l'expérience de travail sur des tâches similaires, cependant, nous voyons qu'ici la tâche est purement technique et ne nécessite pas de mouvements corporels supplémentaires pour être résolue - tout peut être très bien évalué, planifié et réalisé.

Comparaison des sections Habr

Passons à un cas plus intéressant et non trivial de comparaison de fils de discussion et/ou de sections de Habr.

Vérifions notre liste de contrôle de complexité - ici, afin de comprendre chaque point, vous devrez approfondir un peu la tâche elle-même et expérimenter.

  • Au début, vous pensez qu’il existe une API, mais ce n’est pas le cas. Oui, oui, Habr a une API, mais elle n'est tout simplement pas accessible aux utilisateurs (ou peut-être qu'elle ne fonctionne pas du tout).
  • Ensuite, vous commencez simplement à analyser le HTML - « requêtes d'importation », qu'est-ce qui pourrait mal se passer ?
  • Comment analyser quand même ? L'approche la plus simple et la plus fréquemment utilisée consiste à parcourir les identifiants, notez que ce n'est pas la plus efficace et qu'elle devra gérer différents cas - voici un exemple de la densité des identifiants réels parmi tous ceux existants.

    Qu'est-ce qui peut mal se passer avec la science des données ? Collecte de données
    Extrait de cette articles.

  • Les données brutes enveloppées en HTML sur le Web sont pénibles. Par exemple, vous souhaitez collecter et enregistrer la note d'un article : vous avez extrait la note du code HTML et avez décidé de la sauvegarder sous forme de numéro pour un traitement ultérieur : 

    1) int(score) renvoie une erreur : puisque sur Habré il y a un moins, comme, par exemple, dans la ligne « –5 » - c'est un tiret en, pas un signe moins (de façon inattendue, n'est-ce pas ?), donc à à un moment donné, j'ai dû donner vie à l'analyseur avec une solution aussi terrible.

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

    Il se peut qu'il n'y ait pas de date, ni de plus ni de moins (comme nous le voyons ci-dessus dans la fonction check_date, cela s'est produit).

    2) Caractères spéciaux non échappés - ils viendront, vous devez être préparé.

    3) La structure change selon le type de poste.

    4) Les anciens messages peuvent avoir une **structure étrange**.

  • Essentiellement, la gestion des erreurs et ce qui peut ou non arriver devra être géré et vous ne pouvez pas prédire avec certitude ce qui va mal tourner et comment la structure pourrait être autrement et ce qui tombera où - vous devrez simplement essayer de prendre en compte les erreurs générées par l'analyseur.
  • Ensuite, vous réalisez que vous devez analyser dans plusieurs threads, sinon l'analyse dans un seul prendra alors plus de 30 heures (il s'agit uniquement du temps d'exécution d'un analyseur monothread déjà fonctionnel, qui dort et ne tombe sous aucune interdiction). DANS cette article, cela a conduit à un moment donné à un schéma similaire :

Qu'est-ce qui peut mal se passer avec la science des données ? Collecte de données

Liste de contrôle totale par complexité :

  • Travailler avec le réseau et analyser le HTML avec itération et recherche par ID.
  • Documents de structure hétérogène.
  • Il existe de nombreux endroits où le code peut facilement tomber.
  • Il faut écrire || code.
  • La documentation nécessaire, les exemples de code et/ou la communauté sont manquants.

Le temps estimé pour cette tâche sera 3 à 5 fois plus élevé que pour la collecte de données depuis Reddit.

Comparaison des groupes Odnoklassniki

Passons au cas décrit le plus intéressant techniquement. Pour moi, c'était intéressant précisément parce qu'à première vue, cela semble assez trivial, mais cela ne s'avère pas du tout le cas - dès qu'on y met un bâton.

Commençons par notre liste de contrôle des difficultés et notons que beaucoup d'entre elles s'avéreront beaucoup plus difficiles qu'il n'y paraît au premier abord :

  • Il existe une API, mais elle manque presque totalement des fonctions nécessaires.
  • Pour certaines fonctions, vous devez demander l'accès par courrier, c'est-à-dire que l'octroi de l'accès n'est pas instantané.
  • Il est terriblement documenté (pour commencer, les termes russes et anglais sont mélangés partout, et de manière totalement incohérente - il suffit parfois de deviner ce qu'ils attendent de vous quelque part) et, de plus, la conception n'est pas adaptée pour obtenir des données, par exemple , la fonction dont nous avons besoin.
  • Nécessite une session dans la documentation, mais ne l'utilise pas réellement - et il n'y a aucun moyen de comprendre toutes les subtilités des modes API autre que de fouiller et d'espérer que quelque chose fonctionnera.
  • Il n'y a pas d'exemples et pas de communauté ; le seul point d'appui dans la collecte d'informations est un petit papier d'emballage en Python (sans beaucoup d'exemples d'utilisation).
  • Le sélénium semble être l’option la plus viable, car la plupart des données nécessaires sont verrouillées.
    1) Autrement dit, l'autorisation s'effectue par l'intermédiaire d'un utilisateur fictif (et l'enregistrement manuel).

    2) Cependant, avec Selenium, il n'y a aucune garantie d'un travail correct et reproductible (du moins dans le cas de ok.ru, bien sûr).

    3) Le site Web Ok.ru contient des erreurs JavaScript et se comporte parfois de manière étrange et incohérente.

    4) Vous devez faire la pagination, le chargement des éléments, etc...

    5) Les erreurs API fournies par le wrapper devront être gérées de manière maladroite, par exemple, comme ceci (un morceau de code expérimental) :

    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
    

    Mon erreur préférée était :

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

    6) En fin de compte, Selenium + API semble être l'option la plus rationnelle.

  • Il est nécessaire de sauvegarder l'état et de redémarrer le système, de gérer de nombreuses erreurs, y compris un comportement incohérent du site - et ces erreurs sont assez difficiles à imaginer (à moins que vous n'écriviez des analyseurs de manière professionnelle, bien sûr).

L'estimation conditionnelle du temps pour cette tâche sera 3 à 5 fois plus élevée que pour la collecte de données de Habr. Malgré le fait que dans le cas de Habr, nous utilisons une approche frontale avec analyse HTML, et dans le cas de OK, nous pouvons travailler avec l'API dans des endroits critiques.

résultats

Peu importe à quel point il vous est demandé d'estimer les délais « sur place » (nous planifions aujourd'hui !) d'un volumineux module de pipeline de traitement de données, le temps d'exécution n'est presque jamais possible à estimer, même qualitativement, sans analyser les paramètres de la tâche.

Sur une note légèrement plus philosophique, les stratégies d'estimation agiles fonctionnent bien pour les tâches d'ingénierie, mais les problèmes plus expérimentaux et, en un sens, « créatifs » et exploratoires, c'est-à-dire moins prévisibles, ont des difficultés, comme dans les exemples de sujets similaires. dont nous avons discuté ici.

Bien entendu, la collecte de données n’est qu’un excellent exemple : il s’agit généralement d’une tâche incroyablement simple et techniquement peu compliquée, et le diable se cache souvent dans les détails. Et c’est précisément dans cette tâche que nous pouvons montrer toute la gamme des options possibles pour déterminer ce qui peut mal tourner et combien de temps exactement le travail peut prendre.

Si vous regardez les caractéristiques de la tâche sans expériences supplémentaires, alors Reddit et OK se ressemblent : il existe une API, un wrapper python, mais en substance, la différence est énorme. À en juger par ces paramètres, les pars de Habr semblent plus compliqués que OK - mais en pratique, c'est tout le contraire, et c'est exactement ce que l'on peut découvrir en menant des expériences simples pour analyser les paramètres du problème.

D'après mon expérience, l'approche la plus efficace consiste à estimer approximativement le temps dont vous aurez besoin pour l'analyse préliminaire elle-même et les premières expériences simples, en lisant la documentation - celles-ci vous permettront de donner une estimation précise de l'ensemble du travail. En termes de méthodologie agile populaire, je vous demande de créer un ticket pour « estimer les paramètres de la tâche », sur la base duquel je peux donner une évaluation de ce qui peut être accompli dans le cadre du « sprint » et donner une estimation plus précise pour chaque tâche.

L’argument le plus efficace semble donc être celui qui montrerait à un spécialiste « non technique » combien de temps et de ressources varieront en fonction de paramètres qui n’ont pas encore été évalués.

Qu'est-ce qui peut mal se passer avec la science des données ? Collecte de données

Source: habr.com

Ajouter un commentaire