¿Qué puede salir mal con la ciencia de datos? Recopilación de datos



Hoy en día hay 100,500 cursos en Data Science y se sabe desde hace mucho tiempo que la mayor cantidad de dinero en Data Science se puede ganar precisamente con los cursos de Data Science (¿por qué cavar cuando se pueden vender palas?). La principal desventaja de estos cursos es que no tienen nada que ver con el trabajo real: nadie te dará datos limpios y procesados ​​en el formato requerido. Y cuando sales de los cursos y comienzas a resolver el problema real, surgen muchos matices.



Por eso, estamos comenzando una serie de notas "Qué puede salir mal con la Ciencia de Datos", basadas en hechos reales que me sucedieron a mí, a mis compañeros y colegas. Analizaremos tareas típicas en Data Science utilizando ejemplos reales: cómo sucede realmente. Empecemos hoy con la tarea de recopilar datos.



Y lo primero con lo que la gente tropieza cuando comienza a trabajar con datos reales es en realidad recopilar los datos más relevantes para nosotros. El mensaje clave de este artículo:



Subestimamos sistemáticamente el tiempo, los recursos y el esfuerzo necesarios para recopilar, limpiar y preparar los datos.


Y lo más importante, discutiremos qué hacer para prevenir esto.



Según diversas estimaciones, la limpieza, la transformación, el procesamiento de datos, la ingeniería de funciones, etc., toman entre el 80 y el 90% del tiempo y el análisis entre el 10 y el 20%, mientras que casi todo el material educativo se centra exclusivamente en el análisis.



Tomemos como ejemplo típico un problema analítico simple en tres versiones y veamos qué son las "circunstancias agravantes".



Nuevamente, como ejemplo, consideraremos variaciones similares de la tarea de recopilar datos y comparar comunidades para:



  1. Dos subreddits de Reddit
  2. Dos secciones de Habr
  3. Dos grupos de Odnoklassniki


Enfoque condicional en teoría



Abra el sitio y lea los ejemplos, si está claro, dedique unas horas para leer, unas horas para el código con ejemplos y depuración. Agregue unas horas para recolectar. Añada unas horas en reserva (multiplique por dos y agregue N horas).



Punto clave: el tiempo estimado se basa en suposiciones y conjeturas sobre cuánto tiempo llevará.



Es necesario comenzar el análisis de tiempo evaluando los siguientes parámetros para el problema condicional descrito anteriormente:



  • ¿Cuál es el tamaño de los datos y cuánto deben recopilarse físicamente (* ver más abajo *).
  • ¿Cuánto tiempo se tarda en recopilar un registro y cuánto tiempo se tarda en recopilar el segundo?
  • Ponga por escrito código que guarde el estado y comience a reiniciarse cuando (y no si) todo se cae.
  • , API.
  • , — : , , .
  • .
  • , , a workaround.


Lo que es más importante, para estimar el tiempo (en realidad, debe invertir el tiempo y el esfuerzo en "reconocimiento en vigor"), solo entonces su planificación será adecuada. Por lo tanto, no importa cómo lo presionen para decir "cuánto tiempo se tarda en recopilar datos", tómese un tiempo para un análisis preliminar y discuta cuánto variará el tiempo dependiendo de los parámetros reales del problema.



Y ahora demostraremos ejemplos específicos en los que cambiarán dichos parámetros.



Punto clave: La evaluación se basa en un análisis de los factores clave que influyen en el volumen y la complejidad del trabajo.



La estimación Guess es un buen enfoque cuando los elementos funcionales son lo suficientemente pequeños y no hay muchos factores que puedan afectar significativamente la estructura del problema. Pero en el caso de una serie de tareas de ciencia de datos, tales factores se vuelven extremadamente numerosos y tal enfoque se vuelve inadecuado.



Comparación de comunidades de Reddit



Comencemos con el caso más simple (como se verá más adelante). En general, para ser completamente honesto, tenemos un caso casi ideal, revisemos nuestra lista de verificación de dificultad:



  • Hay una API ordenada, sencilla y documentada.
  • Es extremadamente simple e importante que un token se obtenga automáticamente.
  • Hay una envoltura de Python , con un montón de ejemplos.
  • Una comunidad que analiza y recopila datos en reddit (hasta videos de youtube que explican cómo usar la envoltura de Python) , por ejemplo .
  • Los métodos que necesitamos probablemente existan en la API. Además, el código parece compacto y limpio, a continuación se muestra un ejemplo de una función que recopila comentarios en una publicación.


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()
Tomado de esta colección de prácticas utilidades de envoltura.



A pesar de que tenemos el mejor caso aquí, aún vale la pena considerar una serie de factores importantes de la vida real:



  • Límites de API: nos vemos obligados a tomar datos en lotes (suspensión entre solicitudes, etc.).
  • Tiempo de recolección: para un análisis y una comparación completos, tendrá que reservar un tiempo significativo solo para que la araña camine por el subreddit.
  • El bot debe estar ejecutándose en el servidor; no puede simplemente ejecutarlo en su computadora portátil, ponerlo en su mochila y continuar con su trabajo. Así que ejecuté todo en un VPS. Con el código de promoción habrahabr10, puede ahorrar otro 10% del costo.
  • La inaccesibilidad física de algunos datos (son visibles para los administradores o son demasiado difíciles de recopilar): esto debe tenerse en cuenta, no todos los datos, en principio, se pueden recopilar en un tiempo adecuado.
  • Errores de red: la red es una molestia.
  • Estos son datos reales vivos, nunca están limpios.


Por supuesto, es necesario incluir los matices especificados en el desarrollo. Horas / días específicos dependen de la experiencia de desarrollo o la experiencia en trabajar en tareas similares, sin embargo, vemos que aquí la tarea es exclusivamente de ingeniería y no requiere gestos adicionales para resolver - todo se puede evaluar, pintar y hacer muy bien.



