Hoje existem 100.500 cursos em Data Science e há muito se sabe que a maior parte do dinheiro em Data Science pode ser ganha justamente por cursos de Data Science (por que cavar quando se pode vender pás?). A principal desvantagem desses cursos é que eles não têm nada a ver com trabalho real: ninguém irá fornecer dados limpos e processados no formato exigido. E quando você sai dos cursos e começa a resolver o problema real, muitas nuances surgem.
Portanto, estamos iniciando uma série de notas "O que pode dar errado com Data Science", com base em eventos reais que aconteceram comigo, meus camaradas e colegas. Vamos analisar tarefas típicas em Data Science usando exemplos reais: como isso realmente acontece. Vamos começar hoje com a tarefa de coletar dados.
E a primeira coisa em que as pessoas tropeçam quando começam a trabalhar com dados reais é, na verdade, coletar os dados mais relevantes para nós. A mensagem principal deste artigo:
Nós subestimamos sistematicamente o tempo, recursos e esforço envolvidos na coleta, limpeza e preparação de dados.
E o mais importante, discutiremos o que fazer para evitar que isso aconteça.
De acordo com várias estimativas, limpeza, transformação, processamento de dados, engenharia de recursos, etc. ocupam 80-90% do tempo e análise 10-20%, enquanto quase todo o material educacional se concentra exclusivamente na análise.
Tomemos como exemplo típico um problema analítico simples em três versões e vejamos quais são as "circunstâncias agravantes".
Novamente, como exemplo, consideraremos variações semelhantes da tarefa de coleta de dados e comparação de comunidades para:
- Dois subreddits do Reddit
- Duas seções Habr
- Dois grupos de Odnoklassniki
Abordagem condicional em teoria
Abra o site e leia os exemplos, se estiver claro, reserve algumas horas para leitura, algumas horas para o código usando exemplos e depuração. Adicione algumas horas para coletar. Jogue algumas horas na reserva (multiplique por dois e some N horas).
Ponto-chave: a estimativa de tempo é baseada em suposições e estimativas sobre quanto tempo levará.
É necessário iniciar a análise do tempo avaliando os seguintes parâmetros para o problema condicional descrito acima:
- Qual é o tamanho dos dados e quanto eles precisam ser coletados fisicamente (* veja abaixo *).
- Quanto tempo leva para coletar um registro e quanto tempo leva para coletar o segundo.
- Para estabelecer a escrita do código que salva o estado e inicia uma reinicialização quando (e não se) tudo cair.
- , API.
- , — : , , .
- .
- , , a workaround.
Mais importante ainda, para estimar o tempo - você realmente precisa investir tempo e esforço no "reconhecimento em vigor" - só então seu planejamento será adequado. Portanto, não importa como você seja pressionado a dizer “quanto tempo leva para coletar dados” - reserve um tempo para uma análise preliminar e argumente quanto o tempo irá variar dependendo dos parâmetros reais do problema.
E agora iremos demonstrar exemplos específicos onde tais parâmetros serão alterados.
Ponto-chave: A avaliação é baseada na análise dos fatores-chave que influenciam o volume e a complexidade do trabalho.
A estimativa de estimativa é uma boa abordagem quando os elementos funcionais são pequenos o suficiente e não há muitos fatores que podem afetar significativamente a estrutura do problema. Mas, no caso de várias tarefas de Ciência de Dados, esses fatores tornam-se extremamente numerosos e tal abordagem torna-se inadequada.
Comparação de comunidades do Reddit
Vamos começar com o caso mais simples (como descobriremos mais tarde). Em geral, para ser completamente honesto, este é um caso quase ideal, vamos verificar nossa lista de verificação de dificuldade:
- Há uma API limpa, direta e documentada.
- É extremamente simples e importante obter um token automaticamente.
- Existe um wrapper python - com um monte de exemplos.
- Uma comunidade que analisa e coleta dados no reddit (até vídeos do youtube explicando como usar o wrapper python) , por exemplo .
- Os métodos de que precisamos provavelmente existem na API. Além disso, o código parece compacto e limpo, abaixo está um exemplo de uma função que coleta comentários em uma postagem.
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()
Retirado desta coleção de utilitários de wrapper úteis.
Apesar de termos o melhor caso aqui, ainda vale a pena considerar uma série de fatores importantes da vida real:
- Limites da API - somos forçados a receber dados em lotes (suspensão entre solicitações, etc.).
- Tempo de coleta - para uma análise e comparação completas, você terá que reservar um tempo significativo apenas para a aranha percorrer o subreddit.
- O bot deve ser executado no servidor - você não pode simplesmente executá-lo em seu laptop, colocá-lo em sua mochila e começar a trabalhar. Então eu rodei tudo em um VPS. Com o código promocional habrahabr10, você pode economizar outros 10% do custo.
- A inacessibilidade física de alguns dados (são visíveis para os administradores ou muito difíceis de coletar) - isso deve ser levado em consideração, nem todos os dados, em princípio, podem ser coletados em tempo hábil.
- Erros de rede: a rede é uma dor.
- São dados reais vivos - nunca são claros.
Claro, é necessário incluir as nuances especificadas no desenvolvimento. Horas / dias específicos dependem da experiência de desenvolvimento ou experiência em trabalhar em tarefas semelhantes, no entanto, vemos que aqui a tarefa é exclusivamente de engenharia e não requer gestos adicionais para resolver - tudo pode ser muito bem avaliado, pintado e executado.
Comparação de seções Habr
Vamos passar para um caso mais interessante e não trivial de comparação de fluxos e / ou seções Habr.
Vamos verificar nossa lista de dificuldade - aqui, para entender cada ponto, você já precisa cutucar um pouco o problema em si e experimentar.
- A princípio você acha que existe uma API, mas não existe. Sim, sim, o Habr tem uma API, mas apenas não está disponível para os usuários (ou talvez nem funcione).
- Então você apenas começa a analisar o html - "solicitações de importação", o que pode dar errado?
- Como analisar em geral? A abordagem mais simples e mais freqüentemente usada é iterar sobre IDs, observe que não é a mais eficiente e terá que lidar com casos diferentes - por exemplo, a densidade de IDs reais entre todos os existentes.
Retirado deste artigo. - , 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) ** **. - Na verdade, o tratamento de erros e o que pode ou não acontecer terão que ser processados e você não pode prever com certeza o que vai dar errado e de que outra forma a estrutura pode estar e o que vai cair onde - você só terá que tentar e levar em consideração os erros que o analisador gera.
- Então você entende que precisa analisar em vários threads, caso contrário, a análise em um demorará mais de 30 horas (este é puramente o tempo de execução de um analisador de thread único já em funcionamento que dorme e não cai em nenhum ban). No presente artigo, isso levou em algum ponto para um padrão semelhante:
Lista de verificação de dificuldade total:
- Trabalhar com análise web e html com iteração e pesquisa por ID.
- Documentos de estrutura heterogênea.
- Existem muitos lugares onde o código pode cair facilmente.
- É necessário escrever || o código.
- Documentação ausente, exemplos de código e / ou comunidade.
A estimativa de tempo condicional para esta tarefa será 3-5 vezes maior do que para a coleta de dados do Reddit.
Comparação de grupos Odnoklassniki
Vamos passar para o caso descrito mais tecnicamente interessante. Para mim, foi interessante precisamente porque à primeira vista parece bastante trivial, mas não é assim - assim que você cutuca com um pedaço de pau.
Vamos começar com nossa lista de verificação de dificuldade e observar que muitos deles acabarão sendo muito mais difíceis do que parecem à primeira vista:
- Existe uma API, mas quase não possui as funções necessárias.
- Você precisa solicitar o acesso a determinadas funções por e-mail, ou seja, a emissão do acesso não é 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 . - É necessário salvar o estado e reiniciar o sistema, lidar com muitos erros, incluindo comportamento inconsistente do site - e esses erros, que são bastante difíceis de imaginar (se você não estiver escrevendo parsers profissionalmente, é claro).
A estimativa de tempo condicional para esta tarefa será 3-5 vezes maior do que para a coleta de dados do Habr. Apesar do fato de que, no caso do Habr, usamos uma abordagem direta com a análise de HTML, e no caso do OK podemos trabalhar com a API em locais críticos.
conclusões
Não importa o quanto você precise estimar os prazos "no local" (temos planejamento hoje!) De um grande módulo de pipeline de processamento de dados, o tempo de execução quase nunca é possível estimar, mesmo qualitativamente, sem analisar os parâmetros da tarefa.
Falando mais filosoficamente, as estratégias de avaliação ágil são boas para tarefas de engenharia, mas com tarefas que são mais experimentais e, em certo sentido, "criativas" e de pesquisa, ou seja, menos previsíveis, surgem dificuldades, como em exemplos de tópicos semelhantes que discutimos aqui.
Claro, a coleta de dados é apenas um excelente exemplo - geralmente a tarefa parece incrivelmente simples e tecnicamente descomplicada, e é nos detalhes que o diabo se esconde com mais frequência. E é nessa tarefa que se mostra toda a gama de opções possíveis para o que pode dar errado e quanto tempo o trabalho pode levar.
Se você passar os olhos pelas características do problema sem experimentação adicional, o Reddit e o OK parecem semelhantes: há uma API, um wrapper Python, mas, na verdade, a diferença é enorme. A julgar por esses parâmetros, Pars Habr parece mais complicado do que OK - mas na prática é exatamente o oposto, e isso é o que pode ser descoberto conduzindo experimentos simples para analisar os parâmetros do problema.
Na minha experiência, a abordagem mais eficaz é uma estimativa aproximada do tempo que você precisará para a própria análise preliminar e para os primeiros experimentos simples, lendo a documentação - eles permitirão que você dê uma estimativa precisa para todo o trabalho. Em termos da popular metodologia ágil, peço que você crie um tíquete para mim sob a "estimativa dos parâmetros da tarefa", com base na qual posso avaliar o que é possível realizar no "sprint" e dar uma estimativa mais precisa para cada tarefa.
Portanto, o argumento mais eficaz parece ser aquele que mostraria ao especialista “não técnico” quanto tempo e recursos irão variar dependendo de parâmetros que ainda não foram estimados.