在 Google Cloud 上使用 R 进行数据科学研究:探索性数据分析教程

Last reviewed 2024-04-16 UTC

本教程介绍如何在 Google Cloud 上使用 R 大规模开始进行数据科学研究。本教程面向拥有 R 和 Jupyter 笔记本经验且熟悉 SQL 的人员。

本教程重点介绍如何使用 Vertex AI Workbench 用户管理的笔记本和 BigQuery 来执行探索性数据分析。您可以在 GitHub 上的 Jupyter 笔记本中找到本教程的代码。

概览

R 是统计建模中使用最广泛的编程语言之一。它拥有一个庞大的活跃数据科学家和机器学习 (ML) 专业人员社区。R 在综合 R 归档网络 (CRAN) 的开源代码库中拥有超过 15,000 个软件包,并且具有用于所有统计数据分析应用、机器学习和可视化的工具。在过去 20 年里,R 因其语法表现力及其数据和机器学习库的全面性而稳定增长。

作为数据科学家,您可能希望了解如何通过 R 使用技能集,以及如何充分利用机器学习的可扩缩全代管式云服务的优势。

架构

在本教程中,您将使用用户管理的笔记本作为数据科学环境,以执行探索性数据分析 (EDA)。您可将 R 用于在本教程中从 BigQuery(Google 推出的无服务器、可扩缩性强且经济实惠的云数据仓库)提取的数据。分析和处理数据后,转换后的数据会存储在 Cloud Storage 中,以用于其他机器学习任务。下图展示了此流程:

从 BigQuery 到用户管理的笔记本数据流,其中的数据使用 R 进行处理,结果将发送到 Cloud Storage 以供进一步分析。

本教程的数据

本教程中使用的数据集是 BigQuery 出生率数据集。此公开数据集包含有关从 1969 年到 2008 年在美国登记的超过 1.37 亿出生婴儿的信息。

本教程重点介绍 EDA 以及如何使用 R 和 BigQuery 可视化。本教程将向您介绍一个机器学习目标,即基于怀孕的几个因素以及婴儿母亲来预测婴儿的体重,但本教程并未介绍该任务。

用户管理的笔记本

Vertex AI Workbench 用户管理的笔记本是一项用于提供集成式 JupyterLab 环境的服务,具有以下功能:

  • 一键式部署。您只需点击一下,即可启动预配置有最新机器学习和数据科学框架的 JupyterLab 实例。
  • 按需扩缩。刚开始时,您可以从小型机器配置(例如,4 个 vCPU 和 15 GB RAM)开始,当您的数据在一台机器中变得太大时,您可以添加 CPU、RAM 和 GPU 来纵向扩容。
  • Google Cloud 集成。Vertex AI Workbench 用户管理的笔记本实例与 BigQuery 等 Google Cloud 服务集成。通过此集成,您可以轻松进行数据提取、预处理和探索。
  • 按用量计费。没有最低费用限制,也不要求预付费用。请参阅 Vertex AI Workbench 用户管理的笔记本的价格。您还需要为用于用户管理的笔记本实例的 Google Cloud 资源付费。

用户管理的笔记本在 Deep Learning VM Image 上运行。 这些映像经过优化,可支持 PyTorch 和 TensorFlow 等机器学习框架。本教程支持创建具有 R 3.6 的用户管理的笔记本实例。

通过 R 使用 BigQuery

BigQuery 不需要基础架构管理,因此您可以专注于挖掘有意义的数据洞见。BigQuery 让您可以使用熟悉的 SQL 来处理数据,因此您无需数据库管理员。您可以使用 BigQuery 大规模分析大量数据,并使用 BigQuery 的丰富 SQL 分析功能为机器学习准备数据集。

要使用 R 查询 BigQuery 数据,您可以使用 bigrquery(开源 R 库)。Bigrquery 软件包在 BigQuery 的基础上提供以下抽象层级:

  • 低层级 API 在底层 BigQuery REST API 上提供瘦封装容器。

  • DBI 接口可封装低层级 API,并让使用 BigQuery 与使用任何其他数据库系统类似。如果希望在 BigQuery 中运行 SQL 查询或上传小于 100 MB 的数据,这是最方便的层。

  • dbplyr 接口让您可像处理内存中数据帧一样处理 BigQuery 表。如果您不想编写 SQL,而是希望 dbplyr 为您编写,那么这是最方便的层。