Comparación de secciones Habr



Pasemos a un caso más interesante y no trivial de comparar flujos y / o secciones de Habr.



Revisemos nuestra lista de verificación de dificultad: aquí, para comprender cada punto, ya debe hurgar un poco en el problema en sí y experimentar.



  • Al principio crees que hay una API, pero no la hay. Sí, sí, Habr tiene una API, pero solo que no está disponible para los usuarios (o tal vez no funcione en absoluto).
  • Luego, empiece a analizar el html - "solicitudes de importación", ¿qué podría salir mal?
  • ¿Cómo analizar en general? El enfoque más simple y utilizado con más frecuencia es iterar sobre los ID, tenga en cuenta que no es el más eficiente y tendrá que manejar diferentes casos, por ejemplo, la densidad de ID reales entre todos los existentes.





    Tomado de este artículo.
  • , HTML — . , : score html : 



    1) int(score) : , , "–5" — , (, ?), - .



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


    , ( check_date ).



    2) — , .



    3) .



    4) ** **.
  • De hecho, el manejo de errores y lo que puede suceder o no, tendrá que ser manejado y usted no puede predecir con certeza qué saldrá mal y de qué otra manera puede ser la estructura y qué se caerá dónde; solo tendrá que intentar y tener en cuenta los errores que arroja el analizador.
  • Entonces comprende que necesita analizar en varios subprocesos; de lo contrario, el análisis en uno tomará más de 30 horas (este es simplemente el tiempo de ejecución de un analizador de un solo subproceso que ya funciona y que se queda inactivo y no cae bajo ninguna prohibición). En este artículo, esto llevó en algún momento a un patrón similar:






Lista de verificación de dificultad total:



  • Trabajar con análisis web y html con iteración y búsqueda por ID.
  • Documentos de estructura heterogénea.
  • Hay muchos lugares donde el código puede caer fácilmente.
  • Es necesario escribir || el código.
  • Falta documentación, ejemplos de código o comunidad.


El tiempo estimado condicional para esta tarea será de 3 a 5 veces mayor que para la recopilación de datos de Reddit.



Comparación de grupos de Odnoklassniki



Pasemos al caso técnicamente más interesante descrito. Para mí, fue interesante precisamente porque a primera vista parece bastante trivial, pero no resulta serlo, tan pronto como lo pinchas con un palo.



Comencemos con nuestra lista de verificación de dificultades y tengamos en cuenta que muchas de ellas resultarán mucho más difíciles de lo que parecen al principio:



  • Hay una API, pero carece casi por completo de las funciones necesarias.
  • Necesitas solicitar el acceso a determinadas funciones por correo, es decir, la emisión del acceso no es instantánea.
  • ( , , — , - ) , , , , .
  • , — API, , - .
  • , — wrapper ( ).
  • Selenium, .

    1) ( ).



    2) c Selenium ( ok.ru ).



    3) . JavaScript .



    4) , …



    5) API, wrapper , , ( ):



    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
    


    :



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



    6) Selenium + API .
  • Es necesario guardar el estado y reiniciar el sistema, manejar muchos errores, incluido el comportamiento inconsistente del sitio, y estos errores, que son bastante difíciles de imaginar (si no está escribiendo analizadores de manera profesional, por supuesto).


El tiempo estimado condicional para esta tarea será de 3 a 5 veces mayor que para la recopilación de datos de Habr. A pesar de que en el caso de Habr utilizamos un enfoque frontal con análisis de HTML, y en el caso de OK, podemos trabajar con la API en lugares críticos.



conclusiones



No importa cuánto deba estimar los plazos "sobre el terreno" (¡tenemos planificación hoy!) De un módulo de flujo de procesamiento de datos grande, el tiempo de ejecución casi nunca es posible estimar ni siquiera cualitativamente sin analizar los parámetros de la tarea.



Más filosóficamente hablando, las estrategias de evaluación ágiles son buenas para tareas de ingeniería, pero con tareas que son más experimentales y, en cierto sentido, "creativas" e investigadoras, es decir, menos predecibles, surgen dificultades, como en ejemplos de temas similares que hemos analizado aquí.



Por supuesto, la recopilación de datos es solo un excelente ejemplo; por lo general, la tarea parece increíblemente simple y técnicamente sencilla, y es en los detalles donde el diablo acecha con mayor frecuencia. Y es en esta tarea que resulta mostrar toda la gama de opciones posibles sobre lo que puede salir mal y cuánto tiempo puede llevar el trabajo.



Si echa un vistazo por el rabillo del ojo a las características del problema sin experimentación adicional, entonces Reddit y OK se ven similares: hay una API, una envoltura de Python, pero de hecho, la diferencia es enorme. A juzgar por estos parámetros, el análisis de Habr parece más complicado que correcto, pero en la práctica es todo lo contrario, y esto es lo que se puede descubrir al realizar experimentos simples sobre el análisis de los parámetros del problema.



En mi experiencia, el enfoque más efectivo es una estimación aproximada del tiempo que necesitará para el análisis preliminar en sí y los primeros experimentos simples, leyendo la documentación; le permitirán dar una estimación precisa de todo el trabajo. En cuanto a la popular metodología ágil, les pido que me creen un ticket bajo la "estimación de los parámetros del problema", a partir del cual puedo dar una estimación de lo que es posible lograr dentro del "sprint" y dar una estimación más precisa para cada problema.



Por tanto, el argumento más eficaz parece ser el que mostraría al especialista “no técnico” cuánto tiempo y recursos variarán dependiendo de parámetros que aún no se han estimado.






All Articles