이 가이드는 Linux에 대한 기본적인 지식을 필요로 합니다. Google Cloud와 FHIR 사양, 전자 의료 기록 시스템(EHRs)에서 사양의 역할에 대한 기본적인 내용을 숙지하고 있는 것도 도움이 됩니다. 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 데이터 세트 관리자, 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 Bearer 토큰을 가져오고 요청의 승인 헤더에 포함합니다. 이 명령어에 대한 자세한 내용은 gcloud auth application-default print-access-token
을 참조하세요.
익명화에 FHIR 데이터 세트 설정
각 FHIR 리소스는 키-값 쌍을 포함하는 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 프로젝트 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]
는 요청을 추적하는 데 사용되는 데이터 세트 생성 작업 식별자입니다.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
)가 생성됩니다. 환자 식별자는 FHIR 환자 리소스에 연결하도록 FHIR Encounter 리소스에서 사용되는 익명화된 영숫자 문자열입니다.다음 명령어와 함께 FHIR
create
함수를 사용하여 FHIR Encounter 리소스를 FHIR 스토어에 추가합니다. 명령어에서subject.reference
값을 위curl
명령어의 출력에 있는 환자 식별자 값으로 바꿉니다.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 데이터를 익명화합니다.
Patient.name
필드 및 Patient.address
필드와 같은 구조화된 필드에서 모든 PII 요소를 수정하거나 변환합니다. 또한 텍스트에서 구조화되지 않은 데이터의 PII 요소(예: Encounter.reason.text
)를 익명화합니다.
원하는 경우 결과 데이터를 BigQuery에 직접 내보내 분석 및 머신러닝 학습에 사용할 수 있습니다.
이러한 익명화 구성은 인구 건강 분석이나 유사한 사용 사례에 사용될 수 있습니다. 이 가이드의 컨텍스트에서 익명화되고 구조화된 데이터를 BigQuery로 이동하여 대규모 추세를 평가할 수 있습니다. 대규모로 정규화 및 분석하기 어려운 구조화되지 않은 필드가 필요하지 않을 수 있습니다. 하지만 구조화되지 않은 필드는 차조로 이 가이드에 포함되어 있습니다.
FHIR 데이터를 익명화하는 사용 사례에는 여러 가지가 있습니다. 또한 Cloud Healthcare API는 다양한 구성 옵션을 지원합니다. 다양한 시나리오의 샘플 curl
명령어와 PowerShell용 도구 예시를 포함한 자세한 내용은 FHIR 데이터 익명화를 참조하세요.
날짜가 포함된 필드는 날짜 이동을 통해 변환됩니다. 이는 FHIR 리소스의 모든 날짜를 일관된 임의의 시간만큼 변경하는 기법입니다. 날짜 이동은 FHIR 리소스 내에서 일관되게 수행되므로 환자 관련 식별 정보를 공개하지 않고도 환자 나이 및 예약 기간과 같은 의료 관련 세부정보가 유지됩니다. 구조화되지 않은 필드에 있는 모든 식별자도 변환됩니다.
다음 예시에는 name
필드에 대한 해싱 변환도 포함됩니다. 해싱은 이름을 항상 동일한 출력 값으로 변환하여 데이터 세트 내 여러 레코드에서 동일한 환자 이름의 출력을 일관되게 생성하는 단방향 암호화 기술입니다.
이 작업에서는 리소스 간의 링크를 유지하면서 PII를 숨깁니다.
이 예시에서 제공된 암호화 키 U2FsdGVkX19bS2oZsdbK9X5zi2utBn22uY+I2Vo0zOU=
는 다음 명령어를 사용하여 생성된 샘플 AES 암호화 256 비트 base64 인코딩 키입니다.
echo -n "test" | openssl enc -e -aes-256-ofb -a -salt
명령어에서 비밀번호를 입력하라는 메시지가 표시됩니다. 원하는 비밀번호를 입력합니다.
curl
명령어를 사용하여name
필드 및address
필드와 같은 구조화된 필드의 모든 PII 요소를 수정하거나 변환하고 구조화되지 않은 필드의 모든 식별자를 변환합니다.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" } }
위 명령어는 익명화 작업 상태를 반환합니다.
다음 명령어를 실행하고 환자 식별자를 사용하여 새 대상 데이터 세트 내 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 데이터 익명화
- FHIR 리소스를 BigQuery에 내보내기
- Cloud Healthcare API 문서
- 팬데믹 동안 의료 및 생명 과학 조직을 지원하는 Google Cloud Healthcare API 및 기타 솔루션
- Google Cloud에 대한 참조 아키텍처, 다이어그램, 튜토리얼, 권장사항을 살펴봅니다. Cloud 아키텍처 센터를 살펴보세요.