728x90
반응형
  • Machine Learning

빅데이터, Machine Learning, 클라우드, 그리고 Graph Database는 의료 산업을 혁신하고 있어요. 엄청난 양의 관계가 풍부한 의료 데이터가 클라우드의 Graph Database에 저장되고, Machine Learning으로 처리되죠. 그 결과, 우리는 인체에 대해 훨씬 더 깊이 이해하게 돼요. 이러한 지식은 더 나은 예방, 더 정확한 진단, 그리고 더 효과적인 치료로 이어질 거예요.

기술 발전은 의료를 민주화하기도 해요. 비용을 낮추고 의료 절차를 더 효율적이고 광범위하게 만들어서 저소득층도 혜택을 누릴 수 있게 해주죠. 뿐만 아니라 모든 사람이 민간 및 공공 의료 데이터에 더 쉽게 접근할 수 있도록 해줘요. 후자의 중요성은 종종 간과되곤 하는데요. Eric Topol은 자신의 책에서 이렇게 말했어요.

이러한 정보 비대칭은 환자에게 불리하게 작용하는 경우가 많아요. 자신의 의료 기록과 연구 결과에 대한 완전한 접근 권한이 없고, 데이터를 이해하는 소프트웨어 도구도 없는 환자들은 전적으로 의사에게 의존하게 되죠. 이 경우, 의사만이 예방, 진단, 치료를 결정하게 돼요. 심지어 의사들조차도 데이터 접근이 제한되어 어려움을 겪는 경우가 많답니다.

디지털화가 되어있지 않다면 손으로 작성한 의료 기록과 이미지를 쉽게 이용하거나 의사 간에 전송할 수도 없겠죠. 이는 행정 업무와 의료 절차의 낭비적인 중복으로 이어질 수 있어요. 반면에, 최신 의학 연구가 전문직 전반에 너무 느리게 확산되어 많은 의사들이 그로부터 거의 혜택을 받지 못하고 있는 실정이에요.

이러한 신념과 영감을 바탕으로, 네 명의 Neo4j 엔지니어와 저는 싱가포르 헬스케어 AI 데이터톤 및 EXPO 2021에서 Doctor.ai를 만들었어요. Doctor.ai는 Graph Database인 Neo4j와 AWS를 기반으로 하는 음성 가상 비서랍니다. 이 도우미는 대량의 의료 기록을 그래프로 매핑하고, GDS(Graph Data Science) 라이브러리를 사용해서 치료법을 추천할 수 있어요.

그림 1: Doctor.ai의 개념.

Doctor.ai는 작은 데이터톤 프로젝트지만, 공유할 만한 기술적인 내용들이 정말 많아요. 이전 기사에서 Doctor.ai의 설정 단계를 자세히 설명했었죠. 이번 글에서는 챗봇 내부가 어떻게 작동하는지 좀 더 깊이 파헤쳐 볼게요.

Doctor.ai의 데이터, 아키텍처, 그리고 내부 작동 방식

Doctor.ai를 개발하기 위해 eICU 데이터베이스를 사용했어요. 이 데이터베이스는 2014년부터 2015년까지 미국에서 139,000명 이상의 환자로부터 수집한 200,000건의 ICU 기록을 담고 있죠. 테이블도 엄청 많고요. 원본 데이터 외에도, 전처리된 데이터베이스인 eicu_crd_derived도 함께 제공돼요. 데이터베이스에서 실험 결과, 진단, 치료, 인구 통계 정보, 그리고 다른 메타데이터들을 찾을 수 있어요. 데이터톤에서는 6개의 테이블에 있는 모든 정보를 Neo4j로 가져왔어요 (그림 2). 덕분에 각 ICU 입원에 대한 포괄적인 그림을 그릴 수 있었죠.

AWS에 인프라를 구축하기 시작했어요. AuraDB나 Neo4j 퍼블릭 AMI 대신, EC2 인스턴스에 커스텀 Neo4j 설치를 선택했는데, AMI 기본 설정이 너무 제한적이었거든요. Lex는 Doctor.ai의 Natural Language Understanding 엔진이었어요. Neo4j 데이터베이스에 **쿼리**하기 위해, 사용자는 Doctor.ai에 질문을 말하거나 입력했죠. 사용자 의도를 파악하면 Lex는 Lambda 함수를 트리거해서 Neo4j에 대한 **쿼리**를 수행했어요. CI/CD 기반의 React 프론트엔드 Simple Chatbot React는 Lucas Bassetti가 만들었고, Amplify에서 호스팅해서 클라이언트에게 서비스를 제공했답니다 (그림 3).

그림 3: Doctor.ai의 AWS 아키텍처.

