1. はじめに

最終更新日: 2022 年 9 月 22 日
この Codelab では、BigQueryUI と AI Platform Notebooks を使用して、BigQuery に集約された医療データにアクセスして分析するパターンを実装します。このラボでは、HIPPA 準拠の AI Platform Notebooks で、Pandas や Matplotlib などの使い慣れたツールを使用して、大規模なヘルスケア データセットのデータ探索を行う方法について説明します。ポイントは、集計処理の最初の部分を BigQuery で実行して Pandas データセットを取得し、より小規模の Pandas データセットをローカルで処理する点です。AI Platform Notebooks には Jupyter のマネージド環境が用意されているため、ノートブック サーバーを自分で実行する必要はありません。AI Platform Notebooks は、BigQuery や Cloud Storage などの他の GCP サービスと緊密に統合されているため、Google Cloud Platform でのデータ分析と ML の取り組みを迅速かつ簡単に行うことができます。
この Codelab では、次の方法について学びます。
- BigQuery UI を使用して SQL クエリを開発してテストします。
- GCP で AI Platform Notebooks インスタンスを作成して起動します。
- ノートブックから SQL クエリを実行し、クエリ結果を Pandas DataFrame に保存します。
- Matplotlib を使用してグラフを作成する。
- ノートブックを commit して、GCP の Cloud Source Repositories に push します。
この Codelab を実行するには何が必要ですか?
- GCP プロジェクトへのアクセス権が必要です。
- GCP プロジェクトのオーナーのロールが割り当てられている必要があります。
- BigQuery の医療データセットが必要です。
GCP プロジェクトがない場合は、こちらの手順に沿って新しい GCP プロジェクトを作成します。
2. プロジェクトの設定
この Codelab では、BigQuery の既存のデータセット(hcls-testing-data.fhir_20k_patients_analytics)を使用します。このデータセットには、合成医療データが事前入力されています。
合成データセットにアクセスする
- Cloud コンソールへのログインに使用しているメールアドレスから、hcls-solutions-external+subscribe@google.com に参加リクエストを送信します。
- 操作を確認する手順が記載されたメールが届きます。
- メールに返信してグループに参加するオプションを使用します。[
] ボタンはクリックしないでください。 - 確認メールが届いたら、Codelab の次のステップに進みます。
プロジェクトを固定する
- GCP Console でプロジェクトを選択し、BigQuery に移動します。
- [データを追加] プルダウンをクリックし、[プロジェクトを固定] > [プロジェクト名を入力] を選択します。

- プロジェクト名「hcls-testing-data」を入力し、[固定] をクリックします。BigQuery テスト データセット「fhir_20k_patients_analytics」を使用できます。

3. BigQuery UI を使用してクエリを作成する
BigQuery UI の設定
- 左上隅の(ハンバーガー)GCP メニューから [BigQuery] を選択して、BigQuery コンソールに移動します。
- BigQuery コンソールで、[その他] → [クエリの設定] をクリックし、[レガシー SQL] メニューがオンになっていないことを確認します(標準 SQL を使用します)。

クエリを作成する
[クエリエディタ] ウィンドウで、次のクエリを入力し、[実行] をクリックして実行します。次に、[クエリ結果] ウィンドウで結果を確認します。
患者のクエリ
#standardSQL - Query Patients
SELECT
id AS patient_id,
name[safe_offset(0)].given AS given_name,
name[safe_offset(0)].family AS family,
telecom[safe_offset(0)].value AS phone,
birthDate AS birth_date,
deceased.dateTime AS deceased_datetime,
Gender AS fhir_gender_code,
Address[safe_offset(0)].line AS address1_line_1,
Address[safe_offset(0)].city AS address1_city,
Address[safe_offset(0)].state AS address1_state,
Address[safe_offset(0)].postalCode AS address1_postalCode,
Address[safe_offset(0)].country AS address1_country
FROM
`hcls-testing-data.fhir_20k_patients_analytics.Patient` AS Patient
LIMIT 10
「クエリエディタ」のクエリと結果:

クエリの実務担当者
#standardSQL - Query Practitioners
SELECT
id AS practitioner_id,
name[safe_offset(0)].given AS given_name,
name[safe_offset(0)].family AS family_name,
gender
FROM
`hcls-testing-data.fhir_20k_patients_analytics.Practitioner`
LIMIT 10
クエリ結果:

組織をクエリする
データセットと一致するように組織 ID を変更します。
#standardSQL - Query Organization
SELECT
id AS org_id,
type[safe_offset(0)].text AS org_type,
name AS org_name,
address[safe_offset(0)].line AS org_addr,
address[safe_offset(0)].city AS org_addr_city,
address[safe_offset(0)].state AS org_addr_state,
address[safe_offset(0)].postalCode AS org_addr_postalCode,
address[safe_offset(0)].country AS org_addr_country
FROM
`hcls-testing-data.fhir_20k_patients_analytics.Organization` AS Organization
WHERE
id = "b81688f5-bd0e-3c99-963f-860d3e90ab5d"
クエリ結果:

患者によるエンカウンターのクエリ
#standardSQL - Query Encounters by Patient
SELECT
id AS encounter_id,
period.start AS encounter_start,
period.end AS encounter_end,
status AS encounter_status,
class.code AS encounter_type,
subject.patientId as patient_id,
participant[safe_OFFSET(0)].individual.practitionerId as parctitioner_id,
serviceProvider.organizationId as encounter_location_id,
type[safe_OFFSET(0)].text AS encounter_reason
FROM
`hcls-testing-data.fhir_20k_patients_analytics.Encounter` AS Encounter
WHERE
subject.patientId = "900820eb-4166-4981-ae2d-b183a064ac18"
ORDER BY
encounter_end
クエリ結果:

GET AVG LENGTH OF ENCOUNTERS BY ENCOUNTER TYPE
#standardSQL - Get Average length of Encounters by Encounter type
SELECT
class.code encounter_class,
ROUND(AVG(TIMESTAMP_DIFF(TIMESTAMP(period.end), TIMESTAMP(period.start), HOUR)),1) as avg_minutes
FROM
`hcls-testing-data.fhir_20k_patients_analytics.Encounter` AS Encounter
WHERE
period.end >= period.start
GROUP BY
1
ORDER BY
2 DESC
クエリ結果:

A1C レートが 6.5 以上のすべての患者を取得
# Query Patients who have A1C rate >= 6.5
SELECT
id AS observation_id,
subject.patientId AS patient_id,
context.encounterId AS encounter_id,
value.quantity.value,
value.quantity.unit,
code.coding[safe_offset(0)].code,
code.coding[safe_offset(0)].display AS description
FROM
`hcls-testing-data.fhir_20k_patients_analytics.Observation`
WHERE
code.text like '%A1c/Hemoglobin%' AND
value.quantity.value >= 6.5 AND
status = 'final'
クエリ結果:

4. AI Platform Notebooks インスタンスを作成する
このリンクの手順に沿って、新しい AI Platform Notebooks(JupyterLab)インスタンスを作成します。
Compute Engine API を有効にしてください。
[デフォルトのオプションで新しいノートブックを作成する] または [新しいノートブックを作成し、オプションを指定する] を選択できます。
5. データ分析ノートブックを構築する
AI Platform Notebooks インスタンスを開く
このセクションでは、新しい Jupyter ノートブックを最初から作成してコーディングします。
- Google Cloud Platform Console で AI Platform Notebooks のページに移動して、ノートブック インスタンスを開きます。AI PLATFORM NOTEBOOKS のページに移動
- 開きたいインスタンスの [JupyterLab を開く] を選択します。

- AI Platform Notebooks により、ノートブック インスタンスの URL に自動的に移動します

ノートブックを作成する
- JupyterLab で、[File] -> [New] -> [Notebook] に移動し、ポップアップでカーネル「Python 3」を選択するか、ランチャー ウィンドウの [Notebook] セクションで「Python 3」を選択して、Untitled.ipynb ノートブックを作成します。

- Untitled.ipynb を右クリックし、ノートブックの名前を「fhir_data_from_bigquery.ipynb」に変更します。ダブルクリックして開き、クエリを作成して、ノートブックを保存します。
- ノートブックをダウンロードするには、*.ipynb ファイルを右クリックして、メニューから [ダウンロード] を選択します。

- 既存のノートブックをアップロードするには、上矢印ボタンをクリックします。

ノートブックの各コードブロックをビルドして実行する
このセクションで提供されている各コードブロックを 1 つずつコピーして実行します。コードを実行するには、[実行](三角形)をクリックします。

エンカウンターの滞在時間を取得(時間単位)
from google.cloud import bigquery
client = bigquery.Client()
lengthofstay="""
SELECT
class.code as encounter_class,
period.start as start_timestamp,
period.end as end_timestamp,
TIMESTAMP_DIFF(TIMESTAMP(period.end), TIMESTAMP(period.start), HOUR)
as length_of_stay_in_hours
FROM
`hcls-testing-data.fhir_20k_patients_analytics.Encounter`
WHERE
period.end >= period.start
ORDER BY
4 DESC
LIMIT 10
"""
df = client.query(lengthofstay).to_dataframe()
df.head()
コードと実行出力:

