Google Cloud の R によるデータ サイエンス: 探索的データ分析についてのチュートリアル


このチュートリアルでは、Google Cloud で R を使用してデータ サイエンスを大規模に開始する方法について説明します。このチュートリアルは、R および Jupyter ノートブックの使用経験があり、SQL に関して精通している方を対象としています。

このチュートリアルでは、Vertex AI Workbench ユーザー管理ノートブックと BigQuery を使用した探索的データ分析を実行することに重点を置いて説明します。このチュートリアルのコードは、GitHub 上の Jupyter ノートブックにあります。

概要

R は、統計モデルで最も広く使用されるプログラミング言語の 1 つです。R には、データ サイエンティストと機械学習(ML)の専門家が参加する大規模で活発なコミュニティがあります。Comprehensive R Archive Network(CRAN)のオープンソース リポジトリには 15,000 を超えるパッケージがあり、R には、あらゆる統計的データ分析アプリケーション、ML、可視化のためのツールが用意されています。構文の豊富さと、データと ML ライブラリが包括的であるという理由から、R はこの 20 年で着実に成長してきています。

データ サイエンティストは、R を使用してどのように自身のスキルセットを活かせるか、ML 向けのスケーラブルなフルマネージド型クラウド サービスの利点をどのように活用できるかを知りたいことでしょう。

アーキテクチャ

このチュートリアルでは、ユーザー管理のノートブックをデータ サイエンス環境として使用して、探索的データ分析(EDA)を実行します。チュートリアルでは、BigQuery(Google のスケーラビリティと費用対効果に優れたサーバーレスのクラウド データ ウェアハウス)から抽出したデータに対して R を使用します。データの分析と処理が完了すると、変換されたデータは Cloud Storage に保存され、以降の ML タスクに使用されます。以下の図は、このフローを示しています。

BigQuery からユーザー管理のノートブックへのデータフロー。このフローは R を使用して処理され、結果は Cloud Storage に送信されて、詳細な分析が行われます。

チュートリアル用のデータ

このチュートリアルで使用するデータセットは、BigQuery の出生率データセットです。この公開データセットには、1969 年から 2008 年までに米国で登録された 1 億 3,700 万件を超える出生に関する情報が含まれています。

このチュートリアルでは、EDA と、R および BigQuery を使用した可視化に重点を置きます。このチュートリアルでは、妊娠と新生児の母親に関するいくつかの要因を考慮し、新生児の体重を予測する機械学習の目標を設定します。ただし、そのタスクはこのチュートリアルでは扱いません。

ユーザー管理のノートブック

Vertex AI Workbench ユーザー管理ノートブックは、統合された JupyterLab 環境を提供するサービスです。

  • ワンクリック デプロイ。ワンクリックで、最新の機械学習フレームワークとデータ サイエンス フレームワークを使用して事前構成された JupyterLab インスタンスを起動できます。
  • オンデマンドのスケーリング。小規模なマシン構成(たとえば、このチュートリアルに示す 4 つの vCPU と 15 GB の RAM)から開始できます。データのサイズが 1 台のマシンで扱うには過大になった場合は、CPU、RAM、GPU を追加することでスケールアップできます。
  • Google Cloud との統合。Vertex AI Workbench ユーザー管理ノートブック インスタンスは、BigQuery などの Google Cloud サービスと統合されています。この統合により、データの取り込みから前処理、探索を容易に行うことができます。
  • 従量課金。最低料金や事前の契約はありません。Vertex AI Workbench ユーザー管理ノートブックの料金をご覧ください。また、ユーザー管理ノートブック インスタンスで使用する Google Cloud リソースの料金も発生します。

ユーザー管理のノートブックは、Deep Learning VM Image で実行されます。これらのイメージは、PyTorch や TensorFlow などの ML フレームワークをサポートするように最適化されています。このチュートリアルは、R 3.6 を持つユーザー管理ノートブック インスタンスの作成をサポートしています。

R を使用して BigQuery を操作する

BigQuery ではインフラストラクチャ管理が不要なため、有意な分析情報の発見に集中できます。BigQuery では使い慣れた SQL によってデータを処理できるため、データベース管理者を必要としません。BigQuery を使用すると、大量のデータを大規模に分析でき、BigQuery の豊富な SQL 分析機能を使用して ML 用のデータセットを準備できます。

R を使用して BigQuery データをクエリするには、オープンソースの R ライブラリである bigrquery を使用します。bigrquery パッケージは、BigQuery の上に次の抽象化レベルを設定します。

  • 低レベル API には、基盤となる BigQuery REST API の上にシンラッパーが用意されています。

  • DBI インターフェースは、低レベル API をラップし、BigQuery を他のデータベース システムと同じように操作できるようにします。これは、BigQuery で SQL クエリを行う場合や、100 MB 未満のアップロードを行う場合に最も有用なレイヤです。

  • dbplyr インターフェースを使用すると、BigQuery テーブルを、メモリ内データフレームと同様に処理できます。これは、SQL の作成を回避しつつ、dbplyr による自動書き込みを設定する場合に最も有用なレイヤです。

このチュートリアルでは、DBI や dbplyr を必要としない bigrquery の低レベル API を使用します。

目標

  • R をサポートするユーザー管理ノートブック インスタンスを作成する。
  • bigrquery R ライブラリを使用して、BigQuery のデータをクエリおよび分析する。
  • Cloud Storage で ML 用のデータを準備し、保存する。

料金

このドキュメントでは、Google Cloud の次の課金対象のコンポーネントを使用します。

料金計算ツールを使うと、予想使用量に基づいて費用の見積もりを生成できます。 新しい Google Cloud ユーザーは無料トライアルをご利用いただける場合があります。

始める前に

  1. Google Cloud アカウントにログインします。Google Cloud を初めて使用する場合は、アカウントを作成して、実際のシナリオでの Google プロダクトのパフォーマンスを評価してください。新規のお客様には、ワークロードの実行、テスト、デプロイができる無料クレジット $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 Console で、[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. 2000 年以降の出生のサンプルに関して、予測子の候補とターゲット予測変数をいくつか抽出する BigQuery SQL ステートメントを作成します。

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

    結果のプロットは次のようになります。

    体重と妊娠週の関係を示した散布図。

BigQuery で R を使用してデータを処理する

大規模なデータセットを扱う場合は、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 コマンドの出力は次のようになります。これは、新生児の数を母親の年齢別に示したものです。

    新生児の数を母親の年齢別に示したプロット。

    2 番目の ggplot コマンドの出力は次のようになります。これは、新生児の平均体重を母親の年齢別に示したものです。

    新生児の平均体重を母親の年齢別に示したプロット。

可視化に関するその他の例については、ノートブックをご覧ください。

データを CSV ファイルとして保存する

次のタスクは、BigQuery から抽出したデータを CSV ファイルとして Cloud Storage に保存し、後続の ML タスクで使用できるようにすることです。

  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 を入力し、[シャットダウン] をクリックしてプロジェクトを削除します。

次のステップ