EC2와 Amplify 설정은 정말 간단했어요. 코딩 작업 대부분은 Lex와 Lambda에서 이루어졌죠. Lex는 마치 AI 마법으로 모든 일상적인 대화를 이해하는 것처럼 보일 수도 있지만, 사실 Lex는 특수한 봇이에요. 미리 정의된 몇 가지 의도만 이해할 수 있고, 프로그래머가 각 의도를 직접 구현해야 해요.

 

의도(Intent), 발화(Utterance), 슬롯(Slot)은 챗봇 개발에서 중요한 세 가지 개념인데요, 하나씩 살펴볼까요? 의도는 사용자가 챗봇에게 바라는 목표예요. 예를 들어, 사용자가 특정 환자가 ICU를 방문한 횟수를 알고 싶어할 수 있죠. 이걸 챗봇이 수행하려면 사용자는 챗봇에게 어떤 언어적 표현을 사용해야 하는데, 이걸 발화라고 해요.

예를 들어, 사용자는 "환자 ABC가 ICU를 몇 번 방문했어?" 또는 "ABC 환자의 ICU 방문 횟수를 알려줘"라고 말할 수 있어요. 둘 다 환자 ABC의 ICU 방문 횟수를 묻는 거죠. 이때 환자의 이름은 슬롯이 돼요. 슬롯은 쿼리 범위를 좁히는 데 사용되는데, 현재 또는 이전 발화에서 값을 가져와야 해요. 그렇지 않으면 Doctor.ai가 추가 질문을 던질 거예요. 환자 이름이 확인되면 Doctor.ai는 ICU 방문 횟수를 계산하려고 시도하겠죠.

 

Lex에서 의도는 챗봇의 "의도" 페이지에서 정의할 수 있어요 (그림 4). 각 의도는 샘플 발화, 슬롯, 그리고 이행 작업으로 구성돼요. 사용자가 Doctor.ai에게 어떤 발화를 입력하면, Doctor.ai는 사용자의 의도를 분류하려고 시도해요. 분류에 성공하고 모든 슬롯이 채워지면 Doctor.ai가 이행 작업을 수행하죠. 만약 사용자의 의도가 명확하지 않다면, 대체 의도를 정의해야 해요.

그림 4: Doctor.ai의 "의도" 페이지.

"CountICUVisit" Intent를 통해 Intent를 설정하는 방법을 알아볼게요. 이 의도는 환자가 ICU를 몇 번 방문했는지 묻는 것이죠. 먼저 8개의 샘플 발화를 정의했어요. 즉, 사용자가 이 의도를 충족시키기 위해 이러한 표현 중 하나를 사용할 가능성이 높다는 거죠. Lex는 프로덕션 환경에서 다른 유사한 발화를 인식할 수 있도록 이 샘플들을 통해 학습해요. 우리는 환자 한 명의 방문 횟수만 알고 싶기 때문에 환자의 이름을 슬롯으로 설정했고요.

그림 5: "CountICUVisit" Intent.

일반적인 대화에서는 환자의 이름을 계속 반복할 필요가 없죠. 처음 발언에서 언급되면, 양쪽 모두 이후 대화에서 누구를 언급하는지 알게 되잖아요 (그림 6). Lex에서는 "컨텍스트(Context)"를 통해 이걸 설정할 수 있어요 (그림 7). Doctor.ai에게 환자의 ICU 방문 횟수를 묻기 전에 이미 "ProvideName" 또는 "CheckFirstICUVisit" Intent에서 환자의 이름을 알려줬을 수도 있겠죠. 그래서 "입력 컨텍스트(Input Context)"에서 이 두 컨텍스트를 켤 수 있어요. 그리고 Lex에게 해당 "이름" 슬롯이 이 두 컨텍스트에서 값을 얻을 수 있다는 것을 알려주는 거죠 (그림 8). "CountICUVisit" Intent는 이후 대화의 입력 컨텍스트가 될 수도 있으므로, "출력 컨텍스트(Output Context)"에서도 "이름" 값을 "출력"해요 (그림 7).

그림 6: 슬롯 값은 컨텍스트를 통해 제공될 수 있습니다.

그림 7: 컨텍스트 설정.

그림 8: 이름 슬롯은 컨텍스트에서 해당 값을 가져올 수 있습니다.

Lex가 설정되면 "Fulfilment"에서 Lambda를 구성할 수 있어요. Lex는 별칭을 통해 Lambda에 연결되죠 (그림 9).

그림 9: Lex 별칭의 Lambda.

Lex는 발화를 수신하면 "이벤트" 객체를 Lambda 함수로 전송해요. 이는 인텐트의 이름이 포함된 JSON 객체인데요. 그런 다음 Lambda는 해당 함수를 호출해서 적절한 응답을 생성하죠. CountICUVisit에서 Lambda는 다음 Cypher를 사용해서 Neo4j를 쿼리합니다.

그런 다음 Lambda는 결과를 다음과 같은 응답 발화에 통합해요.