本教程使用 bigrquery 中的低层级 API,而无需 DBI 或 dbplyr。

目标

  • 创建支持 R 的用户管理的笔记本实例。
  • 使用 bigrquery R 库查询和分析 BigQuery 中的数据。
  • 准备机器学习的数据并将其存储在 Cloud Storage 中。

费用

在本文档中,您将使用 Google Cloud 的以下收费组件:

您可使用价格计算器根据您的预计使用情况来估算费用。 Google Cloud 新用户可能有资格申请免费试用

准备工作

  1. 登录您的 Google Cloud 账号。如果您是 Google Cloud 新手,请创建一个账号来评估我们的产品在实际场景中的表现。新客户还可获享 $300 赠金,用于运行、测试和部署工作负载。
  2. 在 Google Cloud Console 中的项目选择器页面上,选择或创建一个 Google Cloud 项目

    转到“项目选择器”

  3. 确保您的 Google Cloud 项目已启用结算功能

  4. 启用 Compute Engine API。

    启用 API

  5. 在 Google Cloud Console 中的项目选择器页面上,选择或创建一个 Google Cloud 项目

    转到“项目选择器”

  6. 确保您的 Google Cloud 项目已启用结算功能

  7. 启用 Compute Engine API。

    启用 API

创建使用 R 的用户管理的笔记本实例

第一步是创建可用于本教程的用户管理的笔记本实例。

  1. 在 Google Cloud 控制台中,转到 Notebooks 页面。

    转到 Notebooks

  2. 用户管理的笔记本标签页上,点击  新建笔记本

  3. 选择 R 3.6

    选择 R 版本。

  4. 对于本教程,请保留所有默认值,然后点击创建

    创建新笔记本实例。

    用户管理的笔记本实例最多可能需要 90 秒才能启动。准备就绪后,您会看到其已在笔记本实例窗格中列出,并且实例名称旁边会显示打开 JupyterLab 链接:

    实例准备就绪时的控制台。

打开 JupyterLab

要完成笔记本中的教程,您需要打开 JupyterLab 环境,克隆 ml-on-gcp GitHub 代码库,然后打开笔记本。

  1. 在实例列表中,点击打开 Jupyterlab。这将在浏览器中打开 JupyterLab 环境。

    Jupyter 启动器。

  2. 要启动终端标签页,请点击启动器中的终端

  3. 在终端中,克隆 ml-on-gcp GitHub 代码库:

    git clone https://github.com/GoogleCloudPlatform/ml-on-gcp.git
    

    命令完成后,您会在文件浏览器中看到 ml-on-gcp 文件夹。

  4. 在文件浏览器中,依次打开 ml-on-gcptutorialsR.

    克隆的结果如下所示:

    打开 R 文件。

打开笔记本并设置 R

默认情况下,本教程中需要的 R 库(包括 bigrquery)安装在 R 笔记本中。在此过程中,您需要导入它们,供笔记本使用。

  1. 在文件浏览器中,打开 01-EDA-with-R-and-BigQuery.ipynb 笔记本。

    此笔记本介绍了 R 和 BigQuery 的探索性数据分析教程。在本教程中,您将在笔记本中工作,并运行在 Jupyter 笔记本本身中看到的代码。

  2. 导入本教程所需的 R 库:

    library(bigrquery) # used for querying BigQuery
    library(ggplot2) # used for visualization
    library(dplyr) # used for data wrangling
    
  3. 使用带外身份验证对 bigrquery 进行身份验证:

    bq_auth(use_oob = True)
    
  4. 将变量设置为您在本教程中使用的项目名称:

    # Set the project ID
    PROJECT_ID <- "gcp-data-science-demo"
    
  5. 将变量设置为 Cloud Storage 存储桶的名称:

    BUCKET_NAME <- "bucket-name"
    

    bucket-name 替换为全局唯一的名称。

    您稍后使用存储桶来存储输出数据。

从 BigQuery 查询数据

