本教學課程假設您具備 Linux 的基本知識。此外,對 Google Cloud 和FHIR 規格有基本瞭解,並知道 FHIR 規格在電子健康記錄 (EHR) 系統中的用途,也會很有幫助。請在 Cloud Shell 中執行本教學課程中的所有指令。
目標
費用
本教學課程使用下列 Google Cloud的計費元件:如要根據預測用量估算費用,請使用 Pricing Calculator。
事前準備
所有 Cloud Healthcare API 用量都會發生在Google Cloud 專案的環境中。專案是建立、啟用及使用所有Google Cloud 服務的基本要件,例如管理 API、啟用計費功能、新增及移除協作者,以及管理 Google Cloud資源的權限。請按照下列步驟建立 Google Cloud 專案,或選取您已建立的專案。-
In the Google Cloud console, go to the project selector page.
-
Select or create a Google Cloud project.
Roles required to select or create a project
- Select a project: Selecting a project doesn't require a specific IAM role—you can select any project that you've been granted a role on.
-
Create a project: To create a project, you need the Project Creator
(
roles/resourcemanager.projectCreator
), which contains theresourcemanager.projects.create
permission. Learn how to grant roles.
-
Verify that billing is enabled for your Google Cloud project.
-
Enable the Cloud Healthcare API.
Roles required to enable APIs
To enable APIs, you need the Service Usage Admin IAM role (
roles/serviceusage.serviceUsageAdmin
), which contains theserviceusage.services.enable
permission. Learn how to grant roles. -
In the Google Cloud console, activate Cloud Shell.
At the bottom of the Google Cloud console, a Cloud Shell session starts and displays a command-line prompt. Cloud Shell is a shell environment with the Google Cloud CLI already installed and with values already set for your current project. It can take a few seconds for the session to initialize.
- 在 Cloud Shell 中執行
gcloud components update
指令,確認您使用的是最新版 gcloud CLI,其中包含 Cloud Healthcare API 相關功能。
完成本文所述工作後,您可以刪除已建立的資源,避免繼續計費。詳情請參閱清除所用資源一節。
建立 IAM 服務帳戶
本教學課程需要「醫療保健資料集管理員」、「FHIR 管理員」和「FHIR 資源編輯者」角色。請按照下列步驟建立服務帳戶並指派正確的角色:
- 建立服務帳戶。
-
- Healthcare 資料集管理員
- Healthcare FHIR 管理員
- Healthcare FHIR 資源編輯者
啟用服務帳戶金鑰:
gcloud auth activate-service-account --key-file=path-to-key-file
輸出內容如下:
Activated service account credentials for: [key-name@project-name.iam.gserviceaccount.com]
key-name
是您指派給服務帳戶金鑰的名稱。project-name
是您的 Google Cloud 專案名稱。
取得 OAuth 2.0 存取權杖
如要使用 Cloud Healthcare API 擷取資料,您需要 OAuth 2.0 存取權杖,本教學課程中的指令會為您取得這項權杖。在本教學課程中,部分 Cloud Healthcare API 要求範例會使用 curl
指令列工具。這些範例會使用 gcloud auth print-access-token
指令取得 OAuth 2.0 不記名憑證,並將該憑證納入要求的授權標頭。如要進一步瞭解這個指令,請參閱 gcloud auth application-default print-access-token
。
設定 FHIR 資料集以進行去識別化
每個 FHIR 資源都是類似 JSON 的物件,內含鍵/值組合。部分元素是標準化元素,其他元素則是任意文字。您可以使用去識別化作業執行下列操作:
- 移除 FHIR 資源中特定鍵的值。
- 處理非結構化文字,只移除 PII 元素,文字中的其餘內容則維持不變。
對資料集去識別化時,目的地資料集不得在您呼叫去識別化 API 前存在。去識別化作業會建立目的地資料集。
對單一 FHIR 儲存庫執行去識別化作業時,您必須先建立目的地資料集,才能發出去識別化 API 呼叫。
來源資料集、FHIR 儲存庫和目的地資料集的 FHIR 儲存庫必須位於相同的 Google Cloud 專案。執行去識別化作業時,系統會在與來源資料集和 FHIR 儲存庫相同的 Google Cloud 專案中,建立目的地資料集和 FHIR 儲存庫。
如要產生合成 FHIR 資料以用於本教學課程,可以使用 Synthea,以 FHIR STU3 格式產生合成資料,然後將產生的資料複製到 Cloud Storage bucket,再匯入 Cloud Healthcare API FHIR 儲存庫。Synthea 不會產生含有任意或非結構化文字元件的 FHIR 資料,因此無法用來探索去識別化作業的這些層面。
在本教學課程中,您會按照下列程序,將範例 FHIR 資料匯入 FHIR 儲存庫。
為專案和位置設定環境變數,以便儲存資料集、FHIR 存放區和 FHIR 資料。指派給環境變數的值是範例值,如下所示:
export PROJECT_ID=MyProj export REGION=us-central1 export SOURCE_DATASET_ID=dataset1 export FHIR_STORE_ID=FHIRstore1 export DESTINATION_DATASET_ID=deid-dataset1
先前範例中宣告的環境變數定義如下:
$PROJECT_ID
是您的 Google Cloud 專案 ID。$REGION
是您建立 Cloud Healthcare API 資料集的 Google Cloud 地區。$SOURCE_DATASET_ID
是儲存來源資料的 Cloud Healthcare API 資料集名稱。$FHIR_STORE_ID
是來源 Cloud Healthcare API FHIR 存放區的名稱。$DESTINATION_DATASET_ID
是 Cloud Healthcare API 目的地資料集的名稱,去識別化資料會寫入該資料集。
您也會在本教學課程稍後使用這些環境變數。
建立 Cloud Healthcare API 資料集:
gcloud healthcare datasets create $SOURCE_DATASET_ID --location=$REGION
輸出內容類似於下列內容,其中
[OPERATION_NUMBER]
是用於追蹤要求的資料集建立作業 ID:Create request issued for: $SOURCE_DATASET_ID Waiting for operation [OPERATION_NUMBER] to complete...done. Created dataset $SOURCE_DATASET_ID.
上述指令會在
$REGION
區域中建立名為$SOURCE_DATASET_ID
的來源資料集。使用下列指令建立 FHIR 儲存庫:
gcloud healthcare fhir-stores create $FHIR_STORE_ID \ --dataset=$SOURCE_DATASET_ID --location=$REGION
上述指令會在資料集
$SOURCE_DATASET_ID
中建立名為$FHIR_STORE_ID
的 FHIR 儲存庫。使用下列指令,透過 FHIR
create
函式將 FHIR Patient 資源新增至 FHIR 存放區:curl -X POST \ -H "Authorization: Bearer $(gcloud auth print-access-token)" \ -H "Content-Type: application/fhir+json; charset=utf-8" \ --data "{ \"address\": [ { \"city\": \"Anycity\", \"district\": \"Anydistrict\", \"line\": [ \"123 Main Street\" ], \"period\": { \"start\": \"1990-12-05\" }, \"postalCode\": \"12345\", \"state\": \"CA\", \"text\": \"123 Main Street Anycity, Anydistrict, CA 12345\", \"use\": \"home\" } ], \"name\": [ { \"family\": \"Smith\", \"given\": [ \"Darcy\" ], \"use\": \"official\" } ], \"gender\": \"female\", \"birthDate\": \"1980-12-05\", \"resourceType\": \"Patient\" }" \ "https://healthcare.googleapis.com/v1/projects/$PROJECT_ID/locations/$REGION/datasets/$SOURCE_DATASET_ID/fhirStores/$FHIR_STORE_ID/fhir/Patient"
指令的引數對應至範例 FHIR 資源,也就是 FHIR Patient 資源。
{ "address": [ { "city": "Anycity", "district": "Anydistrict", "line": [ "123 Main Street" ], "period": { "start": "1990-12-05" }, "postalCode": "12345", "state": "CA", "text": "123 Main Street Anycity, Anydistrict, CA 12345", "use": "home" } ], "name": [ { "family": "Smith", "given": [ "Darcy" ], "use": "official" } ], "gender": "female", "birthDate": "1980-12-05", "resourceType": "Patient" }
如果要求成功,伺服器會傳回類似下列內容的輸出內容:
{ "address": [ { "city": "Anycity", "district": "Anydistrict", "line": [ "123 Main Street" ], "period": { "start": "1990-12-05" }, "postalCode": "12345", "state": "CA", "text": "123 Main Street Anycity, Anydistrict, CA 12345", "use": "home" } ], "birthDate": "1980-12-05", "gender": "female", "id": "0359c226-5d63-4845-bd55-74063535e4ef", "meta": { "lastUpdated": "2020-02-08T00:03:21.745220+00:00", "versionId": "MTU4MTEyMDIwMTc0NTIyMDAwMA" }, "name": [ { "family": "Smith", "given": [ "Darcy" ], "use": "official" } ], "resourceType": "Patient" }
上述
curl
指令會在來源 FHIR 存放區中插入新的 Patient 資源。輸出內容會產生病患 ID (id
)。病患 ID 是去識別化的英數字串,用於 FHIR Encounter 資源,連結至 FHIR Patient 資源。使用下列指令,透過 FHIR
create
函式將 FHIR Encounter 資源新增至 FHIR 儲存庫。在指令中,將subject.reference
值替換為先前curl
指令輸出中的病患 ID 值:curl -X POST \ -H "Authorization: Bearer $(gcloud auth print-access-token)" \ -H "Content-Type: application/fhir+json; charset=utf-8" \ --data "{ \"status\": \"finished\", \"class\": { \"system\": \"http://hl7.org/fhir/v3/ActCode\", \"code\": \"IMP\", \"display\": \"inpatient encounter\" }, \"reason\": [ { \"text\": \"Mrs. Smith is a 39-year-old female who has a past medical history significant for a myocardial infarction. Catheterization showed a possible kink in one of her blood vessels.\" } ], \"subject\": { \"reference\": \"Patient/0359c226-5d63-4845-bd55-74063535e4ef\" }, \"resourceType\": \"Encounter\" }" \ "https://healthcare.googleapis.com/v1/projects/$PROJECT_ID/locations/$REGION/datasets/$SOURCE_DATASET_ID/fhirStores/$FHIR_STORE_ID/fhir/Encounter"
指令的引數對應範例 FHIR 資源,也就是 FHIR Encounter 資源:
{ "status": "finished", "class": { "system": "http://hl7.org/fhir/v3/ActCode", "code": "IMP", "display": "inpatient encounter" }, "reason": [ { "text": "Mrs. Smith is a 39-year-old female who has a past medical history significant for a myocardial infarction. Catheterization showed a possible kink in one of her blood vessels." } ], "subject": { "reference": "Patient/0359c226-5d63-4845-bd55-74063535e4ef" }, "resourceType": "Encounter" }
如果要求成功,伺服器會傳回類似下列內容的輸出內容:
{ "class": { "code": "IMP", "display": "inpatient encounter", "system": "http://hl7.org/fhir/v3/ActCode" }, "id": "0038a95f-3c11-4163-8c2e-10842b6b1547", "meta": { "lastUpdated": "2020-02-12T00:39:16.822443+00:00", "versionId": "MTU4MTQ2Nzk1NjgyMjQ0MzAwMA" }, "reason": [ { "text": "Mrs. Smith is a 39-year-old female who has a past medical history significant for a myocardial infarction. Catheterization showed a possible kink in one of her blood vessels." } ], "resourceType": "Encounter", "status": "finished", "subject": { "reference": "Patient/0359c226-5d63-4845-bd55-74063535e4ef" }
上述
curl
指令會在來源 FHIR 存放區中插入新的 Encounter 資源。
將 FHIR 資料去識別化
接著,您要對插入來源 FHIR 儲存庫的 FHIR 資料執行去識別化作業。
您會遮蓋或轉換結構化欄位中的所有 PII 元素,例如 Patient.name
和 Patient.address
欄位。您也可以將文字中非結構化資料的 PII 元素去識別化,例如 Encounter.reason.text
。
您可以選擇將結果資料直接匯出至 BigQuery,以進行分析和機器學習訓練。
這項去識別化設定可用於人口健康分析或類似用途。在本教學課程中,您可以將去識別化的結構化資料移至 BigQuery,評估大規模趨勢。您可能不需要非結構化欄位,因為這類欄位難以大規模正規化和分析。不過,本教學課程仍會納入非結構化欄位,以供參考。
將 FHIR 資料去識別化有許多潛在用途,Cloud Healthcare API 也支援許多設定選項。如需更多資訊,包括範例 curl
指令和不同情境的 PowerShell 工具範例,請參閱去識別化 FHIR 資料。
含有日期的欄位會透過日期轉移轉換,這項技術會將 FHIR 資源中的所有日期,以一致的隨機量變更。日期偏移功能可確保 FHIR 資源內的一致性,因此可保留醫療相關詳細資料 (例如病患年齡和預約間隔時間),同時不會揭露病患的識別資訊。非結構化欄位中的所有 ID 也會轉換。
以下範例也包含 name
欄位的雜湊轉換。雜湊是一種單向加密技術,可確保名稱一律轉換為相同輸出值,並為資料集中的多筆記錄產生一致的病患姓名輸出值。這項作業會遮蓋 PII,同時保留資源之間的連結。
在本範例中,提供的加密金鑰 U2FsdGVkX19bS2oZsdbK9X5zi2utBn22uY+I2Vo0zOU=
是以 AES 加密的 256 位元 Base64 編碼金鑰範例,使用下列指令產生。
echo -n "test" | openssl enc -e -aes-256-ofb -a -salt
系統會要求您輸入密碼。輸入您選擇的密碼。
使用
curl
指令,遮蓋或轉換結構化欄位 (例如name
和address
欄位) 中的所有 PII 元素,以及轉換非結構化欄位中的所有 ID。curl -X POST \ -H "Authorization: Bearer "$(gcloud auth print-access-token) \ -H "Content-Type: application/json; charset=utf-8" \ --data "{ 'destinationDataset': 'projects/$PROJECT_ID/locations/$REGION/datasets/$DESTINATION_DATASET_ID', 'config': { 'fhir': { 'fieldMetadataList': { 'paths': [ 'Patient.address.state', 'Patient.address.line', 'Patient.address.text', 'Patient.address.postalCode' ], 'action': 'TRANSFORM' }, 'fieldMetadataList': { 'paths': [ 'Encounter.reason.text' ], 'action': 'INSPECT_AND_TRANSFORM' }, 'text': { 'transformations': [ { 'infoTypes': [], 'replaceWithInfoTypeConfig': {} } ] }, 'fieldMetadataList': { 'paths': [ 'Patient.name.family', 'Patient.name.given' ], 'action': 'TRANSFORM' }, 'text': { 'transformations': { 'infoTypes': [ 'PERSON_NAME' ], 'cryptoHashConfig': { 'cryptoKey': 'U2FsdGVkX19bS2oZsdbK9X5zi2utBn22uY+I2Vo0zOU=' } } }, 'fieldMetadataList': { 'paths': [ 'Patient.birthDate', 'Patient.address.period.start' ], 'action': 'TRANSFORM' }, 'text': { 'transformations': { 'infoTypes': [ 'DATE' ], 'dateShiftConfig': { 'cryptoKey': 'U2FsdGVkX19bS2oZsdbK9X5zi2utBn22uY+I2Vo0zOU=' } } } } }" "https://healthcare.googleapis.com/v1/projects/$PROJECT_ID/locations/$REGION/datasets/$SOURCE_DATASET_ID:deidentify"
如果要求成功,伺服器會傳回 JSON 格式的回應,如下所示:
{ "name": "projects/$PROJECT_ID/locations/$REGION/datasets/$SOURCE_DATASET_ID/OPERATION_NAME" }
在上述範例中,
curl
指令會透過下列方式轉換值,進而對 FHIR 資源去識別化:- 刪減
Patient.address.line
值、Patient.address.text
值和Patient.address.postalCode
值。 - 將
Patient.name.family
值替換為雜湊值,並將Patient.name.given
值替換為雜湊值。 - 將
Patient.birthDate
欄位和period.start
欄位中的值,替換為日期偏移 100 天後產生的值。 - 在
Encounter.reason.text
欄位中,將病患的姓氏替換為雜湊值,並將病患的年齡替換為字面值[AGE]
。
- 刪減
前述作業的回應包含作業名稱。使用
get
方法追蹤作業狀態:curl -X GET \ -H "Authorization: Bearer "$(gcloud auth print-access-token) \ -H "Content-Type: application/json; charset=utf-8" \ "https://healthcare.googleapis.com/v1/projects/$PROJECT_ID/locations/$REGION/datasets/$SOURCE_DATASET_ID/operations/OPERATION_NAME"
如果要求成功,伺服器會以 JSON 格式傳回回應。去識別化程序完成後,回應中會包含
"done": true
。{ "name": "projects/$PROJECT_ID/locations/$REGION/datasets/$SOURCE_DATASET_ID/operations/OPERATION_NAME", "metadata": { "@type": "type.googleapis.com/google.cloud.healthcare.v1.OperationMetadata", "apiMethodName": "google.cloud.healthcare.v1.dataset.DatasetService.DeidentifyDataset", "createTime": "2018-01-01T00:00:00Z", "endTime": "2018-01-01T00:00:00Z" }, "done": true, "response": { "@type": "...", "successStoreCount": "SUCCESS_STORE_COUNT" } }
上述指令會傳回去識別化作業的狀態。
使用病患 ID 執行下列指令,在新目的地資料集中取得 FHIR Patient 資源的詳細資料:
curl -X GET \ -H "Authorization: Bearer $(gcloud auth print-access-token)" \ "https://healthcare.googleapis.com/v1/projects/$PROJECT_ID/locations/$REGION/datasets/$DESTINATION_DATASET_ID/fhirStores/$FHIR_STORE_ID/fhir/Patient/a952e409-2403-43e6-9815-cb78c5b5eca2/\$everything"
如果要求成功,伺服器會傳回類似下方的回應,這是原始 FHIR 資源的去識別化版本:
"entry": [\ {\ "resource": {\ "class": {\ "code": "IMP",\ "display": "inpatient encounter",\ "system": "http://hl7.org/fhir/v3/ActCode"\ },\ "id": "0038a95f-3c11-4163-8c2e-10842b6b1547",\ "reason": [\ {\ "text": "Mr. NlVBV12Hhb5DD8WNqlTpXboFxzlUSlqAmYDet/jIViQ= is a [AGE] gentleman who has a past medical history significant for a myocardial infarction. Catheterization showed a possible kink in one of his vessels."\ }\ ],\ "resourceType": "Encounter",\ "status": "finished",\ "subject": {\ "reference": "Patient/0359c226-5d63-4845-bd55-74063535e4ef"\ }\ }\ },\ {\ "resource": {\ "address": [\ {\ "city": "Anycity",\ "district": "Anydistrict",\ "line": [\ ""\ ],\ "period": {\ "start": "1990-09-23"\ },\ "postalCode": "",\ "state": "",\ "text": "",\ "use": "home"\ }\ ],\ "birthDate": "1980-09-23",\ "gender": "female",\ "id": "0359c226-5d63-4845-bd55-74063535e4ef",\ "name": [\ {\ "family": "NlVBV12Hhb5DD8WNqlTpXboFxzlUSlqAmYDet/jIViQ=",\ "given": [\ "FSH4e the project.D/IGb80a1rS0L0kqfC3DCDt6//17VPhIkOzH2pk="\ ],\ "use": "official"\ }\ ],\ "resourceType": "Patient"\ }\ }\ ],\ "resourceType": "Bundle",\ "total": 2,\ "type": "searchset"\ }
上述指令會驗證去識別化作業是否成功去識別化 FHIR 資源。
清除所用資源
如要避免系統向您的 Google Cloud 帳戶收取本教學課程中所用資源的相關費用,請刪除含有該項資源的專案,或者保留專案但刪除個別資源。
刪除專案
- In the Google Cloud console, go to the Manage resources page.
- In the project list, select the project that you want to delete, and then click Delete.
- In the dialog, type the project ID, and then click Shut down to delete the project.
刪除個別資源
刪除目的地資料集:
gcloud healthcare datasets delete $DESTINATION_DATASET_ID
後續步驟
- Cloud Healthcare API FHIR 概念。
- 使用 Cloud Healthcare API 將 FHIR 臨床資料匯入雲端。
- 將 FHIR 資料去識別化。
- 將 FHIR 資源匯出至 BigQuery。
- Cloud Healthcare API 說明文件。
- 我們推出的 Cloud Healthcare API 及其他解決方案在疫情期間為醫療照護與生命科學機構提供支援。
- 探索 Google Cloud 的參考架構、圖表和最佳做法。 歡迎瀏覽我們的雲端架構中心。