Lambda는 이 응답을 Lex(그림 6)로 다시 보내서 이 "호출 및 응답" 주기를 끝내요.

다른 의도들도 비슷하게 처리되었어요. "Hello", "ProvideName", "Fallback" 같은 것들은 훨씬 간단했죠. 가장 어려웠던 건 '치료 추천' 의도였는데, 이 의도를 통해 의사는 Doctor.ai에게 환자에게 맞는 치료법을 추천해달라고 요청하게 돼요. 저희는 먼저 실험실 결과를 바탕으로 환자 간의 코사인 유사성을 계산했어요.

그리고 대상 환자에 대한 추천을 해야 할 때가 되면 Doctor.ai는 먼저 나이 차이가 10보다 적고 유사도가 0.9 이상인 동성 환자를 찾아요. 그 유사 환자가 같은 질병을 앓았지만 대상 환자에게는 새로운 치료법을 받았다면, 그걸 제안하는 거죠.

모든 설정이 끝나고 봇을 구축한 다음, 프론트엔드와 연결했어요. React 프론트엔드는 간단한 챗봇 반응 (Lucas Bassetti)을 기반으로 만들어졌어요. AWS 자격 증명과 환경 매개변수 형태의 다른 데이터를 사용해서 Lex와 통신하죠. Chrome 브라우저를 사용해서 음성을 입력하고, "speak-tts" 패키지를 사용해서 응답을 음성화했어요.

그림 10: React 프론트엔드의 치료 권장 사항.

마지막으로 “의 지침에 따라 Doctor.ai를 직접 설정할 수 있어요. AI 기반 의료용 가상 음성 도우미 Doctor.ai.”

결론

Google의 오픈 도메인 챗봇인 Meena와 달리 Doctor.ai는 전문적인 챗봇이에요. 의료 정보학에만 초점을 맞추고 있죠. 따라서 개발자들은 의료 관련 기능을 강화하는 데 노력을 집중할 수 있어요. 현재 Doctor.ai에는 몇 가지 기본적인 기능이 있지만, 앞으로 더 많은 기능이 필요할 거예요.

예를 들어, 실험실 결과가 정상 범위를 벗어나면 경고음이 울릴 수 있도록 하는 거죠. Hetionet과 같은 Knowledge Graph를 활용해서 치료 추천을 향상시킬 수도 있어야 하고요. 의료 기록과 Hetionet이 모두 Neo4j에 저장되어 있으니까, 둘 다 병합을 시도해 볼 수도 있겠죠? 그렇게 하면 Graph Database가 아닌 다른 데이터베이스에서는 너무 복잡한 Queries를 수행할 수 있게 될 거예요.

Doctor.ai의 음성 상호작용도 개선이 필요해요. Chrome은 우리의 받아쓰기를 선택할 수 있었지만 오류가 너무 잦았어요. 반면에 "speak-tts" 패키지는 "ICU"와 같은 많은 약어를 제대로 처리하지 못해서 일부 답변을 이해하기 어렵게 만들었죠. Alan Voice AI 플랫폼은 입력을 즉시 수정하고 인상적인 정확도를 보여주니까, Alan으로 전환하는 것도 하나의 옵션이 될 수 있을 것 같아요.

현재 Doctor.ai는 AWS를 사용하고 있는데, 이러한 의존은 미래에 양날의 검이 될 수 있어요. AWS는 가장 큰 클라우드 제공업체이므로 오랫동안 사업을 계속할 거라고 기대할 수 있지만, Lex는 AWS가 언제든지 수정하거나 종료할 수 있는 SaaS일 뿐이니까요. 따라서 오픈 소스 솔루션으로의 전환을 고려해야 할 수도 있어요. 하지만 언어 AI 훈련은 자본 집약적이라서 소수의 기관만이 감당할 수 있다는 점도 고려해야겠죠.

데이터톤 프로젝트로서 Doctor.ai는 기능성 의료 챗봇이 우리 손에 닿을 수 있다는 것을 보여줬어요. 하지만 얼마나 빨리 국가 의료 시스템의 일부가 될 수 있을까요? 이는 기술적인 문제일 뿐만 아니라 정치적, 윤리적인 문제이기도 해요. 하지만 개별 환자나 의사는 이 가상 비서를 개인적으로 사용해서 자신의 의료 기록을 관리할 수 있으니, 상향식 채택도 가능할 수 있겠죠.


흥미로우신가요? 그래프 기술이 의료 및 기타 생활 서비스에 어떻게 도움이 되는지 자세히 알아보세요.

사용 사례 확인

  • AWS
  • 닥터에이아이
  • Lex
  • Machine Learning

에이치시스템즈LogTree는 Neo4j 기반 GraphRAG 플랫폼으로, 데이터를 자동으로 지식그래프화하고 자연어 질의로 즉시 답을 제공합니다.

👉 에이치시스템즈 홈페이지

728x90
반응형

+ Recent posts