在本教程的这一部分中,您将了解将 BigQuery SQL 语句执行到 R 中的结果,并初步了解数据。

  1. 创建一个 BigQuery SQL 语句,以提取自 2000 年以来的出生婴儿样本作为可能的预测器和目标预测变量:

    sql_query <- "
        SELECT
          ROUND(weight_pounds, 2) AS weight_pounds,
          is_male,
          mother_age,
          plurality,
          gestation_weeks,
          cigarette_use,
          alcohol_use,
          CAST(ABS(FARM_FINGERPRINT(CONCAT(
            CAST(YEAR AS STRING), CAST(month AS STRING),
            CAST(weight_pounds AS STRING)))
            ) AS STRING) AS key
        FROM
            publicdata.samples.natality
        WHERE
          year > 2000
          AND weight_pounds > 0
          AND mother_age > 0
          AND plurality > 0
          AND gestation_weeks > 0
          AND month > 0
        LIMIT %s
    "
    

    key 列是根据 yearmonthweight_pounds 列的串联值生成的行标识符。

  2. 运行查询并将数据作为内存中 data frame 对象检索:

    sample_size <- 10000
    sql_query <- sprintf(sql_query, sample_size)
    
    natality_data <- bq_table_download(
        bq_project_query(
            PROJECT_ID,
            query=sql_query
        )
    )
    
  3. 查看检索到的结果:

    head(natality_data)
    

    输出内容类似如下:

    检索数据帧的结果。

  4. 查看每列的行数和数据类型:

    str(natality_data)
    

    输出内容类似如下:

    Classes ‘tbl_df’, ‘tbl’ and 'data.frame':   10000 obs. of  8 variables:
     $ weight_pounds  : num  7.75 7.4 6.88 9.38 6.98 7.87 6.69 8.05 5.69 9.22 ...
     $ is_male        : logi  FALSE TRUE TRUE TRUE FALSE TRUE ...
     $ mother_age     : int  47 44 42 43 42 43 42 43 45 44 ...
     $ plurality      : int  1 1 1 1 1 1 1 1 1 1 ...
     $ gestation_weeks: int  41 39 38 39 38 40 35 40 38 39 ...
     $ cigarette_use  : logi  NA NA NA NA NA NA ...
     $ alcohol_use    : logi  FALSE FALSE FALSE FALSE FALSE FALSE ...
     $ key            : chr  "3579741977144949713" "8004866792019451772" "7407363968024554640" "3354974946785669169" ...
    
  5. 查看检索到的数据摘要:

    summary(natality_data)
    

    输出内容类似如下:

     weight_pounds     is_male          mother_age     plurality
     Min.   : 0.620   Mode :logical   Min.   :13.0   Min.   :1.000
     1st Qu.: 6.620   FALSE:4825      1st Qu.:22.0   1st Qu.:1.000
     Median : 7.370   TRUE :5175      Median :27.0   Median :1.000
     Mean   : 7.274                   Mean   :27.3   Mean   :1.038
     3rd Qu.: 8.110                   3rd Qu.:32.0   3rd Qu.:1.000
     Max.   :11.440                   Max.   :51.0   Max.   :4.000
     gestation_weeks cigarette_use   alcohol_use         key
     Min.   :18.00   Mode :logical   Mode :logical   Length:10000
     1st Qu.:38.00   FALSE:580       FALSE:8284      Class :character
     Median :39.00   TRUE :83        TRUE :144       Mode  :character
     Mean   :38.68   NA's :9337      NA's :1572
     3rd Qu.:40.00
     Max.   :47.00
    

使用 ggplot2 直观显示数据

在本部分中,您将使用 R 中的 ggplot2 库研究出生率数据集中的某些变量。

  1. 使用直方图显示 weight_pounds 值的分布:

    ggplot(
        data = natality_data,
        aes(x = weight_pounds)
    ) + geom_histogram(bins = 200)
    

    生成的图形类似于以下内容:

    显示体重分布的直方图。

  2. 使用散点图显示 gestation_weeksweight_pounds 之间的关系:

    ggplot(
        data = natality_data,
        aes(x = gestation_weeks, y = weight_pounds)
    ) + geom_point() + geom_smooth(method = "lm")
    

    生成的图形类似于以下内容:

    针对体重的妊娠周数的散点图。

