数据科学可能会出现什么问题? 数据采集

数据科学可能会出现什么问题? 数据采集
如今有 100500 门数据科学课程,人们早就知道数据科学领域的大部分钱可以通过数据科学课程赚到(当你可以卖铁锹时为什么要挖坑呢?)。 这些课程的主要缺点是它们与实际工作无关:没有人会给你所需格式的干净的、经过处理的数据。 当您离开课程并开始解决实际问题时,会出现许多细微差别。

因此,我们根据发生在我、我的同志和同事身上的真实事件,开始了一系列笔记“数据科学可能会出什么问题”。 我们将使用真实的例子来分析典型的数据科学任务:这实际上是如何发生的。 让我们从今天的数据收集任务开始。

当人们开始使用真实数据时,他们遇到的第一件事实际上是收集与我们最相关的数据。 本文的关键信息:

我们系统性地低估了收集、清理和准备数据所需的时间、资源和精力。

最重要的是,我们将讨论如何防止这种情况发生。

根据各种估计,清理、转换、数据处理、特征工程等占据了 80-90% 的时间,分析占据了 10-20% 的时间,而几乎所有的教育材料都只专注于分析。

我们以一个简单的三个版本的分析问题为例,看看什么是“情节严重”。

再次举个例子,我们将考虑收集数据和比较社区的任务的类似变化:

  1. 两个 Reddit 子版块
  2. 哈布尔的两个部分
  3. 两组 Odnoklassniki

理论上的条件方法

打开网站并阅读示例,如果清楚,请留出几个小时用于阅读,几个小时用于使用示例的代码和调试。 增加几个小时的收集时间。 预留几个小时(乘以 XNUMX 再加上 N 小时)。

要点:时间估计是基于对需要多长时间的假设和猜测。

有必要通过估计上述条件问题的以下参数来开始时间分析:

  • 数据的大小是多少以及需要物理收集多少数据(*见下文*)。
  • 一条记录的收集时间是多少?您需要等待多长时间才能收集第二条记录?
  • 考虑编写代码来保存状态并在(而不是如果)一切都失败时启动重新启动。
  • 弄清楚我们是否需要授权并设置通过API获取访问权限的时间。
  • 将错误数量设置为数据复杂性的函数 - 评估特定任务:结构、转换次数、提取内容和方式。
  • 修复网络错误和非标准项目行为问题。
  • 评估所需的功能是否在文档中,如果没有,则需要如何以及需要多少解决方法。

最重要的是,为了估算时间——你实际上需要花费时间和精力进行“武力侦察”——只有这样你的计划才算充分。 因此,无论你多么被迫说“收集数据需要多长时间”,都要为自己争取一些时间进行初步分析,并根据问题的实际参数来讨论时间会变化多少。

现在我们将演示这些参数将发生变化的具体示例。

要点:估算基于对影响工作范围和复杂性的关键因素的分析。

当功能元素足够小并且没有太多因素可以显着影响问题的设计时,基于猜测的估计是一种很好的方法。 但在许多数据科学问题的情况下,此类因素变得极其众多,而这种方法就变得不够充分。

Reddit 社区比较

让我们从最简单的情况开始(稍后会证明)。 一般来说,说实话,我们有一个几乎理想的情况,让我们检查一下我们的复杂性清单:

  • 有一个整洁、清晰且有文档记录的 API。
  • 非常简单,最重要的是,令牌是自动获得的。
  • 蟒蛇包装器 - 有很多例子。
  • 一个在 reddit 上分析和收集数据的社区(甚至是解释如何使用 python 包装器的 YouTube 视频) 例如.
  • 我们需要的方法很可能存在于 API 中。 此外,代码看起来紧凑而干净,下面是一个收集帖子评论的函数示例。

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

摘自 一系列方便的包装实用程序。

尽管这是最好的情况,但仍然值得考虑现实生活中的一些重要因素:

  • API 限制 - 我们被迫批量获取数据(在请求之间休眠等)。
  • 收集时间 - 为了进行完整的分析和比较,您必须留出大量时间让蜘蛛浏览 subreddit。
  • 机器人必须在服务器上运行——你不能只在笔记本电脑上运行它,把它放在背包里,然后继续你的业务。 所以我在 VPS 上运行一切。 使用促销代码 habrahabr10 您还可以节省 10% 的费用。
  • 某些数据的物理不可访问性(管理员可见或太难收集)——必须考虑到这一点;原则上,并非所有数据都可以在足够的时间内收集。
  • 网络错误:网络是一种痛苦。
  • 这是活生生的真实数据——它从来都不是纯粹的。

当然,在开发过程中需要考虑到这些细微差别。 具体的时间/天数取决于开发经验或从事类似任务的经验,但是,我们看到这里的任务纯粹是工程性的,不需要额外的身体动作来解决——一切都可以很好地评估、安排和完成。

哈布尔剖面比较

让我们继续讨论一个更有趣且不平凡的案例,比较 Habr 的线程和/或部分。