観測値を取得する - コレステロール値
observation="""
SELECT
cc.code loinc_code,
cc.display loinc_name,
approx_quantiles(round(o.value.quantity.value,1),4) as quantiles,
count(*) as num_obs
FROM
`hcls-testing-data.fhir_20k_patients_analytics.Observation` o, o.code.coding cc
WHERE
cc.system like '%loinc%' and lower(cc.display) like '%cholesterol%'
GROUP BY 1,2
ORDER BY 4 desc
"""
df2 = client.query(observation).to_dataframe()
df2.head()
実行出力:

近似遭遇分位点を取得する
encounters="""
SELECT
encounter_class,
APPROX_QUANTILES(num_encounters, 4) num_encounters_quantiles
FROM (
SELECT
class.code encounter_class,
subject.reference patient_id,
COUNT(DISTINCT id) AS num_encounters
FROM
`hcls-testing-data.fhir_20k_patients_analytics.Encounter`
GROUP BY
1,2
)
GROUP BY 1
ORDER BY 1
"""
df3 = client.query(encounters).to_dataframe()
df3.head()
実行出力:

エンカウントの平均時間(分)を取得する
avgstay="""
SELECT
class.code encounter_class,
ROUND(AVG(TIMESTAMP_DIFF(TIMESTAMP(period.end), TIMESTAMP(period.start), MINUTE)),1) as avg_minutes
FROM
`hcls-testing-data.fhir_20k_patients_analytics.Encounter`
WHERE
period.end >= period.start
GROUP BY
1
ORDER BY
2 DESC
"""
df4 = client.query(avgstay).to_dataframe()
df4.head()
実行出力:

患者ごとのエンカウンタを取得する
patientencounters="""
SELECT
id AS encounter_id,
period.start AS encounter_start,
period.end AS encounter_end,
status AS encounter_status,
class.code AS encounter_type,
subject.patientId as patient_id,
participant[safe_OFFSET(0)].individual.practitionerId as parctitioner_id,
serviceProvider.organizationId as encounter_location_id,
type[safe_OFFSET(0)].text AS encounter_reason
FROM
`hcls-testing-data.fhir_20k_patients_analytics.Encounter` AS Encounter
WHERE
subject.patientId = "900820eb-4166-4981-ae2d-b183a064ac18"
ORDER BY
encounter_end
"""
df5 = client.query(patientencounters).to_dataframe()
df5.head()
実行出力:

組織を取得する
orgs="""
SELECT
id AS org_id,
type[safe_offset(0)].text AS org_type,
name AS org_name,
address[safe_offset(0)].line AS org_addr,
address[safe_offset(0)].city AS org_addr_city,
address[safe_offset(0)].state AS org_addr_state,
address[safe_offset(0)].postalCode AS org_addr_postalCode,
address[safe_offset(0)].country AS org_addr_country
FROM
`hcls-testing-data.fhir_20k_patients_analytics.Organization` AS Organization
WHERE
id = "b81688f5-bd0e-3c99-963f-860d3e90ab5d"
"""
df6 = client.query(orgs).to_dataframe()
df6.head()
実行結果:

患者の取得
patients="""
SELECT
id AS patient_id,
name[safe_offset(0)].given AS given_name,
name[safe_offset(0)].family AS family,
telecom[safe_offset(0)].value AS phone,
birthDate AS birth_date,
deceased.dateTime AS deceased_datetime,
Gender AS fhir_gender_code,
Address[safe_offset(0)].line AS address1_line_1,
Address[safe_offset(0)].city AS address1_city,
Address[safe_offset(0)].state AS address1_state,
Address[safe_offset(0)].postalCode AS address1_postalCode,
Address[safe_offset(0)].country AS address1_country
FROM
`hcls-testing-data.fhir_20k_patients_analytics.Patient` AS Patient
LIMIT 10
"""
df7 = client.query(patients).to_dataframe()
df7.head()
実行結果:

6. AI Platform Notebooks でグラフを作成する
ノートブック「fhir_data_from_bigquery.ipynb」のコードセルを実行して、棒グラフを描画します。
たとえば、エンカウンターの平均時間を分単位で取得します。
df4.plot(kind='bar', x='encounter_class', y='avg_minutes');
コードと実行結果:

7. ノートブックを Cloud Source Repositories に commit する
- GCP Console で、[ソース リポジトリ] に移動します。初めて使用する場合は、[使ってみる]、[リポジトリを作成] の順にクリックします。

- 次回以降は、GCP -> Cloud Source Repositories に移動し、[+ リポジトリを追加] をクリックして新しいリポジトリを作成します。

- [新しいリポジトリを作成] を選択し、[続行] をクリックします。
- [リポジトリ名] と [プロジェクト名] を指定して、[作成] をクリックします。

- [ローカル Git リポジトリにリポジトリのクローンを作成] を選択し、[手動で生成した認証情報] を選択します。
- ステップ 1 の「Git 認証情報を生成して保存する」の手順(下記参照)に沿って操作します。画面に表示されたスクリプトをコピーします。

- Jupyter でターミナル セッションを開始します。

- [Configure Git] ウィンドウのすべてのコマンドを Jupyter ターミナルに貼り付けます。
- GCP Cloud Source Repositories からリポジトリのクローンパスをコピーします(下のスクリーンショットのステップ 2)。

- このコマンドを JupiterLab ターミナルに貼り付けます。コマンドは次のようになります。
git clone https://source.developers.google.com/p/<your -project-name>/r/my-ai-notebooks
- Jupyterlab に「my-ai-notebooks」フォルダが作成されます。

- ノートブック(fhir_data_from_bigquery.ipynb)をフォルダ「my-ai-notebooks」に移動します。
- Jupyter ターミナルで、ディレクトリを「cd my-ai-notebooks」に変更します。
- Jupyter ターミナルを使用して変更をステージングします。Jupyter UI を使用することもできます([Untracked] 領域のファイルを右クリックして [Track] を選択すると、ファイルが [Tracked] 領域に移動します。逆も同様です)。変更されたファイルが含まれています)。
git remote add my-ai-notebooks https://source.developers.google.com/p/<your -project-name>/r/my-ai-notebooks

- Jupyter ターミナルまたは Jupyter UI を使用して変更を commit します(メッセージを入力して、[チェック済み] ボタンをクリックします)。
git commit -m "message goes here"
- Jupyter ターミナルまたは Jupyter UI(「コミットされた変更を push」アイコン
をクリック)を使用して、変更をリモート リポジトリに push します。
git push --all
- GCP Console で、[ソース リポジトリ] に移動します。my-ai-notebooks をクリックします。「fhir_data_from_bigquery.ipynb」が GCP Source Repository に保存されました。

8. クリーンアップ
この Codelab で使用したリソースに対して Google Cloud Platform アカウントに課金されないように、チュートリアルを完了したら、GCP で作成したリソースをクリーンアップして、割り当てを使い果たすことなく、それらのリソースに課金されないようにします。次のセクションで、このようなリソースを削除または無効にする方法を説明します。
BigQuery データセットの削除
このチュートリアルで作成した BigQuery データセットを削除するには、次の手順を行います。または、テスト データセット fhir_20k_patients_analytics を使用した場合は、BigQuery コンソールに移動して、プロジェクト hcls-testing-data のピンを外します。
AI Platform Notebooks インスタンスをシャットダウンする
このリンク ノートブック インスタンスをシャットダウンする | AI Platform Notebooks の手順に沿って、AI Platform Notebooks インスタンスをシャットダウンします。
プロジェクトの削除
課金をなくす最も簡単な方法は、チュートリアル用に作成したプロジェクトを削除することです。
プロジェクトを削除するには、次の操作を行います。
- GCP Console で [プロジェクト] ページに移動します。プロジェクト ページに移動
- プロジェクト リストで、削除するプロジェクトを選択し、[削除] をクリックします。
- ダイアログにプロジェクト ID を入力し、[シャットダウン] をクリックしてプロジェクトを削除します。
9. 完了
お疲れさまでした。BigQuery と AI Platform Notebooks を使用して FHIR 形式の医療データにアクセスし、クエリを実行して分析するコードラボを完了しました。
GCP で一般公開の BigQuery データセットにアクセスしました。
BigQuery UI を使用して SQL クエリを開発し、テストした。
AI Platform Notebooks インスタンスを作成して起動した。
JupyterLab で SQL クエリを実行し、クエリ結果を Pandas DataFrame に保存しました。
Matplotlib を使用してグラフを作成した。
ノートブックを GCP の Cloud Source Repositories に commit して push した。
これで、Google Cloud Platform の BigQuery と AI Platform Notebooks を使用して医療データ分析を開始するために必要な主な手順を理解できました。
©Google, Inc. or its affiliates. All rights reserved. Do not distribute.