从 R 处理 BigQuery 中的数据

在处理大型数据集时,我们建议您在 BigQuery 中执行尽可能多的分析(聚合、过滤、联接、计算列等),然后检索结果。在 R 中执行这些任务的效率较低。使用 BigQuery 进行分析可利用 BigQuery 的可扩缩性和性能,并确保返回的结果能够适合 R 中的内存。

  1. 创建一个函数,该函数将查找所选列的每个值的记录数和平均体重:

    get_distinct_values <- function(column_name) {
        query <- paste0(
            'SELECT ', column_name, ',
                COUNT(1) AS num_babies,
                AVG(weight_pounds) AS avg_wt
            FROM publicdata.samples.natality
            WHERE year > 2000
            GROUP BY ', column_name)
    
        bq_table_download(
            bq_project_query(
                PROJECT_ID,
                query = query
            )
        )
    }
    
  2. 使用 mother_age 列调用此函数,然后按母亲年龄查看婴儿数量和平均体重:

    df <- get_distinct_values('mother_age')
    ggplot(data = df, aes(x = mother_age, y = num_babies)) + geom_line()
    ggplot(data = df, aes(x = mother_age, y = avg_wt)) + geom_line()
    

    第一个 ggplot 命令的输出如下所示,其中显示了按母亲年龄划分的出生婴儿数量。

    按母亲年龄划分的出生婴儿数量图。

    第二个 ggplot 命令的输出如下所示,其中显示了按母亲年龄划分的婴儿均体重。

    按母亲年龄划分的婴儿平均体重图。

要查看更多可视化示例,请参阅笔记本。

将数据保存为 CSV 文件

下一个任务是将提取的数据从 BigQuery 保存为 Cloud Storage 中的 CSV 文件,以便将其用于其他机器学习任务。

  1. 将训练和评估数据从 BigQuery 加载到 R 中:

    # Prepare training and evaluation data from BigQuery
    sample_size <- 10000
    sql_query <- sprintf(sql_query, sample_size)
    
    train_query <- paste('SELECT * FROM (', sql_query,
      ') WHERE MOD(CAST(key AS INT64), 100) <= 75')
    eval_query <- paste('SELECT * FROM (', sql_query,
      ') WHERE MOD(CAST(key AS INT64), 100) > 75')
    
    # Load training data to data frame
    train_data <- bq_table_download(
        bq_project_query(
            PROJECT_ID,
            query = train_query
        )
    )
    
    # Load evaluation data to data frame
    eval_data <- bq_table_download(
        bq_project_query(
            PROJECT_ID,
            query = eval_query
        )
    )
    
  2. 将数据写入本地 CSV 文件:

    # Write data frames to local CSV files, without headers or row names
    dir.create(file.path('data'), showWarnings = FALSE)
    write.table(train_data, "data/train_data.csv",
       row.names = FALSE, col.names = FALSE, sep = ",")
    write.table(eval_data, "data/eval_data.csv",
       row.names = FALSE, col.names = FALSE, sep = ",")
    
  3. 通过封装传递给系统的 gsutil 命令将 CSV 文件上传到 Cloud Storage:

    # Upload CSV data to Cloud Storage by passing gsutil commands to system
    gcs_url <- paste0("gs://", BUCKET_NAME, "/")
    command <- paste("gsutil mb", gcs_url)
    system(command)
    gcs_data_dir <- paste0("gs://", BUCKET_NAME, "/data")
    command <- paste("gsutil cp data/*_data.csv", gcs_data_dir)
    system(command)
    command <- paste("gsutil ls -l", gcs_data_dir)
    system(command, intern = TRUE)
    

    此步骤的另一个选择是使用 googleCloudStorageR 库通过 Cloud Storage JSON API 执行此操作。

清理

为避免因本教程中使用的资源而导致系统向您的 Google Cloud 账号收取费用,您应该将资源移除。

删除项目

若要避免产生费用,最简单的方法是删除您为本教程创建的项目。

  1. 在 Google Cloud 控制台中,进入管理资源页面。

    转到“管理资源”

  2. 在项目列表中,选择要删除的项目,然后点击删除
  3. 在对话框中输入项目 ID,然后点击关闭以删除项目。

后续步骤