このチュートリアルでは、Linux についての基本的な知識があることを前提としています。また、Google Cloud および、FHIR 仕様と電子カルテシステム(EHR)におけるその使用についての基本的な知識があると有益です。このチュートリアルのコマンドはすべて、Cloud Shell で実行します。
目標
費用
このチュートリアルでは、課金対象である次の Google Cloud コンポーネントを使用します。料金計算ツールを使用すると、予想使用量に基づいて費用の見積もりを生成できます。
始める前に
Cloud Healthcare API の使用はすべて、Google Cloud プロジェクトのコンテキスト内で行われます。プロジェクトは、API の管理、課金の有効化、共同編集者の追加と削除、Google Cloud リソースに対する権限の管理など、すべての Google Cloud サービスの作成、有効化、使用の基礎となります。次の手順を行い、Google Cloud プロジェクトを作成するか、作成済みのプロジェクトを選択します。-
In the Google Cloud console, go to the project selector page.
-
Select or create a Google Cloud project.
-
Make sure that billing is enabled for your Google Cloud project.
-
Enable the Cloud Healthcare API.
-
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
コマンドを実行して、Cloud Healthcare API 関連の機能を含む最新バージョンの gcloud CLI があることを確認します。
このドキュメントに記載されているタスクの完了後、作成したリソースを削除すると、それ以上の請求は発生しません。詳細については、クリーンアップをご覧ください。
IAM サービス アカウントを作成する
このチュートリアルには、Healthcare Dataset 管理者、FHIR 管理者、FHIR リソース編集者のロールが必要です。次の手順でサービス アカウントを作成し、適切なロールを割り当てます。
- サービス アカウントを作成します。
-
- Healthcare Dataset 管理者
- 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 リソースは、Key-Value ペアを含む JSON に似たオブジェクトです。いくつかの要素は標準化されていますが、フリーテキストの要素もあります。匿名化オペレーションを使用して次のことができます。
- FHIR リソース内の特定キーの値を削除する。
- 非構造化テキストを処理して PII 要素のみを削除し、テキストの残りの部分はそのままにする。
データセットの匿名化を行う場合、匿名化 API 呼び出しを行う前に、宛先データセットが存在しないようにする必要があります。匿名化オペレーションにより、宛先データセットが作成されます。
単一の FHIR ストアを匿名化する場合は、匿名化 API 呼び出しを行う前に、宛先データセットが存在している必要があります。
ソース データセット、FHIR ストア、宛先データセットの FHIR ストアは、同じ Google Cloud プロジェクト内に存在する必要があります。匿名化オペレーションを実行すると、宛先データセットと FHIR ストアは、ソース データセットおよび FHIR ストアと同じ Google Cloud プロジェクトに作成されます。
合成 FHIR データを生成して、このチュートリアルで使用する場合は、Synthea を使用して FHIR STU3 形式で合成データを生成し、生成されたデータを Cloud Storage バケットにコピーして、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 プロジェクトの識別子です。$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 患者リソースを 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 リソースの例に対応しています。
{ "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 ストアに挿入します。出力で患者 ID(id
)が生成されます。患者 ID は、FHIR 患者リソースにリンクするために FHIR Encounter リソースで使用される匿名化された英数字の文字列です。次のコマンドで 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 Encounter リソースである FHIR リソースの例に対応しています。
{ "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
コマンドにより、新しい Encounter リソースがソース FHIR ストアに挿入されます。
FHIR データの匿名化
次に、ソース FHIR ストアに挿入した FHIR データを匿名化します。Patient.name
フィールドや Patient.address
フィールドなど、構造化フィールド内のすべての PII 要素を秘匿化または変換します。また、Encounter.reason.text
など、テキスト内の非構造化データ内の PII 要素を匿名化します。
必要に応じて、結果データを BigQuery に直接エクスポートして、分析と機械学習のトレーニングに使用できます。
この匿名化の構成は、公衆衛生分析または同様のユースケースに使用できます。このチュートリアルのコンテキストでは、匿名化された構造化データを BigQuery に移動して、大規模な動向を評価できます。大規模な正規化と分析が困難である非構造化フィールドは不要な場合があります。このチュートリアルでは、参考として非構造化フィールドを含めます。
FHIR データを匿名化するユースケースは、数多く考えられます。また、Cloud Healthcare API でサポートされている構成オプションも多数あります。サンプル curl
コマンドや、さまざまなシナリオにおける Tools for PowerShell の使用例などについては、FHIR データの匿名化をご覧ください。
日付を含むフィールドは、日付シフトによって変換されます。これは、FHIR リソース内のすべての日付を、一貫したランダムな数値で変更する手法です。日付シフトは FHIR リソース内で整合性を維持するため、患者の年齢や予約間隔など、医療関連の詳細情報が、患者の識別情報を明らかにすることなく維持されます。非構造化フィールドのすべての識別子も変換されます。
次の例には、name
フィールドのハッシュ変換も含まれています。ハッシュ化は、常に名前が同じ出力値に変換され、データセット内の複数のレコード間で同じ患者名に対して一貫した出力を生成する一方向暗号化手法です。このオペレーションでは、リソース間のリンクも保持しながら、PII を難読化します。
この例の、指定された暗号鍵 U2FsdGVkX19bS2oZsdbK9X5zi2utBn22uY+I2Vo0zOU=
は、サンプルの AES 暗号化された 256 ビットの Base64 エンコード鍵で、次のコマンドを使用して生成されます。
echo -n "test" | openssl enc -e -aes-256-ofb -a -salt
コマンドから、パスワードの入力を求めるメッセージが表示されます。任意のパスワードを入力します。
name
フィールドやaddress
フィールドなど、構造化フィールド内のすべての PII 要素を秘匿化または変換し、非構造化フィールド内のすべての識別子を変換するには、curl
コマンドを使用します。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 患者リソースの詳細を取得します。
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 データの匿名化。
- BigQuery への FHIR リソースのエクスポート。
- Cloud Healthcare API のドキュメント。
- パンデミック時の医療およびライフ サイエンス関連組織を支える Cloud Healthcare API とその他のソリューション。
- Google Cloud に関するリファレンス アーキテクチャ、図、ベスト プラクティスを確認する。Cloud Architecture Center を確認する。