让我们检查一下我们的复杂性清单 - 在这里,为了理解每一点,您必须深入研究任务本身并进行实验。

  • 起初你以为有 API,但实际上并没有。 是的,是的,Habr 有一个 API,但用户无法访问它(或者可能根本不起作用)。
  • 然后你就开始解析 html - “导入请求”,会出现什么问题?
  • 无论如何如何解析? 最简单和最常用的方法是迭代 ID,请注意,这不是最有效的,并且必须处理不同的情况 - 这是所有现有 ID 中真实 ID 密度的示例。

    数据科学可能会出现什么问题? 数据采集
    摘自 文章。

  • 在 Web 上将原始数据封装在 HTML 中是一件痛苦的事情。 例如,您想要收集并保存一篇文章的评分:您从 html 中取出评分并决定将其保存为数字以供进一步处理: 

    1) int(score) 抛出一个错误:因为在 Habré 上有一个减号,例如,在“–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)旧帖子可能有**奇怪的结构**。

  • 从本质上讲,错误处理以及可能发生或可能不会发生的事情都必须得到处理,并且您无法确定会出现什么问题,结构可能会如何,以及什么会在哪里脱落 - 您只需要尝试并考虑到解析器抛出的错误。
  • 然后你意识到你需要在多个线程中进行解析,否则在一个线程中进行解析将需要 30 多个小时(这纯粹是已经工作的单线程解析器的执行时间,它会休眠并且不会受到任何禁令的影响)。 在 文章中,这在某种程度上导致了类似的方案:

数据科学可能会出现什么问题? 数据采集

按复杂程度列出的总清单:

  • 使用网络和 html 解析进行迭代并按 ID 进行搜索。
  • 异构结构的文档。
  • 有很多地方代码很容易出错。
  • 必须写|| 代码。
  • 缺少必要的文档、代码示例和/或社区。

此任务的预计时间将比从 Reddit 收集数据高 3-5 倍。

Odnoklassniki 组的比较

让我们继续讨论所描述的技术上最有趣的案例。 对我来说,这很有趣,因为乍一看,它看起来很微不足道,但一旦你用棍子戳它,就会发现它根本不是那样的。

让我们从难度清单开始,请注意,其中许多问题会比最初看起来要困难得多:

  • 有一个API,但几乎完全缺乏必要的功能。
  • 对于某些功能,您需要通过邮件请求访问权限,也就是说,访问权限的授予不是即时的。
  • 它的记录非常糟糕(首先,俄语和英语术语到处混合在一起,并且完全不一致 - 有时你只需要猜测他们想从你那里得到什么),而且,该设计不适合获取数据,例如, 我们需要的功能.
  • 需要文档中的会话,但实际上并没有使用它 - 除了四处探索并希望某些东西能够工作之外,没有办法理解 API 模式的所有复杂性。
  • 没有例子,也没有社区;收集信息的唯一支持点是一个小的 包装纸 在Python中(没有很多使用示例)。
  • Selenium 似乎是最可行的选择,因为许多必要的数据都被锁定了。
    1) 即通过虚构用户进行授权(并手动注册)。

    2)但是,使用 Selenium 并不能保证正确且可重复的工作(至少在 ok.ru 的情况下是肯定的)。

    3) Ok.ru 网站包含 JavaScript 错误,有时表现奇怪且不一致。

    4)你需要做分页,加载元素等......

    5)包装器给出的API错误将不得不笨拙地处理,例如,像这样(一段实验代码):

    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 看起来是最合理的选择。

  • 有必要保存状态并重新启动系统,处理许多错误,包括站点的不一致行为 - 这些错误非常难以想象(当然,除非您专业地编写解析器)。

此任务的条件时间估计将比从 Habr 收集数据高 3-5 倍。 尽管事实上,在 Habr 的情况下,我们使用了 HTML 解析的前端方法,并且在 OK 的情况下,我们可以在关键位置使用 API。

发现

无论您需要多少时间来“现场”估计大量数据处理管道模块的最后期限(我们今天正在计划!),如果不分析任务参数,执行时间几乎永远不可能定性估计。

从更哲学的角度来看,敏捷估算策略对于工程任务来说效果很好,但是更具实验性的问题,从某种意义上说,“创造性”和探索性的问题,即不太可预测的问题,有困难,如类似主题的示例所示,我们已经在这里讨论过。

当然,数据收集只是一个典型的例子 - 它通常是一项非常简单且技术上并不复杂的任务,而问题往往在于细节。 正是在这项任务中,我们可以展示可能出现问题的所有可能选项以及工作需要多长时间。

如果你在没有额外实验的情况下看一下任务的特征,那么 Reddit 和 OK 看起来很相似:有一个 API,一个 python 包装器,但本质上,差异是巨大的。 从这些参数来看,Habr 的 pars 看起来比 OK 更复杂——但实际上恰恰相反,这正是通过简单的实验来分析问题的参数可以发现的。

根据我的经验,最有效的方法是粗略估计初步分析本身和简单的第一次实验所需的时间,阅读文档 - 这些将使您能够对整个工作做出准确的估计。 按照流行的敏捷方法论,我要求你创建一个“估算任务参数”的工单,在此基础上我可以评估“冲刺”内可以完成的工作,并对每个任务给出更准确的估算任务。

因此,最有效的论点似乎是向“非技术”专家展示多少时间和资源将根据尚未评估的参数而变化。

数据科学可能会出现什么问题? 数据采集

来源: habr.com

添加评论